From boqun.feng at gmail.com  Fri Nov  1 00:01:53 2024
From: boqun.feng at gmail.com (Boqun Feng)
Date: Fri,  1 Nov 2024 00:01:53 -0700
Subject: [RFC v2.1 11/13] rust: sync: Add memory barriers
In-Reply-To: <20241101060237.1185533-12-boqun.feng@gmail.com>
References: <20241101060237.1185533-12-boqun.feng@gmail.com>
Message-ID: <20241101070153.1197484-1-boqun.feng@gmail.com>

Memory barriers are building blocks for concurrent code, hence provide
a minimal set of them.

The compiler barrier, barrier(), is implemented in inline asm instead of
using core::sync::atomic::compiler_fence() because memory models are
different: kernel's atomics are implemented in inline asm therefore the
compiler barrier should be implemented in inline asm as well.

Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
---
v2 -> v2.1: Add the missing barrier.c

 rust/helpers/barrier.c      | 18 ++++++++++
 rust/helpers/helpers.c      |  1 +
 rust/kernel/sync.rs         |  1 +
 rust/kernel/sync/barrier.rs | 67 +++++++++++++++++++++++++++++++++++++
 4 files changed, 87 insertions(+)
 create mode 100644 rust/helpers/barrier.c
 create mode 100644 rust/kernel/sync/barrier.rs

diff --git a/rust/helpers/barrier.c b/rust/helpers/barrier.c
new file mode 100644
index 000000000000..cdf28ce8e511
--- /dev/null
+++ b/rust/helpers/barrier.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <asm/barrier.h>
+
+void rust_helper_smp_mb(void)
+{
+	smp_mb();
+}
+
+void rust_helper_smp_wmb(void)
+{
+	smp_wmb();
+}
+
+void rust_helper_smp_rmb(void)
+{
+	smp_rmb();
+}
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index ab5a3f1be241..f4a94833b29d 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -8,6 +8,7 @@
  */
 
 #include "atomic.c"
+#include "barrier.c"
 #include "blk.c"
 #include "bug.c"
 #include "build_assert.c"
diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
index 66ac3752ca71..0d0b19441ae8 100644
--- a/rust/kernel/sync.rs
+++ b/rust/kernel/sync.rs
@@ -9,6 +9,7 @@
 
 mod arc;
 pub mod atomic;
+pub mod barrier;
 mod condvar;
 pub mod lock;
 mod locked_by;
diff --git a/rust/kernel/sync/barrier.rs b/rust/kernel/sync/barrier.rs
new file mode 100644
index 000000000000..277aa09747bf
--- /dev/null
+++ b/rust/kernel/sync/barrier.rs
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Memory barriers.
+//!
+//! These primitives have the same semantics as their C counterparts: and the precise definitions of
+//! semantics can be found at [`LKMM`].
+//!
+//! [`LKMM`]: srctree/tools/memory-mode/
+
+/// A compiler barrier.
+///
+/// An explicic compiler barrier function that prevents the compiler from moving the memory
+/// accesses either side of it to the other side.
+pub fn barrier() {
+    // By default, Rust inline asms are treated as being able to access any memory or flags, hence
+    // it suffices as a compiler barrier.
+    //
+    // SAFETY: An empty asm block should be safe.
+    unsafe {
+        core::arch::asm!("");
+    }
+}
+
+/// A full memory barrier.
+///
+/// A barrier function that prevents both the compiler and the CPU from moving the memory accesses
+/// either side of it to the other side.
+pub fn smp_mb() {
+    if cfg!(CONFIG_SMP) {
+        // SAFETY: `smp_mb()` is safe to call.
+        unsafe {
+            bindings::smp_mb();
+        }
+    } else {
+        barrier();
+    }
+}
+
+/// A write-write memory barrier.
+///
+/// A barrier function that prevents both the compiler and the CPU from moving the memory write
+/// accesses either side of it to the other side.
+pub fn smp_wmb() {
+    if cfg!(CONFIG_SMP) {
+        // SAFETY: `smp_wmb()` is safe to call.
+        unsafe {
+            bindings::smp_wmb();
+        }
+    } else {
+        barrier();
+    }
+}
+
+/// A read-read memory barrier.
+///
+/// A barrier function that prevents both the compiler and the CPU from moving the memory read
+/// accesses either side of it to the other side.
+pub fn smp_rmb() {
+    if cfg!(CONFIG_SMP) {
+        // SAFETY: `smp_rmb()` is safe to call.
+        unsafe {
+            bindings::smp_rmb();
+        }
+    } else {
+        barrier();
+    }
+}
-- 
2.45.2



From boqun.feng at gmail.com  Fri Nov  1 00:04:09 2024
From: boqun.feng at gmail.com (Boqun Feng)
Date: Fri, 1 Nov 2024 00:04:09 -0700
Subject: [RFC v2 11/13] rust: sync: Add memory barriers
In-Reply-To: <CABVgOSn1eeZo7HggJYNEzzuGGpKABF=NbyMZLQbNjRwCAKXY-w@mail.gmail.com>
References: <20241101060237.1185533-1-boqun.feng@gmail.com>
 <20241101060237.1185533-12-boqun.feng@gmail.com>
 <CABVgOSn1eeZo7HggJYNEzzuGGpKABF=NbyMZLQbNjRwCAKXY-w@mail.gmail.com>
Message-ID: <ZyR9aTAhtCdpdC-h@boqun-archlinux>

On Fri, Nov 01, 2024 at 02:55:23PM +0800, David Gow wrote:
> On Fri, 1 Nov 2024 at 14:07, Boqun Feng <boqun.feng at gmail.com> wrote:
> >
> > Memory barriers are building blocks for concurrent code, hence provide
> > a minimal set of them.
> >
> > The compiler barrier, barrier(), is implemented in inline asm instead of
> > using core::sync::atomic::compiler_fence() because memory models are
> > different: kernel's atomics are implemented in inline asm therefore the
> > compiler barrier should be implemented in inline asm as well.
> >
> > Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
> > ---
> >  rust/helpers/helpers.c      |  1 +
> >  rust/kernel/sync.rs         |  1 +
> >  rust/kernel/sync/barrier.rs | 67 +++++++++++++++++++++++++++++++++++++
> >  3 files changed, 69 insertions(+)
> >  create mode 100644 rust/kernel/sync/barrier.rs
> >
> > diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
> > index ab5a3f1be241..f4a94833b29d 100644
> > --- a/rust/helpers/helpers.c
> > +++ b/rust/helpers/helpers.c
> > @@ -8,6 +8,7 @@
> >   */
> >
> >  #include "atomic.c"
> > +#include "barrier.c"
> 
> It looks like "barrier.c" is missing, so this isn't compiling for me.
> I assume it was meant to be added in this patch...?
> 

Yes, I just send an updated one.

Glad being "checking missing files" buddies with you ;-) Thanks!

Regards,
Boqun

> Thanks,
> -- David




From krzk at kernel.org  Fri Nov  1 00:51:11 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 1 Nov 2024 08:51:11 +0100
Subject: [PATCH RFC net-next 1/3] dt-bindings: net: Add support for
 Sophgo SG2044 dwmac
In-Reply-To: <20241101014327.513732-2-inochiama@gmail.com>
References: <20241101014327.513732-1-inochiama@gmail.com>
 <20241101014327.513732-2-inochiama@gmail.com>
Message-ID: <uzr6gpmyng3irrhuf3q3bvswlbzyxnr74jwccyosplr32ceczu@jjrva67iq4ce>

On Fri, Nov 01, 2024 at 09:43:25AM +0800, Inochi Amaoto wrote:
> The GMAC IP on SG2044 is almost a standard Synopsys DesignWare
> MAC (version 5.30a) with some extra clock.
> 
> Add necessary compatible string for this device.
> 
> Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
> ---
>  .../devicetree/bindings/net/snps,dwmac.yaml   |   4 +
>  .../bindings/net/sophgo,sg2044-dwmac.yaml     | 124 ++++++++++++++++++
>  2 files changed, 128 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
> 

I wish patches for review were not marked as RFC. I remember this
patch, so I don't consider this as RFC... but that's rather exception.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From inochiama at gmail.com  Fri Nov  1 02:44:27 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Fri, 1 Nov 2024 17:44:27 +0800
Subject: [PATCH RFC net-next 1/3] dt-bindings: net: Add support for
 Sophgo SG2044 dwmac
In-Reply-To: <uzr6gpmyng3irrhuf3q3bvswlbzyxnr74jwccyosplr32ceczu@jjrva67iq4ce>
References: <20241101014327.513732-1-inochiama@gmail.com>
 <20241101014327.513732-2-inochiama@gmail.com>
 <uzr6gpmyng3irrhuf3q3bvswlbzyxnr74jwccyosplr32ceczu@jjrva67iq4ce>
Message-ID: <hlnvrmxos77rw4fftwnyg6q2sfjgvx4vlzdvyuf7kwiuamcvpa@llfuqlijev6t>

On Fri, Nov 01, 2024 at 08:51:11AM +0100, Krzysztof Kozlowski wrote:
> On Fri, Nov 01, 2024 at 09:43:25AM +0800, Inochi Amaoto wrote:
> > The GMAC IP on SG2044 is almost a standard Synopsys DesignWare
> > MAC (version 5.30a) with some extra clock.
> > 
> > Add necessary compatible string for this device.
> > 
> > Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
> > ---
> >  .../devicetree/bindings/net/snps,dwmac.yaml   |   4 +
> >  .../bindings/net/sophgo,sg2044-dwmac.yaml     | 124 ++++++++++++++++++
> >  2 files changed, 128 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
> > 
> 
> I wish patches for review were not marked as RFC. I remember this
> patch, so I don't consider this as RFC... but that's rather exception.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> 
> Best regards,
> Krzysztof
> 

Sorry for the change to RFC. I was told to switch to RFC as it
has a unmerged dependency since v2. Thanks for your review tag
and apology for the confusion.

Regards,
Inochi


From andrew at lunn.ch  Fri Nov  1 05:40:00 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 1 Nov 2024 13:40:00 +0100
Subject: [PATCH] riscv: dts: sophgo: Add ethernet configuration for cv18xx
In-Reply-To: <nkydxanwucqmbzzz2fb24xyelrouj6gvhuuou2ssbf4tvvhfea@6uiuueim7m3a>
References: <20241028011312.274938-1-inochiama@gmail.com>
 <87e215a7-0b27-4336-9f9c-e63ade0772ef@lunn.ch>
 <wgggariprpp2wczsljy3vw6kp7vhnrifg6soxdgiio2seyctym@4owbzlg3ngum>
 <ftfp2rwkytqmzruogcx66d5qkn4tzrgyjtlz4hdduxhwit3tok@kczgzrjdxx46>
 <e389a60d-2fe3-46fd-946c-01dd3a0a0f6f@lunn.ch>
 <nkydxanwucqmbzzz2fb24xyelrouj6gvhuuou2ssbf4tvvhfea@6uiuueim7m3a>
Message-ID: <5b08e092-c302-43a9-a04d-3566bec96e94@lunn.ch>

> > > > > > +			mdio {
> > > > > > +				compatible = "snps,dwmac-mdio";
> > > > > > +				#address-cells = <1>;
> > > > > > +				#size-cells = <0>;
> > > > > > +
> > > > > > +				phy0: phy at 0 {
> > > > > > +					compatible = "ethernet-phy-ieee802.3-c22";
> > > > > > +					reg = <0>;
> > > > > > +				};
> > > > > > +			};
> > > > > 
> > > > > It is not clear to me what cv18xx.dtsi represents, 
> > > > 
> > > > This is a include file to define common ip for the whole
> > > > cv18xx series SoCs (cv1800b, cv1812h, sg2000, sg2000).
> > > > 
> > > > > and where the PHY node should be, here, or in a .dts file. 
> > > > > Is this a SOM, and the PHY is on the SOM? 
> > > > 
> > > > The phy is on the SoC, it is embedded, and no external phy
> > > > is supported. So I think the phy node should stay here, not 
> > > > in the dts file.
> > > 
> > > There is a mistake, Some package supports external rmii/mii
> > > phy. So I will move this phy definition to board specific.
> > 
> > When there is an external PHY, does the internal PHY still exists? If
> > it does, it should be listed, even if it is not used.
> > 
> > Do the internal and external PHY share the same MDIO bus? 
> 
> They share the same MDIO bus and phy id setting.

What do you mean by phy ID?

> When an external phy
> is select, the internal one is not initialized and can not be accessed
> by the SoC.
> 
> > I've seen some SoCs with complex MDIO muxes for internal vs external
> > PHYs.
> > 
> > 	Andrew
> 
> There is a switch register on the SoC to decide which phy/mode is used. 
> By defaut is internal one with rmii mode. I think a driver is needed to
> handle this properly.

This sounds like a complex MDIO mux. You should think about this now,
because others have left this same problem too late and ended up with
a complex design in order to keep backwards compatibility with old DT
blobs which don't actually describe the real hardware.

	Andrew


From broonie at kernel.org  Fri Nov  1 06:07:57 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 1 Nov 2024 13:07:57 +0000
Subject: [PATCH v3 03/14] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <20241009154953.1073471-4-seanjc@google.com>
References: <20241009154953.1073471-1-seanjc@google.com>
 <20241009154953.1073471-4-seanjc@google.com>
Message-ID: <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk>

On Wed, Oct 09, 2024 at 08:49:42AM -0700, Sean Christopherson wrote:
> Return a uint64_t from vcpu_get_reg() instead of having the caller provide
> a pointer to storage, as none of the vcpu_get_reg() usage in KVM selftests
> accesses a register larger than 64 bits, and vcpu_set_reg() only accepts a
> 64-bit value.  If a use case comes along that needs to get a register that
> is larger than 64 bits, then a utility can be added to assert success and
> take a void pointer, but until then, forcing an out param yields ugly code
> and prevents feeding the output of vcpu_get_reg() into vcpu_set_reg().

This commit, which is in today's -next as 5c6c7b71a45c9c, breaks the
build on arm64:

aarch64/psci_test.c: In function ?host_test_system_off2?:
aarch64/psci_test.c:247:9: error: too many arguments to function ?vcpu_get_reg?
  247 |         vcpu_get_reg(target, KVM_REG_ARM_PSCI_VERSION, &psci_version);
      |         ^~~~~~~~~~~~
In file included from aarch64/psci_test.c:18:
include/kvm_util.h:705:24: note: declared here
  705 | static inline uint64_t vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id)
      |                        ^~~~~~~~~~~~
At top level:
cc1: note: unrecognized command-line option ?-Wno-gnu-variable-sized-type-not-at
-end? may have been intended to silence earlier diagnostics

since the updates done to that file did not take account of 72be5aa6be4
("KVM: selftests: Add test for PSCI SYSTEM_OFF2") which has been merged
in the kvm-arm64 tree.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241101/737fd895/attachment.sig>

From miguel.ojeda.sandonis at gmail.com  Fri Nov  1 07:30:01 2024
From: miguel.ojeda.sandonis at gmail.com (Miguel Ojeda)
Date: Fri, 1 Nov 2024 15:30:01 +0100
Subject: [RFC v2 00/13] LKMM *generic* atomics in Rust
In-Reply-To: <20241101060237.1185533-1-boqun.feng@gmail.com>
References: <20241101060237.1185533-1-boqun.feng@gmail.com>
Message-ID: <CANiq72ndWJtzSQSFYuVkRPhdan_PvNpvGEhQXKAZKESnt7JVAA@mail.gmail.com>

On Fri, Nov 1, 2024 at 7:03?AM Boqun Feng <boqun.feng at gmail.com> wrote:
>
> This time, I try implementing a generic atomic type `Atomic<T>`, since
> Benno and Gary suggested last time, and also Rust standard library is
> also going to that direction [1].

I would like to thank Boqun for trying out this approach, even when he
wasn't (and maybe still isn't) convinced.

Cheers,
Miguel


From mr.bossman075 at gmail.com  Fri Nov  1 07:29:44 2024
From: mr.bossman075 at gmail.com (Jesse T)
Date: Fri, 1 Nov 2024 10:29:44 -0400
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <ariqiukhztgziwwgaauqy6q3pghflnoeuwtag4izwkfmtvi2kh@gnlq4d7jsaw4>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com> <6zx3tqdc5bma2vutexwigzlir6nr6adp7arg4qwl5ieyd3avbu@5yyhv57ttwcl>
 <dbeea869-54cd-43fe-9021-783d641f1278@gmail.com> <ariqiukhztgziwwgaauqy6q3pghflnoeuwtag4izwkfmtvi2kh@gnlq4d7jsaw4>
Message-ID: <CAJFTR8T60Azb3refwAB9LALJthKxQz8E1ixZyEA0K=hXfNcUyg@mail.gmail.com>

On Fri, Nov 1, 2024 at 10:24?AM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>
> On Tue, Oct 29, 2024 at 04:36:00PM +0800, Troy Mitchell wrote:
> > On 2024/10/28 15:38, Krzysztof Kozlowski wrote:
> > > On Mon, Oct 28, 2024 at 01:32:19PM +0800, Troy Mitchell wrote:
> > >> The I2C of K1 supports fast-speed-mode and high-speed-mode,
> > >> and supports FIFO transmission.
> > >>
> > >> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
> > >> ---

Change in v2:
- drop fifo-disable property
- unevaluatedProperties goes after required: block
- drop alias

> > >
> > > Where is the changelog? Nothing here, nothing in cover letter.
It seems like it was accidentally dropped seeing there are the dashes.

> > >
> > > I asked for several changes, so now I don't know if you implemented
> > > them.
> >
> > I deleted the FIFO property because I believe your suggestion is correct.
> > this should be decided by the driver, even though the FIFO is provided
> > by the hardware.
> >
> > Apologies for missing the changelog. To correct this, should I send a v3
> > version with the changelog or resend v2?
>
> Reply now with changelog. Your binding has some other unrelated and
> incorrect changes, which I do not understand.

...

Thanks,
Jesse Taube

>
> Best regards,
> Krzysztof
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From krzk at kernel.org  Fri Nov  1 07:37:32 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 1 Nov 2024 15:37:32 +0100
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <CAJFTR8T60Azb3refwAB9LALJthKxQz8E1ixZyEA0K=hXfNcUyg@mail.gmail.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <6zx3tqdc5bma2vutexwigzlir6nr6adp7arg4qwl5ieyd3avbu@5yyhv57ttwcl>
 <dbeea869-54cd-43fe-9021-783d641f1278@gmail.com>
 <ariqiukhztgziwwgaauqy6q3pghflnoeuwtag4izwkfmtvi2kh@gnlq4d7jsaw4>
 <CAJFTR8T60Azb3refwAB9LALJthKxQz8E1ixZyEA0K=hXfNcUyg@mail.gmail.com>
Message-ID: <67aad19f-a512-4674-a8e3-5c6349c4edce@kernel.org>

On 01/11/2024 15:29, Jesse T wrote:
> On Fri, Nov 1, 2024 at 10:24?AM Krzysztof Kozlowski <krzk at kernel.org> wrote:
>>
>> On Tue, Oct 29, 2024 at 04:36:00PM +0800, Troy Mitchell wrote:
>>> On 2024/10/28 15:38, Krzysztof Kozlowski wrote:
>>>> On Mon, Oct 28, 2024 at 01:32:19PM +0800, Troy Mitchell wrote:
>>>>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
>>>>> and supports FIFO transmission.
>>>>>
>>>>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>>>>> ---
> 
> Change in v2:
> - drop fifo-disable property
> - unevaluatedProperties goes after required: block
> - drop alias

b4 diff disagrees with you :/

Best regards,
Krzysztof



From seanjc at google.com  Fri Nov  1 07:48:00 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 1 Nov 2024 07:48:00 -0700
Subject: [PATCH v3 03/14] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk>
References: <20241009154953.1073471-1-seanjc@google.com> <20241009154953.1073471-4-seanjc@google.com>
 <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk>
Message-ID: <ZyTpwwm0s89iU9Pk@google.com>

On Fri, Nov 01, 2024, Mark Brown wrote:
> On Wed, Oct 09, 2024 at 08:49:42AM -0700, Sean Christopherson wrote:
> > Return a uint64_t from vcpu_get_reg() instead of having the caller provide
> > a pointer to storage, as none of the vcpu_get_reg() usage in KVM selftests
> > accesses a register larger than 64 bits, and vcpu_set_reg() only accepts a
> > 64-bit value.  If a use case comes along that needs to get a register that
> > is larger than 64 bits, then a utility can be added to assert success and
> > take a void pointer, but until then, forcing an out param yields ugly code
> > and prevents feeding the output of vcpu_get_reg() into vcpu_set_reg().
> 
> This commit, which is in today's -next as 5c6c7b71a45c9c, breaks the
> build on arm64:
> 
> aarch64/psci_test.c: In function ?host_test_system_off2?:
> aarch64/psci_test.c:247:9: error: too many arguments to function ?vcpu_get_reg?
>   247 |         vcpu_get_reg(target, KVM_REG_ARM_PSCI_VERSION, &psci_version);
>       |         ^~~~~~~~~~~~
> In file included from aarch64/psci_test.c:18:
> include/kvm_util.h:705:24: note: declared here
>   705 | static inline uint64_t vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id)
>       |                        ^~~~~~~~~~~~
> At top level:
> cc1: note: unrecognized command-line option ?-Wno-gnu-variable-sized-type-not-at
> -end? may have been intended to silence earlier diagnostics
> 
> since the updates done to that file did not take account of 72be5aa6be4
> ("KVM: selftests: Add test for PSCI SYSTEM_OFF2") which has been merged
> in the kvm-arm64 tree.

Bugger.  In hindsight, it's obvious that of course arch selftests would add usage
of vcpu_get_reg().

Unless someone has a better idea, I'll drop the series from kvm-x86, post a new
version that applies on linux-next, and then re-apply the series just before the
v6.13 merge window (rinse and repeat as needed if more vcpu_get_reg() users come
along).

That would be a good oppurtunity to do the $(ARCH) directory switch[*] too, e.g.
have a "selftests_late" or whatever topic branch.

Sorry for the pain Mark, you've been playing janitor for us too much lately.

[*] https://lore.kernel.org/all/20240826190116.145945-1-seanjc at google.com


From palmer at rivosinc.com  Fri Nov  1 07:55:27 2024
From: palmer at rivosinc.com (Palmer Dabbelt)
Date: Fri, 01 Nov 2024 07:55:27 -0700 (PDT)
Subject: [GIT PULL] RISC-V Fixes for 6.11-rc6
Message-ID: <mhng-26039e8c-5759-4214-aaaa-765d5736b6a4@palmer-ri-x1c9>

The following changes since commit cfb10de18538e383dbc4f3ce7f477ce49287ff3d:

  riscv: Fix kernel stack size when KASAN is enabled (2024-10-01 13:08:11 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git tags/riscv-for-linus-6.11-rc6

for you to fetch changes up to 5f153a692bacc295f213e2c632ca557979fad7be:

  Merge commit 'bf40167d54d5' into fixes (2024-10-25 06:18:43 -0700)

----------------------------------------------------------------
RISC-V Fixes for 6.11-rc6

* A fix that avoids accessing the early boot ACPI tables via unsafe
  memory attributes, which can result in incorrect ACPI table data
  appearing.  This can cause all sorts of bad behavior.
* A fix to avoid compiler-insert library calls in the VDSO.
* GCC+Rust builds have been disabled, to avoid issues related to ISA
  string mismatched between the GCC and LLVM Rust implementations.
* The NX flag is now set in the EFI PE/COFF headers, which is necessary
  for some distro GRUB versions to boot images.
* A fix to avoid leaking DT node reference counts on ACPI systems during
  cache info parsing.
* CPU numbers are now printed as unsigned values during hotplug.
* A pair of build fixes for usused macros, which can trigger warnings on
  some configurations.

----------------------------------------------------------------
Alexandre Ghiti (2):
      riscv: vdso: Prevent the compiler from inserting calls to memset()
      riscv: Do not use fortify in early code

Chunyan Zhang (2):
      riscv: Remove unused GENERATING_ASM_OFFSETS
      riscv: Remove duplicated GET_RM

Conor Dooley (1):
      RISC-V: disallow gcc + rust builds

Heinrich Schuchardt (1):
      riscv: efi: Set NX compat flag in PE/COFF header

Miquel Sabat?? Sol?? (1):
      riscv: Prevent a bad reference count on CPU nodes

Palmer Dabbelt (1):
      Merge commit 'bf40167d54d5' into fixes

WangYuli (1):
      riscv: Use '%u' to format the output of 'cpu'

Yunhui Cui (1):
      RISC-V: ACPI: fix early_ioremap to early_memremap

 Documentation/rust/arch-support.rst  | 2 +-
 arch/riscv/Kconfig                   | 2 +-
 arch/riscv/errata/Makefile           | 6 ++++++
 arch/riscv/kernel/Makefile           | 5 +++++
 arch/riscv/kernel/acpi.c             | 4 ++--
 arch/riscv/kernel/asm-offsets.c      | 2 --
 arch/riscv/kernel/cacheinfo.c        | 7 +++++--
 arch/riscv/kernel/cpu-hotplug.c      | 2 +-
 arch/riscv/kernel/efi-header.S       | 2 +-
 arch/riscv/kernel/pi/Makefile        | 6 +++++-
 arch/riscv/kernel/traps_misaligned.c | 2 --
 arch/riscv/kernel/vdso/Makefile      | 1 +
 12 files changed, 28 insertions(+), 13 deletions(-)


From seanjc at google.com  Fri Nov  1 08:18:11 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 1 Nov 2024 08:18:11 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <2233397c-f423-40e3-8546-728b50ce0489@amazon.com>
References: <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk> <2233397c-f423-40e3-8546-728b50ce0489@amazon.com>
Message-ID: <ZyTxM7Po4v7VkmHO@google.com>

+David Kaplan

On Thu, Oct 31, 2024, Derek Manwaring wrote:
> On 2024-10-31 at 10:42+0000 Patrick Roy wrote:
> > On Thu, 2024-10-31 at 09:50 +0000, David Hildenbrand wrote:
> > > On 30.10.24 14:49, Patrick Roy wrote:
> > >> Most significantly, I've reduced the patch series to focus only on
> > >> direct map removal for guest_memfd for now, leaving the whole "how to do
> > >> non-CoCo VMs in guest_memfd" for later. If this separation is
> > >> acceptable, then I think I can drop the RFC tag in the next revision
> > >> (I've mainly kept it here because I'm not entirely sure what to do with
> > >> patches 3 and 4).
> > >
> > > Hi,
> > >
> > > keeping upcoming "shared and private memory in guest_memfd" in mind, I
> > > assume the focus would be to only remove the direct map for private memory?
> > >
> > > So in the current upstream state, you would only be removing the direct
> > > map for private memory, currently translating to "encrypted"/"protected"
> > > memory that is inaccessible either way already.
> > >
> > > Correct?
> >
> > Yea, with the upcomming "shared and private" stuff, I would expect the
> > the shared<->private conversions would call the routines from patch 3 to
> > restore direct map entries on private->shared, and zap them on
> > shared->private.
> >
> > But as you said, the current upstream state has no notion of "shared"
> > memory in guest_memfd, so everything is private and thus everything is
> > direct map removed (although it is indeed already inaccessible anyway
> > for TDX and friends. That's what makes this patch series a bit awkward
> > :( )
> 
> TDX and SEV encryption happens between the core and main memory, so
> cached guest data we're most concerned about for transient execution
> attacks isn't necessarily inaccessible.
> 
> I'd be interested what Intel, AMD, and other folks think on this, but I
> think direct map removal is worthwhile for CoCo cases as well.

Removal of the direct map entries for guest private PFNs likely won't affect the
ability of an attacker to glean information from the unencrypted data that's in
the CPU caches, at least not on x86.  Both TDX and SEV steal physical address
bit(s) for tagging encrypted memory, and unless things have changed on recent
AMD microarchitectures (I'm 99.9% certain Intel CPUs haven't changed), those stolen
address bits are propagated into the caches.  I.e. the encrypted and unencrypted
forms of a given PFN are actually two different physical addresses under the hood.

I don't actually know how SEV uses the stolen PA bits though.  I don't see how it
simply be the ASID, because IIUC, AMD CPUs allow for more unique SEV-capable ASIDs
than uniquely addressable PAs by the number of stolen bits.  But I would be very
surprised if the tag for the cache isn't guaranteed to be unique per encryption key.

David?


From oliver.upton at linux.dev  Fri Nov  1 08:38:48 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 1 Nov 2024 08:38:48 -0700
Subject: [PATCH v3 03/14] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <ZyTpwwm0s89iU9Pk@google.com>
References: <20241009154953.1073471-1-seanjc@google.com>
 <20241009154953.1073471-4-seanjc@google.com>
 <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk>
 <ZyTpwwm0s89iU9Pk@google.com>
Message-ID: <ZyT2CB6zodtbWEI9@linux.dev>

Hey,

On Fri, Nov 01, 2024 at 07:48:00AM -0700, Sean Christopherson wrote:
> On Fri, Nov 01, 2024, Mark Brown wrote:
> > On Wed, Oct 09, 2024 at 08:49:42AM -0700, Sean Christopherson wrote:
> > > Return a uint64_t from vcpu_get_reg() instead of having the caller provide
> > > a pointer to storage, as none of the vcpu_get_reg() usage in KVM selftests
> > > accesses a register larger than 64 bits, and vcpu_set_reg() only accepts a
> > > 64-bit value.  If a use case comes along that needs to get a register that
> > > is larger than 64 bits, then a utility can be added to assert success and
> > > take a void pointer, but until then, forcing an out param yields ugly code
> > > and prevents feeding the output of vcpu_get_reg() into vcpu_set_reg().
> > 
> > This commit, which is in today's -next as 5c6c7b71a45c9c, breaks the
> > build on arm64:
> > 
> > aarch64/psci_test.c: In function ?host_test_system_off2?:
> > aarch64/psci_test.c:247:9: error: too many arguments to function ?vcpu_get_reg?
> >   247 |         vcpu_get_reg(target, KVM_REG_ARM_PSCI_VERSION, &psci_version);
> >       |         ^~~~~~~~~~~~
> > In file included from aarch64/psci_test.c:18:
> > include/kvm_util.h:705:24: note: declared here
> >   705 | static inline uint64_t vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id)
> >       |                        ^~~~~~~~~~~~
> > At top level:
> > cc1: note: unrecognized command-line option ?-Wno-gnu-variable-sized-type-not-at
> > -end? may have been intended to silence earlier diagnostics
> > 
> > since the updates done to that file did not take account of 72be5aa6be4
> > ("KVM: selftests: Add test for PSCI SYSTEM_OFF2") which has been merged
> > in the kvm-arm64 tree.
> 
> Bugger.  In hindsight, it's obvious that of course arch selftests would add usage
> of vcpu_get_reg().
> 
> Unless someone has a better idea, I'll drop the series from kvm-x86, post a new
> version that applies on linux-next, and then re-apply the series just before the
> v6.13 merge window (rinse and repeat as needed if more vcpu_get_reg() users come
> along).

Can you instead just push out a topic branch and let the affected
maintainers deal with it? This is the usual way we handle conflicts
between trees...

> That would be a good oppurtunity to do the $(ARCH) directory switch[*] too, e.g.
> have a "selftests_late" or whatever topic branch.

The right time to do KVM-wide changes (even selftests) is *early* in the
development cycle, not last minute. It gives us plenty of time to iron out
the wrinkles.

> Sorry for the pain Mark, you've been playing janitor for us too much lately.

+1, appreciate your help on this.

-- 
Thanks,
Oliver


From seanjc at google.com  Fri Nov  1 08:59:16 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 1 Nov 2024 08:59:16 -0700
Subject: [PATCH v3 03/14] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <ZyT2CB6zodtbWEI9@linux.dev>
References: <20241009154953.1073471-1-seanjc@google.com> <20241009154953.1073471-4-seanjc@google.com>
 <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk> <ZyTpwwm0s89iU9Pk@google.com>
 <ZyT2CB6zodtbWEI9@linux.dev>
Message-ID: <ZyT61FF0-g8gKZfc@google.com>

On Fri, Nov 01, 2024, Oliver Upton wrote:
> Hey,
> 
> On Fri, Nov 01, 2024 at 07:48:00AM -0700, Sean Christopherson wrote:
> > On Fri, Nov 01, 2024, Mark Brown wrote:
> > > On Wed, Oct 09, 2024 at 08:49:42AM -0700, Sean Christopherson wrote:
> > > > Return a uint64_t from vcpu_get_reg() instead of having the caller provide
> > > > a pointer to storage, as none of the vcpu_get_reg() usage in KVM selftests
> > > > accesses a register larger than 64 bits, and vcpu_set_reg() only accepts a
> > > > 64-bit value.  If a use case comes along that needs to get a register that
> > > > is larger than 64 bits, then a utility can be added to assert success and
> > > > take a void pointer, but until then, forcing an out param yields ugly code
> > > > and prevents feeding the output of vcpu_get_reg() into vcpu_set_reg().
> > > 
> > > This commit, which is in today's -next as 5c6c7b71a45c9c, breaks the
> > > build on arm64:
> > > 
> > > aarch64/psci_test.c: In function ?host_test_system_off2?:
> > > aarch64/psci_test.c:247:9: error: too many arguments to function ?vcpu_get_reg?
> > >   247 |         vcpu_get_reg(target, KVM_REG_ARM_PSCI_VERSION, &psci_version);
> > >       |         ^~~~~~~~~~~~
> > > In file included from aarch64/psci_test.c:18:
> > > include/kvm_util.h:705:24: note: declared here
> > >   705 | static inline uint64_t vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id)
> > >       |                        ^~~~~~~~~~~~
> > > At top level:
> > > cc1: note: unrecognized command-line option ?-Wno-gnu-variable-sized-type-not-at
> > > -end? may have been intended to silence earlier diagnostics
> > > 
> > > since the updates done to that file did not take account of 72be5aa6be4
> > > ("KVM: selftests: Add test for PSCI SYSTEM_OFF2") which has been merged
> > > in the kvm-arm64 tree.
> > 
> > Bugger.  In hindsight, it's obvious that of course arch selftests would add usage
> > of vcpu_get_reg().
> > 
> > Unless someone has a better idea, I'll drop the series from kvm-x86, post a new
> > version that applies on linux-next, and then re-apply the series just before the
> > v6.13 merge window (rinse and repeat as needed if more vcpu_get_reg() users come
> > along).
> 
> Can you instead just push out a topic branch and let the affected
> maintainers deal with it? This is the usual way we handle conflicts
> between trees...

That'd work too, but as you note below, doing that now throws a wrench in things
because essentially all arch maintainers would need merge that topic branch,
otherwise linux-next would end up in the same state.

> > That would be a good oppurtunity to do the $(ARCH) directory switch[*] too, e.g.
> > have a "selftests_late" or whatever topic branch.
> 
> The right time to do KVM-wide changes (even selftests) is *early* in the
> development cycle, not last minute. It gives us plenty of time to iron out
> the wrinkles.

Yeah, that was the original plan, then the stupid strict aliasing bug happened,
and I honestly forgot the vcpu_get_reg() changes would need to be consumed by
other architectures.

Other than letting me forget about this mess a few weeks earlier, there's no
good reason to force this into 6.13.  So, I'll drop the series from 6.13, post
new versions of the this and the $(ARCH) series just before the merge window,
and then either send a pull request to Paolo for 6.14 as soon as the 6.13 merge
window closes, or ask/bribe Paolo to apply everything directly.


From dave.hansen at intel.com  Fri Nov  1 09:06:50 2024
From: dave.hansen at intel.com (Dave Hansen)
Date: Fri, 1 Nov 2024 09:06:50 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <2233397c-f423-40e3-8546-728b50ce0489@amazon.com>
References: <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
 <2233397c-f423-40e3-8546-728b50ce0489@amazon.com>
Message-ID: <784d1522-0451-4844-a334-8b7d49019437@intel.com>

On 10/31/24 17:10, Manwaring, Derek wrote:
> TDX and SEV encryption happens between the core and main memory, so
> cached guest data we're most concerned about for transient execution
> attacks isn't necessarily inaccessible.
> 
> I'd be interested what Intel, AMD, and other folks think on this, but I
> think direct map removal is worthwhile for CoCo cases as well.

I'm not sure specifically which attacks you have in mind.  Also, don't
forget that TDX doesn't get any intra-system security from encryption
itself.  All that the encryption does is prevent some physical attacks.

The main thing I think you want to keep in mind is mentioned in the "TDX
Module v1.5 Base Architecture Specification"[1]:

> Any software except guest TD or TDX module must not be able to
> speculatively or non-speculatively access TD private memory,

That's a pretty broad claim and it involves mitigations in hardware and
the TDX module.

I _think_ you might be thinking of attacks like MDS where some random
microarchitectural buffer contains guest data after a VM exit and then
an attacker extracts it.  Direct map removal doesn't affect these
buffers and doesn't mitigate an attacker getting the data out.  TDX
relies on other defenses.

As for the CPU caches, direct map removal doesn't help or hurt anything.
 A malicious VMM would just map the guest data if it could and try to
extract it if that were possible.  If the attack is mitigated when the
data is _mapped_, then it's certainly not possible _unmapped_.

So why bother with direct map removal for TDX?  A VMM write to TD
private data causes machine checks.  So any kernel bug that even
accidentally writes to kernel memory can bring the whole system down.
Not nice.

1. https://cdrdv2.intel.com/v1/dl/getContent/733575


From oliver.upton at linux.dev  Fri Nov  1 09:11:25 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 1 Nov 2024 09:11:25 -0700
Subject: [PATCH v3 03/14] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <ZyT61FF0-g8gKZfc@google.com>
References: <20241009154953.1073471-1-seanjc@google.com>
 <20241009154953.1073471-4-seanjc@google.com>
 <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk>
 <ZyTpwwm0s89iU9Pk@google.com>
 <ZyT2CB6zodtbWEI9@linux.dev>
 <ZyT61FF0-g8gKZfc@google.com>
Message-ID: <ZyT9rSnLcDWkWoL_@linux.dev>

On Fri, Nov 01, 2024 at 08:59:16AM -0700, Sean Christopherson wrote:
> > Can you instead just push out a topic branch and let the affected
> > maintainers deal with it? This is the usual way we handle conflicts
> > between trees...
> 
> That'd work too, but as you note below, doing that now throws a wrench in things
> because essentially all arch maintainers would need merge that topic branch,
> otherwise linux-next would end up in the same state.

TBH, I'm quite happy with that. Recent history has not been particularly
convinincing to me that folks are actually testing arm64, let alone
compiling for it when applying selftests patches.

Otherwise, the alternative of respinning the global change for every -next
breakage adds a decent amount of toil and gives the wrong impression of how
long our patches have actually been baking in -next.

> > > That would be a good oppurtunity to do the $(ARCH) directory switch[*] too, e.g.
> > > have a "selftests_late" or whatever topic branch.
> > 
> > The right time to do KVM-wide changes (even selftests) is *early* in the
> > development cycle, not last minute. It gives us plenty of time to iron out
> > the wrinkles.
> 
> Yeah, that was the original plan, then the stupid strict aliasing bug happened,
> and I honestly forgot the vcpu_get_reg() changes would need to be consumed by
> other architectures.
> 
> Other than letting me forget about this mess a few weeks earlier, there's no
> good reason to force this into 6.13.  So, I'll drop the series from 6.13, post
> new versions of the this and the $(ARCH) series just before the merge window,
> and then either send a pull request to Paolo for 6.14 as soon as the 6.13 merge
> window closes, or ask/bribe Paolo to apply everything directly.

Sounds good, punting to 6.14 seems reasonable.

-- 
Thanks,
Oliver


From seanjc at google.com  Fri Nov  1 09:16:42 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 1 Nov 2024 09:16:42 -0700
Subject: [PATCH v3 03/14] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <ZyT9rSnLcDWkWoL_@linux.dev>
References: <20241009154953.1073471-1-seanjc@google.com> <20241009154953.1073471-4-seanjc@google.com>
 <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk> <ZyTpwwm0s89iU9Pk@google.com>
 <ZyT2CB6zodtbWEI9@linux.dev> <ZyT61FF0-g8gKZfc@google.com> <ZyT9rSnLcDWkWoL_@linux.dev>
Message-ID: <ZyT-6iCNlA1VSAV3@google.com>

On Fri, Nov 01, 2024, Oliver Upton wrote:
> On Fri, Nov 01, 2024 at 08:59:16AM -0700, Sean Christopherson wrote:
> > > Can you instead just push out a topic branch and let the affected
> > > maintainers deal with it? This is the usual way we handle conflicts
> > > between trees...
> > 
> > That'd work too, but as you note below, doing that now throws a wrench in things
> > because essentially all arch maintainers would need merge that topic branch,
> > otherwise linux-next would end up in the same state.
> 
> TBH, I'm quite happy with that. Recent history has not been particularly
> convinincing to me that folks are actually testing arm64, let alone
> compiling for it when applying selftests patches.

FWIW, I did compile all patches on all KVM architectures, including selftests.
But my base obviously didn't include the kvm-arm64 branch :-/

One thing I'll add to my workflow would be to do a local merge (and smoke test)
of linux-next into kvm-x86 next before pushing it out.  This isn't the only snafu
this cycle where such a sanity check would have saved me and others a bit of pain.

https://lore.kernel.org/all/20241101153857.GAZyT2EdLXKs7ZmDFx at fat_crate.local


From oliver.upton at linux.dev  Fri Nov  1 09:22:30 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Fri, 1 Nov 2024 09:22:30 -0700
Subject: [PATCH v3 03/14] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <ZyT-6iCNlA1VSAV3@google.com>
References: <20241009154953.1073471-1-seanjc@google.com>
 <20241009154953.1073471-4-seanjc@google.com>
 <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk>
 <ZyTpwwm0s89iU9Pk@google.com>
 <ZyT2CB6zodtbWEI9@linux.dev>
 <ZyT61FF0-g8gKZfc@google.com>
 <ZyT9rSnLcDWkWoL_@linux.dev>
 <ZyT-6iCNlA1VSAV3@google.com>
Message-ID: <ZyUARgGV4G6DOrRL@linux.dev>

On Fri, Nov 01, 2024 at 09:16:42AM -0700, Sean Christopherson wrote:
> On Fri, Nov 01, 2024, Oliver Upton wrote:
> > On Fri, Nov 01, 2024 at 08:59:16AM -0700, Sean Christopherson wrote:
> > > > Can you instead just push out a topic branch and let the affected
> > > > maintainers deal with it? This is the usual way we handle conflicts
> > > > between trees...
> > > 
> > > That'd work too, but as you note below, doing that now throws a wrench in things
> > > because essentially all arch maintainers would need merge that topic branch,
> > > otherwise linux-next would end up in the same state.
> > 
> > TBH, I'm quite happy with that. Recent history has not been particularly
> > convinincing to me that folks are actually testing arm64, let alone
> > compiling for it when applying selftests patches.
> 
> FWIW, I did compile all patches on all KVM architectures, including selftests.
> But my base obviously didn't include the kvm-arm64 branch :-/

Oh, that rip wasn't aimed at you, commit 76f972c2cfdf ("KVM: selftests: Fix build
on architectures other than x86_64") just came to mind.

> One thing I'll add to my workflow would be to do a local merge (and smoke test)
> of linux-next into kvm-x86 next before pushing it out.  This isn't the only snafu
> this cycle where such a sanity check would have saved me and others a bit of pain.

Eh, shit happens, that's what -next is for :)

The only point I wanted to make was that it is perfectly fine by me to
spread the workload w/ a topic branch if things blow up sometime after
your changes show up in -next.

-- 
Thanks,
Oliver


From seanjc at google.com  Fri Nov  1 09:31:05 2024
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 1 Nov 2024 09:31:05 -0700
Subject: [PATCH v3 03/14] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <ZyUARgGV4G6DOrRL@linux.dev>
References: <20241009154953.1073471-1-seanjc@google.com> <20241009154953.1073471-4-seanjc@google.com>
 <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk> <ZyTpwwm0s89iU9Pk@google.com>
 <ZyT2CB6zodtbWEI9@linux.dev> <ZyT61FF0-g8gKZfc@google.com>
 <ZyT9rSnLcDWkWoL_@linux.dev> <ZyT-6iCNlA1VSAV3@google.com> <ZyUARgGV4G6DOrRL@linux.dev>
Message-ID: <ZyUCSZEv4w1yXwEb@google.com>

On Fri, Nov 01, 2024, Oliver Upton wrote:
> On Fri, Nov 01, 2024 at 09:16:42AM -0700, Sean Christopherson wrote:
> > One thing I'll add to my workflow would be to do a local merge (and smoke test)
> > of linux-next into kvm-x86 next before pushing it out.  This isn't the only snafu
> > this cycle where such a sanity check would have saved me and others a bit of pain.
> 
> Eh, shit happens, that's what -next is for :)

Heh, but I also don't actually test -next, which was another snafu (not my fault
this time!) from this cycle[*].  Testing 6.12-next prior to the merge window
wouldn't have made that any less painful to bisect, but I think it would at least
have allowed me to detect that the issue specifically came in from linux-next,
and the bug report would have gotten to PeterZ almost two months earlier.

https://lore.kernel.org/all/ZwdA0sbA2tJA3IKh at google.com


From broonie at kernel.org  Fri Nov  1 09:37:09 2024
From: broonie at kernel.org (Mark Brown)
Date: Fri, 1 Nov 2024 16:37:09 +0000
Subject: [PATCH v3 03/14] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <ZyUARgGV4G6DOrRL@linux.dev>
References: <20241009154953.1073471-1-seanjc@google.com>
 <20241009154953.1073471-4-seanjc@google.com>
 <39ea24d8-9dae-447a-ae37-e65878c3806f@sirena.org.uk>
 <ZyTpwwm0s89iU9Pk@google.com>
 <ZyT2CB6zodtbWEI9@linux.dev>
 <ZyT61FF0-g8gKZfc@google.com>
 <ZyT9rSnLcDWkWoL_@linux.dev>
 <ZyT-6iCNlA1VSAV3@google.com>
 <ZyUARgGV4G6DOrRL@linux.dev>
Message-ID: <0bd90020-4175-48f9-9017-2eb6073101d0@sirena.org.uk>

On Fri, Nov 01, 2024 at 09:22:30AM -0700, Oliver Upton wrote:
> On Fri, Nov 01, 2024 at 09:16:42AM -0700, Sean Christopherson wrote:

> > One thing I'll add to my workflow would be to do a local merge (and smoke test)
> > of linux-next into kvm-x86 next before pushing it out.  This isn't the only snafu
> > this cycle where such a sanity check would have saved me and others a bit of pain.

> Eh, shit happens, that's what -next is for :)

> The only point I wanted to make was that it is perfectly fine by me to
> spread the workload w/ a topic branch if things blow up sometime after
> your changes show up in -next.

Yeah, the -next breakage is a bit annoying but so long as it gets fixed
promptly it's kind of what it's there for.  It's much more of an issue
when things make it into mainline, and can be very problematic if it
makes it into a tagged -rc (especially -rc1) or something.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241101/909583d6/attachment.sig>

From derekmn at amazon.com  Fri Nov  1 09:56:12 2024
From: derekmn at amazon.com (Manwaring, Derek)
Date: Fri, 1 Nov 2024 09:56:12 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <784d1522-0451-4844-a334-8b7d49019437@intel.com>
References: <784d1522-0451-4844-a334-8b7d49019437@intel.com>
Message-ID: <7bd627df-0303-4ded-b8c8-ceb84fb20f0d@amazon.com>

+Elena

On 2024-11-01 at 16:06+0000, Dave Hansen wrote:
> On 10/31/24 17:10, Manwaring, Derek wrote:
> > TDX and SEV encryption happens between the core and main memory, so
> > cached guest data we're most concerned about for transient execution
> > attacks isn't necessarily inaccessible.
> >
> > I'd be interested what Intel, AMD, and other folks think on this, but I
> > think direct map removal is worthwhile for CoCo cases as well.
>
> I'm not sure specifically which attacks you have in mind.? [...]
>
> I _think_ you might be thinking of attacks like MDS where some random
> microarchitectural buffer contains guest data after a VM exit and then
> an attacker extracts it.? Direct map removal doesn't affect these
> buffers and doesn't mitigate an attacker getting the data out.

Right, the only attacks we can thwart with direct map removal are
transient execution attacks on the host kernel whose leak origin is
"Mapped memory" in Table 1 of the Quarantine paper [2]. Maybe the
simplest hypothetical to consider here is a new spectre v1 gadget in the
host kernel.

> The main thing I think you want to keep in mind is mentioned in the "TDX
> Module v1.5 Base Architecture Specification"[1]:
>
> > Any software except guest TD or TDX module must not be able to
> > speculatively or non-speculatively access TD private memory,
>
> That's a pretty broad claim and it involves mitigations in hardware and
> the TDX module.
>
> 1. https://cdrdv2.intel.com/v1/dl/getContent/733575

Thank you, I hadn't seen that. That is a very strong claim as far as
preventing speculative access; I didn't realize Intel claimed that about
TDX. The comma followed by "to detect if a prior corruption attempt was
successful" makes me wonder a bit if the statement is not quite as broad
as it sounds, but maybe that's just meant to relate it to the integrity
section?

> If the attack is mitigated when the > data is _mapped_, then it's
> certainly not possible _unmapped_.
>
> So why bother with direct map removal for TDX?? A VMM write to TD
> private data causes machine checks.? So any kernel bug that even
> accidentally writes to kernel memory can bring the whole system down.
> Not nice.

Fair enough. It hasn't been clear to me if there is a machine check when
the host kernel accesses guest memory only transiently. I was assuming
there is not. But if other mitigations completely prevent even
speculative access of TD private memory like you're saying, then agree
nothing to gain from direct map removal in the TDX case.

Derek


[2] https://download.vusec.net/papers/quarantine_raid23.pdf


From dave.hansen at intel.com  Fri Nov  1 10:20:39 2024
From: dave.hansen at intel.com (Dave Hansen)
Date: Fri, 1 Nov 2024 10:20:39 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <7bd627df-0303-4ded-b8c8-ceb84fb20f0d@amazon.com>
References: <784d1522-0451-4844-a334-8b7d49019437@intel.com>
 <7bd627df-0303-4ded-b8c8-ceb84fb20f0d@amazon.com>
Message-ID: <51fe5ad1-7057-4d43-b92c-580d187d2aeb@intel.com>

On 11/1/24 09:56, Manwaring, Derek wrote:
...
>>> Any software except guest TD or TDX module must not be able to
>>> speculatively or non-speculatively access TD private memory,
>>
>> That's a pretty broad claim and it involves mitigations in hardware and
>> the TDX module.
>>
>> 1. https://cdrdv2.intel.com/v1/dl/getContent/733575
> 
> Thank you, I hadn't seen that. That is a very strong claim as far as
> preventing speculative access; I didn't realize Intel claimed that about
> TDX. The comma followed by "to detect if a prior corruption attempt was
> successful" makes me wonder a bit if the statement is not quite as broad
> as it sounds, but maybe that's just meant to relate it to the integrity
> section?

I think it's just relating it to the integrity section.

>> If the attack is mitigated when the > data is _mapped_, then it's
>> certainly not possible _unmapped_.
>>
>> So why bother with direct map removal for TDX?? A VMM write to TD
>> private data causes machine checks.? So any kernel bug that even
>> accidentally writes to kernel memory can bring the whole system down.
>> Not nice.
> 
> Fair enough. It hasn't been clear to me if there is a machine check when
> the host kernel accesses guest memory only transiently. I was assuming
> there is not. 

Previous generations of hardware have had some nastiness in this area.
Speculative accesses were (I think) logged in the machine check banks,
but wouldn't raise an #MC.  I believe TDX-capable hardware won't even
log speculative accesses.

> But if other mitigations completely prevent even speculative access
> of TD private memory like you're saying, then agree nothing to gain
> from direct map removal in the TDX case.
Remember, guest unmapping is done in the VMM.  The VMM is not trusted in
the TDX (or SEV-SNP) model.  If any VMM can harm the protections on
guest memory, then we have a big problem.

That isn't to say big problem can't happen.  Say some crazy attack comes
to light where the VMM can attack TDX if the VMM has mapping for a guest
(or TDX module) memory.  Crazier things have happened, and guest
unmapping _would_ help there, if you trusted the VMM.

Basically, I think guest unmapping only helps system security as a whole
if you must _already_ trust the VMM.


From derekmn at amazon.com  Fri Nov  1 11:31:09 2024
From: derekmn at amazon.com (Manwaring, Derek)
Date: Fri, 1 Nov 2024 11:31:09 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <51fe5ad1-7057-4d43-b92c-580d187d2aeb@intel.com>
References: <51fe5ad1-7057-4d43-b92c-580d187d2aeb@intel.com>
Message-ID: <37fbfc65-b145-4a22-a48c-1921204d5635@amazon.com>

On 2024-11-01 at 17:20+0000, Dave Hansen wrote:
> On 11/1/24 09:56, Manwaring, Derek wrote:
> > But if other mitigations completely prevent even speculative access
> > of TD private memory like you're saying, then agree nothing to gain
> > from direct map removal in the TDX case.
> Remember, guest unmapping is done in the VMM.? The VMM is not trusted in
> the TDX (or SEV-SNP) model.? If any VMM can harm the protections on
> guest memory, then we have a big problem.
>
> That isn't to say big problem can't happen.? Say some crazy attack comes
> to light where the VMM can attack TDX if the VMM has mapping for a guest
> (or TDX module) memory.? Crazier things have happened, and guest
> unmapping _would_ help there, if you trusted the VMM.
>
> Basically, I think guest unmapping only helps system security as a whole
> if you must _already_ trust the VMM.

Yeah that makes a lot of sense. I just view the ideal outcome as a
composition of strong, independent defenses. So as a guest you have the
confidentiality and integrity guarantees of the hardware, *and* you have
an up-to-date, good-hygiene (albeit not attested) host kernel just in
case some crazy attack/gap comes up.

>From that standpoint I'm still tempted to turn the question around a bit
for the host kernel's perspective. Like if the host kernel should not
(and indeed cannot with TDX controls in place) access guest private
memory, why not remove it from the direct map?

Derek


From David.Kaplan at amd.com  Fri Nov  1 11:32:38 2024
From: David.Kaplan at amd.com (Kaplan, David)
Date: Fri, 1 Nov 2024 18:32:38 +0000
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <ZyTxM7Po4v7VkmHO@google.com>
References: <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
 <2233397c-f423-40e3-8546-728b50ce0489@amazon.com>
 <ZyTxM7Po4v7VkmHO@google.com>
Message-ID: <LV3PR12MB9265A91412AFCF7B65AD0BA694562@LV3PR12MB9265.namprd12.prod.outlook.com>

[AMD Official Use Only - AMD Internal Distribution Only]

> -----Original Message-----
> From: Sean Christopherson <seanjc at google.com>
> Sent: Friday, November 1, 2024 10:18 AM
> To: Derek Manwaring <derekmn at amazon.com>
> Cc: roypat at amazon.co.uk; ackerleytng at google.com;
> agordeev at linux.ibm.com; aou at eecs.berkeley.edu;
> borntraeger at linux.ibm.com; bp at alien8.de; catalin.marinas at arm.com;
> chenhuacai at kernel.org; corbet at lwn.net; dave.hansen at linux.intel.com;
> david at redhat.com; gerald.schaefer at linux.ibm.com; gor at linux.ibm.com;
> graf at amazon.com; hca at linux.ibm.com; hpa at zytor.com;
> jgowans at amazon.com; jthoughton at google.com; kalyazin at amazon.com;
> kernel at xen0n.name; kvm at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-doc at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-kselftest at vger.kernel.org; linux-
> mm at kvack.org; linux-riscv at lists.infradead.org; linux-s390 at vger.kernel.org;
> linux-trace-kernel at vger.kernel.org; loongarch at lists.linux.dev;
> luto at kernel.org; mathieu.desnoyers at efficios.com; mhiramat at kernel.org;
> mingo at redhat.com; palmer at dabbelt.com; paul.walmsley at sifive.com;
> pbonzini at redhat.com; peterz at infradead.org; quic_eberman at quicinc.com;
> rostedt at goodmis.org; rppt at kernel.org; shuah at kernel.org;
> svens at linux.ibm.com; tabba at google.com; tglx at linutronix.de;
> vannapurve at google.com; will at kernel.org; x86 at kernel.org;
> xmarcalx at amazon.com; Kaplan, David <David.Kaplan at amd.com>
> Subject: Re: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
>
> Caution: This message originated from an External Source. Use proper
> caution when opening attachments, clicking links, or responding.
>
>
> +David Kaplan
>
> On Thu, Oct 31, 2024, Derek Manwaring wrote:
> > On 2024-10-31 at 10:42+0000 Patrick Roy wrote:
> > > On Thu, 2024-10-31 at 09:50 +0000, David Hildenbrand wrote:
> > > > On 30.10.24 14:49, Patrick Roy wrote:
> > > >> Most significantly, I've reduced the patch series to focus only
> > > >> on direct map removal for guest_memfd for now, leaving the whole
> > > >> "how to do non-CoCo VMs in guest_memfd" for later. If this
> > > >> separation is acceptable, then I think I can drop the RFC tag in
> > > >> the next revision (I've mainly kept it here because I'm not
> > > >> entirely sure what to do with patches 3 and 4).
> > > >
> > > > Hi,
> > > >
> > > > keeping upcoming "shared and private memory in guest_memfd" in
> > > > mind, I assume the focus would be to only remove the direct map for
> private memory?
> > > >
> > > > So in the current upstream state, you would only be removing the
> > > > direct map for private memory, currently translating to
> "encrypted"/"protected"
> > > > memory that is inaccessible either way already.
> > > >
> > > > Correct?
> > >
> > > Yea, with the upcomming "shared and private" stuff, I would expect
> > > the the shared<->private conversions would call the routines from
> > > patch 3 to restore direct map entries on private->shared, and zap
> > > them on
> > > shared->private.
> > >
> > > But as you said, the current upstream state has no notion of "shared"
> > > memory in guest_memfd, so everything is private and thus everything
> > > is direct map removed (although it is indeed already inaccessible
> > > anyway for TDX and friends. That's what makes this patch series a
> > > bit awkward :( )
> >
> > TDX and SEV encryption happens between the core and main memory, so
> > cached guest data we're most concerned about for transient execution
> > attacks isn't necessarily inaccessible.
> >
> > I'd be interested what Intel, AMD, and other folks think on this, but
> > I think direct map removal is worthwhile for CoCo cases as well.
>
> Removal of the direct map entries for guest private PFNs likely won't affect
> the ability of an attacker to glean information from the unencrypted data
> that's in the CPU caches, at least not on x86.  Both TDX and SEV steal physical
> address
> bit(s) for tagging encrypted memory, and unless things have changed on
> recent AMD microarchitectures (I'm 99.9% certain Intel CPUs haven't
> changed), those stolen address bits are propagated into the caches.  I.e. the
> encrypted and unencrypted forms of a given PFN are actually two different
> physical addresses under the hood.
>
> I don't actually know how SEV uses the stolen PA bits though.  I don't see
> how it simply be the ASID, because IIUC, AMD CPUs allow for more unique
> SEV-capable ASIDs than uniquely addressable PAs by the number of stolen
> bits.  But I would be very surprised if the tag for the cache isn't guaranteed to
> be unique per encryption key.
>
> David?

How the stolen PA bits are used is a microarchitectural implementation detail.  It is true that the tag will be unique per encryption key.  Beyond that, I'm not sure what other details are relevant to SW.

--David Kaplan


From pr-tracker-bot at kernel.org  Fri Nov  1 11:34:18 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 01 Nov 2024 18:34:18 +0000
Subject: [GIT PULL] RISC-V Fixes for 6.11-rc6
In-Reply-To: <mhng-26039e8c-5759-4214-aaaa-765d5736b6a4@palmer-ri-x1c9>
References: <mhng-26039e8c-5759-4214-aaaa-765d5736b6a4@palmer-ri-x1c9>
Message-ID: <173048605836.2776063.5580936810338977798.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 01 Nov 2024 07:55:27 -0700 (PDT):

> git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git tags/riscv-for-linus-6.11-rc6

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/a031e154043984cc5a073c1b7fe62abdbe25c0c6

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From dave.hansen at intel.com  Fri Nov  1 11:43:52 2024
From: dave.hansen at intel.com (Dave Hansen)
Date: Fri, 1 Nov 2024 11:43:52 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <37fbfc65-b145-4a22-a48c-1921204d5635@amazon.com>
References: <51fe5ad1-7057-4d43-b92c-580d187d2aeb@intel.com>
 <37fbfc65-b145-4a22-a48c-1921204d5635@amazon.com>
Message-ID: <d467e6bd-c673-415f-8bb0-91603f06498a@intel.com>

On 11/1/24 11:31, Manwaring, Derek wrote:
>>From that standpoint I'm still tempted to turn the question around a bit
> for the host kernel's perspective. Like if the host kernel should not
> (and indeed cannot with TDX controls in place) access guest private
> memory, why not remove it from the direct map?

Pretend that the machine check warts aren't there.

It costs performance and complexity, for an only theoretical gain.  This
is especially true for a VMM that's not doing a just doing confidential
guests.  You fracture the direct map to pieces forever (for now).


From robh at kernel.org  Fri Nov  1 12:23:07 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 1 Nov 2024 14:23:07 -0500
Subject: [PATCH] dt-bindings: pinctrl: correct typo of description for
 cv1800
In-Reply-To: <20241029012312.3448287-1-unicornxw@gmail.com>
References: <20241029012312.3448287-1-unicornxw@gmail.com>
Message-ID: <173048898705.4061273.16401199278517673218.robh@kernel.org>


On Tue, 29 Oct 2024 09:23:12 +0800, Chen Wang wrote:
> From: Chen Wang <unicorn_wang at outlook.com>
> 
> It should be PINMUX/PINMUX2, not GPIOMUX/GPIOMUX2, see
> <dt-bindings/pinctrl/pinctrl-cv1800b.h>.
> 
> Fixes: 64aa494de6fa ("dt-bindings: pinctrl: Add pinctrl for Sophgo CV1800 series SoC.")
> Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
> ---
>  .../devicetree/bindings/pinctrl/sophgo,cv1800-pinctrl.yaml      | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From derekmn at amazon.com  Fri Nov  1 12:29:23 2024
From: derekmn at amazon.com (Manwaring, Derek)
Date: Fri, 1 Nov 2024 12:29:23 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <d467e6bd-c673-415f-8bb0-91603f06498a@intel.com>
References: <d467e6bd-c673-415f-8bb0-91603f06498a@intel.com>
Message-ID: <71e9b2c8-0cc4-4646-88f0-7780e108e610@amazon.com>

On 2024-11-01 at 18:43+0000, Dave Hansen wrote:
> On 11/1/24 11:31, Manwaring, Derek wrote:
> > From that standpoint I'm still tempted to turn the question around a bit
> > for the host kernel's perspective. Like if the host kernel should not
> > (and indeed cannot with TDX controls in place) access guest private
> > memory, why not remove it from the direct map?
>
> Pretend that the machine check warts aren't there.
>
> It costs performance and complexity, for an only theoretical gain.? This
> is especially true for a VMM that's not doing a just doing confidential
> guests.? You fracture the direct map to pieces forever (for now).

I'm hopeful we'll navigate the complexity in a worthwhile way for the
non-CoCo case. Assuming we get there and have the option to remove from
direct map, users with CoCo hardware could choose if they want to do
both on their host. For me that's a sensible choice, but maybe that's
just me.

As far as performance, are you talking about just the fracturing or
something beyond that? The data Mike brought to LSFMMBPF 2023 showed the
perf impact from direct map fragmentation for memfd_secret isn't "that
bad" [1].

Derek


[1] https://lwn.net/Articles/931406/


From dave.hansen at intel.com  Fri Nov  1 12:39:21 2024
From: dave.hansen at intel.com (Dave Hansen)
Date: Fri, 1 Nov 2024 12:39:21 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <71e9b2c8-0cc4-4646-88f0-7780e108e610@amazon.com>
References: <d467e6bd-c673-415f-8bb0-91603f06498a@intel.com>
 <71e9b2c8-0cc4-4646-88f0-7780e108e610@amazon.com>
Message-ID: <4a015283-28e2-4459-825a-1fd542b81110@intel.com>

On 11/1/24 12:29, Manwaring, Derek wrote:
> As far as performance, are you talking about just the fracturing or
> something beyond that? The data Mike brought to LSFMMBPF 2023 showed the
> perf impact from direct map fragmentation for memfd_secret isn't "that
> bad" [1].

Just the fracturing.

Mike's data are interesting, but I still think we're pretty far away
from saying that the kernel doesn't need large mappings.


From helgaas at kernel.org  Fri Nov  1 12:51:29 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 1 Nov 2024 14:51:29 -0500
Subject: [PATCH v5 2/2] PCI: microchip: rework reg region handing to
 support using either instance 1 or 2
In-Reply-To: <20240814-outmost-untainted-cedd4adcd551@spud>
Message-ID: <20241101195129.GA1318063@bhelgaas>

On Wed, Aug 14, 2024 at 09:08:42AM +0100, Conor Dooley wrote:
> From: Conor Dooley <conor.dooley at microchip.com>
> 
> The PCI host controller on PolarFire SoC has multiple "instances", each
> with their own bridge and ctrl address spaces. The original binding has
> an "apb" register region, and it is expected to be set to the base
> address of the host controllers register space. Defines in the driver
> were used to compute the addresses of the bridge and ctrl address ranges
> corresponding to instance1. Some customers want to use instance0 however
> and that requires changing the defines in the driver, which is clearly
> not a portable solution.

The subject mentions "instance 1 or 2".

This paragraph implies adding support for "instance0" ("customers want
to use instance0").

The DT patch suggests that we're adding support for "instance2"
("customers want to use instance2").

Both patches suggest that the existing support is for "instance 1".

Maybe what's being added is "instance 2", and this commit log should
s/instance0/instance 2/ ?  And probably s/instance1/instance 1/ so the
style is consistent?

Is this a "pick one or the other but not both" situation, or does this
device support two independent PCIe controllers?

I first thought this driver supported a single PCIe controller, and
you were adding support for a second independent controller.

But the fact that you say "the [singular] host controller on
PolarFire", and you're not changing mc_host_probe() to call
pci_host_common_probe() more than once makes me think there is only a
single PCIe controller, and for some reason you can choose to operate
it using either register set 1 or register set 2.

> The binding has been changed from a single register region to a pair,
> corresponding to the bridge and ctrl regions respectively, so modify the
> driver to read these regions directly from the devicetree rather than
> compute them from the base address of the abp region.
> 
> To maintain backwards compatibility with the existing binding, the
> driver retains code to handle the "abp" reg and computes the base
> address of the bridge and ctrl regions using the defines if it is
> present. reg-names has always been a required property, so this is
> safe to do.
> 
> Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
> ---
> Dropped Daire's Ack due to substantial rebasing.
> ---
>  .../pci/controller/plda/pcie-microchip-host.c | 116 +++++++++---------
>  1 file changed, 61 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/pci/controller/plda/pcie-microchip-host.c b/drivers/pci/controller/plda/pcie-microchip-host.c
> index 48f60a04b740..57f35290c83b 100644
> --- a/drivers/pci/controller/plda/pcie-microchip-host.c
> +++ b/drivers/pci/controller/plda/pcie-microchip-host.c
> @@ -25,9 +25,6 @@
>  #define MC_PCIE1_BRIDGE_ADDR			0x00008000u
>  #define MC_PCIE1_CTRL_ADDR			0x0000a000u
>  
> -#define MC_PCIE_BRIDGE_ADDR			(MC_PCIE1_BRIDGE_ADDR)
> -#define MC_PCIE_CTRL_ADDR			(MC_PCIE1_CTRL_ADDR)
> -
>  /* PCIe Controller Phy Regs */
>  #define SEC_ERROR_EVENT_CNT			0x20
>  #define DED_ERROR_EVENT_CNT			0x24
> @@ -128,7 +125,6 @@
>  	[EVENT_LOCAL_ ## x] = { __stringify(x), s }
>  
>  #define PCIE_EVENT(x) \
> -	.base = MC_PCIE_CTRL_ADDR, \
>  	.offset = PCIE_EVENT_INT, \
>  	.mask_offset = PCIE_EVENT_INT, \
>  	.mask_high = 1, \
> @@ -136,7 +132,6 @@
>  	.enb_mask = PCIE_EVENT_INT_ENB_MASK
>  
>  #define SEC_EVENT(x) \
> -	.base = MC_PCIE_CTRL_ADDR, \
>  	.offset = SEC_ERROR_INT, \
>  	.mask_offset = SEC_ERROR_INT_MASK, \
>  	.mask = SEC_ERROR_INT_ ## x ## _INT, \
> @@ -144,7 +139,6 @@
>  	.enb_mask = 0
>  
>  #define DED_EVENT(x) \
> -	.base = MC_PCIE_CTRL_ADDR, \
>  	.offset = DED_ERROR_INT, \
>  	.mask_offset = DED_ERROR_INT_MASK, \
>  	.mask_high = 1, \
> @@ -152,7 +146,6 @@
>  	.enb_mask = 0
>  
>  #define LOCAL_EVENT(x) \
> -	.base = MC_PCIE_BRIDGE_ADDR, \
>  	.offset = ISTATUS_LOCAL, \
>  	.mask_offset = IMASK_LOCAL, \
>  	.mask_high = 0, \
> @@ -179,7 +172,8 @@ struct event_map {
>  
>  struct mc_pcie {
>  	struct plda_pcie_rp plda;
> -	void __iomem *axi_base_addr;
> +	void __iomem *bridge_base_addr;
> +	void __iomem *ctrl_base_addr;
>  };
>  
>  struct cause {
> @@ -253,7 +247,6 @@ static struct event_map local_status_to_event[] = {
>  };
>  
>  static struct {
> -	u32 base;
>  	u32 offset;
>  	u32 mask;
>  	u32 shift;
> @@ -325,8 +318,7 @@ static inline u32 reg_to_event(u32 reg, struct event_map field)
>  
>  static u32 pcie_events(struct mc_pcie *port)
>  {
> -	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
> -	u32 reg = readl_relaxed(ctrl_base_addr + PCIE_EVENT_INT);
> +	u32 reg = readl_relaxed(port->ctrl_base_addr + PCIE_EVENT_INT);
>  	u32 val = 0;
>  	int i;
>  
> @@ -338,8 +330,7 @@ static u32 pcie_events(struct mc_pcie *port)
>  
>  static u32 sec_errors(struct mc_pcie *port)
>  {
> -	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
> -	u32 reg = readl_relaxed(ctrl_base_addr + SEC_ERROR_INT);
> +	u32 reg = readl_relaxed(port->ctrl_base_addr + SEC_ERROR_INT);
>  	u32 val = 0;
>  	int i;
>  
> @@ -351,8 +342,7 @@ static u32 sec_errors(struct mc_pcie *port)
>  
>  static u32 ded_errors(struct mc_pcie *port)
>  {
> -	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
> -	u32 reg = readl_relaxed(ctrl_base_addr + DED_ERROR_INT);
> +	u32 reg = readl_relaxed(port->ctrl_base_addr + DED_ERROR_INT);
>  	u32 val = 0;
>  	int i;
>  
> @@ -364,8 +354,7 @@ static u32 ded_errors(struct mc_pcie *port)
>  
>  static u32 local_events(struct mc_pcie *port)
>  {
> -	void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
> -	u32 reg = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
> +	u32 reg = readl_relaxed(port->bridge_base_addr + ISTATUS_LOCAL);
>  	u32 val = 0;
>  	int i;
>  
> @@ -412,8 +401,12 @@ static void mc_ack_event_irq(struct irq_data *data)
>  	void __iomem *addr;
>  	u32 mask;
>  
> -	addr = mc_port->axi_base_addr + event_descs[event].base +
> -		event_descs[event].offset;
> +	if (event_descs[event].offset == ISTATUS_LOCAL)
> +		addr = mc_port->bridge_base_addr;
> +	else
> +		addr = mc_port->ctrl_base_addr;
> +
> +	addr += event_descs[event].offset;
>  	mask = event_descs[event].mask;
>  	mask |= event_descs[event].enb_mask;
>  
> @@ -429,8 +422,12 @@ static void mc_mask_event_irq(struct irq_data *data)
>  	u32 mask;
>  	u32 val;
>  
> -	addr = mc_port->axi_base_addr + event_descs[event].base +
> -		event_descs[event].mask_offset;
> +	if (event_descs[event].offset == ISTATUS_LOCAL)
> +		addr = mc_port->bridge_base_addr;
> +	else
> +		addr = mc_port->ctrl_base_addr;
> +
> +	addr += event_descs[event].mask_offset;
>  	mask = event_descs[event].mask;
>  	if (event_descs[event].enb_mask) {
>  		mask <<= PCIE_EVENT_INT_ENB_SHIFT;
> @@ -460,8 +457,12 @@ static void mc_unmask_event_irq(struct irq_data *data)
>  	u32 mask;
>  	u32 val;
>  
> -	addr = mc_port->axi_base_addr + event_descs[event].base +
> -		event_descs[event].mask_offset;
> +	if (event_descs[event].offset == ISTATUS_LOCAL)
> +		addr = mc_port->bridge_base_addr;
> +	else
> +		addr = mc_port->ctrl_base_addr;
> +
> +	addr += event_descs[event].mask_offset;
>  	mask = event_descs[event].mask;
>  
>  	if (event_descs[event].enb_mask)
> @@ -554,26 +555,20 @@ static const struct plda_event mc_event = {
>  
>  static inline void mc_clear_secs(struct mc_pcie *port)
>  {
> -	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
> -
> -	writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
> +	writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, port->ctrl_base_addr +
>  		       SEC_ERROR_INT);
> -	writel_relaxed(0, ctrl_base_addr + SEC_ERROR_EVENT_CNT);
> +	writel_relaxed(0, port->ctrl_base_addr + SEC_ERROR_EVENT_CNT);
>  }
>  
>  static inline void mc_clear_deds(struct mc_pcie *port)
>  {
> -	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
> -
> -	writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
> +	writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, port->ctrl_base_addr +
>  		       DED_ERROR_INT);
> -	writel_relaxed(0, ctrl_base_addr + DED_ERROR_EVENT_CNT);
> +	writel_relaxed(0, port->ctrl_base_addr + DED_ERROR_EVENT_CNT);
>  }
>  
>  static void mc_disable_interrupts(struct mc_pcie *port)
>  {
> -	void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
> -	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
>  	u32 val;
>  
>  	/* Ensure ECC bypass is enabled */
> @@ -581,22 +576,22 @@ static void mc_disable_interrupts(struct mc_pcie *port)
>  	      ECC_CONTROL_RX_RAM_ECC_BYPASS |
>  	      ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS |
>  	      ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS;
> -	writel_relaxed(val, ctrl_base_addr + ECC_CONTROL);
> +	writel_relaxed(val, port->ctrl_base_addr + ECC_CONTROL);
>  
>  	/* Disable SEC errors and clear any outstanding */
> -	writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
> +	writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, port->ctrl_base_addr +
>  		       SEC_ERROR_INT_MASK);
>  	mc_clear_secs(port);
>  
>  	/* Disable DED errors and clear any outstanding */
> -	writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
> +	writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, port->ctrl_base_addr +
>  		       DED_ERROR_INT_MASK);
>  	mc_clear_deds(port);
>  
>  	/* Disable local interrupts and clear any outstanding */
> -	writel_relaxed(0, bridge_base_addr + IMASK_LOCAL);
> -	writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_LOCAL);
> -	writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_MSI);
> +	writel_relaxed(0, port->bridge_base_addr + IMASK_LOCAL);
> +	writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_LOCAL);
> +	writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_MSI);
>  
>  	/* Disable PCIe events and clear any outstanding */
>  	val = PCIE_EVENT_INT_L2_EXIT_INT |
> @@ -605,11 +600,11 @@ static void mc_disable_interrupts(struct mc_pcie *port)
>  	      PCIE_EVENT_INT_L2_EXIT_INT_MASK |
>  	      PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK |
>  	      PCIE_EVENT_INT_DLUP_EXIT_INT_MASK;
> -	writel_relaxed(val, ctrl_base_addr + PCIE_EVENT_INT);
> +	writel_relaxed(val, port->ctrl_base_addr + PCIE_EVENT_INT);
>  
>  	/* Disable host interrupts and clear any outstanding */
> -	writel_relaxed(0, bridge_base_addr + IMASK_HOST);
> -	writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
> +	writel_relaxed(0, port->bridge_base_addr + IMASK_HOST);
> +	writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_HOST);
>  }
>  
>  static int mc_platform_init(struct pci_config_window *cfg)
> @@ -617,12 +612,10 @@ static int mc_platform_init(struct pci_config_window *cfg)
>  	struct device *dev = cfg->parent;
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
> -	void __iomem *bridge_base_addr =
> -		port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
>  	int ret;
>  
>  	/* Configure address translation table 0 for PCIe config space */
> -	plda_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
> +	plda_pcie_setup_window(port->bridge_base_addr, 0, cfg->res.start,
>  			       cfg->res.start,
>  			       resource_size(&cfg->res));
>  
> @@ -649,7 +642,7 @@ static int mc_platform_init(struct pci_config_window *cfg)
>  static int mc_host_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> -	void __iomem *bridge_base_addr;
> +	void __iomem *apb_base_addr;
>  	struct plda_pcie_rp *plda;
>  	int ret;
>  	u32 val;
> @@ -661,30 +654,43 @@ static int mc_host_probe(struct platform_device *pdev)
>  	plda = &port->plda;
>  	plda->dev = dev;
>  
> -	port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
> -	if (IS_ERR(port->axi_base_addr))
> -		return PTR_ERR(port->axi_base_addr);
> +	port->bridge_base_addr = devm_platform_ioremap_resource_byname(pdev, "bridge");
> +	port->ctrl_base_addr = devm_platform_ioremap_resource_byname(pdev, "ctrl");
> +	if (!IS_ERR(port->bridge_base_addr) && !IS_ERR(port->ctrl_base_addr))
> +		goto addrs_set;
>  
> +	/*
> +	 * The original, incorrect, binding that lumped the control and
> +	 * bridge addresses together still needs to be handled by the driver.
> +	 */
> +	apb_base_addr = devm_platform_ioremap_resource_byname(pdev, "apb");
> +	if (IS_ERR(apb_base_addr))
> +		return dev_err_probe(dev, PTR_ERR(apb_base_addr),
> +				     "both legacy apb register and ctrl/bridge regions missing");
> +
> +	port->bridge_base_addr = apb_base_addr + MC_PCIE1_BRIDGE_ADDR;
> +	port->ctrl_base_addr = apb_base_addr + MC_PCIE1_CTRL_ADDR;
> +
> +addrs_set:
>  	mc_disable_interrupts(port);
>  
> -	bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
> -	plda->bridge_addr = bridge_base_addr;
> +	plda->bridge_addr = port->bridge_base_addr;
>  	plda->num_events = NUM_EVENTS;
>  
>  	/* Allow enabling MSI by disabling MSI-X */
> -	val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
> +	val = readl(port->bridge_base_addr + PCIE_PCI_IRQ_DW0);
>  	val &= ~MSIX_CAP_MASK;
> -	writel(val, bridge_base_addr + PCIE_PCI_IRQ_DW0);
> +	writel(val, port->bridge_base_addr + PCIE_PCI_IRQ_DW0);
>  
>  	/* Pick num vectors from bitfile programmed onto FPGA fabric */
> -	val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
> +	val = readl(port->bridge_base_addr + PCIE_PCI_IRQ_DW0);
>  	val &= NUM_MSI_MSGS_MASK;
>  	val >>= NUM_MSI_MSGS_SHIFT;
>  
>  	plda->msi.num_vectors = 1 << val;
>  
>  	/* Pick vector address from design */
> -	plda->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
> +	plda->msi.vector_phy = readl_relaxed(port->bridge_base_addr + IMSI_ADDR);
>  
>  	ret = mc_pcie_init_clks(dev);
>  	if (ret) {
> -- 
> 2.43.0
> 


From unicorn_wang at outlook.com  Fri Nov  1 15:28:50 2024
From: unicorn_wang at outlook.com (Chen Wang)
Date: Sat, 2 Nov 2024 06:28:50 +0800
Subject: [PATCH] riscv: dts: sophgo: fix pinctrl base-address
In-Reply-To: <ihmors43w3ttfun7c4fj75ahh2hnhafdxhlmocbxfwttigj3fq@wxud2d2srisn>
References: <20241028-fix-address-v1-1-dcbe21e59ccf@bootlin.com>
 <ihmors43w3ttfun7c4fj75ahh2hnhafdxhlmocbxfwttigj3fq@wxud2d2srisn>
Message-ID: <MA0P287MB28221D96A094D7C3373C1865FE562@MA0P287MB2822.INDP287.PROD.OUTLOOK.COM>

Hi, Inochi,

Will you pick this on sophgo/for-next?

Regards,

Chen

On 2024/10/30 11:50, Inochi Amaoto wrote:
> On Mon, Oct 28, 2024 at 11:43:24AM +0100, Thomas Bonnefille wrote:
>> Fix the base-address of the pinctrl controller to match its register
>> address.
>>
>> Signed-off-by: Thomas Bonnefille <thomas.bonnefille at bootlin.com>
> Fixes: 93b61555f509 ("riscv: dts: sophgo: Add initial SG2002 SoC device tree")
>


From samuel.holland at sifive.com  Fri Nov  1 17:07:54 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:07:54 -0700
Subject: [PATCH 00/11] riscv: Memory type control for platforms with physical memory aliases
Message-ID: <20241102000843.1301099-1-samuel.holland@sifive.com>


On some RISC-V platforms, including StarFive JH7100 and ESWIN EIC7700,
RAM is mapped to multiple physical address ranges, with each alias
having a different set of statically-determined Physical Memory
Attributes (PMAs). Software selects the PMAs for a page by choosing a
PFN from the corresponding physical address range. On these platforms,
this is the only way to allocate noncached memory for use with
noncoherent DMA.

 - Patch 1 adds a new binding to describe physical memory regions in
   the devicetree.
 - Patches 2-6 refactor existing memory type support to be modeled as
   variants on top of Svpbmt.
 - Patches 7-10 add logic to transform the PFN to use the desired alias
   when reading/writing page tables.
 - Patch 11 enables this new method of memory type control on JH7100.

I have boot-tested this series on platforms with each of the 4 ways to
select a memory type: SiFive FU740 (none), QEMU (Svpbmt), Allwinner D1
(XTheadMae), and ESWIN EIC7700 (aliases).


Samuel Holland (11):
  dt-bindings: riscv: Describe physical memory regions
  riscv: mm: Increment PFN in place when splitting mappings
  riscv: mm: Deduplicate pgtable address conversion functions
  riscv: mm: Deduplicate _PAGE_CHG_MASK definition
  riscv: ptdump: Only show N and MT bits when enabled in the kernel
  riscv: mm: Fix up memory types when writing page tables
  riscv: mm: Expose all page table bits to assembly code
  riscv: alternative: Add an ALTERNATIVE_3 macro
  riscv: alternative: Allow calls with alternate link registers
  riscv: mm: Use physical memory aliases to apply PMAs
  riscv: dts: starfive: jh7100: Use physical memory ranges for DMA

 .../bindings/riscv/physical-memory.yaml       | 101 ++++++++++
 arch/riscv/Kconfig                            |   3 +
 arch/riscv/Kconfig.errata                     |  20 +-
 .../boot/dts/starfive/jh7100-common.dtsi      |  30 +--
 arch/riscv/include/asm/alternative-macros.h   |  45 ++++-
 arch/riscv/include/asm/errata_list.h          |  45 -----
 arch/riscv/include/asm/hwcap.h                |   1 +
 arch/riscv/include/asm/pgtable-32.h           |  19 +-
 arch/riscv/include/asm/pgtable-64.h           | 178 ++++++++++--------
 arch/riscv/include/asm/pgtable-bits.h         |  42 ++++-
 arch/riscv/include/asm/pgtable.h              |  55 +++---
 arch/riscv/kernel/alternative.c               |   4 +-
 arch/riscv/kernel/cpufeature.c                |   6 +
 arch/riscv/kernel/setup.c                     |   1 +
 arch/riscv/mm/Makefile                        |   1 +
 arch/riscv/mm/init.c                          |   8 +-
 arch/riscv/mm/kasan_init.c                    |   8 +-
 arch/riscv/mm/memory-alias.S                  | 101 ++++++++++
 arch/riscv/mm/pageattr.c                      |  17 +-
 arch/riscv/mm/pgtable.c                       |  91 +++++++++
 arch/riscv/mm/ptdump.c                        |  19 +-
 include/dt-bindings/riscv/physical-memory.h   |  44 +++++
 22 files changed, 596 insertions(+), 243 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/riscv/physical-memory.yaml
 create mode 100644 arch/riscv/mm/memory-alias.S
 create mode 100644 include/dt-bindings/riscv/physical-memory.h

-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:07:55 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:07:55 -0700
Subject: [PATCH 01/11] dt-bindings: riscv: Describe physical memory regions
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-2-samuel.holland@sifive.com>

Information about physical memory regions is needed by both the kernel
and M-mode firmware. For example, the kernel needs to know about
noncacheable aliases of cacheable memory in order to allocate coherent
memory pages for DMA. M-mode firmware needs to know about aliases so it
can protect itself from lower-privileged software. Firmware also needs
to know the platform's Physical Address Width in order to efficiently
implement Smmpt.

The RISC-V Privileged Architecture delegates the description of Physical
Memory Attributes to the platform. On DT-based platforms, it makes sense
to put this information in the devicetree.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 .../bindings/riscv/physical-memory.yaml       | 101 ++++++++++++++++++
 include/dt-bindings/riscv/physical-memory.h   |  44 ++++++++
 2 files changed, 145 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/riscv/physical-memory.yaml
 create mode 100644 include/dt-bindings/riscv/physical-memory.h

diff --git a/Documentation/devicetree/bindings/riscv/physical-memory.yaml b/Documentation/devicetree/bindings/riscv/physical-memory.yaml
new file mode 100644
index 000000000000..deb49b34672f
--- /dev/null
+++ b/Documentation/devicetree/bindings/riscv/physical-memory.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/riscv/physical-memory.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Physical Memory Regions
+
+maintainers:
+  - Samuel Holland <samuel.holland at sifive.com>
+
+description:
+  The RISC-V Privileged Architecture defines a number of Physical Memory
+  Attributes (PMAs) which apply to a given region of memory. These include the
+  types of accesses (read, write, execute, LR/SC, and/or AMO) allowed within
+  a region, the supported access widths and alignments, the cacheability and
+  coherence of the region, and whether or not accesses to the region may have
+  side effects.
+
+  Some RISC-V platforms provide multiple physical address mappings for main
+  memory or certain peripherals. Each alias of a region generally has different
+  PMAs (e.g. cacheable vs non-cacheable), which allows software to dynamically
+  select the PMAs for an access by referencing the corresponding alias.
+
+  The RISC-V Supervisor Domains specification defines a platform-specific
+  Physical Address Width (PAW), which describes the largest physical address
+  supported by a platform. Any access to an address >= 2^PAW is guaranteed to
+  raise an access fault, and therefore metadata (e.g. Memory Protection Tables)
+  need not be maintained for those addresses.
+
+  On DT-based RISC-V platforms, all of this information is provided by the
+  riscv,physical-memory-regions property of the root node.
+
+properties:
+  $nodename:
+    const: '/'
+
+  riscv,physical-memory-regions:
+    $ref: /schemas/types.yaml#/definitions/uint32-matrix
+    description:
+      A table of physical memory regions. The first entry in the table must
+      cover the entire range of physical addresses supported by the platform
+      (i.e. 0 to 2^PAW-1) and provides the default PMAs for all addresses not
+      covered by another table entry. Remaining table entries provide PMAs for
+      more specific physical memory regions, which must be contained within the
+      range of entry 0, but which must not overlap with each other.
+    minItems: 1
+    maxItems: 256
+    items:
+      minItems: 4
+      maxItems: 6
+      additionalItems: true
+      items:
+        - description: CPU physical address (#address-cells)
+        - description: >
+            Size (#size-cells). For entry 0, if the size is zero, the size is
+            assumed to be 2^(32 * #size-cells).
+        - description: >
+            Flags describing the most restrictive PMAs for any address within
+            the region.
+
+            The least significant byte indicates the types of accesses allowed
+            for this region. Note that a memory region may support a type of
+            access (e.g. AMOs) even if the CPU does not.
+
+            The next byte describes the cacheability, coherence, idempotency,
+            and ordering PMAs for this region. It also includes a flag to
+            indicate that accesses to a region are unsafe and must be
+            prohibited by software (for example using PMPs or Smmpt).
+
+            The third byte is reserved for future PMAs.
+
+            The most significant byte is the index of the lowest-numbered entry
+            which this entry is an alias of, if any. Aliases need not be the
+            same size, for example if a smaller memory region repeats within a
+            larger alias.
+        - description: Reserved for describing future PMAs
+
+additionalProperties: true
+
+examples:
+  - |
+    #include <dt-bindings/riscv/physical-memory.h>
+
+    / {
+      compatible = "starfive,jh7100";
+      #address-cells = <2>;
+      #size-cells = <2>;
+      riscv,physical-memory-regions =
+          <0x00 0x00000000 0x40 0x00000000 (PMA_RW | PMA_IO) 0x0>,
+          <0x00 0x18000000 0x00 0x00020000 (PMA_RWX | PMA_NONCACHEABLE_MEMORY) 0x0>,
+          <0x00 0x18080000 0x00 0x00020000 (PMA_RWX | PMA_NONCACHEABLE_MEMORY) 0x0>,
+          <0x00 0x41000000 0x00 0x1f000000 (PMA_RWX | PMA_NONCACHEABLE_MEMORY) 0x0>,
+          <0x00 0x61000000 0x00 0x1f000000 (PMA_RWXA | PMA_NONCOHERENT_MEMORY | PMR_ALIAS(3)) 0x0>,
+          <0x00 0x80000000 0x08 0x00000000 (PMA_RWXA | PMA_NONCOHERENT_MEMORY) 0x0>,
+          <0x10 0x00000000 0x08 0x00000000 (PMA_RWX | PMA_NONCACHEABLE_MEMORY | PMR_ALIAS(5)) 0x0>,
+          <0x20 0x00000000 0x10 0x00000000 (PMA_RWX | PMA_NONCACHEABLE_MEMORY) 0x0>,
+          <0x30 0x00000000 0x10 0x00000000 (PMA_RWXA | PMA_NONCOHERENT_MEMORY | PMR_ALIAS(7)) 0x0>;
+    };
+
+...
diff --git a/include/dt-bindings/riscv/physical-memory.h b/include/dt-bindings/riscv/physical-memory.h
new file mode 100644
index 000000000000..7cb2e58fa8c1
--- /dev/null
+++ b/include/dt-bindings/riscv/physical-memory.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_RISCV_PHYSICAL_MEMORY_H
+#define _DT_BINDINGS_RISCV_PHYSICAL_MEMORY_H
+
+#define PMA_READ			(1 << 0)
+#define PMA_WRITE			(1 << 1)
+#define PMA_EXECUTE			(1 << 2)
+#define PMA_AMO_MASK			(3 << 4)
+#define PMA_AMO_NONE			(0 << 4)
+#define PMA_AMO_SWAP			(1 << 4)
+#define PMA_AMO_LOGICAL			(2 << 4)
+#define PMA_AMO_ARITHMETIC		(3 << 4)
+#define PMA_RSRV_MASK			(3 << 6)
+#define PMA_RSRV_NONE			(0 << 6)
+#define PMA_RSRV_NON_EVENTUAL		(1 << 6)
+#define PMA_RSRV_EVENTUAL		(2 << 6)
+
+#define PMA_RW				(PMA_READ | PMA_WRITE)
+#define PMA_RWA				(PMA_RW | PMA_AMO_ARITHMETIC | PMA_RSRV_EVENTUAL)
+#define PMA_RWX				(PMA_RW | PMA_EXECUTE)
+#define PMA_RWXA			(PMA_RWA | PMA_EXECUTE)
+
+#define PMA_ORDER_MASK			(3 << 8)
+#define PMA_ORDER_IO_RELAXED		(0 << 8)
+#define PMA_ORDER_IO_STRONG		(1 << 8)
+#define PMA_ORDER_MEMORY		(2 << 8)
+#define PMA_READ_IDEMPOTENT		(1 << 10)
+#define PMA_WRITE_IDEMPOTENT		(1 << 11)
+#define PMA_CACHEABLE			(1 << 12)
+#define PMA_COHERENT			(1 << 13)
+
+#define PMA_UNSAFE			(1 << 15)
+
+#define PMA_IO				(PMA_ORDER_IO_RELAXED)
+#define PMA_NONCACHEABLE_MEMORY		(PMA_ORDER_MEMORY | PMA_READ_IDEMPOTENT | \
+						PMA_WRITE_IDEMPOTENT)
+#define PMA_NONCOHERENT_MEMORY		(PMA_NONCACHEABLE_MEMORY | PMA_CACHEABLE)
+#define PMA_NORMAL_MEMORY		(PMA_NONCOHERENT_MEMORY | PMA_COHERENT)
+
+#define PMR_ALIAS_MASK			(0xff << 24)
+#define PMR_ALIAS(n)			((n) << 24)
+
+#endif /* _DT_BINDINGS_RISCV_PHYSICAL_MEMORY_H */
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:07:56 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:07:56 -0700
Subject: [PATCH 02/11] riscv: mm: Increment PFN in place when splitting mappings
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-3-samuel.holland@sifive.com>

The current code separates page table entry values into a PFN and a
pgprot_t before incrementing the PFN and combining the two parts using
pfn_pXX(). On some hardware with custom page table formats or memory
aliases, the pfn_pXX() functions need to transform the PTE value, so
these functions would need to apply the opposite transformation when
breaking apart the PTE value.

However, both transformations can be avoided by incrementing the PFN in
place, as done by pte_advance_pfn() and set_ptes().

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/mm/pageattr.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index 271d01a5ba4d..335060adc1a6 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -109,9 +109,8 @@ static int __split_linear_mapping_pmd(pud_t *pudp,
 			continue;
 
 		if (pmd_leaf(pmdp_get(pmdp))) {
+			pte_t pte = pmd_pte(pmdp_get(pmdp));
 			struct page *pte_page;
-			unsigned long pfn = _pmd_pfn(pmdp_get(pmdp));
-			pgprot_t prot = __pgprot(pmd_val(pmdp_get(pmdp)) & ~_PAGE_PFN_MASK);
 			pte_t *ptep_new;
 			int i;
 
@@ -121,7 +120,7 @@ static int __split_linear_mapping_pmd(pud_t *pudp,
 
 			ptep_new = (pte_t *)page_address(pte_page);
 			for (i = 0; i < PTRS_PER_PTE; ++i, ++ptep_new)
-				set_pte(ptep_new, pfn_pte(pfn + i, prot));
+				set_pte(ptep_new, pte_advance_pfn(pte, i));
 
 			smp_wmb();
 
@@ -149,9 +148,8 @@ static int __split_linear_mapping_pud(p4d_t *p4dp,
 			continue;
 
 		if (pud_leaf(pudp_get(pudp))) {
+			pmd_t pmd = __pmd(pud_val(pudp_get(pudp)));
 			struct page *pmd_page;
-			unsigned long pfn = _pud_pfn(pudp_get(pudp));
-			pgprot_t prot = __pgprot(pud_val(pudp_get(pudp)) & ~_PAGE_PFN_MASK);
 			pmd_t *pmdp_new;
 			int i;
 
@@ -162,7 +160,8 @@ static int __split_linear_mapping_pud(p4d_t *p4dp,
 			pmdp_new = (pmd_t *)page_address(pmd_page);
 			for (i = 0; i < PTRS_PER_PMD; ++i, ++pmdp_new)
 				set_pmd(pmdp_new,
-					pfn_pmd(pfn + ((i * PMD_SIZE) >> PAGE_SHIFT), prot));
+					__pmd(pmd_val(pmd) +
+					      (i << (PMD_SHIFT - PAGE_SHIFT + PFN_PTE_SHIFT))));
 
 			smp_wmb();
 
@@ -198,9 +197,8 @@ static int __split_linear_mapping_p4d(pgd_t *pgdp,
 			continue;
 
 		if (p4d_leaf(p4dp_get(p4dp))) {
+			pud_t pud = __pud(p4d_val(p4dp_get(p4dp)));
 			struct page *pud_page;
-			unsigned long pfn = _p4d_pfn(p4dp_get(p4dp));
-			pgprot_t prot = __pgprot(p4d_val(p4dp_get(p4dp)) & ~_PAGE_PFN_MASK);
 			pud_t *pudp_new;
 			int i;
 
@@ -215,7 +213,8 @@ static int __split_linear_mapping_p4d(pgd_t *pgdp,
 			pudp_new = (pud_t *)page_address(pud_page);
 			for (i = 0; i < PTRS_PER_PUD; ++i, ++pudp_new)
 				set_pud(pudp_new,
-					pfn_pud(pfn + ((i * PUD_SIZE) >> PAGE_SHIFT), prot));
+					__pud(pud_val(pud) +
+					      (i << (PUD_SHIFT - PAGE_SHIFT + PFN_PTE_SHIFT))));
 
 			/*
 			 * Make sure the pud filling is not reordered with the
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:07:57 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:07:57 -0700
Subject: [PATCH 03/11] riscv: mm: Deduplicate pgtable address conversion functions
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-4-samuel.holland@sifive.com>

Some functions were defined equivalently in both pgtable.h and
pgtable-64.h. Keep only one definition, and move it to pgtable-64.h
unless it is also used for Sv32. Note that while Sv32 uses only two
levels of page tables, the kernel is not consistent with how they are
folded. THP requires pfn_pmd()/pmd_pfn() and mm/init.c requires
pfn_pgd()/pgd_pfn(), so for now both are provided.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/include/asm/pgtable-32.h |  4 ++++
 arch/riscv/include/asm/pgtable-64.h | 28 ++++++++++++++--------------
 arch/riscv/include/asm/pgtable.h    | 23 ++++-------------------
 arch/riscv/mm/init.c                |  8 ++++----
 arch/riscv/mm/kasan_init.c          |  8 ++++----
 5 files changed, 30 insertions(+), 41 deletions(-)

diff --git a/arch/riscv/include/asm/pgtable-32.h b/arch/riscv/include/asm/pgtable-32.h
index 00f3369570a8..23137347dc15 100644
--- a/arch/riscv/include/asm/pgtable-32.h
+++ b/arch/riscv/include/asm/pgtable-32.h
@@ -33,6 +33,10 @@
 					  _PAGE_WRITE | _PAGE_EXEC |	\
 					  _PAGE_USER | _PAGE_GLOBAL))
 
+#define pud_pfn(pud)				(pmd_pfn((pmd_t){ pud }))
+#define p4d_pfn(p4d)				(pud_pfn((pud_t){ p4d }))
+#define pgd_pfn(pgd)				(p4d_pfn((p4d_t){ pgd }))
+
 static const __maybe_unused int pgtable_l4_enabled;
 static const __maybe_unused int pgtable_l5_enabled;
 
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 0897dd99ab8d..33e7ff049c4a 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -213,19 +213,20 @@ static inline pud_t pfn_pud(unsigned long pfn, pgprot_t prot)
 	return __pud((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
 }
 
-static inline unsigned long _pud_pfn(pud_t pud)
+#define pud_pfn pud_pfn
+static inline unsigned long pud_pfn(pud_t pud)
 {
 	return __page_val_to_pfn(pud_val(pud));
 }
 
 static inline pmd_t *pud_pgtable(pud_t pud)
 {
-	return (pmd_t *)pfn_to_virt(__page_val_to_pfn(pud_val(pud)));
+	return (pmd_t *)pfn_to_virt(pud_pfn(pud));
 }
 
 static inline struct page *pud_page(pud_t pud)
 {
-	return pfn_to_page(__page_val_to_pfn(pud_val(pud)));
+	return pfn_to_page(pud_pfn(pud));
 }
 
 #define mm_p4d_folded  mm_p4d_folded
@@ -257,11 +258,6 @@ static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t prot)
 	return __pmd((pfn << _PAGE_PFN_SHIFT) | prot_val);
 }
 
-static inline unsigned long _pmd_pfn(pmd_t pmd)
-{
-	return __page_val_to_pfn(pmd_val(pmd));
-}
-
 #define mk_pmd(page, prot)    pfn_pmd(page_to_pfn(page), prot)
 
 #define pmd_ERROR(e) \
@@ -316,7 +312,7 @@ static inline p4d_t pfn_p4d(unsigned long pfn, pgprot_t prot)
 	return __p4d((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
 }
 
-static inline unsigned long _p4d_pfn(p4d_t p4d)
+static inline unsigned long p4d_pfn(p4d_t p4d)
 {
 	return __page_val_to_pfn(p4d_val(p4d));
 }
@@ -324,7 +320,7 @@ static inline unsigned long _p4d_pfn(p4d_t p4d)
 static inline pud_t *p4d_pgtable(p4d_t p4d)
 {
 	if (pgtable_l4_enabled)
-		return (pud_t *)pfn_to_virt(__page_val_to_pfn(p4d_val(p4d)));
+		return (pud_t *)pfn_to_virt(p4d_pfn(p4d));
 
 	return (pud_t *)pud_pgtable((pud_t) { p4d_val(p4d) });
 }
@@ -332,7 +328,7 @@ static inline pud_t *p4d_pgtable(p4d_t p4d)
 
 static inline struct page *p4d_page(p4d_t p4d)
 {
-	return pfn_to_page(__page_val_to_pfn(p4d_val(p4d)));
+	return pfn_to_page(p4d_pfn(p4d));
 }
 
 #define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
@@ -378,10 +374,15 @@ static inline void pgd_clear(pgd_t *pgd)
 		set_pgd(pgd, __pgd(0));
 }
 
+static inline unsigned long pgd_pfn(pgd_t pgd)
+{
+	return __page_val_to_pfn(pgd_val(pgd));
+}
+
 static inline p4d_t *pgd_pgtable(pgd_t pgd)
 {
 	if (pgtable_l5_enabled)
-		return (p4d_t *)pfn_to_virt(__page_val_to_pfn(pgd_val(pgd)));
+		return (p4d_t *)pfn_to_virt(pgd_pfn(pgd));
 
 	return (p4d_t *)p4d_pgtable((p4d_t) { pgd_val(pgd) });
 }
@@ -389,9 +390,8 @@ static inline p4d_t *pgd_pgtable(pgd_t pgd)
 
 static inline struct page *pgd_page(pgd_t pgd)
 {
-	return pfn_to_page(__page_val_to_pfn(pgd_val(pgd)));
+	return pfn_to_page(pgd_pfn(pgd));
 }
-#define pgd_page(pgd)	pgd_page(pgd)
 
 #define p4d_index(addr) (((addr) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
 
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index e79f15293492..3e0e1177107d 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -258,19 +258,19 @@ static inline pgd_t pfn_pgd(unsigned long pfn, pgprot_t prot)
 	return __pgd((pfn << _PAGE_PFN_SHIFT) | prot_val);
 }
 
-static inline unsigned long _pgd_pfn(pgd_t pgd)
+static inline unsigned long pmd_pfn(pmd_t pmd)
 {
-	return __page_val_to_pfn(pgd_val(pgd));
+	return __page_val_to_pfn(pmd_val(pmd));
 }
 
 static inline struct page *pmd_page(pmd_t pmd)
 {
-	return pfn_to_page(__page_val_to_pfn(pmd_val(pmd)));
+	return pfn_to_page(pmd_pfn(pmd));
 }
 
 static inline unsigned long pmd_page_vaddr(pmd_t pmd)
 {
-	return (unsigned long)pfn_to_virt(__page_val_to_pfn(pmd_val(pmd)));
+	return (unsigned long)pfn_to_virt(pmd_pfn(pmd));
 }
 
 static inline pte_t pmd_pte(pmd_t pmd)
@@ -673,21 +673,6 @@ static inline pmd_t pmd_mkinvalid(pmd_t pmd)
 	return __pmd(pmd_val(pmd) & ~(_PAGE_PRESENT|_PAGE_PROT_NONE));
 }
 
-#define __pmd_to_phys(pmd)  (__page_val_to_pfn(pmd_val(pmd)) << PAGE_SHIFT)
-
-static inline unsigned long pmd_pfn(pmd_t pmd)
-{
-	return ((__pmd_to_phys(pmd) & PMD_MASK) >> PAGE_SHIFT);
-}
-
-#define __pud_to_phys(pud)  (__page_val_to_pfn(pud_val(pud)) << PAGE_SHIFT)
-
-#define pud_pfn pud_pfn
-static inline unsigned long pud_pfn(pud_t pud)
-{
-	return ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT);
-}
-
 static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
 {
 	return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 0e8c20adcd98..7282b62b7e8d 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -497,7 +497,7 @@ static void __meminit create_pmd_mapping(pmd_t *pmdp,
 		ptep = pt_ops.get_pte_virt(pte_phys);
 		memset(ptep, 0, PAGE_SIZE);
 	} else {
-		pte_phys = PFN_PHYS(_pmd_pfn(pmdp[pmd_idx]));
+		pte_phys = PFN_PHYS(pmd_pfn(pmdp[pmd_idx]));
 		ptep = pt_ops.get_pte_virt(pte_phys);
 	}
 
@@ -599,7 +599,7 @@ static void __meminit create_pud_mapping(pud_t *pudp, uintptr_t va, phys_addr_t
 		nextp = pt_ops.get_pmd_virt(next_phys);
 		memset(nextp, 0, PAGE_SIZE);
 	} else {
-		next_phys = PFN_PHYS(_pud_pfn(pudp[pud_index]));
+		next_phys = PFN_PHYS(pud_pfn(pudp[pud_index]));
 		nextp = pt_ops.get_pmd_virt(next_phys);
 	}
 
@@ -625,7 +625,7 @@ static void __meminit create_p4d_mapping(p4d_t *p4dp, uintptr_t va, phys_addr_t
 		nextp = pt_ops.get_pud_virt(next_phys);
 		memset(nextp, 0, PAGE_SIZE);
 	} else {
-		next_phys = PFN_PHYS(_p4d_pfn(p4dp[p4d_index]));
+		next_phys = PFN_PHYS(p4d_pfn(p4dp[p4d_index]));
 		nextp = pt_ops.get_pud_virt(next_phys);
 	}
 
@@ -682,7 +682,7 @@ void __meminit create_pgd_mapping(pgd_t *pgdp, uintptr_t va, phys_addr_t pa, phy
 		nextp = get_pgd_next_virt(next_phys);
 		memset(nextp, 0, PAGE_SIZE);
 	} else {
-		next_phys = PFN_PHYS(_pgd_pfn(pgdp[pgd_idx]));
+		next_phys = PFN_PHYS(pgd_pfn(pgdp[pgd_idx]));
 		nextp = get_pgd_next_virt(next_phys);
 	}
 
diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c
index c301c8d291d2..bac65e3268a4 100644
--- a/arch/riscv/mm/kasan_init.c
+++ b/arch/riscv/mm/kasan_init.c
@@ -171,7 +171,7 @@ static void __init kasan_early_clear_pud(p4d_t *p4dp,
 	if (!pgtable_l4_enabled) {
 		pudp = (pud_t *)p4dp;
 	} else {
-		base_pud = pt_ops.get_pud_virt(pfn_to_phys(_p4d_pfn(p4dp_get(p4dp))));
+		base_pud = pt_ops.get_pud_virt(pfn_to_phys(p4d_pfn(p4dp_get(p4dp))));
 		pudp = base_pud + pud_index(vaddr);
 	}
 
@@ -196,7 +196,7 @@ static void __init kasan_early_clear_p4d(pgd_t *pgdp,
 	if (!pgtable_l5_enabled) {
 		p4dp = (p4d_t *)pgdp;
 	} else {
-		base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(pgdp_get(pgdp))));
+		base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(pgd_pfn(pgdp_get(pgdp))));
 		p4dp = base_p4d + p4d_index(vaddr);
 	}
 
@@ -242,7 +242,7 @@ static void __init kasan_early_populate_pud(p4d_t *p4dp,
 	if (!pgtable_l4_enabled) {
 		pudp = (pud_t *)p4dp;
 	} else {
-		base_pud = pt_ops.get_pud_virt(pfn_to_phys(_p4d_pfn(p4dp_get(p4dp))));
+		base_pud = pt_ops.get_pud_virt(pfn_to_phys(p4d_pfn(p4dp_get(p4dp))));
 		pudp = base_pud + pud_index(vaddr);
 	}
 
@@ -280,7 +280,7 @@ static void __init kasan_early_populate_p4d(pgd_t *pgdp,
 	if (!pgtable_l5_enabled) {
 		p4dp = (p4d_t *)pgdp;
 	} else {
-		base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(pgdp_get(pgdp))));
+		base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(pgd_pfn(pgdp_get(pgdp))));
 		p4dp = base_p4d + p4d_index(vaddr);
 	}
 
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:07:58 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:07:58 -0700
Subject: [PATCH 04/11] riscv: mm: Deduplicate _PAGE_CHG_MASK definition
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-5-samuel.holland@sifive.com>

The two existing definitions are equivalent because _PAGE_MTMASK is
defined as 0 on riscv32.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/include/asm/pgtable-32.h | 5 -----
 arch/riscv/include/asm/pgtable-64.h | 7 -------
 arch/riscv/include/asm/pgtable.h    | 6 ++++++
 3 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/arch/riscv/include/asm/pgtable-32.h b/arch/riscv/include/asm/pgtable-32.h
index 23137347dc15..7dc0751d67dc 100644
--- a/arch/riscv/include/asm/pgtable-32.h
+++ b/arch/riscv/include/asm/pgtable-32.h
@@ -28,11 +28,6 @@
 #define _PAGE_IO		0
 #define _PAGE_MTMASK		0
 
-/* Set of bits to preserve across pte_modify() */
-#define _PAGE_CHG_MASK  (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ |	\
-					  _PAGE_WRITE | _PAGE_EXEC |	\
-					  _PAGE_USER | _PAGE_GLOBAL))
-
 #define pud_pfn(pud)				(pmd_pfn((pmd_t){ pud }))
 #define p4d_pfn(p4d)				(pud_pfn((pud_t){ p4d }))
 #define pgd_pfn(pgd)				(p4d_pfn((p4d_t){ pgd }))
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 33e7ff049c4a..4ba88592b8d1 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -66,7 +66,6 @@ typedef struct {
 
 #define pmd_val(x)      ((x).pmd)
 #define __pmd(x)        ((pmd_t) { (x) })
-
 #define PTRS_PER_PMD    (PAGE_SIZE / sizeof(pmd_t))
 
 /*
@@ -166,12 +165,6 @@ static inline u64 riscv_page_io(void)
 #define _PAGE_IO		riscv_page_io()
 #define _PAGE_MTMASK		riscv_page_mtmask()
 
-/* Set of bits to preserve across pte_modify() */
-#define _PAGE_CHG_MASK  (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ |	\
-					  _PAGE_WRITE | _PAGE_EXEC |	\
-					  _PAGE_USER | _PAGE_GLOBAL |	\
-					  _PAGE_MTMASK))
-
 static inline int pud_present(pud_t pud)
 {
 	return (pud_val(pud) & _PAGE_PRESENT);
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 3e0e1177107d..afa0b455eaa4 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -201,6 +201,12 @@ extern struct pt_alloc_ops pt_ops __meminitdata;
 #define _PAGE_IOREMAP	((_PAGE_KERNEL & ~_PAGE_MTMASK) | _PAGE_IO)
 #define PAGE_KERNEL_IO		__pgprot(_PAGE_IOREMAP)
 
+/* Set of bits to preserve across pte_modify() */
+#define _PAGE_CHG_MASK  (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ |	\
+					  _PAGE_WRITE | _PAGE_EXEC |	\
+					  _PAGE_USER | _PAGE_GLOBAL |	\
+					  _PAGE_MTMASK))
+
 extern pgd_t swapper_pg_dir[];
 extern pgd_t trampoline_pg_dir[];
 extern pgd_t early_pg_dir[];
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:07:59 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:07:59 -0700
Subject: [PATCH 05/11] riscv: ptdump: Only show N and MT bits when enabled in the kernel
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-6-samuel.holland@sifive.com>

When the Svnapot or Svpbmt extension is not implemented, the
corresponding page table bits are reserved, and must be zero. There is
no need to show them in the ptdump output.

When the Kconfig option for an extension is disabled, we assume it is
not implemented. In that case, the kernel may provide a fallback
definition for the fields, like how _PAGE_MTMASK is defined on riscv32.
Using those fallback definitions in ptdump would produce incorrect
results. To avoid this, hide the fields from the ptdump output.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/mm/ptdump.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
index 9d5f657a251b..58a7322e9a82 100644
--- a/arch/riscv/mm/ptdump.c
+++ b/arch/riscv/mm/ptdump.c
@@ -135,11 +135,13 @@ struct prot_bits {
 
 static const struct prot_bits pte_bits[] = {
 	{
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_RISCV_ISA_SVNAPOT
 		.mask = _PAGE_NAPOT,
 		.set = "N",
 		.clear = ".",
 	}, {
+#endif
+#ifdef CONFIG_RISCV_ISA_SVPBMT
 		.mask = _PAGE_MTMASK_SVPBMT,
 		.set = "MT(%s)",
 		.clear = "  ..  ",
@@ -215,7 +217,7 @@ static void dump_prot(struct pg_state *st)
 		if (val) {
 			if (pte_bits[i].mask == _PAGE_SOFT)
 				sprintf(s, pte_bits[i].set, val >> 8);
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_RISCV_ISA_SVPBMT
 			else if (pte_bits[i].mask == _PAGE_MTMASK_SVPBMT) {
 				if (val == _PAGE_NOCACHE_SVPBMT)
 					sprintf(s, pte_bits[i].set, "NC");
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:08:00 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:08:00 -0700
Subject: [PATCH 06/11] riscv: mm: Fix up memory types when writing page tables
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-7-samuel.holland@sifive.com>

Currently, Linux on RISC-V has three ways to specify the cacheability
and ordering PMAs of a page:
 1) Do nothing; assume the system is entirely cache-coherent and rely on
    the hardware for any ordering requirements
 2) Use the page table bits specified by Svpbmt
 3) Use the page table bits specified by XTheadMae

To support all three methods, the kernel dynamically determines the
definitions of the _PAGE_NOCACHE and _PAGE_IO fields. However, this
alone is not sufficient, as XTheadMae uses a nonzero memory type value
for normal memory pages. So the kernel has an additional alternative
sequence (ALT_THEAD_PMA) to insert the correct memory type when writing
page table entries.

Some RISC-V platforms use a fourth method to specify the cacheability of
a page of RAM: RAM is mapped to multiple physical address ranges, with
each alias having a different set of statically-determined PMAs.
Software selects the PMAs for a page by choosing a PFN from the
corresponding physical address range. This strategy also requires
applying a transformation when writing page table entries. Since these
physical memory aliases should be invisible to the rest of the kernel,
the opposite transformation must be applied when reading page table
entries.

However, with this last method of specifying PMAs, there is no inherent
way to indicate the cacheability of a page in the pgprot_t value, since
the PFN itself determines cacheability. One possible way is to reuse the
PTE bits from Svpbmt, as Svpbmt is the standard extension. This requires
the Svpbmt version of _PAGE_NOCACHE and _PAGE_IO to be available even
when the CPU does not support the extension.

It turns out that with some clever bit manipulation, it is just as
efficient to transform all three Svpbmt memory type values to the
corresponding XTheadMae values, as it is to check for and insert the
one XTheadMae memory type value for normal memory. This allows the
_PAGE_NOCACHE and _PAGE_IO definitions to be compile-time constants,
and it centralizes all memory type handling to one set of ALTERNATIVE
macros.

For a kernel with both Svpbmt and XTheadMae enabled, this change reduces
both kernel text size and the number of alternatives applied at boot.
However, there are a couple of small costs. For platforms using the
first method ("do nothing"), we must mask off the memory type bits when
writing page table entries, whereas previously no action was needed.
Second, when reading page table entries, the XTheadMae values must be
transformed back to the Svpbmt values. This "unfix" operation is also
needed for alias-based PMA selection, so both methods can use the same
ALTERNATIVE.

As a side effect, this change fixes the reporting of the NAPOT and
memory type bits from ptdump on platforms with XTheadMae.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/Kconfig.errata            |   1 +
 arch/riscv/include/asm/errata_list.h |  45 -----------
 arch/riscv/include/asm/pgtable-32.h  |   3 +
 arch/riscv/include/asm/pgtable-64.h  | 108 ++++++++++++++++++---------
 arch/riscv/include/asm/pgtable.h     |  18 +++--
 arch/riscv/mm/ptdump.c               |  13 ++--
 6 files changed, 93 insertions(+), 95 deletions(-)

diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 2acc7d876e1f..2806ed7916c7 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -86,6 +86,7 @@ config ERRATA_THEAD_MAE
 	bool "Apply T-Head's memory attribute extension (XTheadMae) errata"
 	depends on ERRATA_THEAD && 64BIT && MMU
 	select RISCV_ALTERNATIVE_EARLY
+	select RISCV_ISA_SVPBMT
 	default y
 	help
 	  This will apply the memory attribute extension errata to handle the
diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index 7c8a71a526a3..b127f4891083 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -58,51 +58,6 @@ asm(ALTERNATIVE("sfence.vma %0, %1", "sfence.vma", SIFIVE_VENDOR_ID,	\
 		ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200)	\
 		: : "r" (addr), "r" (asid) : "memory")
 
-/*
- * _val is marked as "will be overwritten", so need to set it to 0
- * in the default case.
- */
-#define ALT_SVPBMT_SHIFT 61
-#define ALT_THEAD_MAE_SHIFT 59
-#define ALT_SVPBMT(_val, prot)						\
-asm(ALTERNATIVE_2("li %0, 0\t\nnop",					\
-		  "li %0, %1\t\nslli %0,%0,%3", 0,			\
-			RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,	\
-		  "li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID,	\
-			ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)	\
-		: "=r"(_val)						\
-		: "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT),		\
-		  "I"(prot##_THEAD >> ALT_THEAD_MAE_SHIFT),		\
-		  "I"(ALT_SVPBMT_SHIFT),				\
-		  "I"(ALT_THEAD_MAE_SHIFT))
-
-#ifdef CONFIG_ERRATA_THEAD_MAE
-/*
- * IO/NOCACHE memory types are handled together with svpbmt,
- * so on T-Head chips, check if no other memory type is set,
- * and set the non-0 PMA type if applicable.
- */
-#define ALT_THEAD_PMA(_val)						\
-asm volatile(ALTERNATIVE(						\
-	__nops(7),							\
-	"li      t3, %1\n\t"						\
-	"slli    t3, t3, %3\n\t"					\
-	"and     t3, %0, t3\n\t"					\
-	"bne     t3, zero, 2f\n\t"					\
-	"li      t3, %2\n\t"						\
-	"slli    t3, t3, %3\n\t"					\
-	"or      %0, %0, t3\n\t"					\
-	"2:",  THEAD_VENDOR_ID,						\
-		ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)		\
-	: "+r"(_val)							\
-	: "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_MAE_SHIFT),		\
-	  "I"(_PAGE_PMA_THEAD >> ALT_THEAD_MAE_SHIFT),			\
-	  "I"(ALT_THEAD_MAE_SHIFT)					\
-	: "t3")
-#else
-#define ALT_THEAD_PMA(_val)
-#endif
-
 #define ALT_CMO_OP(_op, _start, _size, _cachesize)			\
 asm volatile(ALTERNATIVE(						\
 	__nops(5),							\
diff --git a/arch/riscv/include/asm/pgtable-32.h b/arch/riscv/include/asm/pgtable-32.h
index 7dc0751d67dc..b422a15fb464 100644
--- a/arch/riscv/include/asm/pgtable-32.h
+++ b/arch/riscv/include/asm/pgtable-32.h
@@ -28,6 +28,9 @@
 #define _PAGE_IO		0
 #define _PAGE_MTMASK		0
 
+#define ALT_FIXUP_MT(_val)
+#define ALT_UNFIX_MT(_val)
+
 #define pud_pfn(pud)				(pmd_pfn((pmd_t){ pud }))
 #define p4d_pfn(p4d)				(pud_pfn((pud_t){ p4d }))
 #define pgd_pfn(pgd)				(p4d_pfn((p4d_t){ pgd }))
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 4ba88592b8d1..4e8a32f035d7 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -8,7 +8,7 @@
 
 #include <linux/bits.h>
 #include <linux/const.h>
-#include <asm/errata_list.h>
+#include <asm/alternative-macros.h>
 
 extern bool pgtable_l4_enabled;
 extern bool pgtable_l5_enabled;
@@ -109,6 +109,8 @@ enum napot_cont_order {
 #define HUGE_MAX_HSTATE		2
 #endif
 
+#ifdef CONFIG_RISCV_ISA_SVPBMT
+
 /*
  * [62:61] Svpbmt Memory Type definitions:
  *
@@ -117,9 +119,9 @@ enum napot_cont_order {
  *  10 - IO     Non-cacheable, non-idempotent, strongly-ordered I/O memory
  *  11 - Rsvd   Reserved for future standard use
  */
-#define _PAGE_NOCACHE_SVPBMT	(1UL << 61)
-#define _PAGE_IO_SVPBMT		(1UL << 62)
-#define _PAGE_MTMASK_SVPBMT	(_PAGE_NOCACHE_SVPBMT | _PAGE_IO_SVPBMT)
+#define _PAGE_NOCACHE		(1UL << 61)
+#define _PAGE_IO		(2UL << 61)
+#define _PAGE_MTMASK		(3UL << 61)
 
 /*
  * [63:59] T-Head Memory Type definitions:
@@ -128,42 +130,66 @@ enum napot_cont_order {
  * bit[61] B - Bufferable
  * bit[60] SH - Shareable
  * bit[59] Sec - Trustable
- * 00110 - NC   Weakly-ordered, Non-cacheable, Bufferable, Shareable, Non-trustable
  * 01110 - PMA  Weakly-ordered, Cacheable, Bufferable, Shareable, Non-trustable
+ * 00110 - NC   Weakly-ordered, Non-cacheable, Bufferable, Shareable, Non-trustable
  * 10010 - IO   Strongly-ordered, Non-cacheable, Non-bufferable, Shareable, Non-trustable
+ *
+ * ALT_FIXUP_MT translates Svpbmt memory types to XTheadMae memory types.
+ * Pseudocode operating on bits [63:60]:
+ *   t0 = mt << 1
+ *   if (t0 == 0)
+ *     t0 |= 2
+ *   t0 ^= 0x5
+ *   mt ^= t0
+ *
+ * ALT_UNFIX_MT translates XTheadMae memory types to Svpbmt memory types.
+ * Pseudocode operating on bits [63:60]:
+ *   t0 = mt & 0xd
+ *   t0 ^= t0 >> 1
+ *   mt ^= t0
  */
-#define _PAGE_PMA_THEAD		((1UL << 62) | (1UL << 61) | (1UL << 60))
-#define _PAGE_NOCACHE_THEAD	((1UL << 61) | (1UL << 60))
-#define _PAGE_IO_THEAD		((1UL << 63) | (1UL << 60))
-#define _PAGE_MTMASK_THEAD	(_PAGE_PMA_THEAD | _PAGE_IO_THEAD | (1UL << 59))
-
-static inline u64 riscv_page_mtmask(void)
-{
-	u64 val;
-
-	ALT_SVPBMT(val, _PAGE_MTMASK);
-	return val;
-}
 
-static inline u64 riscv_page_nocache(void)
-{
-	u64 val;
+#define ALT_FIXUP_MT(_val)								\
+	asm(ALTERNATIVE_2("addi	t0, zero, 0x3\n\t"					\
+			  "slli	t0, t0, 61\n\t"						\
+			  "not	t0, t0\n\t"						\
+			  "and	%0, %0, t0\n\t"						\
+			  "nop\n\t"							\
+			  "nop\n\t"							\
+			  "nop",							\
+			  __nops(7),							\
+			  0, RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,		\
+			  "srli	t0, %0, 59\n\t"						\
+			  "seqz t1, t0\n\t"						\
+			  "slli	t1, t1, 1\n\t"						\
+			  "or	t0, t0, t1\n\t"						\
+			  "xori	t0, t0, 0x5\n\t"					\
+			  "slli	t0, t0, 60\n\t"						\
+			  "xor	%0, %0, t0",						\
+			  THEAD_VENDOR_ID, ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)	\
+			  : "+r" (_val) :: "t0", "t1")
+
+#define ALT_UNFIX_MT(_val)								\
+	asm(ALTERNATIVE(__nops(6),							\
+			  "srli	t0, %0, 60\n\t"						\
+			  "andi	t0, t0, 0xd\n\t"					\
+			  "srli	t1, t0, 1\n\t"						\
+			  "xor	t0, t0, t1\n\t"						\
+			  "slli	t0, t0, 60\n\t"						\
+			  "xor	%0, %0, t0",						\
+			  THEAD_VENDOR_ID, ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)	\
+			  : "+r" (_val) :: "t0", "t1")
 
-	ALT_SVPBMT(val, _PAGE_NOCACHE);
-	return val;
-}
+#else
 
-static inline u64 riscv_page_io(void)
-{
-	u64 val;
+#define _PAGE_NOCACHE		0
+#define _PAGE_IO		0
+#define _PAGE_MTMASK		0
 
-	ALT_SVPBMT(val, _PAGE_IO);
-	return val;
-}
+#define ALT_FIXUP_MT(_val)
+#define ALT_UNFIX_MT(_val)
 
-#define _PAGE_NOCACHE		riscv_page_nocache()
-#define _PAGE_IO		riscv_page_io()
-#define _PAGE_MTMASK		riscv_page_mtmask()
+#endif /* CONFIG_RISCV_ISA_SVPBMT */
 
 static inline int pud_present(pud_t pud)
 {
@@ -203,7 +229,11 @@ static inline void pud_clear(pud_t *pudp)
 
 static inline pud_t pfn_pud(unsigned long pfn, pgprot_t prot)
 {
-	return __pud((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
+	pud_t pud = __pud((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
+
+	ALT_FIXUP_MT(pud);
+
+	return pud;
 }
 
 #define pud_pfn pud_pfn
@@ -244,11 +274,11 @@ static inline bool mm_pud_folded(struct mm_struct *mm)
 
 static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t prot)
 {
-	unsigned long prot_val = pgprot_val(prot);
+	pmd_t pmd = __pmd((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
 
-	ALT_THEAD_PMA(prot_val);
+	ALT_FIXUP_MT(pmd);
 
-	return __pmd((pfn << _PAGE_PFN_SHIFT) | prot_val);
+	return pmd;
 }
 
 #define mk_pmd(page, prot)    pfn_pmd(page_to_pfn(page), prot)
@@ -302,7 +332,11 @@ static inline void p4d_clear(p4d_t *p4d)
 
 static inline p4d_t pfn_p4d(unsigned long pfn, pgprot_t prot)
 {
-	return __p4d((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
+	p4d_t p4d = __p4d((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
+
+	ALT_FIXUP_MT(p4d);
+
+	return p4d;
 }
 
 static inline unsigned long p4d_pfn(p4d_t p4d)
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index afa0b455eaa4..3ffcff76ac0d 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -257,11 +257,11 @@ static inline void pmd_clear(pmd_t *pmdp)
 
 static inline pgd_t pfn_pgd(unsigned long pfn, pgprot_t prot)
 {
-	unsigned long prot_val = pgprot_val(prot);
+	pgd_t pgd = __pgd((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
 
-	ALT_THEAD_PMA(prot_val);
+	ALT_FIXUP_MT(pgd);
 
-	return __pgd((pfn << _PAGE_PFN_SHIFT) | prot_val);
+	return pgd;
 }
 
 static inline unsigned long pmd_pfn(pmd_t pmd)
@@ -338,11 +338,11 @@ static inline unsigned long pte_pfn(pte_t pte)
 /* Constructs a page table entry */
 static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
 {
-	unsigned long prot_val = pgprot_val(prot);
+	pte_t pte = __pte((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
 
-	ALT_THEAD_PMA(prot_val);
+	ALT_FIXUP_MT(pte);
 
-	return __pte((pfn << _PAGE_PFN_SHIFT) | prot_val);
+	return pte;
 }
 
 #define mk_pte(page, prot)       pfn_pte(page_to_pfn(page), prot)
@@ -489,9 +489,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
 	unsigned long newprot_val = pgprot_val(newprot);
 
-	ALT_THEAD_PMA(newprot_val);
+	ALT_UNFIX_MT(pte);
+	pte = __pte((pte_val(pte) & _PAGE_CHG_MASK) | newprot_val);
+	ALT_FIXUP_MT(pte);
 
-	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | newprot_val);
+	return pte;
 }
 
 #define pgd_ERROR(e) \
diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
index 58a7322e9a82..6528c2561437 100644
--- a/arch/riscv/mm/ptdump.c
+++ b/arch/riscv/mm/ptdump.c
@@ -142,7 +142,7 @@ static const struct prot_bits pte_bits[] = {
 	}, {
 #endif
 #ifdef CONFIG_RISCV_ISA_SVPBMT
-		.mask = _PAGE_MTMASK_SVPBMT,
+		.mask = _PAGE_MTMASK,
 		.set = "MT(%s)",
 		.clear = "  ..  ",
 	}, {
@@ -218,10 +218,10 @@ static void dump_prot(struct pg_state *st)
 			if (pte_bits[i].mask == _PAGE_SOFT)
 				sprintf(s, pte_bits[i].set, val >> 8);
 #ifdef CONFIG_RISCV_ISA_SVPBMT
-			else if (pte_bits[i].mask == _PAGE_MTMASK_SVPBMT) {
-				if (val == _PAGE_NOCACHE_SVPBMT)
+			else if (pte_bits[i].mask == _PAGE_MTMASK) {
+				if (val == _PAGE_NOCACHE)
 					sprintf(s, pte_bits[i].set, "NC");
-				else if (val == _PAGE_IO_SVPBMT)
+				else if (val == _PAGE_IO)
 					sprintf(s, pte_bits[i].set, "IO");
 				else
 					sprintf(s, pte_bits[i].set, "??");
@@ -282,9 +282,12 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr,
 		      int level, u64 val)
 {
 	struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
-	u64 pa = PFN_PHYS(pte_pfn(__pte(val)));
 	u64 prot = 0;
+	u64 pa;
 
+	ALT_UNFIX_MT(val);
+
+	pa = PFN_PHYS(pte_pfn(__pte(val)));
 	if (level >= 0)
 		prot = val & pg_level[level].mask;
 
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:08:01 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:08:01 -0700
Subject: [PATCH 07/11] riscv: mm: Expose all page table bits to assembly code
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-8-samuel.holland@sifive.com>

pgtable-32.h and pgtable-64.h are not usable by assembly code, so move
all page table field definitions to pgtable-bits.h.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/include/asm/pgtable-32.h   | 11 -------
 arch/riscv/include/asm/pgtable-64.h   | 30 -------------------
 arch/riscv/include/asm/pgtable-bits.h | 42 +++++++++++++++++++++++++--
 3 files changed, 40 insertions(+), 43 deletions(-)

diff --git a/arch/riscv/include/asm/pgtable-32.h b/arch/riscv/include/asm/pgtable-32.h
index b422a15fb464..ba50b65b434b 100644
--- a/arch/riscv/include/asm/pgtable-32.h
+++ b/arch/riscv/include/asm/pgtable-32.h
@@ -17,17 +17,6 @@
 
 #define MAX_POSSIBLE_PHYSMEM_BITS 34
 
-/*
- * rv32 PTE format:
- * | XLEN-1  10 | 9             8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
- *       PFN      reserved for SW   D   A   G   U   X   W   R   V
- */
-#define _PAGE_PFN_MASK  GENMASK(31, 10)
-
-#define _PAGE_NOCACHE		0
-#define _PAGE_IO		0
-#define _PAGE_MTMASK		0
-
 #define ALT_FIXUP_MT(_val)
 #define ALT_UNFIX_MT(_val)
 
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 4e8a32f035d7..174b6a5837c2 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -68,20 +68,6 @@ typedef struct {
 #define __pmd(x)        ((pmd_t) { (x) })
 #define PTRS_PER_PMD    (PAGE_SIZE / sizeof(pmd_t))
 
-/*
- * rv64 PTE format:
- * | 63 | 62 61 | 60 54 | 53  10 | 9             8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
- *   N      MT     RSV    PFN      reserved for SW   D   A   G   U   X   W   R   V
- */
-#define _PAGE_PFN_MASK  GENMASK(53, 10)
-
-/*
- * [63] Svnapot definitions:
- * 0 Svnapot disabled
- * 1 Svnapot enabled
- */
-#define _PAGE_NAPOT_SHIFT	63
-#define _PAGE_NAPOT		BIT(_PAGE_NAPOT_SHIFT)
 /*
  * Only 64KB (order 4) napot ptes supported.
  */
@@ -111,18 +97,6 @@ enum napot_cont_order {
 
 #ifdef CONFIG_RISCV_ISA_SVPBMT
 
-/*
- * [62:61] Svpbmt Memory Type definitions:
- *
- *  00 - PMA    Normal Cacheable, No change to implied PMA memory type
- *  01 - NC     Non-cacheable, idempotent, weakly-ordered Main Memory
- *  10 - IO     Non-cacheable, non-idempotent, strongly-ordered I/O memory
- *  11 - Rsvd   Reserved for future standard use
- */
-#define _PAGE_NOCACHE		(1UL << 61)
-#define _PAGE_IO		(2UL << 61)
-#define _PAGE_MTMASK		(3UL << 61)
-
 /*
  * [63:59] T-Head Memory Type definitions:
  * bit[63] SO - Strong Order
@@ -182,10 +156,6 @@ enum napot_cont_order {
 
 #else
 
-#define _PAGE_NOCACHE		0
-#define _PAGE_IO		0
-#define _PAGE_MTMASK		0
-
 #define ALT_FIXUP_MT(_val)
 #define ALT_UNFIX_MT(_val)
 
diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
index a8f5205cea54..96710d4c1817 100644
--- a/arch/riscv/include/asm/pgtable-bits.h
+++ b/arch/riscv/include/asm/pgtable-bits.h
@@ -6,6 +6,16 @@
 #ifndef _ASM_RISCV_PGTABLE_BITS_H
 #define _ASM_RISCV_PGTABLE_BITS_H
 
+/*
+ * rv32 PTE format:
+ * | XLEN-1  10 | 9             8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
+ *       PFN      reserved for SW   D   A   G   U   X   W   R   V
+ *
+ * rv64 PTE format:
+ * | 63 | 62 61 | 60 54 | 53 10 | 9             8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
+ *   N      MT     RSV     PFN    reserved for SW   D   A   G   U   X   W   R   V
+ */
+
 #define _PAGE_ACCESSED_OFFSET 6
 
 #define _PAGE_PRESENT   (1 << 0)
@@ -22,6 +32,36 @@
 #define _PAGE_DEVMAP    (1 << 9)    /* RSW, devmap */
 #define _PAGE_TABLE     _PAGE_PRESENT
 
+#define _PAGE_PFN_SHIFT		10
+#ifdef CONFIG_64BIT
+#define _PAGE_PFN_MASK		GENMASK(53, 10)
+#else
+#define _PAGE_PFN_MASK		GENMASK(31, 10)
+#endif /* CONFIG_64BIT */
+
+#ifdef CONFIG_RISCV_ISA_SVPBMT
+/*
+ * [62:61] Svpbmt Memory Type definitions:
+ *
+ *  00 - PMA    Normal Cacheable, No change to implied PMA memory type
+ *  01 - NC     Non-cacheable, idempotent, weakly-ordered Main Memory
+ *  10 - IO     Non-cacheable, non-idempotent, strongly-ordered I/O memory
+ *  11 - Rsvd   Reserved for future standard use
+ */
+#define _PAGE_NOCACHE		(UL(1) << 61)
+#define _PAGE_IO		(UL(2) << 61)
+#define _PAGE_MTMASK		(UL(3) << 61)
+#else
+#define _PAGE_NOCACHE		0
+#define _PAGE_IO		0
+#define _PAGE_MTMASK		0
+#endif /* CONFIG_RISCV_ISA_SVPBMT */
+
+#ifdef CONFIG_RISCV_ISA_SVNAPOT
+#define _PAGE_NAPOT_SHIFT	63
+#define _PAGE_NAPOT		BIT(_PAGE_NAPOT_SHIFT)
+#endif /* CONFIG_RISCV_ISA_SVNAPOT */
+
 /*
  * _PAGE_PROT_NONE is set on not-present pages (and ignored by the hardware) to
  * distinguish them from swapped out pages
@@ -31,8 +71,6 @@
 /* Used for swap PTEs only. */
 #define _PAGE_SWP_EXCLUSIVE _PAGE_ACCESSED
 
-#define _PAGE_PFN_SHIFT 10
-
 /*
  * when all of R/W/X are zero, the PTE is a pointer to the next level
  * of the page table; otherwise, it is a leaf PTE.
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:08:02 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:08:02 -0700
Subject: [PATCH 08/11] riscv: alternative: Add an ALTERNATIVE_3 macro
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-9-samuel.holland@sifive.com>

ALT_FIXUP_PMA() is already using ALTERNATIVE_2(), but needs to be
extended to handle a fourth case. Add ALTERNATIVE_3(), which extends
ALTERNATIVE_2() with another block of new content.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/include/asm/alternative-macros.h | 45 ++++++++++++++++++---
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/arch/riscv/include/asm/alternative-macros.h b/arch/riscv/include/asm/alternative-macros.h
index 721ec275ce57..b6027a8b6b50 100644
--- a/arch/riscv/include/asm/alternative-macros.h
+++ b/arch/riscv/include/asm/alternative-macros.h
@@ -50,8 +50,17 @@
 	ALT_NEW_CONTENT \vendor_id_2, \patch_id_2, \enable_2, "\new_c_2"
 .endm
 
+.macro ALTERNATIVE_CFG_3 old_c, new_c_1, vendor_id_1, patch_id_1, enable_1,	\
+				new_c_2, vendor_id_2, patch_id_2, enable_2,	\
+				new_c_3, vendor_id_3, patch_id_3, enable_3
+	ALTERNATIVE_CFG_2 "\old_c", "\new_c_1", \vendor_id_1, \patch_id_1, \enable_1 \
+				    "\new_c_2", \vendor_id_2, \patch_id_2, \enable_2 \
+	ALT_NEW_CONTENT \vendor_id_3, \patch_id_3, \enable_3, "\new_c_3"
+.endm
+
 #define __ALTERNATIVE_CFG(...)		ALTERNATIVE_CFG __VA_ARGS__
 #define __ALTERNATIVE_CFG_2(...)	ALTERNATIVE_CFG_2 __VA_ARGS__
+#define __ALTERNATIVE_CFG_3(...)	ALTERNATIVE_CFG_3 __VA_ARGS__
 
 #else /* !__ASSEMBLY__ */
 
@@ -98,6 +107,13 @@
 	__ALTERNATIVE_CFG(old_c, new_c_1, vendor_id_1, patch_id_1, enable_1)	\
 	ALT_NEW_CONTENT(vendor_id_2, patch_id_2, enable_2, new_c_2)
 
+#define __ALTERNATIVE_CFG_3(old_c, new_c_1, vendor_id_1, patch_id_1, enable_1,	\
+				   new_c_2, vendor_id_2, patch_id_2, enable_2,	\
+				   new_c_3, vendor_id_3, patch_id_3, enable_3)	\
+	__ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, patch_id_1, enable_1,	\
+				   new_c_2, vendor_id_2, patch_id_2, enable_2)	\
+	ALT_NEW_CONTENT(vendor_id_3, patch_id_3, enable_3, new_c_3)
+
 #endif /* __ASSEMBLY__ */
 
 #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, patch_id, CONFIG_k)	\
@@ -108,6 +124,13 @@
 	__ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, patch_id_1, IS_ENABLED(CONFIG_k_1),	\
 				   new_c_2, vendor_id_2, patch_id_2, IS_ENABLED(CONFIG_k_2))
 
+#define _ALTERNATIVE_CFG_3(old_c, new_c_1, vendor_id_1, patch_id_1, CONFIG_k_1,		\
+				  new_c_2, vendor_id_2, patch_id_2, CONFIG_k_2,		\
+				  new_c_3, vendor_id_3, patch_id_3, CONFIG_k_3)		\
+	__ALTERNATIVE_CFG_3(old_c, new_c_1, vendor_id_1, patch_id_1, IS_ENABLED(CONFIG_k_1),	\
+				   new_c_2, vendor_id_2, patch_id_2, IS_ENABLED(CONFIG_k_2),	\
+				   new_c_3, vendor_id_3, patch_id_3, IS_ENABLED(CONFIG_k_3))
+
 #else /* CONFIG_RISCV_ALTERNATIVE */
 #ifdef __ASSEMBLY__
 
@@ -121,6 +144,9 @@
 #define _ALTERNATIVE_CFG_2(old_c, ...)	\
 	ALTERNATIVE_CFG old_c
 
+#define _ALTERNATIVE_CFG_3(old_c, ...)	\
+	ALTERNATIVE_CFG old_c
+
 #else /* !__ASSEMBLY__ */
 
 #define __ALTERNATIVE_CFG(old_c)	\
@@ -132,6 +158,9 @@
 #define _ALTERNATIVE_CFG_2(old_c, ...)	\
 	__ALTERNATIVE_CFG(old_c)
 
+#define _ALTERNATIVE_CFG_3(old_c, ...)	\
+	__ALTERNATIVE_CFG(old_c)
+
 #endif /* __ASSEMBLY__ */
 #endif /* CONFIG_RISCV_ALTERNATIVE */
 
@@ -152,15 +181,21 @@
 	_ALTERNATIVE_CFG(old_content, new_content, vendor_id, patch_id, CONFIG_k)
 
 /*
- * A vendor wants to replace an old_content, but another vendor has used
- * ALTERNATIVE() to patch its customized content at the same location. In
- * this case, this vendor can create a new macro ALTERNATIVE_2() based
- * on the following sample code and then replace ALTERNATIVE() with
- * ALTERNATIVE_2() to append its customized content.
+ * Variant of ALTERNATIVE() that supports two sets of replacement content.
  */
 #define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1,		\
 				   new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2)		\
 	_ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1,	\
 					new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2)
 
+/*
+ * Variant of ALTERNATIVE() that supports three sets of replacement content.
+ */
+#define ALTERNATIVE_3(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1,		\
+				   new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2,		\
+				   new_content_3, vendor_id_3, patch_id_3, CONFIG_k_3)		\
+	_ALTERNATIVE_CFG_3(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1,	\
+					new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2,	\
+					new_content_3, vendor_id_3, patch_id_3, CONFIG_k_3)
+
 #endif
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:08:03 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:08:03 -0700
Subject: [PATCH 09/11] riscv: alternative: Allow calls with alternate link registers
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-10-samuel.holland@sifive.com>

Alternative assembly code may wish to use an alternate link register to
minimize the number of clobbered registers. Apply the offset fix to all
jalr (not jr) instructions, i.e. where rd is not x0.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/kernel/alternative.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c
index 0128b161bfda..54d79e6f4afa 100644
--- a/arch/riscv/kernel/alternative.c
+++ b/arch/riscv/kernel/alternative.c
@@ -121,8 +121,8 @@ void riscv_alternative_fix_offsets(void *alt_ptr, unsigned int len,
 			if (!riscv_insn_is_jalr(insn2))
 				continue;
 
-			/* if instruction pair is a call, it will use the ra register */
-			if (RV_EXTRACT_RD_REG(insn) != 1)
+			/* if instruction pair is a call, it will save a link register */
+			if (RV_EXTRACT_RD_REG(insn) == 0)
 				continue;
 
 			riscv_alternative_fix_auipc_jalr(alt_ptr + i * sizeof(u32),
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:08:04 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:08:04 -0700
Subject: [PATCH 10/11] riscv: mm: Use physical memory aliases to apply PMAs
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-11-samuel.holland@sifive.com>

On some RISC-V platforms, RAM is mapped to multiple physical address
ranges, with each alias having a different set of statically-determined
Physical Memory Attributes (PMAs). Software selects the PMAs for a page
by choosing a PFN from the corresponding physical address range.

Implement this by transforming the PFN when writing page tables.  If the
memory type field is nonzero, replace the PFN with the corresponding PFN
from the noncached alias. Similarly, when reading from the page tables,
if the PFN is found in a noncached alias, replace it with the
corresponding PFN from the cached alias, and insert _PAGE_NOCACHE.

The rest of the kernel sees only the cached PFNs and _PAGE_MTMASK values
as if Svpbmt was implemented.

Memory alias pairs are determined from the devicetree. A new cpufeature
bit is required because that is the only way to trigger alternative
patching.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/Kconfig                  |   3 +
 arch/riscv/include/asm/hwcap.h      |   1 +
 arch/riscv/include/asm/pgtable-64.h |  27 ++++++--
 arch/riscv/include/asm/pgtable.h    |   8 +++
 arch/riscv/kernel/cpufeature.c      |   6 ++
 arch/riscv/kernel/setup.c           |   1 +
 arch/riscv/mm/Makefile              |   1 +
 arch/riscv/mm/memory-alias.S        | 101 ++++++++++++++++++++++++++++
 arch/riscv/mm/pgtable.c             |  91 +++++++++++++++++++++++++
 9 files changed, 235 insertions(+), 4 deletions(-)
 create mode 100644 arch/riscv/mm/memory-alias.S

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 62545946ecf4..d28d1dab5f26 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -566,6 +566,9 @@ config RISCV_ISA_SVPBMT
 
 	   The Svpbmt extension is only available on 64-bit cpus.
 
+	   This option also controls selection of memory type based on
+	   physical memory aliases.
+
 	   If you don't know what to do here, say Y.
 
 config TOOLCHAIN_HAS_V
diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index 46d9de54179e..8a37e22f4223 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -94,6 +94,7 @@
 #define RISCV_ISA_EXT_ZAWRS		85
 #define RISCV_ISA_EXT_SVVPTC		86
 
+#define RISCV_ISA_EXT_XLINUXMEMALIAS	126
 #define RISCV_ISA_EXT_XLINUXENVCFG	127
 
 #define RISCV_ISA_EXT_MAX		128
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 174b6a5837c2..6b4af408a37a 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -124,27 +124,46 @@ enum napot_cont_order {
  */
 
 #define ALT_FIXUP_MT(_val)								\
-	asm(ALTERNATIVE_2("addi	t0, zero, 0x3\n\t"					\
+	asm(ALTERNATIVE_3("addi	t0, zero, 0x3\n\t"					\
 			  "slli	t0, t0, 61\n\t"						\
 			  "not	t0, t0\n\t"						\
 			  "and	%0, %0, t0\n\t"						\
 			  "nop\n\t"							\
 			  "nop\n\t"							\
+			  "nop\n\t"							\
 			  "nop",							\
-			  __nops(7),							\
+			  __nops(8),							\
 			  0, RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,		\
+			  "addi t0, zero, 0x3\n\t"					\
+			  "slli	t0, t0, 61\n\t"						\
+			  "and	t0, %0, t0\n\t"						\
+			  "beqz t0, 2f\n\t"						\
+			  "xor	t1, %0, t0\n\t"						\
+			  "1: auipc t0, %%pcrel_hi(riscv_fixup_memory_alias)\n\t"	\
+			  "jalr	t0, t0, %%pcrel_lo(1b)\n\t"				\
+			  "mv	%0, t1\n"						\
+			  "2:",								\
+			  0, RISCV_ISA_EXT_XLINUXMEMALIAS, CONFIG_RISCV_ISA_SVPBMT,	\
 			  "srli	t0, %0, 59\n\t"						\
 			  "seqz t1, t0\n\t"						\
 			  "slli	t1, t1, 1\n\t"						\
 			  "or	t0, t0, t1\n\t"						\
 			  "xori	t0, t0, 0x5\n\t"					\
 			  "slli	t0, t0, 60\n\t"						\
-			  "xor	%0, %0, t0",						\
+			  "xor	%0, %0, t0\n\t"						\
+			  "nop",							\
 			  THEAD_VENDOR_ID, ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)	\
 			  : "+r" (_val) :: "t0", "t1")
 
 #define ALT_UNFIX_MT(_val)								\
-	asm(ALTERNATIVE(__nops(6),							\
+	asm(ALTERNATIVE_2(__nops(6),							\
+			  "mv	t1, %0\n\t"						\
+			  "1: auipc t0, %%pcrel_hi(riscv_unfix_memory_alias)\n\t"	\
+			  "jalr	t0, t0, %%pcrel_lo(1b)\n\t"				\
+			  "mv	%0, t1\n\t"						\
+			  "nop\n\t"							\
+			  "nop",							\
+			  0, RISCV_ISA_EXT_XLINUXMEMALIAS, CONFIG_RISCV_ISA_SVPBMT,	\
 			  "srli	t0, %0, 60\n\t"						\
 			  "andi	t0, t0, 0xd\n\t"					\
 			  "srli	t1, t0, 1\n\t"						\
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 3ffcff76ac0d..0e52dfaaff63 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -949,6 +949,14 @@ extern u64 satp_mode;
 void paging_init(void);
 void misc_mem_init(void);
 
+#ifdef CONFIG_RISCV_ISA_SVPBMT
+bool __init riscv_have_memory_alias(void);
+void __init riscv_init_memory_alias(void);
+#else
+static inline bool riscv_have_memory_alias(void) { return false; }
+static inline void riscv_init_memory_alias(void) {}
+#endif /* CONFIG_RISCV_ISA_SVPBMT */
+
 /*
  * ZERO_PAGE is a global shared page that is always zero,
  * used for zero-mapped memory areas, etc.
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 3a8eeaa9310c..ca36f8240a86 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -892,6 +892,12 @@ void __init riscv_fill_hwcap(void)
 			elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
 	}
 
+	/* Vendor-independent alternatives require a bit in the ISA bitmap. */
+	if (riscv_have_memory_alias()) {
+		set_bit(RISCV_ISA_EXT_XLINUXMEMALIAS, riscv_isa);
+		pr_info("Using physical memory alias for noncached mappings\n");
+	}
+
 	memset(print_str, 0, sizeof(print_str));
 	for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)
 		if (riscv_isa[0] & BIT_MASK(i))
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index a2cde65b69e9..ab718fc4538f 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -287,6 +287,7 @@ void __init setup_arch(char **cmdline_p)
 	}
 
 	riscv_init_cbo_blocksizes();
+	riscv_init_memory_alias();
 	riscv_fill_hwcap();
 	init_rt_signal_env();
 	apply_boot_alternatives();
diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index cbe4d775ef56..50d843b298cd 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -33,3 +33,4 @@ endif
 obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
 obj-$(CONFIG_RISCV_DMA_NONCOHERENT) += dma-noncoherent.o
 obj-$(CONFIG_RISCV_NONSTANDARD_CACHE_OPS) += cache-ops.o
+obj-$(CONFIG_RISCV_ISA_SVPBMT) += memory-alias.o
diff --git a/arch/riscv/mm/memory-alias.S b/arch/riscv/mm/memory-alias.S
new file mode 100644
index 000000000000..df2e8cc3f69c
--- /dev/null
+++ b/arch/riscv/mm/memory-alias.S
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2024 SiFive
+ */
+
+#include <linux/bits.h>
+#include <linux/linkage.h>
+#include <asm/asm.h>
+#include <asm/pgtable.h>
+
+#define CACHED_BASE_OFFSET	(0 * RISCV_SZPTR)
+#define NONCACHED_BASE_OFFSET	(1 * RISCV_SZPTR)
+#define SIZE_OFFSET		(2 * RISCV_SZPTR)
+
+#define SIZEOF_PAIR		(4 * RISCV_SZPTR)
+
+SYM_CODE_START(riscv_fixup_memory_alias)
+	addi	sp, sp, -4 * SZREG
+	REG_S	t2, (0 * SZREG)(sp)
+	REG_S	t3, (1 * SZREG)(sp)
+	REG_S	t4, (2 * SZREG)(sp)
+#ifdef CONFIG_RISCV_ISA_SVNAPOT
+	REG_S	t5, (3 * SZREG)(sp)
+
+	/* Save and mask off _PAGE_NAPOT if present. */
+	li	t5, _PAGE_NAPOT
+	and	t5, t1, t5
+	xor	t1, t1, t5
+#endif
+
+	lla	t2, memory_alias_pairs
+.Lfixup_loop:
+	REG_L	t3, SIZE_OFFSET(t2)
+	beqz	t3, .Lfixup_end
+	REG_L	t4, CACHED_BASE_OFFSET(t2)
+	sub	t4, t1, t4
+	bltu	t4, t3, .Lfixup_found
+	addi	t2, t2, SIZEOF_PAIR
+	j	.Lfixup_loop
+
+.Lfixup_found:
+	REG_L	t3, NONCACHED_BASE_OFFSET(t2)
+	add	t1, t3, t4
+
+.Lfixup_end:
+#ifdef CONFIG_RISCV_ISA_SVNAPOT
+	xor	t1, t1, t5
+
+	REG_L	t5, (3 * SZREG)(sp)
+#endif
+	REG_L	t4, (2 * SZREG)(sp)
+	REG_L	t3, (1 * SZREG)(sp)
+	REG_L	t2, (0 * SZREG)(sp)
+	addi	sp, sp, 4 * SZREG
+	jr	t0
+SYM_CODE_END(riscv_fixup_memory_alias)
+
+SYM_CODE_START(riscv_unfix_memory_alias)
+	addi	sp, sp, -4 * SZREG
+	REG_S	t2, (0 * SZREG)(sp)
+	REG_S	t3, (1 * SZREG)(sp)
+	REG_S	t4, (2 * SZREG)(sp)
+#ifdef CONFIG_RISCV_ISA_SVNAPOT
+	REG_S	t5, (3 * SZREG)(sp)
+
+	/* Save and mask off _PAGE_NAPOT if present. */
+	li	t5, _PAGE_NAPOT
+	and	t5, t1, t5
+	xor	t1, t1, t5
+#endif
+
+	lla	t2, memory_alias_pairs
+.Lunfix_loop:
+	REG_L	t3, SIZE_OFFSET(t2)
+	beqz	t3, .Lunfix_end
+	REG_L	t4, NONCACHED_BASE_OFFSET(t2)
+	sub	t4, t1, t4
+	bltu	t4, t3, .Lunfix_found
+	addi	t2, t2, SIZEOF_PAIR
+	j	.Lunfix_loop
+
+.Lunfix_found:
+	REG_L	t3, CACHED_BASE_OFFSET(t2)
+	add	t1, t3, t4
+
+	/* PFN was in the noncached alias, so mark it as such. */
+	li	t2, _PAGE_NOCACHE
+	or	t1, t1, t2
+
+.Lunfix_end:
+#ifdef CONFIG_RISCV_ISA_SVNAPOT
+	xor	t1, t1, t5
+
+	REG_L	t5, (3 * SZREG)(sp)
+#endif
+	REG_L	t4, (2 * SZREG)(sp)
+	REG_L	t3, (1 * SZREG)(sp)
+	REG_L	t2, (0 * SZREG)(sp)
+	addi	sp, sp, 4 * SZREG
+	jr	t0
+SYM_CODE_END(riscv_unfix_memory_alias)
diff --git a/arch/riscv/mm/pgtable.c b/arch/riscv/mm/pgtable.c
index 4ae67324f992..8dd43001cd10 100644
--- a/arch/riscv/mm/pgtable.c
+++ b/arch/riscv/mm/pgtable.c
@@ -1,8 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <asm/pgalloc.h>
+#include <dt-bindings/riscv/physical-memory.h>
+#include <linux/bitfield.h>
 #include <linux/gfp.h>
 #include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
 #include <linux/pgtable.h>
 
 int ptep_set_access_flags(struct vm_area_struct *vma,
@@ -155,3 +159,90 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
 	return pmd;
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+#ifdef CONFIG_RISCV_ISA_SVPBMT
+struct memory_alias_pair {
+	unsigned long cached_base;
+	unsigned long noncached_base;
+	unsigned long size;
+	int index;
+} memory_alias_pairs[5];
+
+bool __init riscv_have_memory_alias(void)
+{
+	return memory_alias_pairs[0].size;
+}
+
+void __init riscv_init_memory_alias(void)
+{
+	int na = of_n_addr_cells(of_root);
+	int ns = of_n_size_cells(of_root);
+	int nc = na + ns + 2;
+	const __be32 *prop;
+	int pairs = 0;
+	int len;
+
+	prop = of_get_property(of_root, "riscv,physical-memory-regions", &len);
+	if (!prop)
+		return;
+
+	len /= sizeof(__be32);
+	for (int i = 0; len >= nc; i++, prop += nc, len -= nc) {
+		unsigned long base = of_read_ulong(prop, na);
+		unsigned long size = of_read_ulong(prop + na, ns);
+		unsigned long flags = be32_to_cpup(prop + na + ns);
+		struct memory_alias_pair *pair;
+		int alias;
+
+		/* We only care about non-coherent memory. */
+		if ((flags & PMA_ORDER_MASK) != PMA_ORDER_MEMORY || (flags & PMA_COHERENT))
+			continue;
+
+		/* The cacheable alias must be usable memory. */
+		if ((flags & PMA_CACHEABLE) &&
+		    !memblock_overlaps_region(&memblock.memory, base, size))
+			continue;
+
+		alias = FIELD_GET(PMR_ALIAS_MASK, flags);
+		if (alias) {
+			pair = NULL;
+			for (int j = 0; j < pairs; j++) {
+				if (alias == memory_alias_pairs[j].index) {
+					pair = &memory_alias_pairs[j];
+					break;
+				}
+			}
+			if (!pair)
+				continue;
+		} else {
+			/* Leave room for the null sentinel. */
+			if (pairs == ARRAY_SIZE(memory_alias_pairs) - 1)
+				continue;
+			pair = &memory_alias_pairs[pairs++];
+			pair->index = i;
+		}
+
+		/* Align the address and size with the page table PFN field. */
+		base >>= PAGE_SHIFT - _PAGE_PFN_SHIFT;
+		size >>= PAGE_SHIFT - _PAGE_PFN_SHIFT;
+
+		if (flags & PMA_CACHEABLE)
+			pair->cached_base = base;
+		else
+			pair->noncached_base = base;
+		pair->size = min_not_zero(pair->size, size);
+	}
+
+	/* Remove any unmatched pairs. */
+	for (int i = 0; i < pairs; i++) {
+		struct memory_alias_pair *pair = &memory_alias_pairs[i];
+
+		if (pair->cached_base && pair->noncached_base && pair->size)
+			continue;
+
+		for (int j = i + 1; j < pairs; j++)
+			memory_alias_pairs[j - 1] = memory_alias_pairs[j];
+		memory_alias_pairs[--pairs].size = 0;
+	}
+}
+#endif /* CONFIG_RISCV_ISA_SVPBMT */
-- 
2.45.1



From samuel.holland at sifive.com  Fri Nov  1 17:08:05 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri,  1 Nov 2024 17:08:05 -0700
Subject: [PATCH 11/11] riscv: dts: starfive: jh7100: Use physical memory ranges for DMA
In-Reply-To: <20241102000843.1301099-1-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
Message-ID: <20241102000843.1301099-12-samuel.holland@sifive.com>

JH7100 provides a physical memory region which is a noncached alias of
normal cacheable DRAM. Now that Linux can apply PMAs by selecting
between aliases of a physical memory region, any page of DRAM can be
marked as noncached for use with DMA, and the preallocated DMA pool is
no longer needed. This allows portable kernels to boot on JH7100 boards.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 arch/riscv/Kconfig.errata                     | 19 ------------
 .../boot/dts/starfive/jh7100-common.dtsi      | 30 ++++---------------
 2 files changed, 6 insertions(+), 43 deletions(-)

diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 2806ed7916c7..fc2c7fb2caff 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -53,25 +53,6 @@ config ERRATA_SIFIVE_CIP_1200
 
 	  If you don't know what to do here, say "Y".
 
-config ERRATA_STARFIVE_JH7100
-	bool "StarFive JH7100 support"
-	depends on ARCH_STARFIVE
-	depends on !DMA_DIRECT_REMAP
-	depends on NONPORTABLE
-	select DMA_GLOBAL_POOL
-	select RISCV_DMA_NONCOHERENT
-	select RISCV_NONSTANDARD_CACHE_OPS
-	select SIFIVE_CCACHE
-	default n
-	help
-	  The StarFive JH7100 was a test chip for the JH7110 and has
-	  caches that are non-coherent with respect to peripheral DMAs.
-	  It was designed before the Zicbom extension so needs non-standard
-	  cache operations through the SiFive cache controller.
-
-	  Say "Y" if you want to support the BeagleV Starlight and/or
-	  StarFive VisionFive V1 boards.
-
 config ERRATA_THEAD
 	bool "T-HEAD errata"
 	depends on RISCV_ALTERNATIVE
diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
index ae1a6aeb0aea..34885fe40e2d 100644
--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
@@ -9,8 +9,14 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
+#include <dt-bindings/riscv/physical-memory.h>
 
 / {
+	riscv,physical-memory-regions =
+		<0x00 0x00000000 0x40 0x00000000 (PMA_RW | PMA_IO) 0x0>,
+		<0x00 0x80000000 0x08 0x00000000 (PMA_RWXA | PMA_NONCOHERENT_MEMORY) 0x0>,
+		<0x10 0x00000000 0x08 0x00000000 (PMA_RWX | PMA_NONCACHEABLE_MEMORY | PMR_ALIAS(1)) 0x0>;
+
 	aliases {
 		mmc0 = &sdio0;
 		mmc1 = &sdio1;
@@ -42,30 +48,6 @@ led-ack {
 		};
 	};
 
-	reserved-memory {
-		#address-cells = <2>;
-		#size-cells = <2>;
-		ranges;
-
-		dma-reserved at fa000000 {
-			reg = <0x0 0xfa000000 0x0 0x1000000>;
-			no-map;
-		};
-
-		linux,dma at 107a000000 {
-			compatible = "shared-dma-pool";
-			reg = <0x10 0x7a000000 0x0 0x1000000>;
-			no-map;
-			linux,dma-default;
-		};
-	};
-
-	soc {
-		dma-ranges = <0x00 0x80000000 0x00 0x80000000 0x00 0x7a000000>,
-			     <0x00 0xfa000000 0x10 0x7a000000 0x00 0x01000000>,
-			     <0x00 0xfb000000 0x00 0xfb000000 0x07 0x85000000>;
-	};
-
 	wifi_pwrseq: wifi-pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		reset-gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
-- 
2.45.1



From inochiama at gmail.com  Fri Nov  1 17:49:26 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Sat, 2 Nov 2024 08:49:26 +0800
Subject: [PATCH] riscv: dts: sophgo: Add ethernet configuration for cv18xx
In-Reply-To: <5b08e092-c302-43a9-a04d-3566bec96e94@lunn.ch>
References: <20241028011312.274938-1-inochiama@gmail.com>
 <87e215a7-0b27-4336-9f9c-e63ade0772ef@lunn.ch>
 <wgggariprpp2wczsljy3vw6kp7vhnrifg6soxdgiio2seyctym@4owbzlg3ngum>
 <ftfp2rwkytqmzruogcx66d5qkn4tzrgyjtlz4hdduxhwit3tok@kczgzrjdxx46>
 <e389a60d-2fe3-46fd-946c-01dd3a0a0f6f@lunn.ch>
 <nkydxanwucqmbzzz2fb24xyelrouj6gvhuuou2ssbf4tvvhfea@6uiuueim7m3a>
 <5b08e092-c302-43a9-a04d-3566bec96e94@lunn.ch>
Message-ID: <nrpyz7kdbcx2zlrgtqd7fkg2fb5n2s4matjj6ouy6jxcubcwzy@vwnlhrgchgm3>

On Fri, Nov 01, 2024 at 01:40:00PM +0100, Andrew Lunn wrote:
> > > > > > > +			mdio {
> > > > > > > +				compatible = "snps,dwmac-mdio";
> > > > > > > +				#address-cells = <1>;
> > > > > > > +				#size-cells = <0>;
> > > > > > > +
> > > > > > > +				phy0: phy at 0 {
> > > > > > > +					compatible = "ethernet-phy-ieee802.3-c22";
> > > > > > > +					reg = <0>;
> > > > > > > +				};
> > > > > > > +			};
> > > > > > 
> > > > > > It is not clear to me what cv18xx.dtsi represents, 
> > > > > 
> > > > > This is a include file to define common ip for the whole
> > > > > cv18xx series SoCs (cv1800b, cv1812h, sg2000, sg2000).
> > > > > 
> > > > > > and where the PHY node should be, here, or in a .dts file. 
> > > > > > Is this a SOM, and the PHY is on the SOM? 
> > > > > 
> > > > > The phy is on the SoC, it is embedded, and no external phy
> > > > > is supported. So I think the phy node should stay here, not 
> > > > > in the dts file.
> > > > 
> > > > There is a mistake, Some package supports external rmii/mii
> > > > phy. So I will move this phy definition to board specific.
> > > 
> > > When there is an external PHY, does the internal PHY still exists? If
> > > it does, it should be listed, even if it is not used.
> > > 
> > > Do the internal and external PHY share the same MDIO bus? 
> > 
> > They share the same MDIO bus and phy id setting.
> 
> What do you mean by phy ID?
> 

It is just part of the MDIO mux. Just ignore it. It is just
used to show only one phy can be used at the same time.

> > When an external phy
> > is select, the internal one is not initialized and can not be accessed
> > by the SoC.
> > 
> > > I've seen some SoCs with complex MDIO muxes for internal vs external
> > > PHYs.
> > > 
> > > 	Andrew
> > 
> > There is a switch register on the SoC to decide which phy/mode is used. 
> > By defaut is internal one with rmii mode. I think a driver is needed to
> > handle this properly.
> 
> This sounds like a complex MDIO mux. You should think about this now,
> because others have left this same problem too late and ended up with
> a complex design in order to keep backwards compatibility with old DT
> blobs which don't actually describe the real hardware.
> 
> 	Andrew

Thanks, I wiil design a driver for it to handle this mux.

Regards,
Inochi


From inochiama at gmail.com  Fri Nov  1 17:50:33 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Sat, 2 Nov 2024 08:50:33 +0800
Subject: [PATCH] riscv: dts: sophgo: fix pinctrl base-address
In-Reply-To: <MA0P287MB28221D96A094D7C3373C1865FE562@MA0P287MB2822.INDP287.PROD.OUTLOOK.COM>
References: <20241028-fix-address-v1-1-dcbe21e59ccf@bootlin.com>
 <ihmors43w3ttfun7c4fj75ahh2hnhafdxhlmocbxfwttigj3fq@wxud2d2srisn>
 <MA0P287MB28221D96A094D7C3373C1865FE562@MA0P287MB2822.INDP287.PROD.OUTLOOK.COM>
Message-ID: <zfnisncpvhjtnsfdciwnqdzlh6bhcdslxx5tp76smmyskgtdpi@wcwdrllaeifo>

On Sat, Nov 02, 2024 at 06:28:50AM +0800, Chen Wang wrote:
> Hi, Inochi,
> 
> Will you pick this on sophgo/for-next?
> 
> Regards,
> 
> Chen
> 
> On 2024/10/30 11:50, Inochi Amaoto wrote:
> > On Mon, Oct 28, 2024 at 11:43:24AM +0100, Thomas Bonnefille wrote:
> > > Fix the base-address of the pinctrl controller to match its register
> > > address.
> > > 
> > > Signed-off-by: Thomas Bonnefille <thomas.bonnefille at bootlin.com>
> > Fixes: 93b61555f509 ("riscv: dts: sophgo: Add initial SG2002 SoC device tree")
> > 

Yeah, I have quened this patch and will merge it once I have
space time, so please wait.

Regards,
Inochi


From robh at kernel.org  Fri Nov  1 18:31:28 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 01 Nov 2024 20:31:28 -0500
Subject: [PATCH 01/11] dt-bindings: riscv: Describe physical memory
 regions
In-Reply-To: <20241102000843.1301099-2-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
 <20241102000843.1301099-2-samuel.holland@sifive.com>
Message-ID: <173051108892.583398.1565228083513288043.robh@kernel.org>


On Fri, 01 Nov 2024 17:07:55 -0700, Samuel Holland wrote:
> Information about physical memory regions is needed by both the kernel
> and M-mode firmware. For example, the kernel needs to know about
> noncacheable aliases of cacheable memory in order to allocate coherent
> memory pages for DMA. M-mode firmware needs to know about aliases so it
> can protect itself from lower-privileged software. Firmware also needs
> to know the platform's Physical Address Width in order to efficiently
> implement Smmpt.
> 
> The RISC-V Privileged Architecture delegates the description of Physical
> Memory Attributes to the platform. On DT-based platforms, it makes sense
> to put this information in the devicetree.
> 
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
> 
>  .../bindings/riscv/physical-memory.yaml       | 101 ++++++++++++++++++
>  include/dt-bindings/riscv/physical-memory.h   |  44 ++++++++
>  2 files changed, 145 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/riscv/physical-memory.yaml
>  create mode 100644 include/dt-bindings/riscv/physical-memory.h
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/riscv/physical-memory.example.dtb: /: compatible: 'oneOf' conditional failed, one must be fixed:
	['starfive,jh7100'] is too short
	'starfive,jh7100' is not one of ['beagle,beaglev-starlight-jh7100-r0', 'starfive,visionfive-v1']
	'starfive,jh7100' is not one of ['milkv,mars', 'pine64,star64', 'starfive,visionfive-2-v1.2a', 'starfive,visionfive-2-v1.3b']
	from schema $id: http://devicetree.org/schemas/riscv/starfive.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/riscv/physical-memory.example.dtb: /: 'model' is a required property
	from schema $id: http://devicetree.org/schemas/root-node.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20241102000843.1301099-2-samuel.holland at sifive.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From samuel.holland at sifive.com  Fri Nov  1 20:48:24 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri, 1 Nov 2024 22:48:24 -0500
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <20241028053220.346283-2-TroyMitchell988@gmail.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
Message-ID: <846b4f2a-602e-431e-affc-0e995db5eee5@sifive.com>

Hi Troy,

On 2024-10-28 12:32 AM, Troy Mitchell wrote:
> The I2C of K1 supports fast-speed-mode and high-speed-mode,
> and supports FIFO transmission.
> 
> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
> ---
>  .../bindings/i2c/spacemit,k1-i2c.yaml         | 51 +++++++++++++++++++
>  1 file changed, 51 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> 
> diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> new file mode 100644
> index 000000000000..57af66f494e7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: I2C controller embedded in SpacemiT's K1 SoC
> +
> +maintainers:
> +  - Troy Mitchell <troymitchell988 at gmail.com>
> +
> +properties:
> +  compatible:
> +    const: spacemit,k1-i2c
> +
> +  reg:
> +    maxItems: 2
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1

Looking at the K1 user manual (9.1.4.77 RCPU I2C0 CLOCK RESET CONTROL
REGISTER(RCPU_I2C0_CLK_RST)), I see two clocks (pclk, fclk) and a reset, which
looks to be standard across the peripherals in this SoC. Please be sure that the
binding covers all resources needed to use this peripheral.

> +
> +  clock-frequency:
> +    description:
> +      Desired I2C bus clock frequency in Hz. As only fast and high-speed
> +      modes are supported by hardware, possible values are 100000 and 400000.
> +    enum: [100000, 400000]

This looks wrong. In the manual I see:

* Supports standard-mode operation up to 100 Kbps
* Supports fast-mode operation up to 400Kbps
* Supports high-speed mode (HS mode) slave operation up to 3.4Mbps(High-speed
I2C only)
* Supports high-speed mode (HS mode) master operation up to 3.3 Mbps (High-speed
I2C only)

So even ignoring HS mode, 100 kHz and 400 kHz are only the maximums, not fixed
frequencies.

Regards,
Samuel

> +    default: 100000
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    i2c at d4010800 {
> +        compatible = "spacemit,k1-i2c";
> +        reg = <0x0 0xd4010800 0x0 0x38>;
> +        interrupt-parent = <&plic>;
> +        interrupts = <36>;
> +        clocks = <&ccu 90>;
> +        clock-frequency = <100000>;
> +    };
> +
> +...



From davidgow at google.com  Sat Nov  2 00:35:36 2024
From: davidgow at google.com (David Gow)
Date: Sat, 2 Nov 2024 15:35:36 +0800
Subject: [RFC v2 00/13] LKMM *generic* atomics in Rust
In-Reply-To: <20241101060237.1185533-1-boqun.feng@gmail.com>
References: <20241101060237.1185533-1-boqun.feng@gmail.com>
Message-ID: <CABVgOSm1cDcrsgYutooRG-ZLuzMypAO+ndNFyPy2w3_5B84TSQ@mail.gmail.com>

On Fri, 1 Nov 2024 at 14:04, Boqun Feng <boqun.feng at gmail.com> wrote:
>
> Hi,
>
> This is another RFC version of LKMM atomics in Rust, you can find the
> previous versions:
>
> v1: https://lore.kernel.org/rust-for-linux/20240612223025.1158537-1-boqun.feng at gmail.com/
> wip: https://lore.kernel.org/rust-for-linux/20240322233838.868874-1-boqun.feng at gmail.com/
>
> I add a few more people Cced this time, so if you're curious about why
> we choose to implement LKMM atomics instead of using the Rust ones, you
> can find some explanation:
>
> * In my Kangrejos talk: https://lwn.net/Articles/993785/
> * In Linus' email: https://lore.kernel.org/rust-for-linux/CAHk-=whkQk=zq5XiMcaU3xj4v69+jyoP-y6Sywhq-TvxSSvfEA at mail.gmail.com/
>
> This time, I try implementing a generic atomic type `Atomic<T>`, since
> Benno and Gary suggested last time, and also Rust standard library is
> also going to that direction [1].
>
> Honestly, a generic atomic type is still not quite necessary for myself,
> but here are a few reasons that it's useful:
>
> *       It's useful for type alias, for example, if you have:
>
>         type c_long = isize;
>
>         Then `Atomic<c_clong>` and `Atomic<isize>` is the same type,
>         this may make FFI code (mapping a C type to a Rust type or vice
>         versa) more readable.
>
> *       In kernel, we sometimes switch atomic to percpu for better
>         scalabity, percpu is naturally a generic type, because it can
>         have data that is larger than machine word size. Making atomic
>         generic ease the potential switching/refactoring.
>
> *       Generic atomics provide all the functionalities that non-generic
>         atomics could have.
>
> That said, currently "generic" is limited to a few types: the type must
> be the same size as atomic_t or atomic64_t, other than basic types, only
> #[repr(<basic types>)] struct can be used in a `Atomic<T>`.
>
> Also this is not a full feature set patchset, things like different
> arithmetic operations and bit operations are still missing, they can be
> either future work or for future versions.
>
> I included an RCU pointer implementation as one example of the usage, so
> a patch from Danilo is added, but I will drop it once his patch merged.
>
> This is based on today's rust-next, and I've run all kunit tests from
> the doc test on x86, arm64 and riscv.
>
> Feedbacks and comments are welcome! Thanks.
>
> Regards,
> Boqun
>
> [1]: https://github.com/rust-lang/rust/issues/130539
>

Thanks, Boqun.

I played around a bit with porting the blk-mq atomic code to this. As
neither an expert in Rust nor an expert in atomics, this is probably
both non-idiomatic and wrong, but unlike the `core` atomics, it
provides an Atomic::<u64> on 32-bit systems, which gets UML's 32-bit
build working again.

Diff below -- I'm not likely to have much time to work on this again
soon, so feel free to pick it up/fix it if it suits.

Thanks,
-- David

---
diff --git a/rust/kernel/block/mq/operations.rs
b/rust/kernel/block/mq/operations.rs
index 9ba7fdfeb4b2..822d64230e11 100644
--- a/rust/kernel/block/mq/operations.rs
+++ b/rust/kernel/block/mq/operations.rs
@@ -11,7 +11,8 @@
     error::{from_result, Result},
     types::ARef,
 };
-use core::{marker::PhantomData, sync::atomic::AtomicU64,
sync::atomic::Ordering};
+use core::marker::PhantomData;
+use kernel::sync::atomic::{Atomic, Relaxed};

 /// Implement this trait to interface blk-mq as block devices.
 ///
@@ -77,7 +78,7 @@ impl<T: Operations> OperationsVTable<T> {
         let request = unsafe { &*(*bd).rq.cast::<Request<T>>() };

         // One refcount for the ARef, one for being in flight
-        request.wrapper_ref().refcount().store(2, Ordering::Relaxed);
+        request.wrapper_ref().refcount().store(2, Relaxed);

         // SAFETY:
         //  - We own a refcount that we took above. We pass that to `ARef`.
@@ -186,7 +187,7 @@ impl<T: Operations> OperationsVTable<T> {

             // SAFETY: The refcount field is allocated but not initialized, so
             // it is valid for writes.
-            unsafe {
RequestDataWrapper::refcount_ptr(pdu.as_ptr()).write(AtomicU64::new(0))
};
+            unsafe {
RequestDataWrapper::refcount_ptr(pdu.as_ptr()).write(Atomic::<u64>::new(0))
};

             Ok(0)
         })
diff --git a/rust/kernel/block/mq/request.rs b/rust/kernel/block/mq/request.rs
index 7943f43b9575..8d4060d65159 100644
--- a/rust/kernel/block/mq/request.rs
+++ b/rust/kernel/block/mq/request.rs
@@ -13,8 +13,8 @@
 use core::{
     marker::PhantomData,
     ptr::{addr_of_mut, NonNull},
-    sync::atomic::{AtomicU64, Ordering},
 };
+use kernel::sync::atomic::{Atomic, Relaxed};

 /// A wrapper around a blk-mq [`struct request`]. This represents an
IO request.
 ///
@@ -102,8 +102,7 @@ fn try_set_end(this: ARef<Self>) -> Result<*mut
bindings::request, ARef<Self>> {
         if let Err(_old) = this.wrapper_ref().refcount().compare_exchange(
             2,
             0,
-            Ordering::Relaxed,
-            Ordering::Relaxed,
+            Relaxed
         ) {
             return Err(this);
         }
@@ -168,13 +167,13 @@ pub(crate) struct RequestDataWrapper {
     /// - 0: The request is owned by C block layer.
     /// - 1: The request is owned by Rust abstractions but there are
no [`ARef`] references to it.
     /// - 2+: There are [`ARef`] references to the request.
-    refcount: AtomicU64,
+    refcount: Atomic::<u64>,
 }

 impl RequestDataWrapper {
     /// Return a reference to the refcount of the request that is embedding
     /// `self`.
-    pub(crate) fn refcount(&self) -> &AtomicU64 {
+    pub(crate) fn refcount(&self) -> &Atomic::<u64> {
         &self.refcount
     }

@@ -184,7 +183,7 @@ pub(crate) fn refcount(&self) -> &AtomicU64 {
     /// # Safety
     ///
     /// - `this` must point to a live allocation of at least the size
of `Self`.
-    pub(crate) unsafe fn refcount_ptr(this: *mut Self) -> *mut AtomicU64 {
+    pub(crate) unsafe fn refcount_ptr(this: *mut Self) -> *mut Atomic::<u64> {
         // SAFETY: Because of the safety requirements of this function, the
         // field projection is safe.
         unsafe { addr_of_mut!((*this).refcount) }
@@ -202,28 +201,22 @@ unsafe impl<T: Operations> Sync for Request<T> {}

 /// Store the result of `op(target.load())` in target, returning new value of
 /// target.
-fn atomic_relaxed_op_return(target: &AtomicU64, op: impl Fn(u64) ->
u64) -> u64 {
-    let old = target.fetch_update(Ordering::Relaxed,
Ordering::Relaxed, |x| Some(op(x)));
-
-    // SAFETY: Because the operation passed to `fetch_update` above always
-    // return `Some`, `old` will always be `Ok`.
-    let old = unsafe { old.unwrap_unchecked() };
-
-    op(old)
+fn atomic_relaxed_op_return(target: &Atomic::<u64>, op: impl Fn(u64)
-> u64) -> u64 {
+    let old = target.load(Relaxed);
+    let new_val = op(old);
+    target.compare_exchange(old, new_val, Relaxed);
+    old
 }

 /// Store the result of `op(target.load)` in `target` if `target.load() !=
 /// pred`, returning [`true`] if the target was updated.
-fn atomic_relaxed_op_unless(target: &AtomicU64, op: impl Fn(u64) ->
u64, pred: u64) -> bool {
-    target
-        .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |x| {
-            if x == pred {
-                None
-            } else {
-                Some(op(x))
-            }
-        })
-        .is_ok()
+fn atomic_relaxed_op_unless(target: &Atomic::<u64>, op: impl Fn(u64)
-> u64, pred: u64) -> bool {
+    let old = target.load(Relaxed);
+    if old == pred {
+        false
+    } else {
+        target.compare_exchange(old, op(old), Relaxed).is_ok()
+    }
 }

 // SAFETY: All instances of `Request<T>` are reference counted. This
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5294 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241102/c02dde40/attachment.p7s>

From herbert at gondor.apana.org.au  Sat Nov  2 02:45:28 2024
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Sat, 2 Nov 2024 17:45:28 +0800
Subject: [PATCH v2 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <20241026040958.GA34351@sol.localdomain>
Message-ID: <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>

Eric Biggers <ebiggers at kernel.org> wrote:
>
> While testing this patchset I notice that none of the crypto API drivers for
> crc32 or crc32c even need to be loaded on my system anymore, as everything on my
> system that uses those algorithms (such as ext4) just uses the library APIs now.
> That makes the "check /proc/crypto" trick stop working anyway.

What's stopping us from removing them altogether?

Thanks,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From ardb at kernel.org  Sat Nov  2 02:58:53 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 2 Nov 2024 10:58:53 +0100
Subject: [PATCH v2 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>
References: <20241026040958.GA34351@sol.localdomain> <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>
Message-ID: <CAMj1kXFfPtO0vd1KqTa+QNSkRWNR7SUJ_A_zX6-Hz5HVLtLYtw@mail.gmail.com>

On Sat, 2 Nov 2024 at 10:45, Herbert Xu <herbert at gondor.apana.org.au> wrote:
>
> Eric Biggers <ebiggers at kernel.org> wrote:
> >
> > While testing this patchset I notice that none of the crypto API drivers for
> > crc32 or crc32c even need to be loaded on my system anymore, as everything on my
> > system that uses those algorithms (such as ext4) just uses the library APIs now.
> > That makes the "check /proc/crypto" trick stop working anyway.
>
> What's stopping us from removing them altogether?
>

At least btrfs supports a variety of checksums/hashes (crc32c, xxhash,
sha) via the shash API.

There are some other remaining uses of crc32c using shash or sync
ahash where the algo is hardcoded (NVMe, infiniband) so I imagine
those might be candidates for conversion as well.


From herbert at gondor.apana.org.au  Sat Nov  2 03:19:52 2024
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Sat, 2 Nov 2024 18:19:52 +0800
Subject: [PATCH v2 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <CAMj1kXFfPtO0vd1KqTa+QNSkRWNR7SUJ_A_zX6-Hz5HVLtLYtw@mail.gmail.com>
References: <20241026040958.GA34351@sol.localdomain>
 <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>
 <CAMj1kXFfPtO0vd1KqTa+QNSkRWNR7SUJ_A_zX6-Hz5HVLtLYtw@mail.gmail.com>
Message-ID: <ZyX8yEqnjXjJ5itO@gondor.apana.org.au>

On Sat, Nov 02, 2024 at 10:58:53AM +0100, Ard Biesheuvel wrote:
>
> At least btrfs supports a variety of checksums/hashes (crc32c, xxhash,
> sha) via the shash API.

OK, given that btrfs is still doing this, I think we should still
register crc32c-arch conditionally.  Having it point to crc32c-generic
is just confusing (at least if you use btrfs).

Thanks,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From ardb at kernel.org  Sat Nov  2 03:46:59 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 2 Nov 2024 11:46:59 +0100
Subject: [PATCH v2 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <ZyX8yEqnjXjJ5itO@gondor.apana.org.au>
References: <20241026040958.GA34351@sol.localdomain> <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>
 <CAMj1kXFfPtO0vd1KqTa+QNSkRWNR7SUJ_A_zX6-Hz5HVLtLYtw@mail.gmail.com> <ZyX8yEqnjXjJ5itO@gondor.apana.org.au>
Message-ID: <CAMj1kXHje-BwJVffAxN9G96Gy4Gom3Ca7dJ-_K7sgcrz7_k7Kw@mail.gmail.com>

On Sat, 2 Nov 2024 at 11:20, Herbert Xu <herbert at gondor.apana.org.au> wrote:
>
> On Sat, Nov 02, 2024 at 10:58:53AM +0100, Ard Biesheuvel wrote:
> >
> > At least btrfs supports a variety of checksums/hashes (crc32c, xxhash,
> > sha) via the shash API.
>
> OK, given that btrfs is still doing this, I think we should still
> register crc32c-arch conditionally.  Having it point to crc32c-generic
> is just confusing (at least if you use btrfs).
>

Agreed. So we should take this patch.

The current issue with btrfs is that it will misidentify
crc32c-generic on arm64 as being 'slow', but this was already fixed by
my patches that are already in cryptodev.

On arm64, crc32 instructions are always available (the only known
micro-architecture that omitted them has been obsolete for years), and
on x86_64 the situation is similar in practice (introduced in SSE
4.2), and so this patch changes very little for the majority of btrfs
users.

But on architectures such as 32-bit ARM, where these instructions are
only available if you are booting a 32-bit kernel on a 64-bit CPU
(which is more common than you might think), this patch will ensure
that crc32-arm / crc32c-arm are only registered if the instructions
are actually available, and btrfs will take the slow async patch for
checksumming if they are not. (I seriously doubt that btrfs on 32-bit
ARM is a thing but who knows)


From ardb at kernel.org  Sat Nov  2 04:05:01 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 2 Nov 2024 12:05:01 +0100
Subject: [PATCH v2 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <CAMj1kXHje-BwJVffAxN9G96Gy4Gom3Ca7dJ-_K7sgcrz7_k7Kw@mail.gmail.com>
References: <20241026040958.GA34351@sol.localdomain> <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>
 <CAMj1kXFfPtO0vd1KqTa+QNSkRWNR7SUJ_A_zX6-Hz5HVLtLYtw@mail.gmail.com>
 <ZyX8yEqnjXjJ5itO@gondor.apana.org.au> <CAMj1kXHje-BwJVffAxN9G96Gy4Gom3Ca7dJ-_K7sgcrz7_k7Kw@mail.gmail.com>
Message-ID: <CAMj1kXG8Nqw_f8OsFTq_UKRbca6w58g4uyRAZXCoCr=OwC2sWA@mail.gmail.com>

On Sat, 2 Nov 2024 at 11:46, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> On Sat, 2 Nov 2024 at 11:20, Herbert Xu <herbert at gondor.apana.org.au> wrote:
> >
> > On Sat, Nov 02, 2024 at 10:58:53AM +0100, Ard Biesheuvel wrote:
> > >
> > > At least btrfs supports a variety of checksums/hashes (crc32c, xxhash,
> > > sha) via the shash API.
> >
> > OK, given that btrfs is still doing this, I think we should still
> > register crc32c-arch conditionally.  Having it point to crc32c-generic
> > is just confusing (at least if you use btrfs).
> >
>
> Agreed. So we should take this patch.
>
> The current issue with btrfs is that it will misidentify
> crc32c-generic on arm64 as being 'slow', but this was already fixed by
> my patches that are already in cryptodev.
>
> On arm64, crc32 instructions are always available (the only known
> micro-architecture that omitted them has been obsolete for years), and
> on x86_64 the situation is similar in practice (introduced in SSE
> 4.2), and so this patch changes very little for the majority of btrfs
> users.
>
> But on architectures such as 32-bit ARM, where these instructions are
> only available if you are booting a 32-bit kernel on a 64-bit CPU
> (which is more common than you might think), this patch will ensure
> that crc32-arm / crc32c-arm are only registered if the instructions
> are actually available, and btrfs will take the slow async patch for
> checksumming if they are not. (I seriously doubt that btrfs on 32-bit
> ARM is a thing but who knows)

(actually, backpedalling a little bit - apologies)

OTOH,btrfs is the only user where this makes a difference, and its use
of the driver name is highly questionable IMO. On x86, it shouldn't
make a difference in practice, on arm64, it was broken for a long
time, and on the remaining architectures, I seriously doubt that
anyone cares about this, and so we can fix this properly if there is a
need.

The only issue resulting from *not* taking this patch is that btrfs
may misidentify the CRC32 implementation as being 'slow' and take an
alternative code path, which does not necessarily result in worse
performance.

And I'd prefer static_call() / static_call_query() over a separate
global variable to keep track of whether or not the generic code is in
use.


From herbert at gondor.apana.org.au  Sat Nov  2 04:08:43 2024
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Sat, 2 Nov 2024 19:08:43 +0800
Subject: [PATCH v2 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <CAMj1kXG8Nqw_f8OsFTq_UKRbca6w58g4uyRAZXCoCr=OwC2sWA@mail.gmail.com>
References: <20241026040958.GA34351@sol.localdomain>
 <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>
 <CAMj1kXFfPtO0vd1KqTa+QNSkRWNR7SUJ_A_zX6-Hz5HVLtLYtw@mail.gmail.com>
 <ZyX8yEqnjXjJ5itO@gondor.apana.org.au>
 <CAMj1kXHje-BwJVffAxN9G96Gy4Gom3Ca7dJ-_K7sgcrz7_k7Kw@mail.gmail.com>
 <CAMj1kXG8Nqw_f8OsFTq_UKRbca6w58g4uyRAZXCoCr=OwC2sWA@mail.gmail.com>
Message-ID: <ZyYIO6RpjTFteaxH@gondor.apana.org.au>

On Sat, Nov 02, 2024 at 12:05:01PM +0100, Ard Biesheuvel wrote:
>
> The only issue resulting from *not* taking this patch is that btrfs
> may misidentify the CRC32 implementation as being 'slow' and take an
> alternative code path, which does not necessarily result in worse
> performance.

If we were removing crc32* (or at least crc32*-arch) from the Crypto
API then these patches would be redundant.  But if we're keeping them
because btrfs uses them then we should definitely make crc32*-arch
do the right thing.  IOW they should not be registered if they're
the same as crc32*-generic.

Thanks,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From inochiama at gmail.com  Sat Nov  2 04:33:25 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Sat,  2 Nov 2024 19:33:25 +0800
Subject: [PATCH 0/2] riscv: dts: sophgo: cv18xx: add emmc and sdio support
In-Reply-To: <20241025112902.1200716-1-inochiama@gmail.com>
References: <20241025112902.1200716-1-inochiama@gmail.com>
Message-ID: <173054635857.778838.7207985849003780014.b4-ty@gmail.com>

On Fri, 25 Oct 2024 19:28:58 +0800, Inochi Amaoto wrote:
> Since the sdhci driver is already supported, it is possible to
> add emmc and sdio device for cv18xx SoC.
> 
> Inochi Amaoto (2):
>   riscv: dts: sophgo: Add sdio configuration for Huashan Pi
>   riscv: dts: sophgo: Add emmc support for Huashan Pi
> 
> [...]

Applied to for-next, thanks!

[1/2] riscv: dts: sophgo: Add sdio configuration for Huashan Pi
      https://github.com/sophgo/linux/commit/06133f48a87144de40bbd3934fcaad449ecc1b93
[2/2] riscv: dts: sophgo: Add emmc support for Huashan Pi
      https://github.com/sophgo/linux/commit/b5cf65cc0fd00aa30ff218ec8170dd48e3cbe78d

Thanks,
Inochi



From inochiama at gmail.com  Sat Nov  2 04:33:26 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Sat,  2 Nov 2024 19:33:26 +0800
Subject: [PATCH] riscv: dts: sophgo: fix pinctrl base-address
In-Reply-To: <20241028-fix-address-v1-1-dcbe21e59ccf@bootlin.com>
References: <20241028-fix-address-v1-1-dcbe21e59ccf@bootlin.com>
Message-ID: <173054635856.778838.205612154809931860.b4-ty@gmail.com>

On Mon, 28 Oct 2024 11:43:24 +0100, Thomas Bonnefille wrote:
> Fix the base-address of the pinctrl controller to match its register
> address.
> 
> 

Applied to for-next, thanks!

[1/1] riscv: dts: sophgo: fix pinctrl base-address
      https://github.com/sophgo/linux/commit/44196383a26fcacbd6dcf5a1ab2dd8bf8e4132c0

Thanks,
Inochi



From kw at linux.com  Sat Nov  2 04:51:17 2024
From: kw at linux.com (Krzysztof =?utf-8?Q?Wilczy=C5=84ski?=)
Date: Sat, 2 Nov 2024 20:51:17 +0900
Subject: [PATCH v5 0/2] PCI: microchip: support using either instance 1
 or 2
In-Reply-To: <20240814-setback-rumbling-c6393c8f1a91@spud>
References: <20240814-setback-rumbling-c6393c8f1a91@spud>
Message-ID: <20241102115117.GD2260768@rocinante>

Hello,

> The current driver and binding for PolarFire SoC's PCI controller assume
> that the root port instance in use is instance 1. The second reg
> property constitutes the region encompassing both "control" and "bridge"
> registers for both instances. In the driver, a fixed offset is applied to
> find the base addresses for instance 1's "control" and "bridge"
> registers. The BeagleV Fire uses root port instance 2, so something must
> be done so that software can differentiate. This series splits the
> second reg property in two, with dedicated "control" and "bridge"
> entries so that either instance can be used.

Applied to controller/microchip, thank you!

[01/02] PCI: dt-bindings: PCI: microchip,pcie-host: Fix reg properties
        https://git.kernel.org/pci/pci/c/ae5ebdb405dd
[02/02] PCI: microchip: Rework reg region handing to support using either instance 1 or 2
        https://git.kernel.org/pci/pci/c/e071e6bd9940

	Krzysztof


From kw at linux.com  Sat Nov  2 04:54:11 2024
From: kw at linux.com (Krzysztof =?utf-8?Q?Wilczy=C5=84ski?=)
Date: Sat, 2 Nov 2024 20:54:11 +0900
Subject: [PATCH v5 2/2] PCI: microchip: rework reg region handing to
 support using either instance 1 or 2
In-Reply-To: <20241101195129.GA1318063@bhelgaas>
References: <20240814-outmost-untainted-cedd4adcd551@spud>
 <20241101195129.GA1318063@bhelgaas>
Message-ID: <20241102115411.GE2260768@rocinante>

Hello,

> > The PCI host controller on PolarFire SoC has multiple "instances", each
> > with their own bridge and ctrl address spaces. The original binding has
> > an "apb" register region, and it is expected to be set to the base
> > address of the host controllers register space. Defines in the driver
> > were used to compute the addresses of the bridge and ctrl address ranges
> > corresponding to instance1. Some customers want to use instance0 however
> > and that requires changing the defines in the driver, which is clearly
> > not a portable solution.
> 
> The subject mentions "instance 1 or 2".
> 
> This paragraph implies adding support for "instance0" ("customers want
> to use instance0").
> 
> The DT patch suggests that we're adding support for "instance2"
> ("customers want to use instance2").
> 
> Both patches suggest that the existing support is for "instance 1".
> 
> Maybe what's being added is "instance 2", and this commit log should
> s/instance0/instance 2/ ?  And probably s/instance1/instance 1/ so the
> style is consistent?
> 
> Is this a "pick one or the other but not both" situation, or does this
> device support two independent PCIe controllers?
> 
> I first thought this driver supported a single PCIe controller, and
> you were adding support for a second independent controller.
> 
> But the fact that you say "the [singular] host controller on
> PolarFire", and you're not changing mc_host_probe() to call
> pci_host_common_probe() more than once makes me think there is only a
> single PCIe controller, and for some reason you can choose to operate
> it using either register set 1 or register set 2.

Conor, let me know if we need to clarify the commit log per Bjorn's
questions.  If so, then I will do it directly on the branch.

	Krzysztof


From lkp at intel.com  Sat Nov  2 08:28:33 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 2 Nov 2024 23:28:33 +0800
Subject: [PATCH 10/11] riscv: mm: Use physical memory aliases to apply
 PMAs
In-Reply-To: <20241102000843.1301099-11-samuel.holland@sifive.com>
References: <20241102000843.1301099-11-samuel.holland@sifive.com>
Message-ID: <202411022337.JHozQieV-lkp@intel.com>

Hi Samuel,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on linus/master v6.12-rc5 next-20241101]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Samuel-Holland/dt-bindings-riscv-Describe-physical-memory-regions/20241102-081311
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20241102000843.1301099-11-samuel.holland%40sifive.com
patch subject: [PATCH 10/11] riscv: mm: Use physical memory aliases to apply PMAs
config: riscv-defconfig (https://download.01.org/0day-ci/archive/20241102/202411022337.JHozQieV-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 639a7ac648f1e50ccd2556e17d401c04f9cce625)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241102/202411022337.JHozQieV-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411022337.JHozQieV-lkp at intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "riscv_fixup_memory_alias" [arch/riscv/kvm/kvm.ko] undefined!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From ebiggers at kernel.org  Sat Nov  2 09:36:05 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sat, 2 Nov 2024 09:36:05 -0700
Subject: [PATCH v2 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <ZyYIO6RpjTFteaxH@gondor.apana.org.au>
References: <20241026040958.GA34351@sol.localdomain>
 <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>
 <CAMj1kXFfPtO0vd1KqTa+QNSkRWNR7SUJ_A_zX6-Hz5HVLtLYtw@mail.gmail.com>
 <ZyX8yEqnjXjJ5itO@gondor.apana.org.au>
 <CAMj1kXHje-BwJVffAxN9G96Gy4Gom3Ca7dJ-_K7sgcrz7_k7Kw@mail.gmail.com>
 <CAMj1kXG8Nqw_f8OsFTq_UKRbca6w58g4uyRAZXCoCr=OwC2sWA@mail.gmail.com>
 <ZyYIO6RpjTFteaxH@gondor.apana.org.au>
Message-ID: <20241102163605.GA28213@sol.localdomain>

On Sat, Nov 02, 2024 at 07:08:43PM +0800, Herbert Xu wrote:
> On Sat, Nov 02, 2024 at 12:05:01PM +0100, Ard Biesheuvel wrote:
> >
> > The only issue resulting from *not* taking this patch is that btrfs
> > may misidentify the CRC32 implementation as being 'slow' and take an
> > alternative code path, which does not necessarily result in worse
> > performance.
> 
> If we were removing crc32* (or at least crc32*-arch) from the Crypto
> API then these patches would be redundant.  But if we're keeping them
> because btrfs uses them then we should definitely make crc32*-arch
> do the right thing.  IOW they should not be registered if they're
> the same as crc32*-generic.
> 
> Thanks,

I would like to eventually remove crc32 and crc32c from the crypto API, but it
will take some time to get all the users converted.  If there are AF_ALG users
it could even be impossible, though the usual culprit, iwd, doesn't appear to
use any CRCs, so hopefully we are fine there.

I will plan to keep this patch, but change it to use a crc32_optimizations()
function instead which was Ard's first suggestion.

I don't think Ard's static_call suggestion would work as-is, since considering
the following:

    static inline u32 __pure crc32_le(u32 crc, const u8 *p, size_t len)
    {
            if (IS_ENABLED(CONFIG_CRC32_ARCH))
                    return static_call(crc32_le_arch)(crc, p, len);
            return crc32_le_base(crc, p, len);
    }

... the 'static_call(crc32_le_arch)(crc, p, len)' will be inlined into every
user, which could be a loadable module which gets loaded after crc32-${arch}.ko.
And AFAIK, static calls in that module won't be updated in that case.

That could be avoided by making crc32_le() a non-inline function in lib/crc32.c,
so the static call would only be in that one place.  That has the slight
disadvantage that it would introduce an extra jump into the common case where
the optimized function is enabled.  Considering that some users are passing
small amounts of data into the CRC functions (e.g., 4 bytes), I would like to
minimize the overhead as much as possible.

It could also be avoided by making CRC32 and CRC32_ARCH bool rather than
tristate.  I would prefer not to do that, since there can be situations where
only loadable modules need these functions so they should not have to be built
into the core kernel.

So I plan to go with the crc32_optimizations() solution in v3.

- Eric


From ardb at kernel.org  Sat Nov  2 09:46:34 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 2 Nov 2024 17:46:34 +0100
Subject: [PATCH v2 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <20241102163605.GA28213@sol.localdomain>
References: <20241026040958.GA34351@sol.localdomain> <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>
 <CAMj1kXFfPtO0vd1KqTa+QNSkRWNR7SUJ_A_zX6-Hz5HVLtLYtw@mail.gmail.com>
 <ZyX8yEqnjXjJ5itO@gondor.apana.org.au> <CAMj1kXHje-BwJVffAxN9G96Gy4Gom3Ca7dJ-_K7sgcrz7_k7Kw@mail.gmail.com>
 <CAMj1kXG8Nqw_f8OsFTq_UKRbca6w58g4uyRAZXCoCr=OwC2sWA@mail.gmail.com>
 <ZyYIO6RpjTFteaxH@gondor.apana.org.au> <20241102163605.GA28213@sol.localdomain>
Message-ID: <CAMj1kXEQHiqkO7j1W55UHGg-LNF2CNiPnpHcKfCdKnxFQSJ14g@mail.gmail.com>

On Sat, 2 Nov 2024 at 17:36, Eric Biggers <ebiggers at kernel.org> wrote:
>
> On Sat, Nov 02, 2024 at 07:08:43PM +0800, Herbert Xu wrote:
> > On Sat, Nov 02, 2024 at 12:05:01PM +0100, Ard Biesheuvel wrote:
> > >
> > > The only issue resulting from *not* taking this patch is that btrfs
> > > may misidentify the CRC32 implementation as being 'slow' and take an
> > > alternative code path, which does not necessarily result in worse
> > > performance.
> >
> > If we were removing crc32* (or at least crc32*-arch) from the Crypto
> > API then these patches would be redundant.  But if we're keeping them
> > because btrfs uses them then we should definitely make crc32*-arch
> > do the right thing.  IOW they should not be registered if they're
> > the same as crc32*-generic.
> >
> > Thanks,
>
> I would like to eventually remove crc32 and crc32c from the crypto API, but it
> will take some time to get all the users converted.  If there are AF_ALG users
> it could even be impossible, though the usual culprit, iwd, doesn't appear to
> use any CRCs, so hopefully we are fine there.
>
> I will plan to keep this patch, but change it to use a crc32_optimizations()
> function instead which was Ard's first suggestion.
>
> I don't think Ard's static_call suggestion would work as-is, since considering
> the following:
>
>     static inline u32 __pure crc32_le(u32 crc, const u8 *p, size_t len)
>     {
>             if (IS_ENABLED(CONFIG_CRC32_ARCH))
>                     return static_call(crc32_le_arch)(crc, p, len);
>             return crc32_le_base(crc, p, len);
>     }
>
> ... the 'static_call(crc32_le_arch)(crc, p, len)' will be inlined into every
> user, which could be a loadable module which gets loaded after crc32-${arch}.ko.
> And AFAIK, static calls in that module won't be updated in that case.
>

Any call to static_call_update() will update all existing users, so
this should work as expected.

(Only x86 has a non-trivial implementation that patches callers inline
- otherwise, it is either an indirect call involving a global function
pointer variable, or a single trampoline that gets patched to point
somewhere else)

...
>
> So I plan to go with the crc32_optimizations() solution in v3.
>

That is also fine with me.


From gmazyland at gmail.com  Sat Nov  2 10:21:48 2024
From: gmazyland at gmail.com (Milan Broz)
Date: Sat, 2 Nov 2024 18:21:48 +0100
Subject: [PATCH v2 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <20241102163605.GA28213@sol.localdomain>
References: <20241026040958.GA34351@sol.localdomain>
 <ZyX0uGHg4Cmsk2oz@gondor.apana.org.au>
 <CAMj1kXFfPtO0vd1KqTa+QNSkRWNR7SUJ_A_zX6-Hz5HVLtLYtw@mail.gmail.com>
 <ZyX8yEqnjXjJ5itO@gondor.apana.org.au>
 <CAMj1kXHje-BwJVffAxN9G96Gy4Gom3Ca7dJ-_K7sgcrz7_k7Kw@mail.gmail.com>
 <CAMj1kXG8Nqw_f8OsFTq_UKRbca6w58g4uyRAZXCoCr=OwC2sWA@mail.gmail.com>
 <ZyYIO6RpjTFteaxH@gondor.apana.org.au>
 <20241102163605.GA28213@sol.localdomain>
Message-ID: <8784622f-ccdc-4086-83f7-50462d6369df@gmail.com>

On 11/2/24 5:36 PM, Eric Biggers wrote:
> On Sat, Nov 02, 2024 at 07:08:43PM +0800, Herbert Xu wrote:
>> On Sat, Nov 02, 2024 at 12:05:01PM +0100, Ard Biesheuvel wrote:
>>>
>>> The only issue resulting from *not* taking this patch is that btrfs
>>> may misidentify the CRC32 implementation as being 'slow' and take an
>>> alternative code path, which does not necessarily result in worse
>>> performance.
>>
>> If we were removing crc32* (or at least crc32*-arch) from the Crypto
>> API then these patches would be redundant.  But if we're keeping them
>> because btrfs uses them then we should definitely make crc32*-arch
>> do the right thing.  IOW they should not be registered if they're
>> the same as crc32*-generic.
>>
>> Thanks,
> 
> I would like to eventually remove crc32 and crc32c from the crypto API, but it
> will take some time to get all the users converted.  If there are AF_ALG users
> it could even be impossible, though the usual culprit, iwd, doesn't appear to
> use any CRCs, so hopefully we are fine there.

Hi,

Please do not forget about dm-integrity, it can use crc32/crc32c for non-cryptographic
integrity through crypto API.
To test it, cryptsetup testsuite should cover these variants (integrity-compat-test).

Also, libcryptsetup can be compiled with userspace kernel crypto (AF_ALG) as a crypto backend.
At least, I think we never used CRC32 though AF_ALG from userspace there...

Thanks,
Milan



From samuel.holland at sifive.com  Sat Nov  2 12:57:13 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Sat, 2 Nov 2024 14:57:13 -0500
Subject: [PATCH 6/6] riscv: Remove CONFIG_PAGE_OFFSET
In-Reply-To: <CAJFTR8RJYdT6CQ=FgBkM3jUj=PnYnuyi3+bO3=NPeH6xJ6TTaw@mail.gmail.com>
References: <20241026171441.3047904-1-samuel.holland@sifive.com>
 <20241026171441.3047904-7-samuel.holland@sifive.com>
 <CAJFTR8RJYdT6CQ=FgBkM3jUj=PnYnuyi3+bO3=NPeH6xJ6TTaw@mail.gmail.com>
Message-ID: <5ee03973-1f14-44eb-b9ac-a41bc9ae474e@sifive.com>

Hi Jesse,

On 2024-10-27 3:25 PM, Jesse T wrote:
> On Sat, Oct 26, 2024 at 1:16?PM Samuel Holland
> <samuel.holland at sifive.com> wrote:
>>
>> The current definition of CONFIG_PAGE_OFFSET is problematic for a couple
>> of reasons:
>>  1) The value is misleading for normal 64-bit kernels, where it is
>>     overridden at runtime if Sv48 or Sv39 is chosen. This is especially
>>     the case for XIP kernels, which always use Sv39.
>>  2) The option is not user-visible, but for NOMMU kernels it must be a
>>     valid RAM address, and for !RELOCATABLE it must additionally be the
>>     exact address where the kernel is loaded.
>>
>> Fix both of these by removing the option.
>>  1) For MMU kernels, drop the indirection through Kconfig. Additionally,
>>     for XIP, drop the indirection through kernel_map.
>>  2) For NOMMU kernels, use the user-visible physical RAM base if
>>     provided. Otherwise, force the kernel to be relocatable.
>>
>> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> Reviewed-by: Jesse Taube <mr.bossman075 at gmail.com>

Thanks!

>> ---
>>
>>  arch/riscv/Kconfig               |  8 +-------
>>  arch/riscv/include/asm/page.h    | 15 ++++++++-------
>>  arch/riscv/include/asm/pgtable.h |  2 +-
>>  arch/riscv/mm/init.c             |  8 ++------
>>  4 files changed, 12 insertions(+), 21 deletions(-)
>>
>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
>> index 33aa79d84021..297ccbf4b5ce 100644
>> --- a/arch/riscv/Kconfig
>> +++ b/arch/riscv/Kconfig
>> @@ -195,6 +195,7 @@ config RISCV
>>         select PCI_DOMAINS_GENERIC if PCI
>>         select PCI_ECAM if (ACPI && PCI)
>>         select PCI_MSI if PCI
>> +       select RELOCATABLE if !MMU && !PHYS_RAM_BASE_FIXED
>>         select RISCV_ALTERNATIVE if !XIP_KERNEL
>>         select RISCV_APLIC
>>         select RISCV_IMSIC
>> @@ -282,13 +283,6 @@ config MMU
>>           Select if you want MMU-based virtualised addressing space
>>           support by paged memory management. If unsure, say 'Y'.
>>
>> -config PAGE_OFFSET
>> -       hex
>> -       default 0x80000000 if !MMU && RISCV_M_MODE
>> -       default 0x80200000 if !MMU
> 
> Should the default values above now be moved to CONFIG_PHYS_RAM_BASE?

No, there doesn't need to be a default address, because the default behavior is
to be relocatable. If the kernel is running in S-mode, then it does not have
access to all of RAM, because the firmware is using some of it. So in that case
I don't think it makes sense to hardcode any addresses in the kernel.

For M-mode, the default for CONFIG_PHYS_RAM_BASE is already 0x80000000.

Regards,
Samuel

>> -       default 0xc0000000 if 32BIT
>> -       default 0xff60000000000000 if 64BIT
>> -
>>  config KASAN_SHADOW_OFFSET
>>         hex
>>         depends on KASAN_GENERIC
>> diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
>> index 24d1ac052609..d1acd1efe0dc 100644
>> --- a/arch/riscv/include/asm/page.h
>> +++ b/arch/riscv/include/asm/page.h
>> @@ -28,15 +28,16 @@
>>   */
>>  #ifdef CONFIG_MMU
>>  #ifdef CONFIG_64BIT
>> -#define PAGE_OFFSET            kernel_map.page_offset
>> -/*
>> - * By default, CONFIG_PAGE_OFFSET value corresponds to SV57 address space so
>> - * define the PAGE_OFFSET value for SV48 and SV39.
>> - */
>> +#define PAGE_OFFSET_L5         _AC(0xff60000000000000, UL)
>>  #define PAGE_OFFSET_L4         _AC(0xffffaf8000000000, UL)
>>  #define PAGE_OFFSET_L3         _AC(0xffffffd600000000, UL)
>> +#ifdef CONFIG_XIP_KERNEL
>> +#define PAGE_OFFSET            PAGE_OFFSET_L3
>>  #else
>> -#define PAGE_OFFSET            _AC(CONFIG_PAGE_OFFSET, UL)
>> +#define PAGE_OFFSET            kernel_map.page_offset
>> +#endif /* CONFIG_XIP_KERNEL */
>> +#else
>> +#define PAGE_OFFSET            _AC(0xc0000000, UL)
>>  #endif /* CONFIG_64BIT */
>>  #else
>>  #define PAGE_OFFSET            ((unsigned long)phys_ram_base)
>> @@ -100,7 +101,6 @@ typedef struct page *pgtable_t;
>>  #define ARCH_PFN_OFFSET                (PFN_DOWN((unsigned long)phys_ram_base))
>>
>>  struct kernel_mapping {
>> -       unsigned long page_offset;
>>         unsigned long virt_addr;
>>         unsigned long virt_offset;
>>         uintptr_t phys_addr;
>> @@ -114,6 +114,7 @@ struct kernel_mapping {
>>         uintptr_t xiprom;
>>         uintptr_t xiprom_sz;
>>  #else
>> +       unsigned long page_offset;
>>         unsigned long va_kernel_pa_offset;
>>  #endif
>>  };
>> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
>> index d0190ee9b2e4..b8125c3aa85d 100644
>> --- a/arch/riscv/include/asm/pgtable.h
>> +++ b/arch/riscv/include/asm/pgtable.h
>> @@ -15,7 +15,7 @@
>>  #ifdef CONFIG_RELOCATABLE
>>  #define KERNEL_LINK_ADDR       UL(0)
>>  #else
>> -#define KERNEL_LINK_ADDR       _AC(CONFIG_PAGE_OFFSET, UL)
>> +#define KERNEL_LINK_ADDR       _AC(CONFIG_PHYS_RAM_BASE, UL)
>>  #endif
>>  #define KERN_VIRT_SIZE         (UL(-1))
>>  #else
>> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
>> index 0aad925848a4..a1a185e6faf0 100644
>> --- a/arch/riscv/mm/init.c
>> +++ b/arch/riscv/mm/init.c
>> @@ -843,6 +843,8 @@ static __init void set_satp_mode(uintptr_t dtb_pa)
>>         uintptr_t set_satp_mode_pmd = ((unsigned long)set_satp_mode) & PMD_MASK;
>>         u64 satp_mode_cmdline = __pi_set_satp_mode_from_cmdline(dtb_pa);
>>
>> +       kernel_map.page_offset = PAGE_OFFSET_L5;
>> +
>>         if (satp_mode_cmdline == SATP_MODE_57) {
>>                 disable_pgtable_l5();
>>         } else if (satp_mode_cmdline == SATP_MODE_48) {
>> @@ -1090,11 +1092,6 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
>>         kernel_map.virt_addr = KERNEL_LINK_ADDR + kernel_map.virt_offset;
>>
>>  #ifdef CONFIG_XIP_KERNEL
>> -#ifdef CONFIG_64BIT
>> -       kernel_map.page_offset = PAGE_OFFSET_L3;
>> -#else
>> -       kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL);
>> -#endif
>>         kernel_map.xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR;
>>         kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom);
>>
>> @@ -1106,7 +1103,6 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
>>         kernel_map.va_kernel_xip_data_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr
>>                                                 + (uintptr_t)&_sdata - (uintptr_t)&_start;
>>  #else
>> -       kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL);
>>         kernel_map.phys_addr = (uintptr_t)(&_start);
>>         kernel_map.size = (uintptr_t)(&_end) - kernel_map.phys_addr;
>>         kernel_map.va_kernel_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr;
>> --
>> 2.45.1
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv



From samuel.holland at sifive.com  Sat Nov  2 13:16:51 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Sat, 2 Nov 2024 15:16:51 -0500
Subject: [PATCH v4 1/2] RISC-V: clarify what some RISCV_ISA* config
 options do
In-Reply-To: <20241024-overdue-slogan-0b0f69d3da91@spud>
References: <20241024-aspire-rectify-9982da6943e5@spud>
 <20241024-overdue-slogan-0b0f69d3da91@spud>
Message-ID: <43f05f71-71f7-4073-ae3b-5f5fa35ad2b8@sifive.com>

On 2024-10-24 5:19 AM, Conor Dooley wrote:
> From: Conor Dooley <conor.dooley at microchip.com>
> 
> During some discussion on IRC yesterday and on Pu's bpf patch [1]
> I noticed that these RISCV_ISA* Kconfig options are not really clear
> about their implications. Many of these options have no impact on what
> userspace is allowed to do, for example an application can use Zbb
> regardless of whether or not the kernel does. Change the help text to
> try and clarify whether or not an option affects just the kernel, or
> also userspace. None of these options actually control whether or not an
> extension is detected dynamically as that's done regardless of Kconfig
> options, so drop any text that implies the option is required for
> dynamic detection, rewording them as "do x when y is detected".
> 
> Link: https://lore.kernel.org/linux-riscv/20240328-ferocity-repose-c554f75a676c at spud/ [1]
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
> ---
>  arch/riscv/Kconfig | 36 +++++++++++++++++++-----------------
>  1 file changed, 19 insertions(+), 17 deletions(-)

Reviewed-by: Samuel Holland <samuel.holland at sifive.com>



From samuel.holland at sifive.com  Sat Nov  2 13:18:05 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Sat, 2 Nov 2024 15:18:05 -0500
Subject: [PATCH v4 2/2] RISC-V: separate Zbb optimisations requiring and
 not requiring toolchain support
In-Reply-To: <20241024-chump-freebase-d26b6d81af33@spud>
References: <20241024-aspire-rectify-9982da6943e5@spud>
 <20241024-chump-freebase-d26b6d81af33@spud>
Message-ID: <9617eb4f-842d-4678-926e-478471de479b@sifive.com>

On 2024-10-24 5:19 AM, Conor Dooley wrote:
> From: Conor Dooley <conor.dooley at microchip.com>
> 
> It seems a bit ridiculous to require toolchain support for BPF to
> assemble Zbb instructions, so move the dependency on toolchain support
> for Zbb optimisations out of the Kconfig option and to the callsites.
> 
> Zbb support has always depended on alternatives, so while adjusting the
> config options guarding optimisations, remove any checks for
> whether or not alternatives are enabled.
> 
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
> ---
>  arch/riscv/Kconfig                    |  4 ++--
>  arch/riscv/include/asm/arch_hweight.h |  6 +++---
>  arch/riscv/include/asm/bitops.h       |  4 ++--
>  arch/riscv/include/asm/checksum.h     |  3 +--
>  arch/riscv/lib/csum.c                 | 21 +++------------------
>  arch/riscv/lib/strcmp.S               |  5 +++--
>  arch/riscv/lib/strlen.S               |  5 +++--
>  arch/riscv/lib/strncmp.S              |  5 +++--
>  8 files changed, 20 insertions(+), 33 deletions(-)

Reviewed-by: Samuel Holland <samuel.holland at sifive.com>



From jassisinghbrar at gmail.com  Sat Nov  2 17:23:01 2024
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Sat, 2 Nov 2024 19:23:01 -0500
Subject: [PATCH v2 3/3] mailbox: add Microchip IPC support
In-Reply-To: <20241025125110.1347757-4-valentina.fernandezalanis@microchip.com>
References: <20241025125110.1347757-1-valentina.fernandezalanis@microchip.com> <20241025125110.1347757-4-valentina.fernandezalanis@microchip.com>
Message-ID: <CABb+yY3cDD-E-P1MPKQjdX7R2XVVKjwXUW-BANWcz-9aR6kskA@mail.gmail.com>

On Fri, Oct 25, 2024 at 7:36?AM Valentina Fernandez
<valentina.fernandezalanis at microchip.com> wrote:

....
> +
> +enum ipc_irq_type {
> +       IPC_OPS_NOT_SUPPORTED   = 1,
> +       IPC_MP_IRQ              = 2,
> +       IPC_MC_IRQ              = 4,
> +};
totally unused.

> +
> +/**
> + * struct mchp_ipc_probe - IPC probe message format
> + *
> + * @hw_type:           IPC implementation available in the hardware
> + * @num_channels:      number of IPC channels available in the hardware
> + *
> + * Used to retrieve information on the IPC implementation
> + * using the SBI_EXT_IPC_PROBE SBI function id.
> + */
> +struct mchp_ipc_probe {
 same as the driver.probe(), so maybe call this microchip_mbox_info

......

> +struct mchp_ipc_cluster_cfg {
> +       void *buf_base;
> +       unsigned long buf_base_addr;
> +       int irq;
> +};
> +
> +struct ipc_chan_info {
 I suggest s/ipc_chan_info/microchip_sbi_chan and hooking it to
mbox_chan.con_priv

....

> +       unsigned long buf_base_tx_addr;
> +       unsigned long buf_base_rx_addr;
> +       unsigned long msg_buf_tx_addr;
> +       unsigned long msg_buf_rx_addr;
If these are __pa(), then phys_addr_t please.

> +       int chan_aggregated_irq;
> +       int mp_irq;
> +       int mc_irq;
> +       u32 id;
> +       u32 max_msg_size;
> +};
> +
> +struct microchip_ipc {
 Maybe s/microchip_ipc/microchip_sbi_mbox ?


> +       struct device *dev;
> +       struct mbox_chan *chans;
> +       struct mchp_ipc_cluster_cfg *cluster_cfg;
> +       struct ipc_chan_info *priv;
  replace this with 'struct mbox_chan *chan' and hook
     chan[i].con_priv = priv[i]
  this will help avoid having to EXPORT mchp_ipc_get_chan_id


> +       void *buf_base;
> +       unsigned long buf_base_addr;
phys_addr_t buf_base_addr ?

> +       struct mbox_controller controller;
> +       u8 num_channels;
this could be dropped by directly using 'controller.num_chans'

......

> +static int mchp_ipc_send_data(struct mbox_chan *chan, void *data)
> +{
> +       struct ipc_chan_info *chan_info = (struct ipc_chan_info *)chan->con_priv;
> +       const struct mchp_ipc_msg *msg = data;
> +       struct mchp_ipc_sbi_msg sbi_payload;
> +
> +       memcpy(chan_info->msg_buf_tx, msg->buf, msg->size);
> +       sbi_payload.buf_addr = chan_info->msg_buf_tx_addr;
> +       sbi_payload.size = msg->size;
> +       memcpy(chan_info->buf_base_tx, &sbi_payload, sizeof(sbi_payload));
How does this work? sizeof(sbi_payload) is more than
sizeof(*chan_info->buf_base_tx)
I think buf_base_tx needs to be u8 array of max{sizeof(struct
mchp_ipc_init), sizeof(struct mchp_ipc_sbi_msg)}, if there are
alignment requirements then maybe kmalloc that size.
Similarly for buf_base_rx.

...

> +static struct platform_driver mchp_ipc_driver = {
> +       .driver = {
> +               .name = "microchip_ipc",
> +               .of_match_table = mchp_ipc_of_match,
> +       },
> +       .probe = mchp_ipc_probe,
The driver could be built as a module, so please provide .remove()
even if you never intend to unload it.

cheers.


From inochiama at gmail.com  Sun Nov  3 00:49:54 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Sun,  3 Nov 2024 15:49:54 +0800
Subject: [PATCH v2 0/3] riscv: Add bfloat16 instruction support
Message-ID: <20241103074959.1135240-1-inochiama@gmail.com>

Add description for the BFloat16 precision Floating-Point ISA extension,
(Zfbfmin, Zvfbfmin, Zvfbfwma). which was ratified in commit 4dc23d62
("Added Chapter title to BF16") of the riscv-isa-manual.

Changed from v1:
1. add missing code in sys_hwprobe.c

Inochi Amaoto (3):
  dt-bindings: riscv: add bfloat16 ISA extension description
  riscv: add ISA extension parsing for bfloat16 ISA extension
  riscv: hwprobe: export bfloat16 ISA extension

 Documentation/arch/riscv/hwprobe.rst          | 12 +++++
 .../devicetree/bindings/riscv/extensions.yaml | 45 +++++++++++++++++++
 arch/riscv/include/asm/hwcap.h                |  3 ++
 arch/riscv/include/uapi/asm/hwprobe.h         |  3 ++
 arch/riscv/kernel/cpufeature.c                |  3 ++
 arch/riscv/kernel/sys_hwprobe.c               |  3 ++
 6 files changed, 69 insertions(+)

--
2.47.0



From inochiama at gmail.com  Sun Nov  3 00:49:55 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Sun,  3 Nov 2024 15:49:55 +0800
Subject: [PATCH v2 1/3] dt-bindings: riscv: add bfloat16 ISA extension description
In-Reply-To: <20241103074959.1135240-1-inochiama@gmail.com>
References: <20241103074959.1135240-1-inochiama@gmail.com>
Message-ID: <20241103074959.1135240-2-inochiama@gmail.com>

Add description for the BFloat16 precision Floating-Point ISA extension,
(Zfbfmin, Zvfbfmin, Zvfbfwma). which was ratified in commit 4dc23d62
("Added Chapter title to BF16") of the riscv-isa-manual.

Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
---
 .../devicetree/bindings/riscv/extensions.yaml | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
index 2cf2026cff57..99d8b70fa321 100644
--- a/Documentation/devicetree/bindings/riscv/extensions.yaml
+++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
@@ -277,6 +277,12 @@ properties:
             instructions, as ratified in commit 056b6ff ("Zfa is ratified") of
             riscv-isa-manual.
 
+        - const: zfbfmin
+          description:
+            The standard Zfbfmin extension which provides minimal support for
+            16-bit half-precision brain floating-point instructions, as ratified
+            in commit 4dc23d62 ("Added Chapter title to BF16") of riscv-isa-manual.
+
         - const: zfh
           description:
             The standard Zfh extension for 16-bit half-precision binary
@@ -467,6 +473,18 @@ properties:
             in commit 6f702a2 ("Vector extensions are now ratified") of
             riscv-v-spec.
 
+        - const: zvfbfmin
+          description:
+            The standard Zvfbfmin extension for minimal support for vectored
+            16-bit half-precision brain floating-point instructions, as ratified
+            in commit 4dc23d62 ("Added Chapter title to BF16") of riscv-isa-manual.
+
+        - const: zvfbfwma
+          description:
+            The standard Zvfbfwma extension for vectored half-precision brain
+            floating-point widening multiply-accumulate instructions, as ratified
+            in commit 4dc23d62 ("Added Chapter title to BF16") of riscv-isa-manual.
+
         - const: zvfh
           description:
             The standard Zvfh extension for vectored half-precision
@@ -605,6 +623,33 @@ properties:
         then:
           contains:
             const: zca
+      # Zfbfmin depends on F
+      - if:
+          contains:
+            const: zfbfmin
+        then:
+          contains:
+            const: f
+      # Zvfbfmin depends on V or Zve32f
+      - if:
+          contains:
+            const: zvfbfmin
+        then:
+          oneOf:
+            - contains:
+                const: v
+            - contains:
+                const: zve32f
+      # Zvfbfwma depends on Zfbfmin and Zvfbfmin
+      - if:
+          contains:
+            const: zvfbfwma
+        then:
+          allOf:
+            - contains:
+                const: zfbfmin
+            - contains:
+                const: zvfbfmin
 
 allOf:
   # Zcf extension does not exist on rv64
-- 
2.47.0



From inochiama at gmail.com  Sun Nov  3 00:49:56 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Sun,  3 Nov 2024 15:49:56 +0800
Subject: [PATCH v2 2/3] riscv: add ISA extension parsing for bfloat16 ISA extension
In-Reply-To: <20241103074959.1135240-1-inochiama@gmail.com>
References: <20241103074959.1135240-1-inochiama@gmail.com>
Message-ID: <20241103074959.1135240-3-inochiama@gmail.com>

Add parsing for Zfbmin, Zvfbfmin, Zvfbfwma ISA extension which
were ratified in 4dc23d62 ("Added Chapter title to BF16") of
the riscv-isa-manual.

Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
---
 arch/riscv/include/asm/hwcap.h | 3 +++
 arch/riscv/kernel/cpufeature.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index 46d9de54179e..97657fb63af6 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -93,6 +93,9 @@
 #define RISCV_ISA_EXT_ZCMOP		84
 #define RISCV_ISA_EXT_ZAWRS		85
 #define RISCV_ISA_EXT_SVVPTC		86
+#define RISCV_ISA_EXT_ZFBFMIN		87
+#define RISCV_ISA_EXT_ZVFBFMIN		88
+#define RISCV_ISA_EXT_ZVFBFWMA		89
 
 #define RISCV_ISA_EXT_XLINUXENVCFG	127
 
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 3a8eeaa9310c..1b286f5bc591 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -325,6 +325,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 	__RISCV_ISA_EXT_DATA(zacas, RISCV_ISA_EXT_ZACAS),
 	__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
 	__RISCV_ISA_EXT_DATA(zfa, RISCV_ISA_EXT_ZFA),
+	__RISCV_ISA_EXT_DATA(zfbfmin, RISCV_ISA_EXT_ZFBFMIN),
 	__RISCV_ISA_EXT_DATA(zfh, RISCV_ISA_EXT_ZFH),
 	__RISCV_ISA_EXT_DATA(zfhmin, RISCV_ISA_EXT_ZFHMIN),
 	__RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA),
@@ -357,6 +358,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 	__RISCV_ISA_EXT_SUPERSET(zve64d, RISCV_ISA_EXT_ZVE64D, riscv_zve64d_exts),
 	__RISCV_ISA_EXT_SUPERSET(zve64f, RISCV_ISA_EXT_ZVE64F, riscv_zve64f_exts),
 	__RISCV_ISA_EXT_SUPERSET(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts),
+	__RISCV_ISA_EXT_DATA(zvfbfmin, RISCV_ISA_EXT_ZVFBFMIN),
+	__RISCV_ISA_EXT_DATA(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA),
 	__RISCV_ISA_EXT_DATA(zvfh, RISCV_ISA_EXT_ZVFH),
 	__RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN),
 	__RISCV_ISA_EXT_DATA(zvkb, RISCV_ISA_EXT_ZVKB),
-- 
2.47.0



From inochiama at gmail.com  Sun Nov  3 00:49:57 2024
From: inochiama at gmail.com (Inochi Amaoto)
Date: Sun,  3 Nov 2024 15:49:57 +0800
Subject: [PATCH v2 3/3] riscv: hwprobe: export bfloat16 ISA extension
In-Reply-To: <20241103074959.1135240-1-inochiama@gmail.com>
References: <20241103074959.1135240-1-inochiama@gmail.com>
Message-ID: <20241103074959.1135240-4-inochiama@gmail.com>

Export Zfbmin, Zvfbfmin, Zvfbfwma ISA extension through hwprobe.

Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
---
 Documentation/arch/riscv/hwprobe.rst  | 12 ++++++++++++
 arch/riscv/include/uapi/asm/hwprobe.h |  3 +++
 arch/riscv/kernel/sys_hwprobe.c       |  3 +++
 3 files changed, 18 insertions(+)

diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
index 85b709257918..8c30dd06f3c0 100644
--- a/Documentation/arch/riscv/hwprobe.rst
+++ b/Documentation/arch/riscv/hwprobe.rst
@@ -239,6 +239,18 @@ The following keys are defined:
        ratified in commit 98918c844281 ("Merge pull request #1217 from
        riscv/zawrs") of riscv-isa-manual.
 
+  * :c:macro:`RISCV_HWPROBE_EXT_ZFBFMIN`: The Zfbfmin extension is supported as
+       defined in the RISC-V ISA manual starting from commit 4dc23d6229de
+       ("Added Chapter title to BF16").
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZVFBFMIN`: The Zvfbfmin extension is supported as
+       defined in the RISC-V ISA manual starting from commit 4dc23d6229de
+       ("Added Chapter title to BF16").
+
+  * :c:macro:`RISCV_HWPROBE_EXT_ZVFBFWMA`: The Zvfbfwma extension is supported as
+       defined in the RISC-V ISA manual starting from commit 4dc23d6229de
+       ("Added Chapter title to BF16").
+
 * :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: Deprecated.  Returns similar values to
      :c:macro:`RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF`, but the key was
      mistakenly classified as a bitmask rather than a value.
diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
index 1e153cda57db..95d00a065b4e 100644
--- a/arch/riscv/include/uapi/asm/hwprobe.h
+++ b/arch/riscv/include/uapi/asm/hwprobe.h
@@ -72,6 +72,9 @@ struct riscv_hwprobe {
 #define		RISCV_HWPROBE_EXT_ZCF		(1ULL << 46)
 #define		RISCV_HWPROBE_EXT_ZCMOP		(1ULL << 47)
 #define		RISCV_HWPROBE_EXT_ZAWRS		(1ULL << 48)
+#define		RISCV_HWPROBE_EXT_ZFBFMIN	(1ULL << 49)
+#define		RISCV_HWPROBE_EXT_ZVFBFMIN	(1ULL << 50)
+#define		RISCV_HWPROBE_EXT_ZVFBFWMA	(1ULL << 51)
 #define RISCV_HWPROBE_KEY_CPUPERF_0	5
 #define		RISCV_HWPROBE_MISALIGNED_UNKNOWN	(0 << 0)
 #define		RISCV_HWPROBE_MISALIGNED_EMULATED	(1 << 0)
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index cea0ca2bf2a2..de1966bd1776 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -131,6 +131,8 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
 			EXT_KEY(ZVE64D);
 			EXT_KEY(ZVE64F);
 			EXT_KEY(ZVE64X);
+			EXT_KEY(ZVFBFMIN);
+			EXT_KEY(ZVFBFWMA);
 			EXT_KEY(ZVFH);
 			EXT_KEY(ZVFHMIN);
 			EXT_KEY(ZVKB);
@@ -147,6 +149,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
 			EXT_KEY(ZCD);
 			EXT_KEY(ZCF);
 			EXT_KEY(ZFA);
+			EXT_KEY(ZFBFMIN);
 			EXT_KEY(ZFH);
 			EXT_KEY(ZFHMIN);
 		}
-- 
2.47.0



From 00107082 at 163.com  Sun Nov  3 01:05:52 2024
From: 00107082 at 163.com (David Wang)
Date: Sun,  3 Nov 2024 16:05:52 +0800
Subject: [PATCH] kernel/irq/proc: performance: replace seq_printf with seq_put_decimal_ull_width
Message-ID: <20241103080552.4787-1-00107082@163.com>

seq_printf is costy, when stress reading /proc/interrupts, profiling indicates
seq_printf takes about ~47% of show_interrupts samples:

    show_interrupts(94.495% 5166019/5466991)
	seq_printf(47.429% 2450210/5166019)
	    vsnprintf(89.232% 2186366/2450210)
		format_decode(24.005% 524831/2186366)
		number(19.488% 426084/2186366)
		memcpy_orig(3.739% 81753/2186366)
		...
	_raw_spin_unlock_irqrestore(26.643% 1376379/5166019)
	mtree_load(8.059% 416304/5166019)

On a system with n CPUs and m interrupts, there will be n*m decimal
values yielded via seq_printf(.."%10u "..) which is less efficient
than seq_put_decimal_ull_width, stress reading /proc/interrupts
indicates ~30% performance improvement with this patch, and profiling
data shows:

	show_interrupts(92.221% 3609371/3913823)
	    _raw_spin_unlock_irqrestore(39.123% 1412078/3609371)
	    mtree_load(11.942% 431036/3609371)
	    seq_put_decimal_ull_width(11.635% 419958/3609371)
	    seq_printf(9.025% 325754/3609371)
	    ...

The improvement has pratical significance, considering many monitoring
tools would read /proc/interrupts periodically.

seq_put_decimal_ull_width(..," ", v, 10) is equivalent to
seq_printf(.., " %10llu", v), not "%10llu "; Hence there is space
adjustment along.

Signed-off-by: David Wang <00107082 at 163.com>
---
 arch/alpha/kernel/irq.c     |   8 +--
 arch/arm/kernel/smp.c       |   4 +-
 arch/arm64/kernel/smp.c     |   3 +-
 arch/csky/kernel/smp.c      |   4 +-
 arch/loongarch/kernel/smp.c |   2 +-
 arch/parisc/kernel/irq.c    |  34 ++++++------
 arch/powerpc/kernel/irq.c   |  44 ++++++++--------
 arch/riscv/kernel/smp.c     |   3 +-
 arch/sh/kernel/irq.c        |   4 +-
 arch/sparc/kernel/irq_32.c  |  12 ++---
 arch/sparc/kernel/irq_64.c  |   4 +-
 arch/x86/kernel/irq.c       | 100 ++++++++++++++++++------------------
 arch/xtensa/kernel/irq.c    |   2 +-
 arch/xtensa/kernel/smp.c    |   4 +-
 kernel/irq/proc.c           |   6 ++-
 15 files changed, 120 insertions(+), 114 deletions(-)

diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index c67047c5d830..0dbb8d3ed647 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -72,14 +72,14 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 	int j;
 
 #ifdef CONFIG_SMP
-	seq_puts(p, "IPI: ");
+	seq_puts(p, "IPI:");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10lu ", cpu_data[j].ipi_count);
+		seq_put_decimal_ull_width(p, " ", cpu_data[j].ipi_count, 10);
 	seq_putc(p, '\n');
 #endif
-	seq_puts(p, "PMI: ");
+	seq_puts(p, "PMI:");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10lu ", per_cpu(irq_pmi_count, j));
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_pmi_count, j), 10);
 	seq_puts(p, "          Performance Monitoring\n");
 	seq_printf(p, "ERR: %10lu\n", irq_err_count);
 	return 0;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 3431c0553f45..1b0680477ae1 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -551,10 +551,10 @@ void show_ipi_list(struct seq_file *p, int prec)
 		if (!ipi_desc[i])
 			continue;
 
-		seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
+		seq_printf(p, "%*s%u:", prec - 1, "IPI", i);
 
 		for_each_online_cpu(cpu)
-			seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu));
+			seq_put_decimal_ull_width(p, " ", irq_desc_kstat_cpu(ipi_desc[i], cpu), 10);
 
 		seq_printf(p, " %s\n", ipi_types[i]);
 	}
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 3b3f6b56e733..35734a30ed8d 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -844,7 +844,8 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
 			   prec >= 4 ? " " : "");
 		for_each_online_cpu(cpu)
-			seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu));
+			seq_put_decimal_ull_width(p, " ",
+						  irq_desc_kstat_cpu(ipi_desc[i], cpu), 10);
 		seq_printf(p, "      %s\n", ipi_types[i]);
 	}
 
diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c
index 92dbbf3e0205..65f399afc3f0 100644
--- a/arch/csky/kernel/smp.c
+++ b/arch/csky/kernel/smp.c
@@ -112,8 +112,8 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
 			   prec >= 4 ? " " : "");
 		for_each_online_cpu(cpu)
-			seq_printf(p, "%10lu ",
-				per_cpu_ptr(&ipi_data, cpu)->stats[i]);
+			seq_put_decimal_ull_width(p, " ",
+						  per_cpu_ptr(&ipi_data, cpu)->stats[i], 10);
 		seq_printf(p, " %s\n", ipi_names[i]);
 	}
 
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
index 9afc2d8b3414..86664adfb3cf 100644
--- a/arch/loongarch/kernel/smp.c
+++ b/arch/loongarch/kernel/smp.c
@@ -82,7 +82,7 @@ void show_ipi_list(struct seq_file *p, int prec)
 	for (i = 0; i < NR_IPI; i++) {
 		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, prec >= 4 ? " " : "");
 		for_each_online_cpu(cpu)
-			seq_printf(p, "%10u ", per_cpu(irq_stat, cpu).ipi_irqs[i]);
+			seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, cpu).ipi_irqs[i], 10);
 		seq_printf(p, " LoongArch  %d  %s\n", i + 1, ipi_types[i]);
 	}
 }
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index dff66be65d29..b060d7e6da46 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -133,40 +133,42 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 	int j;
 
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
-	seq_printf(p, "%*s: ", prec, "STK");
+	seq_printf(p, "%*s:", prec, "STK");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->kernel_stack_usage, 10);
 	seq_puts(p, "  Kernel stack usage\n");
 # ifdef CONFIG_IRQSTACKS
-	seq_printf(p, "%*s: ", prec, "IST");
+	seq_printf(p, "%*s:", prec, "IST");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_stack_usage, 10);
 	seq_puts(p, "  Interrupt stack usage\n");
 # endif
 #endif
 #ifdef CONFIG_SMP
 	if (num_online_cpus() > 1) {
-		seq_printf(p, "%*s: ", prec, "RES");
+		seq_printf(p, "%*s:", prec, "RES");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
+			seq_put_decimal_ull_width(p, " ",
+						  irq_stats(j)->irq_resched_count, 10);
 		seq_puts(p, "  Rescheduling interrupts\n");
-		seq_printf(p, "%*s: ", prec, "CAL");
+		seq_printf(p, "%*s:", prec, "CAL");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
+			seq_put_decimal_ull_width(p, " ",
+						  irq_stats(j)->irq_call_count, 10);
 		seq_puts(p, "  Function call interrupts\n");
 	}
 #endif
-	seq_printf(p, "%*s: ", prec, "UAH");
+	seq_printf(p, "%*s:", prec, "UAH");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_unaligned_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_unaligned_count, 10);
 	seq_puts(p, "  Unaligned access handler traps\n");
-	seq_printf(p, "%*s: ", prec, "FPA");
+	seq_printf(p, "%*s:", prec, "FPA");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_fpassist_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_fpassist_count, 10);
 	seq_puts(p, "  Floating point assist traps\n");
-	seq_printf(p, "%*s: ", prec, "TLB");
+	seq_printf(p, "%*s:", prec, "TLB");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_tlb_count, 10);
 	seq_puts(p, "  TLB shootdowns\n");
 	return 0;
 }
@@ -195,10 +197,10 @@ int show_interrupts(struct seq_file *p, void *v)
 		action = desc->action;
 		if (!action)
 			goto skip;
-		seq_printf(p, "%3d: ", i);
+		seq_printf(p, "%3d:", i);
 
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", irq_desc_kstat_cpu(desc, j));
+			seq_put_decimal_ull_width(p, " ", irq_desc_kstat_cpu(desc, j), 10);
 
 		seq_printf(p, " %14s", irq_desc_get_chip(desc)->name);
 #ifndef PARISC_IRQ_CR16_COUNTS
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 2e1600a8bbbb..a0e8b998c9b5 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -89,69 +89,69 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 
 #if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
 	if (tau_initialized) {
-		seq_printf(p, "%*s: ", prec, "TAU");
+		seq_printf(p, "%*s:", prec, "TAU");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", tau_interrupts(j));
+			seq_put_decimal_ull_width(p, " ", tau_interrupts(j), 10);
 		seq_puts(p, "  PowerPC             Thermal Assist (cpu temp)\n");
 	}
 #endif /* CONFIG_PPC32 && CONFIG_TAU_INT */
 
-	seq_printf(p, "%*s: ", prec, "LOC");
+	seq_printf(p, "%*s:", prec, "LOC");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(irq_stat, j).timer_irqs_event);
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).timer_irqs_event, 10);
         seq_printf(p, "  Local timer interrupts for timer event device\n");
 
-	seq_printf(p, "%*s: ", prec, "BCT");
+	seq_printf(p, "%*s:", prec, "BCT");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(irq_stat, j).broadcast_irqs_event);
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).broadcast_irqs_event, 10);
 	seq_printf(p, "  Broadcast timer interrupts for timer event device\n");
 
-	seq_printf(p, "%*s: ", prec, "LOC");
+	seq_printf(p, "%*s:", prec, "LOC");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(irq_stat, j).timer_irqs_others);
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).timer_irqs_others, 10);
         seq_printf(p, "  Local timer interrupts for others\n");
 
-	seq_printf(p, "%*s: ", prec, "SPU");
+	seq_printf(p, "%*s:", prec, "SPU");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(irq_stat, j).spurious_irqs);
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).spurious_irqs, 10);
 	seq_printf(p, "  Spurious interrupts\n");
 
-	seq_printf(p, "%*s: ", prec, "PMI");
+	seq_printf(p, "%*s:", prec, "PMI");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs);
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).pmu_irqs, 10);
 	seq_printf(p, "  Performance monitoring interrupts\n");
 
-	seq_printf(p, "%*s: ", prec, "MCE");
+	seq_printf(p, "%*s:", prec, "MCE");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions);
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).mce_exceptions, 10);
 	seq_printf(p, "  Machine check exceptions\n");
 
 #ifdef CONFIG_PPC_BOOK3S_64
 	if (cpu_has_feature(CPU_FTR_HVMODE)) {
-		seq_printf(p, "%*s: ", prec, "HMI");
+		seq_printf(p, "%*s:", prec, "HMI");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", paca_ptrs[j]->hmi_irqs);
+			seq_put_decimal_ull_width(p, " ", paca_ptrs[j]->hmi_irqs, 10);
 		seq_printf(p, "  Hypervisor Maintenance Interrupts\n");
 	}
 #endif
 
-	seq_printf(p, "%*s: ", prec, "NMI");
+	seq_printf(p, "%*s:", prec, "NMI");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(irq_stat, j).sreset_irqs);
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).sreset_irqs, 10);
 	seq_printf(p, "  System Reset interrupts\n");
 
 #ifdef CONFIG_PPC_WATCHDOG
-	seq_printf(p, "%*s: ", prec, "WDG");
+	seq_printf(p, "%*s:", prec, "WDG");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(irq_stat, j).soft_nmi_irqs);
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).soft_nmi_irqs, 10);
 	seq_printf(p, "  Watchdog soft-NMI interrupts\n");
 #endif
 
 #ifdef CONFIG_PPC_DOORBELL
 	if (cpu_has_feature(CPU_FTR_DBELL)) {
-		seq_printf(p, "%*s: ", prec, "DBL");
+		seq_printf(p, "%*s:", prec, "DBL");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", per_cpu(irq_stat, j).doorbell_irqs);
+			seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).doorbell_irqs, 10);
 		seq_printf(p, "  Doorbell interrupts\n");
 	}
 #endif
diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index c180a647a30e..f1e9c3db094c 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -226,7 +226,8 @@ void show_ipi_stats(struct seq_file *p, int prec)
 		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
 			   prec >= 4 ? " " : "");
 		for_each_online_cpu(cpu)
-			seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu));
+			seq_put_decimal_ull_width(p, " ",
+						  irq_desc_kstat_cpu(ipi_desc[i], cpu), 10);
 		seq_printf(p, " %s\n", ipi_names[i]);
 	}
 }
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 4e6835de54cf..9022d8af9d68 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -43,9 +43,9 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 {
 	int j;
 
-	seq_printf(p, "%*s: ", prec, "NMI");
+	seq_printf(p, "%*s:", prec, "NMI");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(irq_stat.__nmi_count, j));
+		seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat.__nmi_count, j), 10);
 	seq_printf(p, "  Non-maskable interrupts\n");
 
 	seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index 8605dd710f3c..5210991429d5 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -199,18 +199,18 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 	int j;
 
 #ifdef CONFIG_SMP
-	seq_printf(p, "RES: ");
+	seq_printf(p, "RES:");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", cpu_data(j).irq_resched_count);
+		seq_put_decimal_ull_width(p, " ", cpu_data(j).irq_resched_count, 10);
 	seq_printf(p, "     IPI rescheduling interrupts\n");
-	seq_printf(p, "CAL: ");
+	seq_printf(p, "CAL:");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", cpu_data(j).irq_call_count);
+		seq_put_decimal_ull_width(p, " ", cpu_data(j).irq_call_count, 10);
 	seq_printf(p, "     IPI function call interrupts\n");
 #endif
-	seq_printf(p, "NMI: ");
+	seq_printf(p, "NMI:");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", cpu_data(j).counter);
+		seq_put_decimal_ull_width(p, " ", cpu_data(j).counter, 10);
 	seq_printf(p, "     Non-maskable interrupts\n");
 	return 0;
 }
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 01ee800efde3..9ab6e79b617b 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -304,9 +304,9 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 {
 	int j;
 
-	seq_printf(p, "NMI: ");
+	seq_printf(p, "NMI:");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", cpu_data(j).__nmi_count);
+		seq_put_decimal_ull_width(p, " ", cpu_data(j).__nmi_count, 10);
 	seq_printf(p, "     Non-maskable interrupts\n");
 	return 0;
 }
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 385e3a5fc304..66cc8f001bd0 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -62,103 +62,103 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 {
 	int j;
 
-	seq_printf(p, "%*s: ", prec, "NMI");
+	seq_printf(p, "%*s:", prec, "NMI");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->__nmi_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->__nmi_count, 10);
 	seq_puts(p, "  Non-maskable interrupts\n");
 #ifdef CONFIG_X86_LOCAL_APIC
-	seq_printf(p, "%*s: ", prec, "LOC");
+	seq_printf(p, "%*s:", prec, "LOC");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->apic_timer_irqs, 10);
 	seq_puts(p, "  Local timer interrupts\n");
 
-	seq_printf(p, "%*s: ", prec, "SPU");
+	seq_printf(p, "%*s:", prec, "SPU");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_spurious_count, 10);
 	seq_puts(p, "  Spurious interrupts\n");
-	seq_printf(p, "%*s: ", prec, "PMI");
+	seq_printf(p, "%*s:", prec, "PMI");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->apic_perf_irqs, 10);
 	seq_puts(p, "  Performance monitoring interrupts\n");
-	seq_printf(p, "%*s: ", prec, "IWI");
+	seq_printf(p, "%*s:", prec, "IWI");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->apic_irq_work_irqs);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->apic_irq_work_irqs, 10);
 	seq_puts(p, "  IRQ work interrupts\n");
-	seq_printf(p, "%*s: ", prec, "RTR");
+	seq_printf(p, "%*s:", prec, "RTR");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->icr_read_retry_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->icr_read_retry_count, 10);
 	seq_puts(p, "  APIC ICR read retries\n");
 	if (x86_platform_ipi_callback) {
-		seq_printf(p, "%*s: ", prec, "PLT");
+		seq_printf(p, "%*s:", prec, "PLT");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ", irq_stats(j)->x86_platform_ipis);
+			seq_put_decimal_ull_width(p, " ", irq_stats(j)->x86_platform_ipis, 10);
 		seq_puts(p, "  Platform interrupts\n");
 	}
 #endif
 #ifdef CONFIG_SMP
-	seq_printf(p, "%*s: ", prec, "RES");
+	seq_printf(p, "%*s:", prec, "RES");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_resched_count, 10);
 	seq_puts(p, "  Rescheduling interrupts\n");
-	seq_printf(p, "%*s: ", prec, "CAL");
+	seq_printf(p, "%*s:", prec, "CAL");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_call_count, 10);
 	seq_puts(p, "  Function call interrupts\n");
-	seq_printf(p, "%*s: ", prec, "TLB");
+	seq_printf(p, "%*s:", prec, "TLB");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_tlb_count, 10);
 	seq_puts(p, "  TLB shootdowns\n");
 #endif
 #ifdef CONFIG_X86_THERMAL_VECTOR
-	seq_printf(p, "%*s: ", prec, "TRM");
+	seq_printf(p, "%*s:", prec, "TRM");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_thermal_count, 10);
 	seq_puts(p, "  Thermal event interrupts\n");
 #endif
 #ifdef CONFIG_X86_MCE_THRESHOLD
-	seq_printf(p, "%*s: ", prec, "THR");
+	seq_printf(p, "%*s:", prec, "THR");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_threshold_count, 10);
 	seq_puts(p, "  Threshold APIC interrupts\n");
 #endif
 #ifdef CONFIG_X86_MCE_AMD
-	seq_printf(p, "%*s: ", prec, "DFR");
+	seq_printf(p, "%*s:", prec, "DFR");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->irq_deferred_error_count);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->irq_deferred_error_count, 10);
 	seq_puts(p, "  Deferred Error APIC interrupts\n");
 #endif
 #ifdef CONFIG_X86_MCE
-	seq_printf(p, "%*s: ", prec, "MCE");
+	seq_printf(p, "%*s:", prec, "MCE");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(mce_exception_count, j));
+		seq_put_decimal_ull_width(p, " ", per_cpu(mce_exception_count, j), 10);
 	seq_puts(p, "  Machine check exceptions\n");
-	seq_printf(p, "%*s: ", prec, "MCP");
+	seq_printf(p, "%*s:", prec, "MCP");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
+		seq_put_decimal_ull_width(p, " ", per_cpu(mce_poll_count, j), 10);
 	seq_puts(p, "  Machine check polls\n");
 #endif
 #ifdef CONFIG_X86_HV_CALLBACK_VECTOR
 	if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
-		seq_printf(p, "%*s: ", prec, "HYP");
+		seq_printf(p, "%*s:", prec, "HYP");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ",
-				   irq_stats(j)->irq_hv_callback_count);
+			seq_put_decimal_ull_width(p, " ",
+						  irq_stats(j)->irq_hv_callback_count, 10);
 		seq_puts(p, "  Hypervisor callback interrupts\n");
 	}
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
 	if (test_bit(HYPERV_REENLIGHTENMENT_VECTOR, system_vectors)) {
-		seq_printf(p, "%*s: ", prec, "HRE");
+		seq_printf(p, "%*s:", prec, "HRE");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ",
-				   irq_stats(j)->irq_hv_reenlightenment_count);
+			seq_put_decimal_ull_width(p, " ",
+						  irq_stats(j)->irq_hv_reenlightenment_count, 10);
 		seq_puts(p, "  Hyper-V reenlightenment interrupts\n");
 	}
 	if (test_bit(HYPERV_STIMER0_VECTOR, system_vectors)) {
-		seq_printf(p, "%*s: ", prec, "HVS");
+		seq_printf(p, "%*s:", prec, "HVS");
 		for_each_online_cpu(j)
-			seq_printf(p, "%10u ",
-				   irq_stats(j)->hyperv_stimer0_count);
+			seq_put_decimal_ull_width(p, " ",
+						  irq_stats(j)->hyperv_stimer0_count, 10);
 		seq_puts(p, "  Hyper-V stimer0 interrupts\n");
 	}
 #endif
@@ -167,28 +167,28 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 	seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count));
 #endif
 #if IS_ENABLED(CONFIG_KVM)
-	seq_printf(p, "%*s: ", prec, "PIN");
+	seq_printf(p, "%*s:", prec, "PIN");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", irq_stats(j)->kvm_posted_intr_ipis);
+		seq_put_decimal_ull_width(p, " ", irq_stats(j)->kvm_posted_intr_ipis, 10);
 	seq_puts(p, "  Posted-interrupt notification event\n");
 
-	seq_printf(p, "%*s: ", prec, "NPI");
+	seq_printf(p, "%*s:", prec, "NPI");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ",
-			   irq_stats(j)->kvm_posted_intr_nested_ipis);
+		seq_put_decimal_ull_width(p, " ",
+					  irq_stats(j)->kvm_posted_intr_nested_ipis, 10);
 	seq_puts(p, "  Nested posted-interrupt event\n");
 
-	seq_printf(p, "%*s: ", prec, "PIW");
+	seq_printf(p, "%*s:", prec, "PIW");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ",
-			   irq_stats(j)->kvm_posted_intr_wakeup_ipis);
+		seq_put_decimal_ull_width(p, " ",
+					  irq_stats(j)->kvm_posted_intr_wakeup_ipis, 10);
 	seq_puts(p, "  Posted-interrupt wakeup event\n");
 #endif
 #ifdef CONFIG_X86_POSTED_MSI
-	seq_printf(p, "%*s: ", prec, "PMN");
+	seq_printf(p, "%*s:", prec, "PMN");
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ",
-			   irq_stats(j)->posted_msi_notification_count);
+		seq_put_decimal_ull_width(p, " ",
+					  irq_stats(j)->posted_msi_notification_count, 10);
 	seq_puts(p, "  Posted MSI notification event\n");
 #endif
 	return 0;
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index b1e410f6b5ab..c4f46989f9b7 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -58,7 +58,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 #if XTENSA_FAKE_NMI
 	seq_printf(p, "%*s:", prec, "NMI");
 	for_each_online_cpu(cpu)
-		seq_printf(p, " %10lu", per_cpu(nmi_count, cpu));
+		seq_put_decimal_ull_width(p, " ", per_cpu(nmi_count, cpu), 10);
 	seq_puts(p, "   Non-maskable interrupts\n");
 #endif
 	return 0;
diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c
index 94a23f100726..71ec9eced8b9 100644
--- a/arch/xtensa/kernel/smp.c
+++ b/arch/xtensa/kernel/smp.c
@@ -453,8 +453,8 @@ void show_ipi_list(struct seq_file *p, int prec)
 	for (i = 0; i < IPI_MAX; ++i) {
 		seq_printf(p, "%*s:", prec, ipi_text[i].short_text);
 		for_each_online_cpu(cpu)
-			seq_printf(p, " %10lu",
-					per_cpu(ipi_data, cpu).ipi_count[i]);
+			seq_put_decimal_ull_width(p, " ",
+						  per_cpu(ipi_data, cpu).ipi_count[i], 10);
 		seq_printf(p, "   %s\n", ipi_text[i].long_text);
 	}
 }
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 9081ada81c3d..988ce781e813 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -494,9 +494,11 @@ int show_interrupts(struct seq_file *p, void *v)
 	if (!desc->action || irq_desc_is_chained(desc) || !desc->kstat_irqs)
 		goto outsparse;
 
-	seq_printf(p, "%*d: ", prec, i);
+	seq_printf(p, "%*d:", prec, i);
 	for_each_online_cpu(j)
-		seq_printf(p, "%10u ", desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, j) : 0);
+		seq_put_decimal_ull_width(p, " ",
+					  desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, j) : 0,
+					  10);
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	if (desc->irq_data.chip) {
-- 
2.39.2



From wangyuli at uniontech.com  Sun Nov  3 05:36:55 2024
From: wangyuli at uniontech.com (WangYuli)
Date: Sun,  3 Nov 2024 21:36:55 +0800
Subject: [PATCH v2 06/18] loongarch/crc32: expose CRC32 functions through lib
In-Reply-To: <20241025191454.72616-7-ebiggers@kernel.org>
References: <20241025191454.72616-7-ebiggers@kernel.org>
Message-ID: <DA8BCDFFEACDA1C6+20241103133655.217375-1-wangyuli@uniontech.com>

Even though the narrower CRC instructions doesn't require GRLEN=64, they still *aren't* part of LA32 (LoongArch reference manual v1.10, Volume 1, Table 2-1).
Link: https://lore.kernel.org/all/0a7d0a9e-c56e-4ee2-a83b-00164a450abe at xen0n.name/

Therefore, we could not directly add ARCH_HAS_CRC32 to config LOONGARCH.

Thanks,
--
WangYuli


From ebiggers at kernel.org  Sun Nov  3 05:57:30 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun, 3 Nov 2024 05:57:30 -0800
Subject: [PATCH v2 06/18] loongarch/crc32: expose CRC32 functions through
 lib
In-Reply-To: <DA8BCDFFEACDA1C6+20241103133655.217375-1-wangyuli@uniontech.com>
References: <20241025191454.72616-7-ebiggers@kernel.org>
 <DA8BCDFFEACDA1C6+20241103133655.217375-1-wangyuli@uniontech.com>
Message-ID: <20241103135730.GA813@quark.localdomain>

On Sun, Nov 03, 2024 at 09:36:55PM +0800, WangYuli wrote:
> Even though the narrower CRC instructions doesn't require GRLEN=64, they still *aren't* part of LA32 (LoongArch reference manual v1.10, Volume 1, Table 2-1).
> Link: https://lore.kernel.org/all/0a7d0a9e-c56e-4ee2-a83b-00164a450abe at xen0n.name/
> 
> Therefore, we could not directly add ARCH_HAS_CRC32 to config LOONGARCH.
> 

There's still a runtime CPU feature check of cpu_has(CPU_FEATURE_CRC32).
See arch/loongarch/lib/crc32-loongarch.c.  So it's the same as before.
ARCH_HAS_CRC32 just means that the file will be compiled.

If you're trying to say that you think this file should be built only when
CONFIG_64BIT=y, then that would be an existing bug since the existing file
arch/loongarch/crypto/crc32-loongarch.c was built for both 32-bit and 64-bit.
But if you think this is a bug, I can fix this too.

- Eric


From alexghiti at rivosinc.com  Sun Nov  3 06:51:40 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:40 +0100
Subject: [PATCH v6 00/13] Zacas/Zabha support and qspinlocks
Message-ID: <20241103145153.105097-1-alexghiti@rivosinc.com>

This implements [cmp]xchgXX() macros using Zacas and Zabha extensions
and finally uses those newly introduced macros to add support for
qspinlocks: note that this implementation of qspinlocks satisfies the
forward progress guarantee.

It also uses Ziccrse to provide the qspinlock implementation.

Thanks to Guo and Leonardo for their work!

v5: https://lore.kernel.org/linux-riscv/20240818063538.6651-1-alexghiti at rivosinc.com/
v4: https://lore.kernel.org/linux-riscv/20240731072405.197046-1-alexghiti at rivosinc.com/
v3: https://lore.kernel.org/linux-riscv/20240717061957.140712-1-alexghiti at rivosinc.com/
v2: https://lore.kernel.org/linux-riscv/20240626130347.520750-1-alexghiti at rivosinc.com/
v1: https://lore.kernel.org/linux-riscv/20240528151052.313031-1-alexghiti at rivosinc.com/

Changes in v6:
- Rebase on 6.12-rc5
- Fix comment about macros (Drew)
- Add RB from Drew

Changes in v5:
- Remove useless include in cpufeature.h and add required ones (Drew)
- Add RB from Drew
- Add AB from Conor and Peter
- use macros to help readability of arch_cmpxchg_XXX() (Drew)
- restore the build_bug() for size > 8 (Drew)
- Update Ziccrse riscv profile spec version commit hash (Conor)

Changes in v4:
- rename sc_sfx into sc_cas_sfx in _arch_cmpxchg (Drew)
- cmpxchg() depends on 64BIT (Drew)
- rename xX register into tX (Drew)
- cas operations require the old value in rd, make this assignment more explicit
  as it seems to confuse people (Drew, Andrea)
- Fix ticket/queued configs build errors (Andrea)
- riscv_spinlock_init() is only needed for combo spinlocks but implement it
  anyway to inform of the type of spinlocks used (Andrea)
- Add RB from Guo
- Add NONPORTABLE to RISCV_QUEUED_SPINLOCKS (Samuel)
- Add a link to Guo's qspinlocks results on the sophgo platform
- Reorder ZICCRSE (Samuel)
- Use riscv_has_extention_unlikely() instead of direct asm goto, which is way
  cleaner and fixes the llvm 16 bug
- add dependency on RISCV_ALTERNATIVES in kconfig
- Rebase on top of 6.11, add patches to fix header circular dependency and
  to fix build_bug()

Changes in v3:
- Fix patch 4 to restrict the optimization to fully ordered AMO (Andrea)
- Move RISCV_ISA_EXT_ZABHA definition to patch 4 (Andrea)
- !Zacas at build time => no CAS from Zabha too (Andrea)
- drop patch 7 "riscv: Improve amoswap.X use in xchg()" (Andrea)
- Switch lr/sc and cas order (Guo)
- Combo spinlocks do not depend on Zabha
- Add a Kconfig for ticket/queued/combo (Guo)
- Use Ziccrse (Guo)

Changes in v2:
- Add patch for Zabha dtbinding (Conor)
- Fix cmpxchg128() build warnings missed in v1
- Make arch_cmpxchg128() fully ordered
- Improve Kconfig help texts for both extensions (Conor)
- Fix Makefile dependencies by requiring TOOLCHAIN_HAS_XXX (Nathan)
- Fix compilation errors when the toolchain does not support the
  extensions (Nathan)
- Fix C23 warnings about label at the end of coumpound statements (Nathan)
- Fix Zabha and !Zacas configurations (Andrea)
- Add COMBO spinlocks (Guo)
- Improve amocas fully ordered operations by using .aqrl semantics and
  removing the fence rw, rw (Andrea)
- Rebase on top "riscv: Fix fully ordered LR/SC xchg[8|16]() implementations"
- Add ARCH_WEAK_RELEASE_ACQUIRE (Andrea)
- Remove the extension version in march for LLVM since it is only required
  for experimental extensions (Nathan)
- Fix cmpxchg128() implementation by adding both registers of a pair
  in the list of input/output operands

Alexandre Ghiti (11):
  riscv: Move cpufeature.h macros into their own header
  riscv: Do not fail to build on byte/halfword operations with Zawrs
  riscv: Implement cmpxchg32/64() using Zacas
  dt-bindings: riscv: Add Zabha ISA extension description
  riscv: Implement cmpxchg8/16() using Zabha
  riscv: Improve zacas fully-ordered cmpxchg()
  riscv: Implement arch_cmpxchg128() using Zacas
  riscv: Implement xchg8/16() using Zabha
  riscv: Add ISA extension parsing for Ziccrse
  dt-bindings: riscv: Add Ziccrse ISA extension description
  riscv: Add qspinlock support

Guo Ren (2):
  asm-generic: ticket-lock: Reuse arch_spinlock_t of qspinlock
  asm-generic: ticket-lock: Add separate ticket-lock.h

 .../devicetree/bindings/riscv/extensions.yaml |  12 +
 .../locking/queued-spinlocks/arch-support.txt |   2 +-
 arch/riscv/Kconfig                            |  69 +++++
 arch/riscv/Makefile                           |   6 +
 arch/riscv/include/asm/Kbuild                 |   4 +-
 arch/riscv/include/asm/cmpxchg.h              | 286 +++++++++++++-----
 arch/riscv/include/asm/cpufeature-macros.h    |  66 ++++
 arch/riscv/include/asm/cpufeature.h           |  61 +---
 arch/riscv/include/asm/hwcap.h                |   2 +
 arch/riscv/include/asm/spinlock.h             |  47 +++
 arch/riscv/kernel/cpufeature.c                |   2 +
 arch/riscv/kernel/setup.c                     |  37 +++
 include/asm-generic/qspinlock.h               |   2 +
 include/asm-generic/spinlock.h                |  87 +-----
 include/asm-generic/spinlock_types.h          |  12 +-
 include/asm-generic/ticket_spinlock.h         | 105 +++++++
 16 files changed, 567 insertions(+), 233 deletions(-)
 create mode 100644 arch/riscv/include/asm/cpufeature-macros.h
 create mode 100644 arch/riscv/include/asm/spinlock.h
 create mode 100644 include/asm-generic/ticket_spinlock.h

-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:41 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:41 +0100
Subject: [PATCH v6 01/13] riscv: Move cpufeature.h macros into their own header
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-2-alexghiti@rivosinc.com>

asm/cmpxchg.h will soon need riscv_has_extension_unlikely() macros and
then needs to include asm/cpufeature.h which introduces a lot of header
circular dependencies.

So move the riscv_has_extension_XXX() macros into their own header which
prevents such circular dependencies by including a restricted number of
headers.

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/include/asm/cpufeature-macros.h | 66 ++++++++++++++++++++++
 arch/riscv/include/asm/cpufeature.h        | 61 ++------------------
 2 files changed, 70 insertions(+), 57 deletions(-)
 create mode 100644 arch/riscv/include/asm/cpufeature-macros.h

diff --git a/arch/riscv/include/asm/cpufeature-macros.h b/arch/riscv/include/asm/cpufeature-macros.h
new file mode 100644
index 000000000000..a8103edbf51f
--- /dev/null
+++ b/arch/riscv/include/asm/cpufeature-macros.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2022-2024 Rivos, Inc
+ */
+
+#ifndef _ASM_CPUFEATURE_MACROS_H
+#define _ASM_CPUFEATURE_MACROS_H
+
+#include <asm/hwcap.h>
+#include <asm/alternative-macros.h>
+
+#define STANDARD_EXT		0
+
+bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, unsigned int bit);
+#define riscv_isa_extension_available(isa_bitmap, ext)	\
+	__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_##ext)
+
+static __always_inline bool __riscv_has_extension_likely(const unsigned long vendor,
+							 const unsigned long ext)
+{
+	asm goto(ALTERNATIVE("j	%l[l_no]", "nop", %[vendor], %[ext], 1)
+	:
+	: [vendor] "i" (vendor), [ext] "i" (ext)
+	:
+	: l_no);
+
+	return true;
+l_no:
+	return false;
+}
+
+static __always_inline bool __riscv_has_extension_unlikely(const unsigned long vendor,
+							   const unsigned long ext)
+{
+	asm goto(ALTERNATIVE("nop", "j	%l[l_yes]", %[vendor], %[ext], 1)
+	:
+	: [vendor] "i" (vendor), [ext] "i" (ext)
+	:
+	: l_yes);
+
+	return false;
+l_yes:
+	return true;
+}
+
+static __always_inline bool riscv_has_extension_unlikely(const unsigned long ext)
+{
+	compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX");
+
+	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
+		return __riscv_has_extension_unlikely(STANDARD_EXT, ext);
+
+	return __riscv_isa_extension_available(NULL, ext);
+}
+
+static __always_inline bool riscv_has_extension_likely(const unsigned long ext)
+{
+	compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX");
+
+	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
+		return __riscv_has_extension_likely(STANDARD_EXT, ext);
+
+	return __riscv_isa_extension_available(NULL, ext);
+}
+
+#endif /* _ASM_CPUFEATURE_MACROS_H */
diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h
index 45f9c1171a48..87ed88fc950d 100644
--- a/arch/riscv/include/asm/cpufeature.h
+++ b/arch/riscv/include/asm/cpufeature.h
@@ -8,9 +8,11 @@
 
 #include <linux/bitmap.h>
 #include <linux/jump_label.h>
+#include <linux/kconfig.h>
+#include <linux/percpu-defs.h>
+#include <linux/threads.h>
 #include <asm/hwcap.h>
-#include <asm/alternative-macros.h>
-#include <asm/errno.h>
+#include <asm/cpufeature-macros.h>
 
 /*
  * These are probed via a device_initcall(), via either the SBI or directly
@@ -103,61 +105,6 @@ extern const size_t riscv_isa_ext_count;
 extern bool riscv_isa_fallback;
 
 unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
-
-#define STANDARD_EXT		0
-
-bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, unsigned int bit);
-#define riscv_isa_extension_available(isa_bitmap, ext)	\
-	__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_##ext)
-
-static __always_inline bool __riscv_has_extension_likely(const unsigned long vendor,
-							 const unsigned long ext)
-{
-	asm goto(ALTERNATIVE("j	%l[l_no]", "nop", %[vendor], %[ext], 1)
-	:
-	: [vendor] "i" (vendor), [ext] "i" (ext)
-	:
-	: l_no);
-
-	return true;
-l_no:
-	return false;
-}
-
-static __always_inline bool __riscv_has_extension_unlikely(const unsigned long vendor,
-							   const unsigned long ext)
-{
-	asm goto(ALTERNATIVE("nop", "j	%l[l_yes]", %[vendor], %[ext], 1)
-	:
-	: [vendor] "i" (vendor), [ext] "i" (ext)
-	:
-	: l_yes);
-
-	return false;
-l_yes:
-	return true;
-}
-
-static __always_inline bool riscv_has_extension_unlikely(const unsigned long ext)
-{
-	compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX");
-
-	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
-		return __riscv_has_extension_unlikely(STANDARD_EXT, ext);
-
-	return __riscv_isa_extension_available(NULL, ext);
-}
-
-static __always_inline bool riscv_has_extension_likely(const unsigned long ext)
-{
-	compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX");
-
-	if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE))
-		return __riscv_has_extension_likely(STANDARD_EXT, ext);
-
-	return __riscv_isa_extension_available(NULL, ext);
-}
-
 static __always_inline bool riscv_cpu_has_extension_likely(int cpu, const unsigned long ext)
 {
 	compiletime_assert(ext < RISCV_ISA_EXT_MAX, "ext must be < RISCV_ISA_EXT_MAX");
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:42 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:42 +0100
Subject: [PATCH v6 02/13] riscv: Do not fail to build on byte/halfword operations with Zawrs
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-3-alexghiti@rivosinc.com>

riscv does not have lr instructions on byte and halfword but the
qspinlock implementation actually uses such atomics provided by the
Zabha extension, so those sizes are legitimate.

Then instead of failing to build, just fallback to the !Zawrs path.

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/include/asm/cmpxchg.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index ebbce134917c..ac1d7df898ef 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -245,6 +245,11 @@ static __always_inline void __cmpwait(volatile void *ptr,
 		 : : : : no_zawrs);
 
 	switch (size) {
+	case 1:
+		fallthrough;
+	case 2:
+		/* RISC-V doesn't have lr instructions on byte and half-word. */
+		goto no_zawrs;
 	case 4:
 		asm volatile(
 		"	lr.w	%0, %1\n"
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:43 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:43 +0100
Subject: [PATCH v6 03/13] riscv: Implement cmpxchg32/64() using Zacas
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-4-alexghiti@rivosinc.com>

This adds runtime support for Zacas in cmpxchg operations.

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/Kconfig               | 16 +++++++++++
 arch/riscv/Makefile              |  3 ++
 arch/riscv/include/asm/cmpxchg.h | 48 +++++++++++++++++++++-----------
 3 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 62545946ecf4..3542efe3088b 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -632,6 +632,22 @@ config RISCV_ISA_ZAWRS
 	  use of these instructions in the kernel when the Zawrs extension is
 	  detected at boot.
 
+config TOOLCHAIN_HAS_ZACAS
+	bool
+	default y
+	depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zacas)
+	depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zacas)
+	depends on AS_HAS_OPTION_ARCH
+
+config RISCV_ISA_ZACAS
+	bool "Zacas extension support for atomic CAS"
+	depends on TOOLCHAIN_HAS_ZACAS
+	depends on RISCV_ALTERNATIVE
+	default y
+	help
+	  Enable the use of the Zacas ISA-extension to implement kernel atomic
+	  cmpxchg operations when it is detected at boot.
+
 	  If you don't know what to do here, say Y.
 
 config TOOLCHAIN_HAS_ZBB
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index d469db9f46f4..3700a1574413 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -82,6 +82,9 @@ else
 riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei
 endif
 
+# Check if the toolchain supports Zacas
+riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZACAS) := $(riscv-march-y)_zacas
+
 # Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
 # matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
 KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index ac1d7df898ef..39c1daf39f6a 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -12,6 +12,7 @@
 #include <asm/fence.h>
 #include <asm/hwcap.h>
 #include <asm/insn-def.h>
+#include <asm/cpufeature-macros.h>
 
 #define __arch_xchg_masked(sc_sfx, prepend, append, r, p, n)		\
 ({									\
@@ -137,24 +138,37 @@
 	r = (__typeof__(*(p)))((__retx & __mask) >> __s);		\
 })
 
-#define __arch_cmpxchg(lr_sfx, sc_sfx, prepend, append, r, p, co, o, n)	\
+#define __arch_cmpxchg(lr_sfx, sc_cas_sfx, prepend, append, r, p, co, o, n)	\
 ({									\
-	register unsigned int __rc;					\
+	if (IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) &&			\
+	    riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS)) {	\
+		r = o;							\
 									\
-	__asm__ __volatile__ (						\
-		prepend							\
-		"0:	lr" lr_sfx " %0, %2\n"				\
-		"	bne  %0, %z3, 1f\n"				\
-		"	sc" sc_sfx " %1, %z4, %2\n"			\
-		"	bnez %1, 0b\n"					\
-		append							\
-		"1:\n"							\
-		: "=&r" (r), "=&r" (__rc), "+A" (*(p))			\
-		: "rJ" (co o), "rJ" (n)					\
-		: "memory");						\
+		__asm__ __volatile__ (					\
+			prepend						\
+			"	amocas" sc_cas_sfx " %0, %z2, %1\n"	\
+			append						\
+			: "+&r" (r), "+A" (*(p))			\
+			: "rJ" (n)					\
+			: "memory");					\
+	} else {							\
+		register unsigned int __rc;				\
+									\
+		__asm__ __volatile__ (					\
+			prepend						\
+			"0:	lr" lr_sfx " %0, %2\n"			\
+			"	bne  %0, %z3, 1f\n"			\
+			"	sc" sc_cas_sfx " %1, %z4, %2\n"		\
+			"	bnez %1, 0b\n"				\
+			append						\
+			"1:\n"						\
+			: "=&r" (r), "=&r" (__rc), "+A" (*(p))		\
+			: "rJ" (co o), "rJ" (n)				\
+			: "memory");					\
+	}								\
 })
 
-#define _arch_cmpxchg(ptr, old, new, sc_sfx, prepend, append)		\
+#define _arch_cmpxchg(ptr, old, new, sc_cas_sfx, prepend, append)	\
 ({									\
 	__typeof__(ptr) __ptr = (ptr);					\
 	__typeof__(*(__ptr)) __old = (old);				\
@@ -164,15 +178,15 @@
 	switch (sizeof(*__ptr)) {					\
 	case 1:								\
 	case 2:								\
-		__arch_cmpxchg_masked(sc_sfx, prepend, append,		\
+		__arch_cmpxchg_masked(sc_cas_sfx, prepend, append,	\
 					__ret, __ptr, __old, __new);	\
 		break;							\
 	case 4:								\
-		__arch_cmpxchg(".w", ".w" sc_sfx, prepend, append,	\
+		__arch_cmpxchg(".w", ".w" sc_cas_sfx, prepend, append,	\
 				__ret, __ptr, (long), __old, __new);	\
 		break;							\
 	case 8:								\
-		__arch_cmpxchg(".d", ".d" sc_sfx, prepend, append,	\
+		__arch_cmpxchg(".d", ".d" sc_cas_sfx, prepend, append,	\
 				__ret, __ptr, /**/, __old, __new);	\
 		break;							\
 	default:							\
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:44 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:44 +0100
Subject: [PATCH v6 04/13] dt-bindings: riscv: Add Zabha ISA extension description
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-5-alexghiti@rivosinc.com>

Add description for the Zabha ISA extension which was ratified in April
2024.

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Guo Ren <guoren at kernel.org>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 Documentation/devicetree/bindings/riscv/extensions.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
index 2cf2026cff57..db062107823b 100644
--- a/Documentation/devicetree/bindings/riscv/extensions.yaml
+++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
@@ -178,6 +178,12 @@ properties:
             as ratified at commit 4a69197e5617 ("Update to ratified state") of
             riscv-svvptc.
 
+        - const: zabha
+          description: |
+            The Zabha extension for Byte and Halfword Atomic Memory Operations
+            as ratified at commit 49f49c842ff9 ("Update to Rafified state") of
+            riscv-zabha.
+
         - const: zacas
           description: |
             The Zacas extension for Atomic Compare-and-Swap (CAS) instructions
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:45 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:45 +0100
Subject: [PATCH v6 05/13] riscv: Implement cmpxchg8/16() using Zabha
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-6-alexghiti@rivosinc.com>

This adds runtime support for Zabha in cmpxchg8/16() operations.

Note that in the absence of Zacas support in the toolchain, CAS
instructions from Zabha won't be used.

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/Kconfig               | 18 ++++++++
 arch/riscv/Makefile              |  3 ++
 arch/riscv/include/asm/cmpxchg.h | 78 ++++++++++++++++++++------------
 arch/riscv/include/asm/hwcap.h   |  1 +
 arch/riscv/kernel/cpufeature.c   |  1 +
 5 files changed, 72 insertions(+), 29 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 3542efe3088b..668be90a42e4 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -632,6 +632,24 @@ config RISCV_ISA_ZAWRS
 	  use of these instructions in the kernel when the Zawrs extension is
 	  detected at boot.
 
+config TOOLCHAIN_HAS_ZABHA
+	bool
+	default y
+	depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zabha)
+	depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zabha)
+	depends on AS_HAS_OPTION_ARCH
+
+config RISCV_ISA_ZABHA
+	bool "Zabha extension support for atomic byte/halfword operations"
+	depends on TOOLCHAIN_HAS_ZABHA
+	depends on RISCV_ALTERNATIVE
+	default y
+	help
+	  Enable the use of the Zabha ISA-extension to implement kernel
+	  byte/halfword atomic memory operations when it is detected at boot.
+
+	  If you don't know what to do here, say Y.
+
 config TOOLCHAIN_HAS_ZACAS
 	bool
 	default y
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 3700a1574413..9fe1ee740dda 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -85,6 +85,9 @@ endif
 # Check if the toolchain supports Zacas
 riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZACAS) := $(riscv-march-y)_zacas
 
+# Check if the toolchain supports Zabha
+riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZABHA) := $(riscv-march-y)_zabha
+
 # Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
 # matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
 KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 39c1daf39f6a..1f4cd12e4664 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -108,34 +108,49 @@
  * indicated by comparing RETURN with OLD.
  */
 
-#define __arch_cmpxchg_masked(sc_sfx, prepend, append, r, p, o, n)	\
-({									\
-	u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3);			\
-	ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE;	\
-	ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0)	\
-			<< __s;						\
-	ulong __newx = (ulong)(n) << __s;				\
-	ulong __oldx = (ulong)(o) << __s;				\
-	ulong __retx;							\
-	ulong __rc;							\
-									\
-	__asm__ __volatile__ (						\
-		prepend							\
-		"0:	lr.w %0, %2\n"					\
-		"	and  %1, %0, %z5\n"				\
-		"	bne  %1, %z3, 1f\n"				\
-		"	and  %1, %0, %z6\n"				\
-		"	or   %1, %1, %z4\n"				\
-		"	sc.w" sc_sfx " %1, %1, %2\n"			\
-		"	bnez %1, 0b\n"					\
-		append							\
-		"1:\n"							\
-		: "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b))	\
-		: "rJ" ((long)__oldx), "rJ" (__newx),			\
-		  "rJ" (__mask), "rJ" (~__mask)				\
-		: "memory");						\
-									\
-	r = (__typeof__(*(p)))((__retx & __mask) >> __s);		\
+#define __arch_cmpxchg_masked(sc_sfx, cas_sfx, prepend, append, r, p, o, n)	\
+({										\
+	if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) &&				\
+	    IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) &&				\
+	    riscv_has_extension_unlikely(RISCV_ISA_EXT_ZABHA) &&		\
+	    riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS)) {		\
+		r = o;								\
+										\
+		__asm__ __volatile__ (						\
+			prepend							\
+			"	amocas" cas_sfx " %0, %z2, %1\n"		\
+			append							\
+			: "+&r" (r), "+A" (*(p))				\
+			: "rJ" (n)						\
+			: "memory");						\
+	} else {								\
+		u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3);			\
+		ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE;	\
+		ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0)	\
+			       << __s;						\
+		ulong __newx = (ulong)(n) << __s;				\
+		ulong __oldx = (ulong)(o) << __s;				\
+		ulong __retx;							\
+		ulong __rc;							\
+										\
+		__asm__ __volatile__ (						\
+			prepend							\
+			"0:	lr.w %0, %2\n"					\
+			"	and  %1, %0, %z5\n"				\
+			"	bne  %1, %z3, 1f\n"				\
+			"	and  %1, %0, %z6\n"				\
+			"	or   %1, %1, %z4\n"				\
+			"	sc.w" sc_sfx " %1, %1, %2\n"			\
+			"	bnez %1, 0b\n"					\
+			append							\
+			"1:\n"							\
+			: "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b))	\
+			: "rJ" ((long)__oldx), "rJ" (__newx),			\
+			  "rJ" (__mask), "rJ" (~__mask)				\
+			: "memory");						\
+										\
+		r = (__typeof__(*(p)))((__retx & __mask) >> __s);		\
+	}									\
 })
 
 #define __arch_cmpxchg(lr_sfx, sc_cas_sfx, prepend, append, r, p, co, o, n)	\
@@ -177,8 +192,13 @@
 									\
 	switch (sizeof(*__ptr)) {					\
 	case 1:								\
+		__arch_cmpxchg_masked(sc_cas_sfx, ".b" sc_cas_sfx,	\
+					prepend, append,		\
+					__ret, __ptr, __old, __new);    \
+		break;							\
 	case 2:								\
-		__arch_cmpxchg_masked(sc_cas_sfx, prepend, append,	\
+		__arch_cmpxchg_masked(sc_cas_sfx, ".h" sc_cas_sfx,	\
+					prepend, append,		\
 					__ret, __ptr, __old, __new);	\
 		break;							\
 	case 4:								\
diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index 46d9de54179e..74bcb0e2bd1f 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -93,6 +93,7 @@
 #define RISCV_ISA_EXT_ZCMOP		84
 #define RISCV_ISA_EXT_ZAWRS		85
 #define RISCV_ISA_EXT_SVVPTC		86
+#define RISCV_ISA_EXT_ZABHA		87
 
 #define RISCV_ISA_EXT_XLINUXENVCFG	127
 
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 3a8eeaa9310c..5e743d8d34f5 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -322,6 +322,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 	__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
 	__RISCV_ISA_EXT_DATA(zihpm, RISCV_ISA_EXT_ZIHPM),
 	__RISCV_ISA_EXT_DATA(zimop, RISCV_ISA_EXT_ZIMOP),
+	__RISCV_ISA_EXT_DATA(zabha, RISCV_ISA_EXT_ZABHA),
 	__RISCV_ISA_EXT_DATA(zacas, RISCV_ISA_EXT_ZACAS),
 	__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
 	__RISCV_ISA_EXT_DATA(zfa, RISCV_ISA_EXT_ZFA),
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:46 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:46 +0100
Subject: [PATCH v6 06/13] riscv: Improve zacas fully-ordered cmpxchg()
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-7-alexghiti@rivosinc.com>

The current fully-ordered cmpxchgXX() implementation results in:

  amocas.X.rl     a5,a4,(s1)
  fence           rw,rw

This provides enough sync but we can actually use the following better
mapping instead:

  amocas.X.aqrl   a5,a4,(s1)

Suggested-by: Andrea Parri <andrea at rivosinc.com>
Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/include/asm/cmpxchg.h | 92 ++++++++++++++++++++++----------
 1 file changed, 64 insertions(+), 28 deletions(-)

diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 1f4cd12e4664..052418aba11a 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -107,8 +107,10 @@
  * store NEW in MEM.  Return the initial value in MEM.  Success is
  * indicated by comparing RETURN with OLD.
  */
-
-#define __arch_cmpxchg_masked(sc_sfx, cas_sfx, prepend, append, r, p, o, n)	\
+#define __arch_cmpxchg_masked(sc_sfx, cas_sfx,					\
+			      sc_prepend, sc_append,				\
+			      cas_prepend, cas_append,				\
+			      r, p, o, n)					\
 ({										\
 	if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) &&				\
 	    IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) &&				\
@@ -117,9 +119,9 @@
 		r = o;								\
 										\
 		__asm__ __volatile__ (						\
-			prepend							\
+			cas_prepend							\
 			"	amocas" cas_sfx " %0, %z2, %1\n"		\
-			append							\
+			cas_append							\
 			: "+&r" (r), "+A" (*(p))				\
 			: "rJ" (n)						\
 			: "memory");						\
@@ -134,7 +136,7 @@
 		ulong __rc;							\
 										\
 		__asm__ __volatile__ (						\
-			prepend							\
+			sc_prepend							\
 			"0:	lr.w %0, %2\n"					\
 			"	and  %1, %0, %z5\n"				\
 			"	bne  %1, %z3, 1f\n"				\
@@ -142,7 +144,7 @@
 			"	or   %1, %1, %z4\n"				\
 			"	sc.w" sc_sfx " %1, %1, %2\n"			\
 			"	bnez %1, 0b\n"					\
-			append							\
+			sc_append							\
 			"1:\n"							\
 			: "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b))	\
 			: "rJ" ((long)__oldx), "rJ" (__newx),			\
@@ -153,16 +155,19 @@
 	}									\
 })
 
-#define __arch_cmpxchg(lr_sfx, sc_cas_sfx, prepend, append, r, p, co, o, n)	\
+#define __arch_cmpxchg(lr_sfx, sc_sfx, cas_sfx,				\
+		       sc_prepend, sc_append,				\
+		       cas_prepend, cas_append,				\
+		       r, p, co, o, n)					\
 ({									\
 	if (IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) &&			\
 	    riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS)) {	\
 		r = o;							\
 									\
 		__asm__ __volatile__ (					\
-			prepend						\
-			"	amocas" sc_cas_sfx " %0, %z2, %1\n"	\
-			append						\
+			cas_prepend					\
+			"	amocas" cas_sfx " %0, %z2, %1\n"	\
+			cas_append					\
 			: "+&r" (r), "+A" (*(p))			\
 			: "rJ" (n)					\
 			: "memory");					\
@@ -170,12 +175,12 @@
 		register unsigned int __rc;				\
 									\
 		__asm__ __volatile__ (					\
-			prepend						\
+			sc_prepend					\
 			"0:	lr" lr_sfx " %0, %2\n"			\
 			"	bne  %0, %z3, 1f\n"			\
-			"	sc" sc_cas_sfx " %1, %z4, %2\n"		\
+			"	sc" sc_sfx " %1, %z4, %2\n"		\
 			"	bnez %1, 0b\n"				\
-			append						\
+			sc_append					\
 			"1:\n"						\
 			: "=&r" (r), "=&r" (__rc), "+A" (*(p))		\
 			: "rJ" (co o), "rJ" (n)				\
@@ -183,7 +188,9 @@
 	}								\
 })
 
-#define _arch_cmpxchg(ptr, old, new, sc_cas_sfx, prepend, append)	\
+#define _arch_cmpxchg(ptr, old, new, sc_sfx, cas_sfx,			\
+		      sc_prepend, sc_append,				\
+		      cas_prepend, cas_append)				\
 ({									\
 	__typeof__(ptr) __ptr = (ptr);					\
 	__typeof__(*(__ptr)) __old = (old);				\
@@ -192,22 +199,28 @@
 									\
 	switch (sizeof(*__ptr)) {					\
 	case 1:								\
-		__arch_cmpxchg_masked(sc_cas_sfx, ".b" sc_cas_sfx,	\
-					prepend, append,		\
-					__ret, __ptr, __old, __new);    \
+		__arch_cmpxchg_masked(sc_sfx, ".b" cas_sfx,		\
+				      sc_prepend, sc_append,		\
+				      cas_prepend, cas_append,		\
+				      __ret, __ptr, __old, __new);	\
 		break;							\
 	case 2:								\
-		__arch_cmpxchg_masked(sc_cas_sfx, ".h" sc_cas_sfx,	\
-					prepend, append,		\
-					__ret, __ptr, __old, __new);	\
+		__arch_cmpxchg_masked(sc_sfx, ".h" cas_sfx,		\
+				      sc_prepend, sc_append,		\
+				      cas_prepend, cas_append,		\
+				      __ret, __ptr, __old, __new);	\
 		break;							\
 	case 4:								\
-		__arch_cmpxchg(".w", ".w" sc_cas_sfx, prepend, append,	\
-				__ret, __ptr, (long), __old, __new);	\
+		__arch_cmpxchg(".w", ".w" sc_sfx, ".w" cas_sfx,		\
+			       sc_prepend, sc_append,			\
+			       cas_prepend, cas_append,			\
+			       __ret, __ptr, (long), __old, __new);	\
 		break;							\
 	case 8:								\
-		__arch_cmpxchg(".d", ".d" sc_cas_sfx, prepend, append,	\
-				__ret, __ptr, /**/, __old, __new);	\
+		__arch_cmpxchg(".d", ".d" sc_sfx, ".d" cas_sfx,		\
+			       sc_prepend, sc_append,			\
+			       cas_prepend, cas_append,			\
+			       __ret, __ptr, /**/, __old, __new);	\
 		break;							\
 	default:							\
 		BUILD_BUG();						\
@@ -215,17 +228,40 @@
 	(__typeof__(*(__ptr)))__ret;					\
 })
 
+/*
+ * These macros are here to improve the readability of the arch_cmpxchg_XXX()
+ * macros.
+ */
+#define SC_SFX(x)	x
+#define CAS_SFX(x)	x
+#define SC_PREPEND(x)	x
+#define SC_APPEND(x)	x
+#define CAS_PREPEND(x)	x
+#define CAS_APPEND(x)	x
+
 #define arch_cmpxchg_relaxed(ptr, o, n)					\
-	_arch_cmpxchg((ptr), (o), (n), "", "", "")
+	_arch_cmpxchg((ptr), (o), (n),					\
+		      SC_SFX(""), CAS_SFX(""),				\
+		      SC_PREPEND(""), SC_APPEND(""),			\
+		      CAS_PREPEND(""), CAS_APPEND(""))
 
 #define arch_cmpxchg_acquire(ptr, o, n)					\
-	_arch_cmpxchg((ptr), (o), (n), "", "", RISCV_ACQUIRE_BARRIER)
+	_arch_cmpxchg((ptr), (o), (n),					\
+		      SC_SFX(""), CAS_SFX(""),				\
+		      SC_PREPEND(""), SC_APPEND(RISCV_ACQUIRE_BARRIER),	\
+		      CAS_PREPEND(""), CAS_APPEND(RISCV_ACQUIRE_BARRIER))
 
 #define arch_cmpxchg_release(ptr, o, n)					\
-	_arch_cmpxchg((ptr), (o), (n), "", RISCV_RELEASE_BARRIER, "")
+	_arch_cmpxchg((ptr), (o), (n),					\
+		      SC_SFX(""), CAS_SFX(""),				\
+		      SC_PREPEND(RISCV_RELEASE_BARRIER), SC_APPEND(""),	\
+		      CAS_PREPEND(RISCV_RELEASE_BARRIER), CAS_APPEND(""))
 
 #define arch_cmpxchg(ptr, o, n)						\
-	_arch_cmpxchg((ptr), (o), (n), ".rl", "", "	fence rw, rw\n")
+	_arch_cmpxchg((ptr), (o), (n),					\
+		      SC_SFX(".rl"), CAS_SFX(".aqrl"),			\
+		      SC_PREPEND(""), SC_APPEND(RISCV_FULL_BARRIER),	\
+		      CAS_PREPEND(""), CAS_APPEND(""))
 
 #define arch_cmpxchg_local(ptr, o, n)					\
 	arch_cmpxchg_relaxed((ptr), (o), (n))
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:47 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:47 +0100
Subject: [PATCH v6 07/13] riscv: Implement arch_cmpxchg128() using Zacas
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-8-alexghiti@rivosinc.com>

Now that Zacas is supported in the kernel, let's use the double word
atomic version of amocas to improve the SLUB allocator.

Note that we have to select fixed registers, otherwise gcc fails to pick
even registers and then produces a reserved encoding which fails to
assemble.

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/Kconfig               |  1 +
 arch/riscv/include/asm/cmpxchg.h | 38 ++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 668be90a42e4..093ee6537331 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -115,6 +115,7 @@ config RISCV
 	select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO
 	select HARDIRQS_SW_RESEND
 	select HAS_IOPORT if MMU
+	select HAVE_ALIGNED_STRUCT_PAGE
 	select HAVE_ARCH_AUDITSYSCALL
 	select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
 	select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 052418aba11a..f95929f538b2 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -296,6 +296,44 @@
 	arch_cmpxchg_release((ptr), (o), (n));				\
 })
 
+#if defined(CONFIG_64BIT) && defined(CONFIG_RISCV_ISA_ZACAS)
+
+#define system_has_cmpxchg128()        riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS)
+
+union __u128_halves {
+	u128 full;
+	struct {
+		u64 low, high;
+	};
+};
+
+#define __arch_cmpxchg128(p, o, n, cas_sfx)					\
+({										\
+	__typeof__(*(p)) __o = (o);                                             \
+	union __u128_halves __hn = { .full = (n) };				\
+	union __u128_halves __ho = { .full = (__o) };				\
+	register unsigned long t1 asm ("t1") = __hn.low;			\
+	register unsigned long t2 asm ("t2") = __hn.high;			\
+	register unsigned long t3 asm ("t3") = __ho.low;			\
+	register unsigned long t4 asm ("t4") = __ho.high;			\
+										\
+	__asm__ __volatile__ (							\
+		 "       amocas.q" cas_sfx " %0, %z3, %2"			\
+		 : "+&r" (t3), "+&r" (t4), "+A" (*(p))				\
+		 : "rJ" (t1), "rJ" (t2)						\
+		 : "memory");							\
+										\
+		 ((u128)t4 << 64) | t3;						\
+})
+
+#define arch_cmpxchg128(ptr, o, n)						\
+	__arch_cmpxchg128((ptr), (o), (n), ".aqrl")
+
+#define arch_cmpxchg128_local(ptr, o, n)					\
+	__arch_cmpxchg128((ptr), (o), (n), "")
+
+#endif /* CONFIG_64BIT && CONFIG_RISCV_ISA_ZACAS */
+
 #ifdef CONFIG_RISCV_ISA_ZAWRS
 /*
  * Despite wrs.nto being "WRS-with-no-timeout", in the absence of changes to
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:48 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:48 +0100
Subject: [PATCH v6 08/13] riscv: Implement xchg8/16() using Zabha
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-9-alexghiti@rivosinc.com>

This adds runtime support for Zabha in xchg8/16() operations.

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/include/asm/cmpxchg.h | 65 ++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 24 deletions(-)

diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index f95929f538b2..4cadc56220fe 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -14,29 +14,41 @@
 #include <asm/insn-def.h>
 #include <asm/cpufeature-macros.h>
 
-#define __arch_xchg_masked(sc_sfx, prepend, append, r, p, n)		\
-({									\
-	u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3);			\
-	ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE;	\
-	ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0)	\
-			<< __s;						\
-	ulong __newx = (ulong)(n) << __s;				\
-	ulong __retx;							\
-	ulong __rc;							\
-									\
-	__asm__ __volatile__ (						\
-	       prepend							\
-	       "0:	lr.w %0, %2\n"					\
-	       "	and  %1, %0, %z4\n"				\
-	       "	or   %1, %1, %z3\n"				\
-	       "	sc.w" sc_sfx " %1, %1, %2\n"			\
-	       "	bnez %1, 0b\n"					\
-	       append							\
-	       : "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b))	\
-	       : "rJ" (__newx), "rJ" (~__mask)				\
-	       : "memory");						\
-									\
-	r = (__typeof__(*(p)))((__retx & __mask) >> __s);		\
+#define __arch_xchg_masked(sc_sfx, swap_sfx, prepend, sc_append,		\
+			   swap_append, r, p, n)				\
+({										\
+	if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) &&				\
+	    riscv_has_extension_unlikely(RISCV_ISA_EXT_ZABHA)) {		\
+		__asm__ __volatile__ (						\
+			prepend							\
+			"	amoswap" swap_sfx " %0, %z2, %1\n"		\
+			swap_append						\
+			: "=&r" (r), "+A" (*(p))				\
+			: "rJ" (n)						\
+			: "memory");						\
+	} else {								\
+		u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3);			\
+		ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE;	\
+		ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0)	\
+				<< __s;						\
+		ulong __newx = (ulong)(n) << __s;				\
+		ulong __retx;							\
+		ulong __rc;							\
+										\
+		__asm__ __volatile__ (						\
+		       prepend							\
+		       "0:	lr.w %0, %2\n"					\
+		       "	and  %1, %0, %z4\n"				\
+		       "	or   %1, %1, %z3\n"				\
+		       "	sc.w" sc_sfx " %1, %1, %2\n"			\
+		       "	bnez %1, 0b\n"					\
+		       sc_append						\
+		       : "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b))	\
+		       : "rJ" (__newx), "rJ" (~__mask)				\
+		       : "memory");						\
+										\
+		r = (__typeof__(*(p)))((__retx & __mask) >> __s);		\
+	}									\
 })
 
 #define __arch_xchg(sfx, prepend, append, r, p, n)			\
@@ -59,8 +71,13 @@
 									\
 	switch (sizeof(*__ptr)) {					\
 	case 1:								\
+		__arch_xchg_masked(sc_sfx, ".b" swap_sfx,		\
+				   prepend, sc_append, swap_append,	\
+				   __ret, __ptr, __new);		\
+		break;							\
 	case 2:								\
-		__arch_xchg_masked(sc_sfx, prepend, sc_append,		\
+		__arch_xchg_masked(sc_sfx, ".h" swap_sfx,		\
+				   prepend, sc_append, swap_append,	\
 				   __ret, __ptr, __new);		\
 		break;							\
 	case 4:								\
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:49 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:49 +0100
Subject: [PATCH v6 09/13] asm-generic: ticket-lock: Reuse arch_spinlock_t of qspinlock
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-10-alexghiti@rivosinc.com>

From: Guo Ren <guoren at linux.alibaba.com>

The arch_spinlock_t of qspinlock has contained the atomic_t val, which
satisfies the ticket-lock requirement. Thus, unify the arch_spinlock_t
into qspinlock_types.h. This is the preparation for the next combo
spinlock.

Reviewed-by: Leonardo Bras <leobras at redhat.com>
Suggested-by: Arnd Bergmann <arnd at arndb.de>
Link: https://lore.kernel.org/linux-riscv/CAK8P3a2rnz9mQqhN6-e0CGUUv9rntRELFdxt_weiD7FxH7fkfQ at mail.gmail.com/
Signed-off-by: Guo Ren <guoren at kernel.org>
Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Acked-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 include/asm-generic/spinlock.h       | 14 +++++++-------
 include/asm-generic/spinlock_types.h | 12 ++----------
 2 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/include/asm-generic/spinlock.h b/include/asm-generic/spinlock.h
index 90803a826ba0..4773334ee638 100644
--- a/include/asm-generic/spinlock.h
+++ b/include/asm-generic/spinlock.h
@@ -32,7 +32,7 @@
 
 static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
 {
-	u32 val = atomic_fetch_add(1<<16, lock);
+	u32 val = atomic_fetch_add(1<<16, &lock->val);
 	u16 ticket = val >> 16;
 
 	if (ticket == (u16)val)
@@ -46,31 +46,31 @@ static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
 	 * have no outstanding writes due to the atomic_fetch_add() the extra
 	 * orderings are free.
 	 */
-	atomic_cond_read_acquire(lock, ticket == (u16)VAL);
+	atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
 	smp_mb();
 }
 
 static __always_inline bool arch_spin_trylock(arch_spinlock_t *lock)
 {
-	u32 old = atomic_read(lock);
+	u32 old = atomic_read(&lock->val);
 
 	if ((old >> 16) != (old & 0xffff))
 		return false;
 
-	return atomic_try_cmpxchg(lock, &old, old + (1<<16)); /* SC, for RCsc */
+	return atomic_try_cmpxchg(&lock->val, &old, old + (1<<16)); /* SC, for RCsc */
 }
 
 static __always_inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	u16 *ptr = (u16 *)lock + IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
-	u32 val = atomic_read(lock);
+	u32 val = atomic_read(&lock->val);
 
 	smp_store_release(ptr, (u16)val + 1);
 }
 
 static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock)
 {
-	u32 val = lock.counter;
+	u32 val = lock.val.counter;
 
 	return ((val >> 16) == (val & 0xffff));
 }
@@ -84,7 +84,7 @@ static __always_inline int arch_spin_is_locked(arch_spinlock_t *lock)
 
 static __always_inline int arch_spin_is_contended(arch_spinlock_t *lock)
 {
-	u32 val = atomic_read(lock);
+	u32 val = atomic_read(&lock->val);
 
 	return (s16)((val >> 16) - (val & 0xffff)) > 1;
 }
diff --git a/include/asm-generic/spinlock_types.h b/include/asm-generic/spinlock_types.h
index 8962bb730945..f534aa5de394 100644
--- a/include/asm-generic/spinlock_types.h
+++ b/include/asm-generic/spinlock_types.h
@@ -3,15 +3,7 @@
 #ifndef __ASM_GENERIC_SPINLOCK_TYPES_H
 #define __ASM_GENERIC_SPINLOCK_TYPES_H
 
-#include <linux/types.h>
-typedef atomic_t arch_spinlock_t;
-
-/*
- * qrwlock_types depends on arch_spinlock_t, so we must typedef that before the
- * include.
- */
-#include <asm/qrwlock_types.h>
-
-#define __ARCH_SPIN_LOCK_UNLOCKED	ATOMIC_INIT(0)
+#include <asm-generic/qspinlock_types.h>
+#include <asm-generic/qrwlock_types.h>
 
 #endif /* __ASM_GENERIC_SPINLOCK_TYPES_H */
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:50 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:50 +0100
Subject: [PATCH v6 10/13] asm-generic: ticket-lock: Add separate ticket-lock.h
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-11-alexghiti@rivosinc.com>

From: Guo Ren <guoren at linux.alibaba.com>

Add a separate ticket-lock.h to include multiple spinlock versions and
select one at compile time or runtime.

Reviewed-by: Leonardo Bras <leobras at redhat.com>
Suggested-by: Arnd Bergmann <arnd at arndb.de>
Link: https://lore.kernel.org/linux-riscv/CAK8P3a2rnz9mQqhN6-e0CGUUv9rntRELFdxt_weiD7FxH7fkfQ at mail.gmail.com/
Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 include/asm-generic/spinlock.h        |  87 +---------------------
 include/asm-generic/ticket_spinlock.h | 103 ++++++++++++++++++++++++++
 2 files changed, 104 insertions(+), 86 deletions(-)
 create mode 100644 include/asm-generic/ticket_spinlock.h

diff --git a/include/asm-generic/spinlock.h b/include/asm-generic/spinlock.h
index 4773334ee638..970590baf61b 100644
--- a/include/asm-generic/spinlock.h
+++ b/include/asm-generic/spinlock.h
@@ -1,94 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
-/*
- * 'Generic' ticket-lock implementation.
- *
- * It relies on atomic_fetch_add() having well defined forward progress
- * guarantees under contention. If your architecture cannot provide this, stick
- * to a test-and-set lock.
- *
- * It also relies on atomic_fetch_add() being safe vs smp_store_release() on a
- * sub-word of the value. This is generally true for anything LL/SC although
- * you'd be hard pressed to find anything useful in architecture specifications
- * about this. If your architecture cannot do this you might be better off with
- * a test-and-set.
- *
- * It further assumes atomic_*_release() + atomic_*_acquire() is RCpc and hence
- * uses atomic_fetch_add() which is RCsc to create an RCsc hot path, along with
- * a full fence after the spin to upgrade the otherwise-RCpc
- * atomic_cond_read_acquire().
- *
- * The implementation uses smp_cond_load_acquire() to spin, so if the
- * architecture has WFE like instructions to sleep instead of poll for word
- * modifications be sure to implement that (see ARM64 for example).
- *
- */
-
 #ifndef __ASM_GENERIC_SPINLOCK_H
 #define __ASM_GENERIC_SPINLOCK_H
 
-#include <linux/atomic.h>
-#include <asm-generic/spinlock_types.h>
-
-static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
-{
-	u32 val = atomic_fetch_add(1<<16, &lock->val);
-	u16 ticket = val >> 16;
-
-	if (ticket == (u16)val)
-		return;
-
-	/*
-	 * atomic_cond_read_acquire() is RCpc, but rather than defining a
-	 * custom cond_read_rcsc() here we just emit a full fence.  We only
-	 * need the prior reads before subsequent writes ordering from
-	 * smb_mb(), but as atomic_cond_read_acquire() just emits reads and we
-	 * have no outstanding writes due to the atomic_fetch_add() the extra
-	 * orderings are free.
-	 */
-	atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
-	smp_mb();
-}
-
-static __always_inline bool arch_spin_trylock(arch_spinlock_t *lock)
-{
-	u32 old = atomic_read(&lock->val);
-
-	if ((old >> 16) != (old & 0xffff))
-		return false;
-
-	return atomic_try_cmpxchg(&lock->val, &old, old + (1<<16)); /* SC, for RCsc */
-}
-
-static __always_inline void arch_spin_unlock(arch_spinlock_t *lock)
-{
-	u16 *ptr = (u16 *)lock + IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
-	u32 val = atomic_read(&lock->val);
-
-	smp_store_release(ptr, (u16)val + 1);
-}
-
-static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock)
-{
-	u32 val = lock.val.counter;
-
-	return ((val >> 16) == (val & 0xffff));
-}
-
-static __always_inline int arch_spin_is_locked(arch_spinlock_t *lock)
-{
-	arch_spinlock_t val = READ_ONCE(*lock);
-
-	return !arch_spin_value_unlocked(val);
-}
-
-static __always_inline int arch_spin_is_contended(arch_spinlock_t *lock)
-{
-	u32 val = atomic_read(&lock->val);
-
-	return (s16)((val >> 16) - (val & 0xffff)) > 1;
-}
-
+#include <asm-generic/ticket_spinlock.h>
 #include <asm/qrwlock.h>
 
 #endif /* __ASM_GENERIC_SPINLOCK_H */
diff --git a/include/asm-generic/ticket_spinlock.h b/include/asm-generic/ticket_spinlock.h
new file mode 100644
index 000000000000..cfcff22b37b3
--- /dev/null
+++ b/include/asm-generic/ticket_spinlock.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * 'Generic' ticket-lock implementation.
+ *
+ * It relies on atomic_fetch_add() having well defined forward progress
+ * guarantees under contention. If your architecture cannot provide this, stick
+ * to a test-and-set lock.
+ *
+ * It also relies on atomic_fetch_add() being safe vs smp_store_release() on a
+ * sub-word of the value. This is generally true for anything LL/SC although
+ * you'd be hard pressed to find anything useful in architecture specifications
+ * about this. If your architecture cannot do this you might be better off with
+ * a test-and-set.
+ *
+ * It further assumes atomic_*_release() + atomic_*_acquire() is RCpc and hence
+ * uses atomic_fetch_add() which is RCsc to create an RCsc hot path, along with
+ * a full fence after the spin to upgrade the otherwise-RCpc
+ * atomic_cond_read_acquire().
+ *
+ * The implementation uses smp_cond_load_acquire() to spin, so if the
+ * architecture has WFE like instructions to sleep instead of poll for word
+ * modifications be sure to implement that (see ARM64 for example).
+ *
+ */
+
+#ifndef __ASM_GENERIC_TICKET_SPINLOCK_H
+#define __ASM_GENERIC_TICKET_SPINLOCK_H
+
+#include <linux/atomic.h>
+#include <asm-generic/spinlock_types.h>
+
+static __always_inline void ticket_spin_lock(arch_spinlock_t *lock)
+{
+	u32 val = atomic_fetch_add(1<<16, &lock->val);
+	u16 ticket = val >> 16;
+
+	if (ticket == (u16)val)
+		return;
+
+	/*
+	 * atomic_cond_read_acquire() is RCpc, but rather than defining a
+	 * custom cond_read_rcsc() here we just emit a full fence.  We only
+	 * need the prior reads before subsequent writes ordering from
+	 * smb_mb(), but as atomic_cond_read_acquire() just emits reads and we
+	 * have no outstanding writes due to the atomic_fetch_add() the extra
+	 * orderings are free.
+	 */
+	atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
+	smp_mb();
+}
+
+static __always_inline bool ticket_spin_trylock(arch_spinlock_t *lock)
+{
+	u32 old = atomic_read(&lock->val);
+
+	if ((old >> 16) != (old & 0xffff))
+		return false;
+
+	return atomic_try_cmpxchg(&lock->val, &old, old + (1<<16)); /* SC, for RCsc */
+}
+
+static __always_inline void ticket_spin_unlock(arch_spinlock_t *lock)
+{
+	u16 *ptr = (u16 *)lock + IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
+	u32 val = atomic_read(&lock->val);
+
+	smp_store_release(ptr, (u16)val + 1);
+}
+
+static __always_inline int ticket_spin_value_unlocked(arch_spinlock_t lock)
+{
+	u32 val = lock.val.counter;
+
+	return ((val >> 16) == (val & 0xffff));
+}
+
+static __always_inline int ticket_spin_is_locked(arch_spinlock_t *lock)
+{
+	arch_spinlock_t val = READ_ONCE(*lock);
+
+	return !ticket_spin_value_unlocked(val);
+}
+
+static __always_inline int ticket_spin_is_contended(arch_spinlock_t *lock)
+{
+	u32 val = atomic_read(&lock->val);
+
+	return (s16)((val >> 16) - (val & 0xffff)) > 1;
+}
+
+/*
+ * Remapping spinlock architecture specific functions to the corresponding
+ * ticket spinlock functions.
+ */
+#define arch_spin_is_locked(l)		ticket_spin_is_locked(l)
+#define arch_spin_is_contended(l)	ticket_spin_is_contended(l)
+#define arch_spin_value_unlocked(l)	ticket_spin_value_unlocked(l)
+#define arch_spin_lock(l)		ticket_spin_lock(l)
+#define arch_spin_trylock(l)		ticket_spin_trylock(l)
+#define arch_spin_unlock(l)		ticket_spin_unlock(l)
+
+#endif /* __ASM_GENERIC_TICKET_SPINLOCK_H */
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:51 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:51 +0100
Subject: [PATCH v6 11/13] riscv: Add ISA extension parsing for Ziccrse
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-12-alexghiti@rivosinc.com>

Add support to parse the Ziccrse string in the riscv,isa string.

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/include/asm/hwcap.h | 1 +
 arch/riscv/kernel/cpufeature.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index 74bcb0e2bd1f..0aa3c3f5e682 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -94,6 +94,7 @@
 #define RISCV_ISA_EXT_ZAWRS		85
 #define RISCV_ISA_EXT_SVVPTC		86
 #define RISCV_ISA_EXT_ZABHA		87
+#define RISCV_ISA_EXT_ZICCRSE		88
 
 #define RISCV_ISA_EXT_XLINUXENVCFG	127
 
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 5e743d8d34f5..5f453a039ec9 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -314,6 +314,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 					  riscv_ext_zicbom_validate),
 	__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts,
 					  riscv_ext_zicboz_validate),
+	__RISCV_ISA_EXT_DATA(ziccrse, RISCV_ISA_EXT_ZICCRSE),
 	__RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
 	__RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND),
 	__RISCV_ISA_EXT_DATA(zicsr, RISCV_ISA_EXT_ZICSR),
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:52 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:52 +0100
Subject: [PATCH v6 12/13] dt-bindings: riscv: Add Ziccrse ISA extension description
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-13-alexghiti@rivosinc.com>

Add description for the Ziccrse ISA extension which was ratified in
the riscv profiles specification v1.0.

Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Guo Ren <guoren at kernel.org>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
 Documentation/devicetree/bindings/riscv/extensions.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
index db062107823b..35a9ad1d7e63 100644
--- a/Documentation/devicetree/bindings/riscv/extensions.yaml
+++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
@@ -296,6 +296,12 @@ properties:
             in commit 64074bc ("Update version numbers for Zfh/Zfinx") of
             riscv-isa-manual.
 
+        - const: ziccrse
+          description:
+            The standard Ziccrse extension which provides forward progress
+            guarantee on LR/SC sequences, as ratified in commit b1d806605f87
+            ("Updated to ratified state.") of the riscv profiles specification.
+
         - const: zk
           description:
             The standard Zk Standard Scalar cryptography extension as ratified
-- 
2.39.2



From alexghiti at rivosinc.com  Sun Nov  3 06:51:53 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Sun,  3 Nov 2024 15:51:53 +0100
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <20241103145153.105097-14-alexghiti@rivosinc.com>

In order to produce a generic kernel, a user can select
CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
spinlock implementation if Zabha or Ziccrse are not present.

Note that we can't use alternatives here because the discovery of
extensions is done too late and we need to start with the qspinlock
implementation because the ticket spinlock implementation would pollute
the spinlock value, so let's use static keys.

This is largely based on Guo's work and Leonardo reviews at [1].

Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
Signed-off-by: Guo Ren <guoren at kernel.org>
Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
---
 .../locking/queued-spinlocks/arch-support.txt |  2 +-
 arch/riscv/Kconfig                            | 34 ++++++++++++++
 arch/riscv/include/asm/Kbuild                 |  4 +-
 arch/riscv/include/asm/spinlock.h             | 47 +++++++++++++++++++
 arch/riscv/kernel/setup.c                     | 37 +++++++++++++++
 include/asm-generic/qspinlock.h               |  2 +
 include/asm-generic/ticket_spinlock.h         |  2 +
 7 files changed, 126 insertions(+), 2 deletions(-)
 create mode 100644 arch/riscv/include/asm/spinlock.h

diff --git a/Documentation/features/locking/queued-spinlocks/arch-support.txt b/Documentation/features/locking/queued-spinlocks/arch-support.txt
index 22f2990392ff..cf26042480e2 100644
--- a/Documentation/features/locking/queued-spinlocks/arch-support.txt
+++ b/Documentation/features/locking/queued-spinlocks/arch-support.txt
@@ -20,7 +20,7 @@
     |    openrisc: |  ok  |
     |      parisc: | TODO |
     |     powerpc: |  ok  |
-    |       riscv: | TODO |
+    |       riscv: |  ok  |
     |        s390: | TODO |
     |          sh: | TODO |
     |       sparc: |  ok  |
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 093ee6537331..f5698ecc5ccc 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -82,6 +82,7 @@ config RISCV
 	select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
 	select ARCH_WANTS_NO_INSTR
 	select ARCH_WANTS_THP_SWAP if HAVE_ARCH_TRANSPARENT_HUGEPAGE
+	select ARCH_WEAK_RELEASE_ACQUIRE if ARCH_USE_QUEUED_SPINLOCKS
 	select BINFMT_FLAT_NO_DATA_START_OFFSET if !MMU
 	select BUILDTIME_TABLE_SORT if MMU
 	select CLINT_TIMER if RISCV_M_MODE
@@ -507,6 +508,39 @@ config NODES_SHIFT
 	  Specify the maximum number of NUMA Nodes available on the target
 	  system.  Increases memory reserved to accommodate various tables.
 
+choice
+	prompt "RISC-V spinlock type"
+	default RISCV_COMBO_SPINLOCKS
+
+config RISCV_TICKET_SPINLOCKS
+	bool "Using ticket spinlock"
+
+config RISCV_QUEUED_SPINLOCKS
+	bool "Using queued spinlock"
+	depends on SMP && MMU && NONPORTABLE
+	select ARCH_USE_QUEUED_SPINLOCKS
+	help
+	  The queued spinlock implementation requires the forward progress
+	  guarantee of cmpxchg()/xchg() atomic operations: CAS with Zabha or
+	  LR/SC with Ziccrse provide such guarantee.
+
+	  Select this if and only if Zabha or Ziccrse is available on your
+	  platform, RISCV_QUEUED_SPINLOCKS must not be selected for platforms
+	  without one of those extensions.
+
+	  If unsure, select RISCV_COMBO_SPINLOCKS, which will use qspinlocks
+	  when supported and otherwise ticket spinlocks.
+
+config RISCV_COMBO_SPINLOCKS
+	bool "Using combo spinlock"
+	depends on SMP && MMU
+	select ARCH_USE_QUEUED_SPINLOCKS
+	help
+	  Embed both queued spinlock and ticket lock so that the spinlock
+	  implementation can be chosen at runtime.
+
+endchoice
+
 config RISCV_ALTERNATIVE
 	bool
 	depends on !XIP_KERNEL
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 1461af12da6e..de13d5a234f8 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -6,10 +6,12 @@ generic-y += early_ioremap.h
 generic-y += flat.h
 generic-y += kvm_para.h
 generic-y += mmzone.h
+generic-y += mcs_spinlock.h
 generic-y += parport.h
-generic-y += spinlock.h
 generic-y += spinlock_types.h
+generic-y += ticket_spinlock.h
 generic-y += qrwlock.h
 generic-y += qrwlock_types.h
+generic-y += qspinlock.h
 generic-y += user.h
 generic-y += vmlinux.lds.h
diff --git a/arch/riscv/include/asm/spinlock.h b/arch/riscv/include/asm/spinlock.h
new file mode 100644
index 000000000000..e5121b89acea
--- /dev/null
+++ b/arch/riscv/include/asm/spinlock.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_RISCV_SPINLOCK_H
+#define __ASM_RISCV_SPINLOCK_H
+
+#ifdef CONFIG_RISCV_COMBO_SPINLOCKS
+#define _Q_PENDING_LOOPS	(1 << 9)
+
+#define __no_arch_spinlock_redefine
+#include <asm/ticket_spinlock.h>
+#include <asm/qspinlock.h>
+#include <asm/jump_label.h>
+
+/*
+ * TODO: Use an alternative instead of a static key when we are able to parse
+ * the extensions string earlier in the boot process.
+ */
+DECLARE_STATIC_KEY_TRUE(qspinlock_key);
+
+#define SPINLOCK_BASE_DECLARE(op, type, type_lock)			\
+static __always_inline type arch_spin_##op(type_lock lock)		\
+{									\
+	if (static_branch_unlikely(&qspinlock_key))			\
+		return queued_spin_##op(lock);				\
+	return ticket_spin_##op(lock);					\
+}
+
+SPINLOCK_BASE_DECLARE(lock, void, arch_spinlock_t *)
+SPINLOCK_BASE_DECLARE(unlock, void, arch_spinlock_t *)
+SPINLOCK_BASE_DECLARE(is_locked, int, arch_spinlock_t *)
+SPINLOCK_BASE_DECLARE(is_contended, int, arch_spinlock_t *)
+SPINLOCK_BASE_DECLARE(trylock, bool, arch_spinlock_t *)
+SPINLOCK_BASE_DECLARE(value_unlocked, int, arch_spinlock_t)
+
+#elif defined(CONFIG_RISCV_QUEUED_SPINLOCKS)
+
+#include <asm/qspinlock.h>
+
+#else
+
+#include <asm/ticket_spinlock.h>
+
+#endif
+
+#include <asm/qrwlock.h>
+
+#endif /* __ASM_RISCV_SPINLOCK_H */
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index a2cde65b69e9..438e4f6ad2ad 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -244,6 +244,42 @@ static void __init parse_dtb(void)
 #endif
 }
 
+#if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
+DEFINE_STATIC_KEY_TRUE(qspinlock_key);
+EXPORT_SYMBOL(qspinlock_key);
+#endif
+
+static void __init riscv_spinlock_init(void)
+{
+	char *using_ext = NULL;
+
+	if (IS_ENABLED(CONFIG_RISCV_TICKET_SPINLOCKS)) {
+		pr_info("Ticket spinlock: enabled\n");
+		return;
+	}
+
+	if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) &&
+	    IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) &&
+	    riscv_isa_extension_available(NULL, ZABHA) &&
+	    riscv_isa_extension_available(NULL, ZACAS)) {
+		using_ext = "using Zabha";
+	} else if (riscv_isa_extension_available(NULL, ZICCRSE)) {
+		using_ext = "using Ziccrse";
+	}
+#if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
+	else {
+		static_branch_disable(&qspinlock_key);
+		pr_info("Ticket spinlock: enabled\n");
+		return;
+	}
+#endif
+
+	if (!using_ext)
+		pr_err("Queued spinlock without Zabha or Ziccrse");
+	else
+		pr_info("Queued spinlock %s: enabled\n", using_ext);
+}
+
 extern void __init init_rt_signal_env(void);
 
 void __init setup_arch(char **cmdline_p)
@@ -297,6 +333,7 @@ void __init setup_arch(char **cmdline_p)
 	riscv_set_dma_cache_alignment();
 
 	riscv_user_isa_enable();
+	riscv_spinlock_init();
 }
 
 bool arch_cpu_is_hotpluggable(int cpu)
diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h
index 0655aa5b57b2..bf47cca2c375 100644
--- a/include/asm-generic/qspinlock.h
+++ b/include/asm-generic/qspinlock.h
@@ -136,6 +136,7 @@ static __always_inline bool virt_spin_lock(struct qspinlock *lock)
 }
 #endif
 
+#ifndef __no_arch_spinlock_redefine
 /*
  * Remapping spinlock architecture specific functions to the corresponding
  * queued spinlock functions.
@@ -146,5 +147,6 @@ static __always_inline bool virt_spin_lock(struct qspinlock *lock)
 #define arch_spin_lock(l)		queued_spin_lock(l)
 #define arch_spin_trylock(l)		queued_spin_trylock(l)
 #define arch_spin_unlock(l)		queued_spin_unlock(l)
+#endif
 
 #endif /* __ASM_GENERIC_QSPINLOCK_H */
diff --git a/include/asm-generic/ticket_spinlock.h b/include/asm-generic/ticket_spinlock.h
index cfcff22b37b3..325779970d8a 100644
--- a/include/asm-generic/ticket_spinlock.h
+++ b/include/asm-generic/ticket_spinlock.h
@@ -89,6 +89,7 @@ static __always_inline int ticket_spin_is_contended(arch_spinlock_t *lock)
 	return (s16)((val >> 16) - (val & 0xffff)) > 1;
 }
 
+#ifndef __no_arch_spinlock_redefine
 /*
  * Remapping spinlock architecture specific functions to the corresponding
  * ticket spinlock functions.
@@ -99,5 +100,6 @@ static __always_inline int ticket_spin_is_contended(arch_spinlock_t *lock)
 #define arch_spin_lock(l)		ticket_spin_lock(l)
 #define arch_spin_trylock(l)		ticket_spin_trylock(l)
 #define arch_spin_unlock(l)		ticket_spin_unlock(l)
+#endif
 
 #endif /* __ASM_GENERIC_TICKET_SPINLOCK_H */
-- 
2.39.2



From dfustini at tenstorrent.com  Sun Nov  3 08:57:58 2024
From: dfustini at tenstorrent.com (Drew Fustini)
Date: Sun, 03 Nov 2024 08:57:58 -0800
Subject: [PATCH net-next v7 0/2] Add the dwmac driver support for T-HEAD
 TH1520 SoC
Message-ID: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>

This series adds support for dwmac gigabit ethernet in the T-Head TH1520
RISC-V SoC used on boards like BeagleV Ahead and the LicheePi 4A.

The gigabit ethernet on these boards does need pinctrl support to mux
the necessary pads. The pinctrl-th1520 driver, pinctrl binding, and
related dts patches are in linux-next. However, they are not yet in
net-next/main.

Therefore, I am dropping the dts patch for v5 as it will not build on
net-next/main due to the lack of the padctrl0_apsys pin controller node
in next-next/main version th1520.dtsi. It does exist in linux-next [1]
and the two patches in this series allow the ethernet ports to work
correctly on the LPi4A and Ahead when applied to linux-next.

The dwmac-thead driver in this series does not need the pinctrl-th1520
driver to build. Nor does the thead,th1520-gmac.yaml binding need the
pinctrl binding to pass the schema check.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/riscv/boot/dts/thead/th1520.dtsi

Changes in v7:
 - Remove GMAC_RXCLK_DELAY_VAL(x), GMAC_RXCLK_DELAY_VAL(x) and
   GMAC_PLLCLK_DIV_NUM(x) marcos
 - Fix register write in thead_dwmac_fix_speed() by using FIELD_PREP()
   directly instead of the above macros
 - Fix thead_dwmac_init() to preserve bypass and invert bits when writing
   to GMAC_RXCLK_DELAY_CTRL and GMAC_TXCLK_DELAY_CTRL
 - Add sentinel to end of thead_dwmac_match[]
 - Normalize capitalization in dev_err_probe message
 - Link to v6: https://lore.kernel.org/r/20241030-th1520-gmac-v6-0-e48176d45116 at tenstorrent.com

Changes in v6:
 - Remove unnecessary semicolon from end of switch() blocks
 - Add Rb from Andrew Lunn on both patches
 - Link to v5: https://lore.kernel.org/r/20241025-th1520-gmac-v5-0-38d0a48406ff at tenstorrent.com

Changes in v5:
 - Rebase on net-next/main
 - Drop the dts patch from this series. It applies to linux-next but
   not net-next/main.
 - Remove repeated properties from required: in binding
 - Add Rb from Krzysztof for binding
 - Link to v4: https://lore.kernel.org/r/20241020-th1520-dwmac-v4-0-c77acd33ccef at tenstorrent.com

Changes in v4:
 - Rebase on next for pinctrl dependency
 - Add 'net-next' prefix to subject per maintainer-netdev.rst
 - Add clocks, clock-names, interrupts and interrupt-names to binding
 - Simplify driver code by switching from regmap to regualar mmio

Changes in v3:
 - Rebase on v6.12-rc1
 - Remove thead,rx-internal-delay and thead,tx-internal-delay properties
 - Remove unneeded call to thead_dwmac_fix_speed() during probe
 - Fix filename for the yaml file in MAINTAINERS patch
 - Link: https://lore.kernel.org/linux-riscv/20240930-th1520-dwmac-v3-0-ae3e03c225ab at tenstorrent.com/

Changes in v2:
 - Drop the first patch as it is no longer needed due to upstream commit
   d01e0e98de31 ("dt-bindings: net: dwmac: Validate PBL for all IP-cores")
 - Rename compatible from "thead,th1520-dwmac" to "thead,th1520-gmac"
 - Add thead,rx-internal-delay and thead,tx-internal-delay properties
   and check that it does not exceed the maximum value
 - Convert from stmmac_dvr_probe() to devm_stmmac_pltfr_probe() and
   delete the .remove_new hook as it is no longer needed
 - Handle return value of regmap_write() in case it fails
 - Add phy reset delay properties to the BeagleV Ahead device tree
 - Link: https://lore.kernel.org/linux-riscv/20240926-th1520-dwmac-v2-0-f34f28ad1dc9 at tenstorrent.com/

Changes in v1:
 - remove thead,gmacapb that references syscon for APB registers
 - add a second memory region to gmac nodes for the APB registers
 - Link: https://lore.kernel.org/all/20240713-thead-dwmac-v1-0-81f04480cd31 at tenstorrent.com/

---
Jisheng Zhang (2):
      dt-bindings: net: Add T-HEAD dwmac support
      net: stmmac: Add glue layer for T-HEAD TH1520 SoC

 .../devicetree/bindings/net/snps,dwmac.yaml        |   1 +
 .../devicetree/bindings/net/thead,th1520-gmac.yaml | 110 +++++++++
 MAINTAINERS                                        |   2 +
 drivers/net/ethernet/stmicro/stmmac/Kconfig        |  10 +
 drivers/net/ethernet/stmicro/stmmac/Makefile       |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c  | 273 +++++++++++++++++++++
 6 files changed, 397 insertions(+)
---
base-commit: 03fc07a24735e0be8646563913abf5f5cb71ad19
change-id: 20241025-th1520-gmac-78a76aa90c62

Best regards,
-- 
Drew Fustini <dfustini at tenstorrent.com>



From dfustini at tenstorrent.com  Sun Nov  3 08:57:59 2024
From: dfustini at tenstorrent.com (Drew Fustini)
Date: Sun, 03 Nov 2024 08:57:59 -0800
Subject: [PATCH net-next v7 1/2] dt-bindings: net: Add T-HEAD dwmac support
In-Reply-To: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>
References: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>
Message-ID: <20241103-th1520-gmac-v7-1-ef094a30169c@tenstorrent.com>

From: Jisheng Zhang <jszhang at kernel.org>

Add documentation to describe the DesginWare-based GMAC controllers in
the T-HEAD TH1520 SoC.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
Signed-off-by: Emil Renner Berthing <emil.renner.berthing at canonical.com>
[drew: rename compatible, add apb registers as second reg of gmac node,
       add clocks and interrupts poroperties]
Signed-off-by: Drew Fustini <dfustini at tenstorrent.com>
---
 .../devicetree/bindings/net/snps,dwmac.yaml        |   1 +
 .../devicetree/bindings/net/thead,th1520-gmac.yaml | 110 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 3 files changed, 112 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index 4e2ba1bf788c..474ade185033 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -99,6 +99,7 @@ properties:
         - snps,dwxgmac-2.10
         - starfive,jh7100-dwmac
         - starfive,jh7110-dwmac
+        - thead,th1520-gmac
 
   reg:
     minItems: 1
diff --git a/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml b/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
new file mode 100644
index 000000000000..6d9de3303762
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/thead,th1520-gmac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: T-HEAD TH1520 GMAC Ethernet controller
+
+maintainers:
+  - Drew Fustini <dfustini at tenstorrent.com>
+
+description: |
+  The TH1520 GMAC is described in the TH1520 Peripheral Interface User Manual
+  https://git.beagleboard.org/beaglev-ahead/beaglev-ahead/-/tree/main/docs
+
+  Features include
+    - Compliant with IEEE802.3 Specification
+    - IEEE 1588-2008 standard for precision networked clock synchronization
+    - Supports 10/100/1000Mbps data transfer rate
+    - Supports RGMII/MII interface
+    - Preamble and start of frame data (SFD) insertion in Transmit path
+    - Preamble and SFD deletion in the Receive path
+    - Automatic CRC and pad generation options for receive frames
+    - MDIO master interface for PHY device configuration and management
+
+  The GMAC Registers consists of two parts
+    - APB registers are used to configure clock frequency/clock enable/clock
+      direction/PHY interface type.
+    - AHB registers are use to configure GMAC core (DesignWare Core part).
+      GMAC core register consists of DMA registers and GMAC registers.
+
+select:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - thead,th1520-gmac
+  required:
+    - compatible
+
+allOf:
+  - $ref: snps,dwmac.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - thead,th1520-gmac
+      - const: snps,dwmac-3.70a
+
+  reg:
+    items:
+      - description: DesignWare GMAC IP core registers
+      - description: GMAC APB registers
+
+  reg-names:
+    items:
+      - const: dwmac
+      - const: apb
+
+  clocks:
+    items:
+      - description: GMAC main clock
+      - description: Peripheral registers interface clock
+
+  clock-names:
+    items:
+      - const: stmmaceth
+      - const: pclk
+
+  interrupts:
+    items:
+      - description: Combined signal for various interrupt events
+
+  interrupt-names:
+    items:
+      - const: macirq
+
+required:
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    gmac0: ethernet at e7070000 {
+        compatible = "thead,th1520-gmac", "snps,dwmac-3.70a";
+        reg = <0xe7070000 0x2000>, <0xec003000 0x1000>;
+        reg-names = "dwmac", "apb";
+        clocks = <&clk 1>, <&clk 2>;
+        clock-names = "stmmaceth", "pclk";
+        interrupts = <66>;
+        interrupt-names = "macirq";
+        phy-mode = "rgmii-id";
+        snps,fixed-burst;
+        snps,axi-config = <&stmmac_axi_setup>;
+        snps,pbl = <32>;
+        phy-handle = <&phy0>;
+
+        mdio {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            compatible = "snps,dwmac-mdio";
+
+            phy0: ethernet-phy at 0 {
+                reg = <0>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index f39ab140710f..72dee6d07ced 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19827,6 +19827,7 @@ L:	linux-riscv at lists.infradead.org
 S:	Maintained
 T:	git https://github.com/pdp7/linux.git
 F:	Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml
+F:	Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
 F:	arch/riscv/boot/dts/thead/
 F:	drivers/clk/thead/clk-th1520-ap.c
 F:	include/dt-bindings/clock/thead,th1520-clk-ap.h

-- 
2.34.1



From dfustini at tenstorrent.com  Sun Nov  3 08:58:00 2024
From: dfustini at tenstorrent.com (Drew Fustini)
Date: Sun, 03 Nov 2024 08:58:00 -0800
Subject: [PATCH net-next v7 2/2] net: stmmac: Add glue layer for T-HEAD
 TH1520 SoC
In-Reply-To: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>
References: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>
Message-ID: <20241103-th1520-gmac-v7-2-ef094a30169c@tenstorrent.com>

From: Jisheng Zhang <jszhang at kernel.org>

Add dwmac glue driver to support the DesignWare-based GMAC controllers
on the T-HEAD TH1520 SoC.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
[esmil: rename plat->interface -> plat->mac_interface,
        use devm_stmmac_probe_config_dt()]
Signed-off-by: Emil Renner Berthing <emil.renner.berthing at canonical.com>
[drew: convert from stmmac_dvr_probe() to devm_stmmac_pltfr_probe(),
       convert register access from regmap to regular mmio]
Signed-off-by: Drew Fustini <dfustini at tenstorrent.com>
---
 MAINTAINERS                                       |   1 +
 drivers/net/ethernet/stmicro/stmmac/Kconfig       |  10 +
 drivers/net/ethernet/stmicro/stmmac/Makefile      |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c | 273 ++++++++++++++++++++++
 4 files changed, 285 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 72dee6d07ced..b53f9f6b3e04 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19830,6 +19830,7 @@ F:	Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml
 F:	Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
 F:	arch/riscv/boot/dts/thead/
 F:	drivers/clk/thead/clk-th1520-ap.c
+F:	drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
 F:	include/dt-bindings/clock/thead,th1520-clk-ap.h
 
 RNBD BLOCK DRIVERS
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 05cc07b8f48c..6658536a4e17 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -228,6 +228,16 @@ config DWMAC_SUN8I
 	  stmmac device driver. This driver is used for H3/A83T/A64
 	  EMAC ethernet controller.
 
+config DWMAC_THEAD
+	tristate "T-HEAD dwmac support"
+	depends on OF && (ARCH_THEAD || COMPILE_TEST)
+	help
+	  Support for ethernet controllers on T-HEAD RISC-V SoCs
+
+	  This selects the T-HEAD platform specific glue layer support for
+	  the stmmac device driver. This driver is used for T-HEAD TH1520
+	  ethernet controller.
+
 config DWMAC_IMX8
 	tristate "NXP IMX8 DWMAC support"
 	default ARCH_MXC
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index c2f0e91f6bf8..d065634c6223 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_DWMAC_STI)		+= dwmac-sti.o
 obj-$(CONFIG_DWMAC_STM32)	+= dwmac-stm32.o
 obj-$(CONFIG_DWMAC_SUNXI)	+= dwmac-sunxi.o
 obj-$(CONFIG_DWMAC_SUN8I)	+= dwmac-sun8i.o
+obj-$(CONFIG_DWMAC_THEAD)	+= dwmac-thead.o
 obj-$(CONFIG_DWMAC_DWC_QOS_ETH)	+= dwmac-dwc-qos-eth.o
 obj-$(CONFIG_DWMAC_INTEL_PLAT)	+= dwmac-intel-plat.o
 obj-$(CONFIG_DWMAC_LOONGSON1)	+= dwmac-loongson1.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
new file mode 100644
index 000000000000..dce84ed184e9
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * T-HEAD DWMAC platform driver
+ *
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ * Copyright (C) 2023 Jisheng Zhang <jszhang at kernel.org>
+ *
+ */
+
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_net.h>
+#include <linux/platform_device.h>
+
+#include "stmmac_platform.h"
+
+#define GMAC_CLK_EN			0x00
+#define  GMAC_TX_CLK_EN			BIT(1)
+#define  GMAC_TX_CLK_N_EN		BIT(2)
+#define  GMAC_TX_CLK_OUT_EN		BIT(3)
+#define  GMAC_RX_CLK_EN			BIT(4)
+#define  GMAC_RX_CLK_N_EN		BIT(5)
+#define  GMAC_EPHY_REF_CLK_EN		BIT(6)
+#define GMAC_RXCLK_DELAY_CTRL		0x04
+#define  GMAC_RXCLK_BYPASS		BIT(15)
+#define  GMAC_RXCLK_INVERT		BIT(14)
+#define  GMAC_RXCLK_DELAY		GENMASK(4, 0)
+#define GMAC_TXCLK_DELAY_CTRL		0x08
+#define  GMAC_TXCLK_BYPASS		BIT(15)
+#define  GMAC_TXCLK_INVERT		BIT(14)
+#define  GMAC_TXCLK_DELAY		GENMASK(4, 0)
+#define GMAC_PLLCLK_DIV			0x0c
+#define  GMAC_PLLCLK_DIV_EN		BIT(31)
+#define  GMAC_PLLCLK_DIV_NUM		GENMASK(7, 0)
+#define GMAC_GTXCLK_SEL			0x18
+#define  GMAC_GTXCLK_SEL_PLL		BIT(0)
+#define GMAC_INTF_CTRL			0x1c
+#define  PHY_INTF_MASK			BIT(0)
+#define  PHY_INTF_RGMII			FIELD_PREP(PHY_INTF_MASK, 1)
+#define  PHY_INTF_MII_GMII		FIELD_PREP(PHY_INTF_MASK, 0)
+#define GMAC_TXCLK_OEN			0x20
+#define  TXCLK_DIR_MASK			BIT(0)
+#define  TXCLK_DIR_OUTPUT		FIELD_PREP(TXCLK_DIR_MASK, 0)
+#define  TXCLK_DIR_INPUT		FIELD_PREP(TXCLK_DIR_MASK, 1)
+
+#define GMAC_GMII_RGMII_RATE	125000000
+#define GMAC_MII_RATE		25000000
+
+struct thead_dwmac {
+	struct plat_stmmacenet_data *plat;
+	void __iomem *apb_base;
+	struct device *dev;
+};
+
+static int thead_dwmac_set_phy_if(struct plat_stmmacenet_data *plat)
+{
+	struct thead_dwmac *dwmac = plat->bsp_priv;
+	u32 phyif;
+
+	switch (plat->mac_interface) {
+	case PHY_INTERFACE_MODE_MII:
+		phyif = PHY_INTF_MII_GMII;
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		phyif = PHY_INTF_RGMII;
+		break;
+	default:
+		dev_err(dwmac->dev, "unsupported phy interface %d\n",
+			plat->mac_interface);
+		return -EINVAL;
+	}
+
+	writel(phyif, dwmac->apb_base + GMAC_INTF_CTRL);
+	return 0;
+}
+
+static int thead_dwmac_set_txclk_dir(struct plat_stmmacenet_data *plat)
+{
+	struct thead_dwmac *dwmac = plat->bsp_priv;
+	u32 txclk_dir;
+
+	switch (plat->mac_interface) {
+	case PHY_INTERFACE_MODE_MII:
+		txclk_dir = TXCLK_DIR_INPUT;
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		txclk_dir = TXCLK_DIR_OUTPUT;
+		break;
+	default:
+		dev_err(dwmac->dev, "unsupported phy interface %d\n",
+			plat->mac_interface);
+		return -EINVAL;
+	}
+
+	writel(txclk_dir, dwmac->apb_base + GMAC_TXCLK_OEN);
+	return 0;
+}
+
+static void thead_dwmac_fix_speed(void *priv, unsigned int speed, unsigned int mode)
+{
+	struct plat_stmmacenet_data *plat;
+	struct thead_dwmac *dwmac = priv;
+	unsigned long rate;
+	u32 div, reg;
+
+	plat = dwmac->plat;
+
+	switch (plat->mac_interface) {
+	/* For MII, rxc/txc is provided by phy */
+	case PHY_INTERFACE_MODE_MII:
+		return;
+
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		rate = clk_get_rate(plat->stmmac_clk);
+		if (!rate || rate % GMAC_GMII_RGMII_RATE != 0 ||
+		    rate % GMAC_MII_RATE != 0) {
+			dev_err(dwmac->dev, "invalid gmac rate %ld\n", rate);
+			return;
+		}
+
+		writel(0, dwmac->apb_base + GMAC_PLLCLK_DIV);
+
+		switch (speed) {
+		case SPEED_1000:
+			div = rate / GMAC_GMII_RGMII_RATE;
+			break;
+		case SPEED_100:
+			div = rate / GMAC_MII_RATE;
+			break;
+		case SPEED_10:
+			div = rate * 10 / GMAC_MII_RATE;
+			break;
+		default:
+			dev_err(dwmac->dev, "invalid speed %u\n", speed);
+			return;
+		}
+
+		reg = FIELD_PREP(GMAC_PLLCLK_DIV_EN, 1) |
+		      FIELD_PREP(GMAC_PLLCLK_DIV_NUM, div);
+		writel(reg, dwmac->apb_base + GMAC_PLLCLK_DIV);
+		break;
+	default:
+		dev_err(dwmac->dev, "unsupported phy interface %d\n",
+			plat->mac_interface);
+		return;
+	}
+}
+
+static int thead_dwmac_enable_clk(struct plat_stmmacenet_data *plat)
+{
+	struct thead_dwmac *dwmac = plat->bsp_priv;
+	u32 reg;
+
+	switch (plat->mac_interface) {
+	case PHY_INTERFACE_MODE_MII:
+		reg = GMAC_RX_CLK_EN | GMAC_TX_CLK_EN;
+		break;
+
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		/* use pll */
+		writel(GMAC_GTXCLK_SEL_PLL, dwmac->apb_base + GMAC_GTXCLK_SEL);
+		reg = GMAC_TX_CLK_EN | GMAC_TX_CLK_N_EN | GMAC_TX_CLK_OUT_EN |
+		      GMAC_RX_CLK_EN | GMAC_RX_CLK_N_EN;
+		break;
+
+	default:
+		dev_err(dwmac->dev, "unsupported phy interface %d\n",
+			plat->mac_interface);
+		return -EINVAL;
+	}
+
+	writel(reg, dwmac->apb_base + GMAC_CLK_EN);
+	return 0;
+}
+
+static int thead_dwmac_init(struct platform_device *pdev, void *priv)
+{
+	struct thead_dwmac *dwmac = priv;
+	unsigned int reg;
+	int ret;
+
+	ret = thead_dwmac_set_phy_if(dwmac->plat);
+	if (ret)
+		return ret;
+
+	ret = thead_dwmac_set_txclk_dir(dwmac->plat);
+	if (ret)
+		return ret;
+
+	reg = readl(dwmac->apb_base + GMAC_RXCLK_DELAY_CTRL);
+	reg &= ~(GMAC_RXCLK_DELAY);
+	reg |= FIELD_PREP(GMAC_RXCLK_DELAY, 0);
+	writel(reg, dwmac->apb_base + GMAC_RXCLK_DELAY_CTRL);
+
+	reg = readl(dwmac->apb_base + GMAC_TXCLK_DELAY_CTRL);
+	reg &= ~(GMAC_TXCLK_DELAY);
+	reg |= FIELD_PREP(GMAC_TXCLK_DELAY, 0);
+	writel(reg, dwmac->apb_base + GMAC_TXCLK_DELAY_CTRL);
+
+	return thead_dwmac_enable_clk(dwmac->plat);
+}
+
+static int thead_dwmac_probe(struct platform_device *pdev)
+{
+	struct stmmac_resources stmmac_res;
+	struct plat_stmmacenet_data *plat;
+	struct thead_dwmac *dwmac;
+	void __iomem *apb;
+	int ret;
+
+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to get resources\n");
+
+	plat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	if (IS_ERR(plat))
+		return dev_err_probe(&pdev->dev, PTR_ERR(plat),
+				     "dt configuration failed\n");
+
+	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
+	if (!dwmac)
+		return -ENOMEM;
+
+	apb = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(apb))
+		return dev_err_probe(&pdev->dev, PTR_ERR(apb),
+				     "failed to remap gmac apb registers\n");
+
+	dwmac->dev = &pdev->dev;
+	dwmac->plat = plat;
+	dwmac->apb_base = apb;
+	plat->bsp_priv = dwmac;
+	plat->fix_mac_speed = thead_dwmac_fix_speed;
+	plat->init = thead_dwmac_init;
+
+	return devm_stmmac_pltfr_probe(pdev, plat, &stmmac_res);
+}
+
+static const struct of_device_id thead_dwmac_match[] = {
+	{ .compatible = "thead,th1520-gmac" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, thead_dwmac_match);
+
+static struct platform_driver thead_dwmac_driver = {
+	.probe = thead_dwmac_probe,
+	.driver = {
+		.name = "thead-dwmac",
+		.pm = &stmmac_pltfr_pm_ops,
+		.of_match_table = thead_dwmac_match,
+	},
+};
+module_platform_driver(thead_dwmac_driver);
+
+MODULE_AUTHOR("Jisheng Zhang <jszhang at kernel.org>");
+MODULE_AUTHOR("Drew Fustini <drew at pdp7.com>");
+MODULE_DESCRIPTION("T-HEAD DWMAC platform driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1



From andrew at lunn.ch  Sun Nov  3 10:12:24 2024
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 3 Nov 2024 19:12:24 +0100
Subject: [PATCH net-next v7 0/2] Add the dwmac driver support for T-HEAD
 TH1520 SoC
In-Reply-To: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>
References: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>
Message-ID: <662a8258-291d-4cfc-b21a-f3c92f9588f2@lunn.ch>

On Sun, Nov 03, 2024 at 08:57:58AM -0800, Drew Fustini wrote:
> This series adds support for dwmac gigabit ethernet in the T-Head TH1520
> RISC-V SoC used on boards like BeagleV Ahead and the LicheePi 4A.
> 
> The gigabit ethernet on these boards does need pinctrl support to mux
> the necessary pads. The pinctrl-th1520 driver, pinctrl binding, and
> related dts patches are in linux-next. However, they are not yet in
> net-next/main.
> 
> Therefore, I am dropping the dts patch for v5 as it will not build on
> net-next/main due to the lack of the padctrl0_apsys pin controller node
> in next-next/main version th1520.dtsi.

You should send the .dts patch to the Maintainer responsible for
merging all the RISC-V DT patches, maybe via a sub Maintainer. All the
different parts will then meet up in linux-next.

	Andrew


From pdp7pdp7 at gmail.com  Sun Nov  3 14:09:37 2024
From: pdp7pdp7 at gmail.com (Drew Fustini)
Date: Sun, 3 Nov 2024 14:09:37 -0800
Subject: [PATCH net-next v7 0/2] Add the dwmac driver support for T-HEAD
 TH1520 SoC
In-Reply-To: <662a8258-291d-4cfc-b21a-f3c92f9588f2@lunn.ch>
References: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>
 <662a8258-291d-4cfc-b21a-f3c92f9588f2@lunn.ch>
Message-ID: <Zyf0oVGk6FiVrPsB@x1>

On Sun, Nov 03, 2024 at 07:12:24PM +0100, Andrew Lunn wrote:
> On Sun, Nov 03, 2024 at 08:57:58AM -0800, Drew Fustini wrote:
> > This series adds support for dwmac gigabit ethernet in the T-Head TH1520
> > RISC-V SoC used on boards like BeagleV Ahead and the LicheePi 4A.
> > 
> > The gigabit ethernet on these boards does need pinctrl support to mux
> > the necessary pads. The pinctrl-th1520 driver, pinctrl binding, and
> > related dts patches are in linux-next. However, they are not yet in
> > net-next/main.
> > 
> > Therefore, I am dropping the dts patch for v5 as it will not build on
> > net-next/main due to the lack of the padctrl0_apsys pin controller node
> > in next-next/main version th1520.dtsi.
> 
> You should send the .dts patch to the Maintainer responsible for
> merging all the RISC-V DT patches, maybe via a sub Maintainer. All the
> different parts will then meet up in linux-next.
> 
> 	Andrew

I am the maintainer for arch/riscv/boot/dts/thead. I'm planning to apply
the dts patch to my for-next branch once this series with the binding
and driver are applied to net-next.

Thanks,
Drew


From ebiggers at kernel.org  Sun Nov  3 14:31:38 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:38 -0800
Subject: [PATCH v3 02/18] lib/crc32: improve support for arch-specific overrides
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-3-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Currently the CRC32 library functions are defined as weak symbols, and
the arm64 and riscv architectures override them.

This method of arch-specific overrides has the limitation that it only
works when both the base and arch code is built-in.  Also, it makes the
arch-specific code be silently not used if it is accidentally built with
lib-y instead of obj-y; unfortunately the RISC-V code does this.

This commit reorganizes the code to have explicit *_arch() functions
that are called when they are enabled, similar to how some of the crypto
library code works (e.g. chacha_crypt() calls chacha_crypt_arch()).

Make the existing kconfig choice for the CRC32 implementation also
control whether the arch-optimized implementation (if one is available)
is enabled or not.  Make it enabled by default if CRC32 is also enabled.

The result is that arch-optimized CRC32 library functions will be
included automatically when appropriate, but it is now possible to
disable them.  They can also now be built as a loadable module if the
CRC32 library functions happen to be used only by loadable modules, in
which case the arch and base CRC32 modules will be automatically loaded
via direct symbol dependency when appropriate.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm64/Kconfig                        |  1 +
 arch/arm64/lib/Makefile                   |  3 +-
 arch/arm64/lib/crc32-glue.c               | 13 ++++-
 arch/riscv/Kconfig                        |  1 +
 arch/riscv/lib/Makefile                   |  3 +-
 arch/riscv/lib/{crc32.c => crc32-riscv.c} | 13 ++++-
 crypto/crc32_generic.c                    |  4 +-
 crypto/crc32c_generic.c                   |  4 +-
 include/linux/crc32.h                     | 35 +++++++++---
 lib/Kconfig                               | 70 +++++++++++++++++------
 lib/crc32.c                               | 22 +++----
 11 files changed, 118 insertions(+), 51 deletions(-)
 rename arch/riscv/lib/{crc32.c => crc32-riscv.c} (94%)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index fd9df6dcc593..1e48f40f654e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -19,10 +19,11 @@ config ARM64
 	select ARCH_ENABLE_MEMORY_HOTPLUG
 	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
 	select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
 	select ARCH_HAS_CACHE_LINE_SIZE
+	select ARCH_HAS_CRC32
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DMA_OPS if XEN
 	select ARCH_HAS_DMA_PREP_COHERENT
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 8e882f479d98..5fbcf0d56665 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -11,11 +11,12 @@ CFLAGS_xor-neon.o		+= $(CC_FLAGS_FPU)
 CFLAGS_REMOVE_xor-neon.o	+= $(CC_FLAGS_NO_FPU)
 endif
 
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
 
-obj-$(CONFIG_CRC32) += crc32.o crc32-glue.o
+obj-$(CONFIG_CRC32_ARCH) += crc32-arm64.o
+crc32-arm64-y := crc32.o crc32-glue.o
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 
 obj-$(CONFIG_ARM64_MTE) += mte.o
 
diff --git a/arch/arm64/lib/crc32-glue.c b/arch/arm64/lib/crc32-glue.c
index ad015223d15d..d7f6e1cbf0d2 100644
--- a/arch/arm64/lib/crc32-glue.c
+++ b/arch/arm64/lib/crc32-glue.c
@@ -1,9 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
 #include <linux/crc32.h>
 #include <linux/linkage.h>
+#include <linux/module.h>
 
 #include <asm/alternative.h>
 #include <asm/cpufeature.h>
 #include <asm/neon.h>
 #include <asm/simd.h>
@@ -19,11 +20,11 @@ asmlinkage u32 crc32_be_arm64(u32 crc, unsigned char const *p, size_t len);
 
 asmlinkage u32 crc32_le_arm64_4way(u32 crc, unsigned char const *p, size_t len);
 asmlinkage u32 crc32c_le_arm64_4way(u32 crc, unsigned char const *p, size_t len);
 asmlinkage u32 crc32_be_arm64_4way(u32 crc, unsigned char const *p, size_t len);
 
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le_arch(u32 crc, const u8 *p, size_t len)
 {
 	if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
 		return crc32_le_base(crc, p, len);
 
 	if (len >= min_len && cpu_have_named_feature(PMULL) && crypto_simd_usable()) {
@@ -38,12 +39,13 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 			return crc;
 	}
 
 	return crc32_le_arm64(crc, p, len);
 }
+EXPORT_SYMBOL(crc32_le_arch);
 
-u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32c_le_arch(u32 crc, const u8 *p, size_t len)
 {
 	if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
 		return crc32c_le_base(crc, p, len);
 
 	if (len >= min_len && cpu_have_named_feature(PMULL) && crypto_simd_usable()) {
@@ -58,12 +60,13 @@ u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 			return crc;
 	}
 
 	return crc32c_le_arm64(crc, p, len);
 }
+EXPORT_SYMBOL(crc32c_le_arch);
 
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
 {
 	if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
 		return crc32_be_base(crc, p, len);
 
 	if (len >= min_len && cpu_have_named_feature(PMULL) && crypto_simd_usable()) {
@@ -78,5 +81,9 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 			return crc;
 	}
 
 	return crc32_be_arm64(crc, p, len);
 }
+EXPORT_SYMBOL(crc32_be_arch);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("arm64-optimized CRC32 functions");
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index f4c570538d55..046f0cb119da 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -22,10 +22,11 @@ config RISCV
 	select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM_VMEMMAP
 	select ARCH_ENABLE_MEMORY_HOTREMOVE if MEMORY_HOTPLUG
 	select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
 	select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
 	select ARCH_HAS_BINFMT_FLAT
+	select ARCH_HAS_CRC32 if RISCV_ISA_ZBC
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL if MMU
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEBUG_WX
 	select ARCH_HAS_FAST_MULTIPLIER
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 8eec6b69a875..79368a895fee 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -13,10 +13,9 @@ ifeq ($(CONFIG_MMU), y)
 lib-$(CONFIG_RISCV_ISA_V)	+= uaccess_vector.o
 endif
 lib-$(CONFIG_MMU)	+= uaccess.o
 lib-$(CONFIG_64BIT)	+= tishift.o
 lib-$(CONFIG_RISCV_ISA_ZICBOZ)	+= clear_page.o
-lib-$(CONFIG_RISCV_ISA_ZBC)	+= crc32.o
-
+obj-$(CONFIG_CRC32_ARCH)	+= crc32-riscv.o
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 lib-$(CONFIG_RISCV_ISA_V)	+= xor.o
 lib-$(CONFIG_RISCV_ISA_V)	+= riscv_v_helpers.o
diff --git a/arch/riscv/lib/crc32.c b/arch/riscv/lib/crc32-riscv.c
similarity index 94%
rename from arch/riscv/lib/crc32.c
rename to arch/riscv/lib/crc32-riscv.c
index 333fb7af1192..a3ff7db2a1ce 100644
--- a/arch/riscv/lib/crc32.c
+++ b/arch/riscv/lib/crc32-riscv.c
@@ -12,10 +12,11 @@
 #include <linux/types.h>
 #include <linux/minmax.h>
 #include <linux/crc32poly.h>
 #include <linux/crc32.h>
 #include <linux/byteorder/generic.h>
+#include <linux/module.h>
 
 /*
  * Refer to https://www.corsix.org/content/barrett-reduction-polynomials for
  * better understanding of how this math works.
  *
@@ -215,21 +216,23 @@ static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p,
 
 legacy:
 	return crc_fb(crc, p, len);
 }
 
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le_arch(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, CRC32_POLY_LE, CRC32_POLY_QT_LE,
 				crc32_le_base);
 }
+EXPORT_SYMBOL(crc32_le_arch);
 
-u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32c_le_arch(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, CRC32C_POLY_LE,
 				CRC32C_POLY_QT_LE, crc32c_le_base);
 }
+EXPORT_SYMBOL(crc32c_le_arch);
 
 static inline u32 crc32_be_unaligned(u32 crc, unsigned char const *p,
 				     size_t len)
 {
 	size_t bits = len * 8;
@@ -251,11 +254,11 @@ static inline u32 crc32_be_unaligned(u32 crc, unsigned char const *p,
 	crc ^= crc_low;
 
 	return crc;
 }
 
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
 {
 	size_t offset, head_len, tail_len;
 	unsigned long const *p_ul;
 	unsigned long s;
 
@@ -290,5 +293,9 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 	return crc;
 
 legacy:
 	return crc32_be_base(crc, p, len);
 }
+EXPORT_SYMBOL(crc32_be_arch);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Accelerated CRC32 implementation with Zbc extension");
diff --git a/crypto/crc32_generic.c b/crypto/crc32_generic.c
index 6a55d206fab3..cc064ea8240e 100644
--- a/crypto/crc32_generic.c
+++ b/crypto/crc32_generic.c
@@ -158,16 +158,16 @@ static struct shash_alg algs[] = {{
 }};
 
 static int __init crc32_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + (&crc32_le != &crc32_le_base));
+	return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
 }
 
 static void __exit crc32_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + (&crc32_le != &crc32_le_base));
+	crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
 }
 
 subsys_initcall(crc32_mod_init);
 module_exit(crc32_mod_fini);
 
diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c
index 635599b255ec..04b03d825cf4 100644
--- a/crypto/crc32c_generic.c
+++ b/crypto/crc32c_generic.c
@@ -198,16 +198,16 @@ static struct shash_alg algs[] = {{
 }};
 
 static int __init crc32c_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + (&__crc32c_le != &crc32c_le_base));
+	return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
 }
 
 static void __exit crc32c_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + (&__crc32c_le != &crc32c_le_base));
+	crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
 }
 
 subsys_initcall(crc32c_mod_init);
 module_exit(crc32c_mod_fini);
 
diff --git a/include/linux/crc32.h b/include/linux/crc32.h
index 5b07fc9081c4..58c632533b08 100644
--- a/include/linux/crc32.h
+++ b/include/linux/crc32.h
@@ -6,14 +6,38 @@
 #define _LINUX_CRC32_H
 
 #include <linux/types.h>
 #include <linux/bitrev.h>
 
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len);
-u32 __pure crc32_le_base(u32 crc, unsigned char const *p, size_t len);
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len);
-u32 __pure crc32_be_base(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32_le_arch(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32_le_base(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32_be_base(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32c_le_arch(u32 crc, const u8 *p, size_t len);
+u32 __pure crc32c_le_base(u32 crc, const u8 *p, size_t len);
+
+static inline u32 __pure crc32_le(u32 crc, const u8 *p, size_t len)
+{
+	if (IS_ENABLED(CONFIG_CRC32_ARCH))
+		return crc32_le_arch(crc, p, len);
+	return crc32_le_base(crc, p, len);
+}
+
+static inline u32 __pure crc32_be(u32 crc, const u8 *p, size_t len)
+{
+	if (IS_ENABLED(CONFIG_CRC32_ARCH))
+		return crc32_be_arch(crc, p, len);
+	return crc32_be_base(crc, p, len);
+}
+
+/* TODO: leading underscores should be dropped once callers have been updated */
+static inline u32 __pure __crc32c_le(u32 crc, const u8 *p, size_t len)
+{
+	if (IS_ENABLED(CONFIG_CRC32_ARCH))
+		return crc32c_le_arch(crc, p, len);
+	return crc32c_le_base(crc, p, len);
+}
 
 /**
  * crc32_le_combine - Combine two crc32 check values into one. For two
  * 		      sequences of bytes, seq1 and seq2 with lengths len1
  * 		      and len2, crc32_le() check values were calculated
@@ -36,13 +60,10 @@ u32 __attribute_const__ crc32_le_shift(u32 crc, size_t len);
 static inline u32 crc32_le_combine(u32 crc1, u32 crc2, size_t len2)
 {
 	return crc32_le_shift(crc1, len2) ^ crc2;
 }
 
-u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len);
-u32 __pure crc32c_le_base(u32 crc, unsigned char const *p, size_t len);
-
 /**
  * __crc32c_le_combine - Combine two crc32c check values into one. For two
  * 			 sequences of bytes, seq1 and seq2 with lengths len1
  * 			 and len2, __crc32c_le() check values were calculated
  * 			 for each, crc1 and crc2.
diff --git a/lib/Kconfig b/lib/Kconfig
index b38849af6f13..07afcf214f35 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -176,10 +176,13 @@ config CRC32
 	  This option is provided for the case where no in-kernel-tree
 	  modules require CRC32/CRC32c functions, but a module built outside
 	  the kernel tree does. Such modules that use library CRC32/CRC32c
 	  functions require M here.
 
+config ARCH_HAS_CRC32
+	bool
+
 config CRC32_SELFTEST
 	tristate "CRC32 perform self test on init"
 	depends on CRC32
 	help
 	  This option enables the CRC32 library functions to perform a
@@ -188,54 +191,89 @@ config CRC32_SELFTEST
 	  and computes the total elapsed time and number of bytes processed.
 
 choice
 	prompt "CRC32 implementation"
 	depends on CRC32
-	default CRC32_SLICEBY8
+	default CRC32_IMPL_ARCH_PLUS_SLICEBY8 if ARCH_HAS_CRC32
+	default CRC32_IMPL_SLICEBY8 if !ARCH_HAS_CRC32
 	help
-	  This option allows a kernel builder to override the default choice
-	  of CRC32 algorithm.  Choose the default ("slice by 8") unless you
-	  know that you need one of the others.
+	  This option allows you to override the default choice of CRC32
+	  implementation.  Choose the default unless you know that you need one
+	  of the others.
 
-config CRC32_SLICEBY8
+config CRC32_IMPL_ARCH_PLUS_SLICEBY8
+	bool "Arch-optimized, with fallback to slice-by-8" if ARCH_HAS_CRC32
+	help
+	  Use architecture-optimized implementation of CRC32.  Fall back to
+	  slice-by-8 in cases where the arch-optimized implementation cannot be
+	  used, e.g. if the CPU lacks support for the needed instructions.
+
+	  This is the default when an arch-optimized implementation exists.
+
+config CRC32_IMPL_ARCH_PLUS_SLICEBY1
+	bool "Arch-optimized, with fallback to slice-by-1" if ARCH_HAS_CRC32
+	help
+	  Use architecture-optimized implementation of CRC32, but fall back to
+	  slice-by-1 instead of slice-by-8 in order to reduce the binary size.
+
+config CRC32_IMPL_SLICEBY8
 	bool "Slice by 8 bytes"
 	help
 	  Calculate checksum 8 bytes at a time with a clever slicing algorithm.
-	  This is the fastest algorithm, but comes with a 8KiB lookup table.
-	  Most modern processors have enough cache to hold this table without
-	  thrashing the cache.
-
-	  This is the default implementation choice.  Choose this one unless
-	  you have a good reason not to.
+	  This is much slower than the architecture-optimized implementation of
+	  CRC32 (if the selected arch has one), but it is portable and is the
+	  fastest implementation when no arch-optimized implementation is
+	  available.  It uses an 8KiB lookup table.  Most modern processors have
+	  enough cache to hold this table without thrashing the cache.
 
-config CRC32_SLICEBY4
+config CRC32_IMPL_SLICEBY4
 	bool "Slice by 4 bytes"
 	help
 	  Calculate checksum 4 bytes at a time with a clever slicing algorithm.
 	  This is a bit slower than slice by 8, but has a smaller 4KiB lookup
 	  table.
 
 	  Only choose this option if you know what you are doing.
 
-config CRC32_SARWATE
-	bool "Sarwate's Algorithm (one byte at a time)"
+config CRC32_IMPL_SLICEBY1
+	bool "Slice by 1 byte (Sarwate's algorithm)"
 	help
 	  Calculate checksum a byte at a time using Sarwate's algorithm.  This
-	  is not particularly fast, but has a small 256 byte lookup table.
+	  is not particularly fast, but has a small 1KiB lookup table.
 
 	  Only choose this option if you know what you are doing.
 
-config CRC32_BIT
+config CRC32_IMPL_BIT
 	bool "Classic Algorithm (one bit at a time)"
 	help
 	  Calculate checksum one bit at a time.  This is VERY slow, but has
 	  no lookup table.  This is provided as a debugging option.
 
 	  Only choose this option if you are debugging crc32.
 
 endchoice
 
+config CRC32_ARCH
+	tristate
+	default CRC32 if CRC32_IMPL_ARCH_PLUS_SLICEBY8 || CRC32_IMPL_ARCH_PLUS_SLICEBY1
+
+config CRC32_SLICEBY8
+	bool
+	default y if CRC32_IMPL_SLICEBY8 || CRC32_IMPL_ARCH_PLUS_SLICEBY8
+
+config CRC32_SLICEBY4
+	bool
+	default y if CRC32_IMPL_SLICEBY4
+
+config CRC32_SARWATE
+	bool
+	default y if CRC32_IMPL_SLICEBY1 || CRC32_IMPL_ARCH_PLUS_SLICEBY1
+
+config CRC32_BIT
+	bool
+	default y if CRC32_IMPL_BIT
+
 config CRC64
 	tristate "CRC64 functions"
 	help
 	  This option is provided for the case where no in-kernel-tree
 	  modules require CRC64 functions, but a module built outside
diff --git a/lib/crc32.c b/lib/crc32.c
index c67059b0082b..47151624332e 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -181,39 +181,31 @@ static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p,
 #endif
 	return crc;
 }
 
 #if CRC_LE_BITS == 1
-u32 __pure __weak crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, NULL, CRC32_POLY_LE);
 }
-u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32c_le_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, NULL, CRC32C_POLY_LE);
 }
 #else
-u32 __pure __weak crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, crc32table_le, CRC32_POLY_LE);
 }
-u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32c_le_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE);
 }
 #endif
-EXPORT_SYMBOL(crc32_le);
-EXPORT_SYMBOL(__crc32c_le);
-
-u32 __pure crc32_le_base(u32, unsigned char const *, size_t) __alias(crc32_le);
 EXPORT_SYMBOL(crc32_le_base);
-
-u32 __pure crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le);
 EXPORT_SYMBOL(crc32c_le_base);
 
-u32 __pure crc32_be_base(u32, unsigned char const *, size_t) __alias(crc32_be);
-
 /*
  * This multiplies the polynomials x and y modulo the given modulus.
  * This follows the "little-endian" CRC convention that the lsbit
  * represents the highest power of x, and the msbit represents x^0.
  */
@@ -333,16 +325,16 @@ static inline u32 __pure crc32_be_generic(u32 crc, unsigned char const *p,
 # endif
 	return crc;
 }
 
 #if CRC_BE_BITS == 1
-u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, NULL, CRC32_POLY_BE);
 }
 #else
-u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be_base(u32 crc, const u8 *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, crc32table_be, CRC32_POLY_BE);
 }
 #endif
-EXPORT_SYMBOL(crc32_be);
+EXPORT_SYMBOL(crc32_be_base);
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:40 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:40 -0800
Subject: [PATCH v3 04/18] crypto: crc32 - don't unnecessarily register arch algorithms
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-5-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Instead of registering the crc32-$arch and crc32c-$arch algorithms if
the arch-specific code was built, only register them when that code was
built *and* is not falling back to the base implementation at runtime.

This avoids confusing users like btrfs which checks the shash driver
name to determine whether it is crc32c-generic.

(It would also make sense to change btrfs to test the crc32_optimization
flags itself, so that it doesn't have to use the weird hack of parsing
the driver name.  This change still makes sense either way though.)

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 crypto/crc32_generic.c  | 8 ++++++--
 crypto/crc32c_generic.c | 8 ++++++--
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/crypto/crc32_generic.c b/crypto/crc32_generic.c
index cc064ea8240e..783a30b27398 100644
--- a/crypto/crc32_generic.c
+++ b/crypto/crc32_generic.c
@@ -155,19 +155,23 @@ static struct shash_alg algs[] = {{
 	.base.cra_ctxsize	= sizeof(u32),
 	.base.cra_module	= THIS_MODULE,
 	.base.cra_init		= crc32_cra_init,
 }};
 
+static int num_algs;
+
 static int __init crc32_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
+	num_algs = 1 + ((crc32_optimizations() & CRC32_LE_OPTIMIZATION) != 0);
+
+	return crypto_register_shashes(algs, num_algs);
 }
 
 static void __exit crc32_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
+	crypto_unregister_shashes(algs, num_algs);
 }
 
 subsys_initcall(crc32_mod_init);
 module_exit(crc32_mod_fini);
 
diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c
index 04b03d825cf4..985da981d6e2 100644
--- a/crypto/crc32c_generic.c
+++ b/crypto/crc32c_generic.c
@@ -195,19 +195,23 @@ static struct shash_alg algs[] = {{
 	.base.cra_ctxsize	= sizeof(struct chksum_ctx),
 	.base.cra_module	= THIS_MODULE,
 	.base.cra_init		= crc32c_cra_init,
 }};
 
+static int num_algs;
+
 static int __init crc32c_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
+	num_algs = 1 + ((crc32_optimizations() & CRC32C_OPTIMIZATION) != 0);
+
+	return crypto_register_shashes(algs, num_algs);
 }
 
 static void __exit crc32c_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
+	crypto_unregister_shashes(algs, num_algs);
 }
 
 subsys_initcall(crc32c_mod_init);
 module_exit(crc32c_mod_fini);
 
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:39 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:39 -0800
Subject: [PATCH v3 03/18] lib/crc32: expose whether the lib is really optimized at runtime
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-4-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Make the CRC32 library export a function crc32_optimizations() which
returns flags that indicate which CRC32 functions are actually executing
optimized code at runtime.

This will be used to determine whether the crc32[c]-$arch shash
algorithms should be registered in the crypto API.  btrfs could also
start using these flags instead of the hack that it currently uses where
it parses the crypto_shash_driver_name.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm64/lib/crc32-glue.c  | 10 ++++++++++
 arch/riscv/lib/crc32-riscv.c | 10 ++++++++++
 include/linux/crc32.h        | 15 +++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/arch/arm64/lib/crc32-glue.c b/arch/arm64/lib/crc32-glue.c
index d7f6e1cbf0d2..15c4c9db573e 100644
--- a/arch/arm64/lib/crc32-glue.c
+++ b/arch/arm64/lib/crc32-glue.c
@@ -83,7 +83,17 @@ u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
 
 	return crc32_be_arm64(crc, p, len);
 }
 EXPORT_SYMBOL(crc32_be_arch);
 
+u32 crc32_optimizations(void)
+{
+	if (alternative_has_cap_likely(ARM64_HAS_CRC32))
+		return CRC32_LE_OPTIMIZATION |
+		       CRC32_BE_OPTIMIZATION |
+		       CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("arm64-optimized CRC32 functions");
diff --git a/arch/riscv/lib/crc32-riscv.c b/arch/riscv/lib/crc32-riscv.c
index a3ff7db2a1ce..53d56ab422c7 100644
--- a/arch/riscv/lib/crc32-riscv.c
+++ b/arch/riscv/lib/crc32-riscv.c
@@ -295,7 +295,17 @@ u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
 legacy:
 	return crc32_be_base(crc, p, len);
 }
 EXPORT_SYMBOL(crc32_be_arch);
 
+u32 crc32_optimizations(void)
+{
+	if (riscv_has_extension_likely(RISCV_ISA_EXT_ZBC))
+		return CRC32_LE_OPTIMIZATION |
+		       CRC32_BE_OPTIMIZATION |
+		       CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Accelerated CRC32 implementation with Zbc extension");
diff --git a/include/linux/crc32.h b/include/linux/crc32.h
index 58c632533b08..e9bd40056687 100644
--- a/include/linux/crc32.h
+++ b/include/linux/crc32.h
@@ -35,10 +35,25 @@ static inline u32 __pure __crc32c_le(u32 crc, const u8 *p, size_t len)
 	if (IS_ENABLED(CONFIG_CRC32_ARCH))
 		return crc32c_le_arch(crc, p, len);
 	return crc32c_le_base(crc, p, len);
 }
 
+/*
+ * crc32_optimizations() returns flags that indicate which CRC32 library
+ * functions are using architecture-specific optimizations.  Unlike
+ * IS_ENABLED(CONFIG_CRC32_ARCH) it takes into account the different CRC32
+ * variants and also whether any needed CPU features are available at runtime.
+ */
+#define CRC32_LE_OPTIMIZATION	BIT(0) /* crc32_le() is optimized */
+#define CRC32_BE_OPTIMIZATION	BIT(1) /* crc32_be() is optimized */
+#define CRC32C_OPTIMIZATION	BIT(2) /* __crc32c_le() is optimized */
+#if IS_ENABLED(CONFIG_CRC32_ARCH)
+u32 crc32_optimizations(void);
+#else
+static inline u32 crc32_optimizations(void) { return 0; }
+#endif
+
 /**
  * crc32_le_combine - Combine two crc32 check values into one. For two
  * 		      sequences of bytes, seq1 and seq2 with lengths len1
  * 		      and len2, crc32_le() check values were calculated
  * 		      for each, crc1 and crc2.
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:36 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:36 -0800
Subject: [PATCH v3 00/18] Wire up CRC32 library functions to arch-optimized code
Message-ID: <20241103223154.136127-1-ebiggers@kernel.org>

This patchset is also available in git via:

    git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git crc32-lib-v3

CRC32 is a family of common non-cryptographic integrity check algorithms
that are fairly fast with a portable C implementation and become far
faster still with the CRC32 or carryless multiplication instructions
that most CPUs have.  9 architectures already have optimized code for at
least some CRC32 variants; however, except for arm64 this optimized code
was only accessible through the crypto API, not the library functions.

This patchset fixes that so that the CRC32 library functions use the
optimized code.  This allows users to just use the library instead of
the crypto API.  This is much simpler and also improves performance due
to eliminating the crypto API overhead including an indirect call.  Some
examples of updating users are included at the end of the patchset.

Note: crc32c() was a weird case.  It was a library function layered on
top of the crypto API, which in turn is layered on top of the real
library functions.  So while it was easy to use, it was still subject to
the crypto API overhead.  This patchset provides CRC32C acceleration in
the real library functions directly.

The updated CRC32 library design is:

- Each arch's CRC32 code (all variants) is in arch/$ARCH/lib/crc32*.
  This adopts what arm64 and riscv already did.  Note, the crypto
  directory is not used because CRC32 is not a cryptographic algorithm.

- Weak symbols are no longer used.  Instead there are crc32*_base() and
  crc32*_arch(), and the appropriate ones are called based on the
  kconfig.  This is similar to how the ChaCha20 library code works.

- Each arch's CRC32 library code is enabled by default when CRC32 is
  enabled, but it can now be disabled, controlled by the choice that
  previously controlled the base implementation only.  It can also now
  be built as a module if CRC32 is a module too, in which case it will
  be automatically loaded via direct symbol dependency when appropriate.

- Instead of lots of pointless glue code that wires up each CRC32
  variant to the crypto API for each architecture, we now just rely on
  the existing shash algorithms that use the library functions.

- As before, the library functions don't provide access to off-CPU
  crypto accelerators.  But these appear to have very little, if any,
  real-world relevance for CRC32 which is very fast on CPUs.

Future work should apply a similar cleanup to crct10dif which is a
variant of CRC16.

I tested all arches in QEMU using CONFIG_CRC32_SELFTEST and the crypto
self-tests, except for mips which I couldn't figure out how to do.

This patchset has the following dependencies on recent patches which
have been applied to the appropriate trees and are in linux-next:

- "crypto - move crypto_simd_disabled_for_test to lib"
  (https://lore.kernel.org/linux-crypto/20241018235343.425758-1-ebiggers at kernel.org/)
- "crypto: x86/crc32c - jump table elimination and other cleanups"
  (https://lore.kernel.org/linux-crypto/20241014042447.50197-1-ebiggers at kernel.org/)
- "arm64: Speed up CRC-32 using PMULL instructions"
  (https://lore.kernel.org/linux-crypto/20241018075347.2821102-5-ardb+git at google.com/)
- "crypto: Enable fuzz testing for arch code"
  (https://lore.kernel.org/linux-crypto/20241016185722.400643-4-ardb+git at google.com/)
- "crypto: mips/crc32 - fix the CRC32C implementation"
  (https://lore.kernel.org/linux-crypto/20241020180258.8060-1-ebiggers at kernel.org/)
- "bcachefs: Explicitly select CRYPTO from BCACHEFS_FS"
  (https://lore.kernel.org/linux-bcachefs/20241023183521.3752681-1-ebiggers at kernel.org/)

Everything can be retrieved from git using the command given earlier.

The dependencies will be merged for 6.13.  I suggest that for 6.14 I
submit a pull request to Linus with patches 1-14.  Acks would be
appreciated.  Converting users from the crypto API to the library API
would then happen later through the appropriate subsystem trees.

Changed in v3:
  - Replaced crc32_optimizations global variable with
    crc32_optimizations() function.
  - Make ISCSI_TARGET keep selecting CRYPTO_HASH, since
    iscsi_target_auth.c still uses the shash API for other algorithms.

Changed in v2:
  - Added a way to determine if the arch-optimized code is actually
    being used at runtime, and used this to register the appropriate
    shash algorithms with crypto API.
  - Added a patch that converts iSCSI to use the library.
  - Listed a bcachefs patch as a dependency.
  - Added Ard's Reviewed-by.

Eric Biggers (18):
  lib/crc32: drop leading underscores from __crc32c_le_base
  lib/crc32: improve support for arch-specific overrides
  lib/crc32: expose whether the lib is really optimized at runtime
  crypto: crc32 - don't unnecessarily register arch algorithms
  arm/crc32: expose CRC32 functions through lib
  loongarch/crc32: expose CRC32 functions through lib
  mips/crc32: expose CRC32 functions through lib
  powerpc/crc32: expose CRC32 functions through lib
  s390/crc32: expose CRC32 functions through lib
  sparc/crc32: expose CRC32 functions through lib
  x86/crc32: update prototype for crc_pcl()
  x86/crc32: update prototype for crc32_pclmul_le_16()
  x86/crc32: expose CRC32 functions through lib
  lib/crc32: make crc32c() go directly to lib
  ext4: switch to using the crc32c library
  jbd2: switch to using the crc32c library
  f2fs: switch to using the crc32 library
  scsi: target: iscsi: switch to using the crc32c library

 arch/arm/Kconfig                              |   1 +
 arch/arm/configs/milbeaut_m10v_defconfig      |   1 -
 arch/arm/configs/multi_v7_defconfig           |   1 -
 arch/arm/crypto/Kconfig                       |  14 -
 arch/arm/crypto/Makefile                      |   2 -
 arch/arm/crypto/crc32-ce-glue.c               | 247 ------------
 arch/arm/lib/Makefile                         |   3 +
 .../crc32-ce-core.S => lib/crc32-core.S}      |   0
 arch/arm/lib/crc32-glue.c                     | 123 ++++++
 arch/arm64/Kconfig                            |   1 +
 arch/arm64/lib/Makefile                       |   3 +-
 arch/arm64/lib/crc32-glue.c                   |  25 +-
 arch/loongarch/Kconfig                        |   1 +
 arch/loongarch/configs/loongson3_defconfig    |   1 -
 arch/loongarch/crypto/Kconfig                 |   9 -
 arch/loongarch/crypto/Makefile                |   2 -
 arch/loongarch/crypto/crc32-loongarch.c       | 300 ---------------
 arch/loongarch/lib/Makefile                   |   2 +
 arch/loongarch/lib/crc32-loongarch.c          | 135 +++++++
 arch/mips/Kconfig                             |   5 +-
 arch/mips/configs/eyeq5_defconfig             |   1 -
 arch/mips/configs/eyeq6_defconfig             |   1 -
 arch/mips/configs/generic/32r6.config         |   2 -
 arch/mips/configs/generic/64r6.config         |   1 -
 arch/mips/crypto/Kconfig                      |   9 -
 arch/mips/crypto/Makefile                     |   2 -
 arch/mips/crypto/crc32-mips.c                 | 354 ------------------
 arch/mips/lib/Makefile                        |   2 +
 arch/mips/lib/crc32-mips.c                    | 192 ++++++++++
 arch/powerpc/Kconfig                          |   1 +
 arch/powerpc/configs/powernv_defconfig        |   1 -
 arch/powerpc/configs/ppc64_defconfig          |   1 -
 arch/powerpc/crypto/Kconfig                   |  15 +-
 arch/powerpc/crypto/Makefile                  |   2 -
 arch/powerpc/crypto/crc32c-vpmsum_glue.c      | 173 ---------
 arch/powerpc/crypto/crct10dif-vpmsum_asm.S    |   2 +-
 arch/powerpc/lib/Makefile                     |   3 +
 arch/powerpc/lib/crc32-glue.c                 |  92 +++++
 .../{crypto => lib}/crc32-vpmsum_core.S       |   0
 .../{crypto => lib}/crc32c-vpmsum_asm.S       |   0
 arch/riscv/Kconfig                            |   1 +
 arch/riscv/lib/Makefile                       |   3 +-
 arch/riscv/lib/{crc32.c => crc32-riscv.c}     |  25 +-
 arch/s390/Kconfig                             |   1 +
 arch/s390/configs/debug_defconfig             |   1 -
 arch/s390/configs/defconfig                   |   1 -
 arch/s390/crypto/Kconfig                      |  12 -
 arch/s390/crypto/Makefile                     |   2 -
 arch/s390/crypto/crc32-vx.c                   | 306 ---------------
 arch/s390/lib/Makefile                        |   3 +
 arch/s390/lib/crc32-glue.c                    |  92 +++++
 arch/s390/{crypto => lib}/crc32-vx.h          |   0
 arch/s390/{crypto => lib}/crc32be-vx.c        |   0
 arch/s390/{crypto => lib}/crc32le-vx.c        |   0
 arch/sparc/Kconfig                            |   1 +
 arch/sparc/crypto/Kconfig                     |  10 -
 arch/sparc/crypto/Makefile                    |   4 -
 arch/sparc/crypto/crc32c_glue.c               | 184 ---------
 arch/sparc/lib/Makefile                       |   2 +
 arch/sparc/lib/crc32_glue.c                   |  93 +++++
 arch/sparc/{crypto => lib}/crc32c_asm.S       |   2 +-
 arch/x86/Kconfig                              |   1 +
 arch/x86/crypto/Kconfig                       |  22 --
 arch/x86/crypto/Makefile                      |   7 -
 arch/x86/crypto/crc32-pclmul_glue.c           | 202 ----------
 arch/x86/crypto/crc32c-intel_glue.c           | 250 -------------
 arch/x86/lib/Makefile                         |   4 +
 arch/x86/lib/crc32-glue.c                     | 124 ++++++
 .../crc32-pclmul_asm.S => lib/crc32-pclmul.S} |  19 +-
 .../crc32c-3way.S}                            |  63 ++--
 crypto/crc32_generic.c                        |   8 +-
 crypto/crc32c_generic.c                       |  12 +-
 drivers/target/iscsi/Kconfig                  |   4 +-
 drivers/target/iscsi/iscsi_target.c           | 153 +++-----
 drivers/target/iscsi/iscsi_target_login.c     |  50 ---
 drivers/target/iscsi/iscsi_target_login.h     |   1 -
 drivers/target/iscsi/iscsi_target_nego.c      |  21 +-
 fs/ext4/Kconfig                               |   3 +-
 fs/ext4/ext4.h                                |  25 +-
 fs/ext4/super.c                               |  15 -
 fs/f2fs/Kconfig                               |   3 +-
 fs/f2fs/f2fs.h                                |  19 +-
 fs/f2fs/super.c                               |  15 -
 fs/jbd2/Kconfig                               |   2 -
 fs/jbd2/journal.c                             |  25 +-
 include/linux/crc32.h                         |  50 ++-
 include/linux/crc32c.h                        |   7 +-
 include/linux/jbd2.h                          |  31 +-
 include/target/iscsi/iscsi_target_core.h      |   3 -
 lib/Kconfig                                   |  80 ++--
 lib/Makefile                                  |   1 -
 lib/crc32.c                                   |  24 +-
 lib/crc32test.c                               |   2 +-
 lib/libcrc32c.c                               |  74 ----
 94 files changed, 1156 insertions(+), 2637 deletions(-)
 delete mode 100644 arch/arm/crypto/crc32-ce-glue.c
 rename arch/arm/{crypto/crc32-ce-core.S => lib/crc32-core.S} (100%)
 create mode 100644 arch/arm/lib/crc32-glue.c
 delete mode 100644 arch/loongarch/crypto/crc32-loongarch.c
 create mode 100644 arch/loongarch/lib/crc32-loongarch.c
 delete mode 100644 arch/mips/crypto/crc32-mips.c
 create mode 100644 arch/mips/lib/crc32-mips.c
 delete mode 100644 arch/powerpc/crypto/crc32c-vpmsum_glue.c
 create mode 100644 arch/powerpc/lib/crc32-glue.c
 rename arch/powerpc/{crypto => lib}/crc32-vpmsum_core.S (100%)
 rename arch/powerpc/{crypto => lib}/crc32c-vpmsum_asm.S (100%)
 rename arch/riscv/lib/{crc32.c => crc32-riscv.c} (91%)
 delete mode 100644 arch/s390/crypto/crc32-vx.c
 create mode 100644 arch/s390/lib/crc32-glue.c
 rename arch/s390/{crypto => lib}/crc32-vx.h (100%)
 rename arch/s390/{crypto => lib}/crc32be-vx.c (100%)
 rename arch/s390/{crypto => lib}/crc32le-vx.c (100%)
 delete mode 100644 arch/sparc/crypto/crc32c_glue.c
 create mode 100644 arch/sparc/lib/crc32_glue.c
 rename arch/sparc/{crypto => lib}/crc32c_asm.S (92%)
 delete mode 100644 arch/x86/crypto/crc32-pclmul_glue.c
 delete mode 100644 arch/x86/crypto/crc32c-intel_glue.c
 create mode 100644 arch/x86/lib/crc32-glue.c
 rename arch/x86/{crypto/crc32-pclmul_asm.S => lib/crc32-pclmul.S} (95%)
 rename arch/x86/{crypto/crc32c-pcl-intel-asm_64.S => lib/crc32c-3way.S} (92%)
 delete mode 100644 lib/libcrc32c.c

-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:37 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:37 -0800
Subject: [PATCH v3 01/18] lib/crc32: drop leading underscores from __crc32c_le_base
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-2-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Remove the leading underscores from __crc32c_le_base().

This is in preparation for adding crc32c_le_arch() and eventually
renaming __crc32c_le() to crc32c_le().

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm64/lib/crc32-glue.c | 2 +-
 arch/riscv/lib/crc32.c      | 2 +-
 crypto/crc32c_generic.c     | 8 ++++----
 include/linux/crc32.h       | 2 +-
 lib/crc32.c                 | 4 ++--
 lib/crc32test.c             | 2 +-
 6 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/lib/crc32-glue.c b/arch/arm64/lib/crc32-glue.c
index 295ae3e6b997..ad015223d15d 100644
--- a/arch/arm64/lib/crc32-glue.c
+++ b/arch/arm64/lib/crc32-glue.c
@@ -42,11 +42,11 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 }
 
 u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 {
 	if (!alternative_has_cap_likely(ARM64_HAS_CRC32))
-		return __crc32c_le_base(crc, p, len);
+		return crc32c_le_base(crc, p, len);
 
 	if (len >= min_len && cpu_have_named_feature(PMULL) && crypto_simd_usable()) {
 		kernel_neon_begin();
 		crc = crc32c_le_arm64_4way(crc, p, len);
 		kernel_neon_end();
diff --git a/arch/riscv/lib/crc32.c b/arch/riscv/lib/crc32.c
index d7dc599af3ef..333fb7af1192 100644
--- a/arch/riscv/lib/crc32.c
+++ b/arch/riscv/lib/crc32.c
@@ -224,11 +224,11 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 }
 
 u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 {
 	return crc32_le_generic(crc, p, len, CRC32C_POLY_LE,
-				CRC32C_POLY_QT_LE, __crc32c_le_base);
+				CRC32C_POLY_QT_LE, crc32c_le_base);
 }
 
 static inline u32 crc32_be_unaligned(u32 crc, unsigned char const *p,
 				     size_t len)
 {
diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c
index 7c2357c30fdf..635599b255ec 100644
--- a/crypto/crc32c_generic.c
+++ b/crypto/crc32c_generic.c
@@ -83,11 +83,11 @@ static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
 static int chksum_update(struct shash_desc *desc, const u8 *data,
 			 unsigned int length)
 {
 	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
-	ctx->crc = __crc32c_le_base(ctx->crc, data, length);
+	ctx->crc = crc32c_le_base(ctx->crc, data, length);
 	return 0;
 }
 
 static int chksum_update_arch(struct shash_desc *desc, const u8 *data,
 			      unsigned int length)
@@ -106,11 +106,11 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
 	return 0;
 }
 
 static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
 {
-	put_unaligned_le32(~__crc32c_le_base(*crcp, data, len), out);
+	put_unaligned_le32(~crc32c_le_base(*crcp, data, len), out);
 	return 0;
 }
 
 static int __chksum_finup_arch(u32 *crcp, const u8 *data, unsigned int len,
 			       u8 *out)
@@ -198,16 +198,16 @@ static struct shash_alg algs[] = {{
 }};
 
 static int __init crc32c_mod_init(void)
 {
 	/* register the arch flavor only if it differs from the generic one */
-	return crypto_register_shashes(algs, 1 + (&__crc32c_le != &__crc32c_le_base));
+	return crypto_register_shashes(algs, 1 + (&__crc32c_le != &crc32c_le_base));
 }
 
 static void __exit crc32c_mod_fini(void)
 {
-	crypto_unregister_shashes(algs, 1 + (&__crc32c_le != &__crc32c_le_base));
+	crypto_unregister_shashes(algs, 1 + (&__crc32c_le != &crc32c_le_base));
 }
 
 subsys_initcall(crc32c_mod_init);
 module_exit(crc32c_mod_fini);
 
diff --git a/include/linux/crc32.h b/include/linux/crc32.h
index 87f788c0d607..5b07fc9081c4 100644
--- a/include/linux/crc32.h
+++ b/include/linux/crc32.h
@@ -37,11 +37,11 @@ static inline u32 crc32_le_combine(u32 crc1, u32 crc2, size_t len2)
 {
 	return crc32_le_shift(crc1, len2) ^ crc2;
 }
 
 u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len);
-u32 __pure __crc32c_le_base(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32c_le_base(u32 crc, unsigned char const *p, size_t len);
 
 /**
  * __crc32c_le_combine - Combine two crc32c check values into one. For two
  * 			 sequences of bytes, seq1 and seq2 with lengths len1
  * 			 and len2, __crc32c_le() check values were calculated
diff --git a/lib/crc32.c b/lib/crc32.c
index ff587fee3893..c67059b0082b 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -205,12 +205,12 @@ EXPORT_SYMBOL(crc32_le);
 EXPORT_SYMBOL(__crc32c_le);
 
 u32 __pure crc32_le_base(u32, unsigned char const *, size_t) __alias(crc32_le);
 EXPORT_SYMBOL(crc32_le_base);
 
-u32 __pure __crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le);
-EXPORT_SYMBOL(__crc32c_le_base);
+u32 __pure crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le);
+EXPORT_SYMBOL(crc32c_le_base);
 
 u32 __pure crc32_be_base(u32, unsigned char const *, size_t) __alias(crc32_be);
 
 /*
  * This multiplies the polynomials x and y modulo the given modulus.
diff --git a/lib/crc32test.c b/lib/crc32test.c
index 03cf5c1f2f5d..30b8da4d8be4 100644
--- a/lib/crc32test.c
+++ b/lib/crc32test.c
@@ -824,11 +824,11 @@ static void crc32test_regenerate(void)
 	for (i = 0; i < ARRAY_SIZE(test); i++) {
 		pr_info("{0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x},\n",
 			test[i].crc, test[i].start, test[i].length,
 			crc32_le_base(test[i].crc, test_buf + test[i].start, test[i].length),
 			crc32_be_base(test[i].crc, test_buf + test[i].start, test[i].length),
-			__crc32c_le_base(test[i].crc, test_buf + test[i].start, test[i].length));
+			crc32c_le_base(test[i].crc, test_buf + test[i].start, test[i].length));
 	}
 }
 
 static int __init crc32test_init(void)
 {
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:41 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:41 -0800
Subject: [PATCH v3 05/18] arm/crc32: expose CRC32 functions through lib
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-6-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the arm CRC32 assembly code into the lib directory and wire it up
to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/arm/crypto/crc32-ce-glue.c to
arch/arm/lib/crc32-glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm/Kconfig                              |   1 +
 arch/arm/configs/milbeaut_m10v_defconfig      |   1 -
 arch/arm/configs/multi_v7_defconfig           |   1 -
 arch/arm/crypto/Kconfig                       |  14 -
 arch/arm/crypto/Makefile                      |   2 -
 arch/arm/crypto/crc32-ce-glue.c               | 247 ------------------
 arch/arm/lib/Makefile                         |   3 +
 .../crc32-ce-core.S => lib/crc32-core.S}      |   0
 arch/arm/lib/crc32-glue.c                     | 123 +++++++++
 9 files changed, 127 insertions(+), 265 deletions(-)
 delete mode 100644 arch/arm/crypto/crc32-ce-glue.c
 rename arch/arm/{crypto/crc32-ce-core.S => lib/crc32-core.S} (100%)
 create mode 100644 arch/arm/lib/crc32-glue.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 749179a1d162..851260303234 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -5,10 +5,11 @@ config ARM
 	select ARCH_32BIT_OFF_T
 	select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
 	select ARCH_HAS_BINFMT_FLAT
 	select ARCH_HAS_CPU_CACHE_ALIASING
 	select ARCH_HAS_CPU_FINALIZE_INIT if MMU
+	select ARCH_HAS_CRC32 if KERNEL_MODE_NEON
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL if MMU
 	select ARCH_HAS_DMA_ALLOC if MMU
 	select ARCH_HAS_DMA_OPS
 	select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
diff --git a/arch/arm/configs/milbeaut_m10v_defconfig b/arch/arm/configs/milbeaut_m10v_defconfig
index f5eeac9c65c3..acd16204f8d7 100644
--- a/arch/arm/configs/milbeaut_m10v_defconfig
+++ b/arch/arm/configs/milbeaut_m10v_defconfig
@@ -105,11 +105,10 @@ CONFIG_CRYPTO_SHA2_ARM_CE=m
 CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_AES_ARM_CE=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
-CONFIG_CRYPTO_CRC32_ARM_CE=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC_ITU_T=m
 CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=64
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 9a5f5c439b87..287ca055965f 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -1304,11 +1304,10 @@ CONFIG_CRYPTO_SHA2_ARM_CE=m
 CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_AES_ARM_CE=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
-CONFIG_CRYPTO_CRC32_ARM_CE=m
 CONFIG_CRYPTO_DEV_SUN4I_SS=m
 CONFIG_CRYPTO_DEV_FSL_CAAM=m
 CONFIG_CRYPTO_DEV_EXYNOS_RNG=m
 CONFIG_CRYPTO_DEV_S5P=m
 CONFIG_CRYPTO_DEV_ATMEL_AES=m
diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig
index 5ff49a5e9afc..ea0ebf336d0d 100644
--- a/arch/arm/crypto/Kconfig
+++ b/arch/arm/crypto/Kconfig
@@ -220,24 +220,10 @@ config CRYPTO_CHACHA20_NEON
 	  stream cipher algorithms
 
 	  Architecture: arm using:
 	  - NEON (Advanced SIMD) extensions
 
-config CRYPTO_CRC32_ARM_CE
-	tristate "CRC32C and CRC32"
-	depends on KERNEL_MODE_NEON
-	depends on CRC32
-	select CRYPTO_HASH
-	help
-	  CRC32c CRC algorithm with the iSCSI polynomial (RFC 3385 and RFC 3720)
-	  and CRC32 CRC algorithm (IEEE 802.3)
-
-	  Architecture: arm using:
-	  - CRC and/or PMULL instructions
-
-	  Drivers: crc32-arm-ce and crc32c-arm-ce
-
 config CRYPTO_CRCT10DIF_ARM_CE
 	tristate "CRCT10DIF"
 	depends on KERNEL_MODE_NEON
 	depends on CRC_T10DIF
 	select CRYPTO_HASH
diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile
index 13e62c7c25dc..38ec5cc1e844 100644
--- a/arch/arm/crypto/Makefile
+++ b/arch/arm/crypto/Makefile
@@ -19,11 +19,10 @@ obj-$(CONFIG_CRYPTO_CURVE25519_NEON) += curve25519-neon.o
 obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o
 obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o
 obj-$(CONFIG_CRYPTO_GHASH_ARM_CE) += ghash-arm-ce.o
 obj-$(CONFIG_CRYPTO_CRCT10DIF_ARM_CE) += crct10dif-arm-ce.o
-obj-$(CONFIG_CRYPTO_CRC32_ARM_CE) += crc32-arm-ce.o
 
 aes-arm-y	:= aes-cipher-core.o aes-cipher-glue.o
 aes-arm-bs-y	:= aes-neonbs-core.o aes-neonbs-glue.o
 sha1-arm-y	:= sha1-armv4-large.o sha1_glue.o
 sha1-arm-neon-y	:= sha1-armv7-neon.o sha1_neon_glue.o
@@ -36,11 +35,10 @@ blake2b-neon-y  := blake2b-neon-core.o blake2b-neon-glue.o
 sha1-arm-ce-y	:= sha1-ce-core.o sha1-ce-glue.o
 sha2-arm-ce-y	:= sha2-ce-core.o sha2-ce-glue.o
 aes-arm-ce-y	:= aes-ce-core.o aes-ce-glue.o
 ghash-arm-ce-y	:= ghash-ce-core.o ghash-ce-glue.o
 crct10dif-arm-ce-y	:= crct10dif-ce-core.o crct10dif-ce-glue.o
-crc32-arm-ce-y:= crc32-ce-core.o crc32-ce-glue.o
 chacha-neon-y := chacha-scalar-core.o chacha-glue.o
 chacha-neon-$(CONFIG_KERNEL_MODE_NEON) += chacha-neon-core.o
 poly1305-arm-y := poly1305-core.o poly1305-glue.o
 nhpoly1305-neon-y := nh-neon-core.o nhpoly1305-neon-glue.o
 curve25519-neon-y := curve25519-core.o curve25519-glue.o
diff --git a/arch/arm/crypto/crc32-ce-glue.c b/arch/arm/crypto/crc32-ce-glue.c
deleted file mode 100644
index 20b4dff13e3a..000000000000
--- a/arch/arm/crypto/crc32-ce-glue.c
+++ /dev/null
@@ -1,247 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions instructions
- *
- * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel at linaro.org>
- */
-
-#include <linux/cpufeature.h>
-#include <linux/crc32.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-
-#include <asm/hwcap.h>
-#include <asm/neon.h>
-#include <asm/simd.h>
-#include <linux/unaligned.h>
-
-#define PMULL_MIN_LEN		64L	/* minimum size of buffer
-					 * for crc32_pmull_le_16 */
-#define SCALE_F			16L	/* size of NEON register */
-
-asmlinkage u32 crc32_pmull_le(const u8 buf[], u32 len, u32 init_crc);
-asmlinkage u32 crc32_armv8_le(u32 init_crc, const u8 buf[], u32 len);
-
-asmlinkage u32 crc32c_pmull_le(const u8 buf[], u32 len, u32 init_crc);
-asmlinkage u32 crc32c_armv8_le(u32 init_crc, const u8 buf[], u32 len);
-
-static u32 (*fallback_crc32)(u32 init_crc, const u8 buf[], u32 len);
-static u32 (*fallback_crc32c)(u32 init_crc, const u8 buf[], u32 len);
-
-static int crc32_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = 0;
-	return 0;
-}
-
-static int crc32c_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = ~0;
-	return 0;
-}
-
-static int crc32_setkey(struct crypto_shash *hash, const u8 *key,
-			unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = le32_to_cpup((__le32 *)key);
-	return 0;
-}
-
-static int crc32_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crc = shash_desc_ctx(desc);
-
-	*crc = *mctx;
-	return 0;
-}
-
-static int crc32_update(struct shash_desc *desc, const u8 *data,
-			unsigned int length)
-{
-	u32 *crc = shash_desc_ctx(desc);
-
-	*crc = crc32_armv8_le(*crc, data, length);
-	return 0;
-}
-
-static int crc32c_update(struct shash_desc *desc, const u8 *data,
-			 unsigned int length)
-{
-	u32 *crc = shash_desc_ctx(desc);
-
-	*crc = crc32c_armv8_le(*crc, data, length);
-	return 0;
-}
-
-static int crc32_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crc = shash_desc_ctx(desc);
-
-	put_unaligned_le32(*crc, out);
-	return 0;
-}
-
-static int crc32c_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crc = shash_desc_ctx(desc);
-
-	put_unaligned_le32(~*crc, out);
-	return 0;
-}
-
-static int crc32_pmull_update(struct shash_desc *desc, const u8 *data,
-			      unsigned int length)
-{
-	u32 *crc = shash_desc_ctx(desc);
-	unsigned int l;
-
-	if (crypto_simd_usable()) {
-		if ((u32)data % SCALE_F) {
-			l = min_t(u32, length, SCALE_F - ((u32)data % SCALE_F));
-
-			*crc = fallback_crc32(*crc, data, l);
-
-			data += l;
-			length -= l;
-		}
-
-		if (length >= PMULL_MIN_LEN) {
-			l = round_down(length, SCALE_F);
-
-			kernel_neon_begin();
-			*crc = crc32_pmull_le(data, l, *crc);
-			kernel_neon_end();
-
-			data += l;
-			length -= l;
-		}
-	}
-
-	if (length > 0)
-		*crc = fallback_crc32(*crc, data, length);
-
-	return 0;
-}
-
-static int crc32c_pmull_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int length)
-{
-	u32 *crc = shash_desc_ctx(desc);
-	unsigned int l;
-
-	if (crypto_simd_usable()) {
-		if ((u32)data % SCALE_F) {
-			l = min_t(u32, length, SCALE_F - ((u32)data % SCALE_F));
-
-			*crc = fallback_crc32c(*crc, data, l);
-
-			data += l;
-			length -= l;
-		}
-
-		if (length >= PMULL_MIN_LEN) {
-			l = round_down(length, SCALE_F);
-
-			kernel_neon_begin();
-			*crc = crc32c_pmull_le(data, l, *crc);
-			kernel_neon_end();
-
-			data += l;
-			length -= l;
-		}
-	}
-
-	if (length > 0)
-		*crc = fallback_crc32c(*crc, data, length);
-
-	return 0;
-}
-
-static struct shash_alg crc32_pmull_algs[] = { {
-	.setkey			= crc32_setkey,
-	.init			= crc32_init,
-	.update			= crc32_update,
-	.final			= crc32_final,
-	.descsize		= sizeof(u32),
-	.digestsize		= sizeof(u32),
-
-	.base.cra_ctxsize	= sizeof(u32),
-	.base.cra_init		= crc32_cra_init,
-	.base.cra_name		= "crc32",
-	.base.cra_driver_name	= "crc32-arm-ce",
-	.base.cra_priority	= 200,
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_blocksize	= 1,
-	.base.cra_module	= THIS_MODULE,
-}, {
-	.setkey			= crc32_setkey,
-	.init			= crc32_init,
-	.update			= crc32c_update,
-	.final			= crc32c_final,
-	.descsize		= sizeof(u32),
-	.digestsize		= sizeof(u32),
-
-	.base.cra_ctxsize	= sizeof(u32),
-	.base.cra_init		= crc32c_cra_init,
-	.base.cra_name		= "crc32c",
-	.base.cra_driver_name	= "crc32c-arm-ce",
-	.base.cra_priority	= 200,
-	.base.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-	.base.cra_blocksize	= 1,
-	.base.cra_module	= THIS_MODULE,
-} };
-
-static int __init crc32_pmull_mod_init(void)
-{
-	if (elf_hwcap2 & HWCAP2_PMULL) {
-		crc32_pmull_algs[0].update = crc32_pmull_update;
-		crc32_pmull_algs[1].update = crc32c_pmull_update;
-
-		if (elf_hwcap2 & HWCAP2_CRC32) {
-			fallback_crc32 = crc32_armv8_le;
-			fallback_crc32c = crc32c_armv8_le;
-		} else {
-			fallback_crc32 = crc32_le;
-			fallback_crc32c = __crc32c_le;
-		}
-	} else if (!(elf_hwcap2 & HWCAP2_CRC32)) {
-		return -ENODEV;
-	}
-
-	return crypto_register_shashes(crc32_pmull_algs,
-				       ARRAY_SIZE(crc32_pmull_algs));
-}
-
-static void __exit crc32_pmull_mod_exit(void)
-{
-	crypto_unregister_shashes(crc32_pmull_algs,
-				  ARRAY_SIZE(crc32_pmull_algs));
-}
-
-static const struct cpu_feature __maybe_unused crc32_cpu_feature[] = {
-	{ cpu_feature(CRC32) }, { cpu_feature(PMULL) }, { }
-};
-MODULE_DEVICE_TABLE(cpu, crc32_cpu_feature);
-
-module_init(crc32_pmull_mod_init);
-module_exit(crc32_pmull_mod_exit);
-
-MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel at linaro.org>");
-MODULE_DESCRIPTION("Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS_CRYPTO("crc32");
-MODULE_ALIAS_CRYPTO("crc32c");
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 0ca5aae1bcc3..01cd4db2ed47 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -43,5 +43,8 @@ ifeq ($(CONFIG_KERNEL_MODE_NEON),y)
   CFLAGS_xor-neon.o		+= $(CC_FLAGS_FPU)
   obj-$(CONFIG_XOR_BLOCKS)	+= xor-neon.o
 endif
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
+
+obj-$(CONFIG_CRC32_ARCH) += crc32-arm.o
+crc32-arm-y := crc32-glue.o crc32-core.o
diff --git a/arch/arm/crypto/crc32-ce-core.S b/arch/arm/lib/crc32-core.S
similarity index 100%
rename from arch/arm/crypto/crc32-ce-core.S
rename to arch/arm/lib/crc32-core.S
diff --git a/arch/arm/lib/crc32-glue.c b/arch/arm/lib/crc32-glue.c
new file mode 100644
index 000000000000..2d56fb2b0a1c
--- /dev/null
+++ b/arch/arm/lib/crc32-glue.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions instructions
+ *
+ * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel at linaro.org>
+ */
+
+#include <linux/cpufeature.h>
+#include <linux/crc32.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <crypto/internal/simd.h>
+
+#include <asm/hwcap.h>
+#include <asm/neon.h>
+#include <asm/simd.h>
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32);
+static DEFINE_STATIC_KEY_FALSE(have_pmull);
+
+#define PMULL_MIN_LEN	64	/* min size of buffer for pmull functions */
+
+asmlinkage u32 crc32_pmull_le(const u8 buf[], u32 len, u32 init_crc);
+asmlinkage u32 crc32_armv8_le(u32 init_crc, const u8 buf[], u32 len);
+
+asmlinkage u32 crc32c_pmull_le(const u8 buf[], u32 len, u32 init_crc);
+asmlinkage u32 crc32c_armv8_le(u32 init_crc, const u8 buf[], u32 len);
+
+static u32 crc32_le_scalar(u32 crc, const u8 *p, size_t len)
+{
+	if (static_branch_likely(&have_crc32))
+		return crc32_armv8_le(crc, p, len);
+	return crc32_le_base(crc, p, len);
+}
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (len >= PMULL_MIN_LEN + 15 &&
+	    crypto_simd_usable() && static_branch_likely(&have_pmull)) {
+		size_t n = -(uintptr_t)p & 15;
+
+		/* align p to 16-byte boundary */
+		if (n) {
+			crc = crc32_le_scalar(crc, p, n);
+			p += n;
+			len -= n;
+		}
+		n = round_down(len, 16);
+		kernel_neon_begin();
+		crc = crc32_pmull_le(p, n, crc);
+		kernel_neon_end();
+		p += n;
+		len -= n;
+	}
+	return crc32_le_scalar(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+static u32 crc32c_le_scalar(u32 crc, const u8 *p, size_t len)
+{
+	if (static_branch_likely(&have_crc32))
+		return crc32c_armv8_le(crc, p, len);
+	return crc32c_le_base(crc, p, len);
+}
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (len >= PMULL_MIN_LEN + 15 &&
+	    crypto_simd_usable() && static_branch_likely(&have_pmull)) {
+		size_t n = -(uintptr_t)p & 15;
+
+		/* align p to 16-byte boundary */
+		if (n) {
+			crc = crc32c_le_scalar(crc, p, n);
+			p += n;
+			len -= n;
+		}
+		n = round_down(len, 16);
+		kernel_neon_begin();
+		crc = crc32c_pmull_le(p, n, crc);
+		kernel_neon_end();
+		p += n;
+		len -= n;
+	}
+	return crc32c_le_scalar(crc, p, len);
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_arm_init(void)
+{
+	if (elf_hwcap2 & HWCAP2_CRC32)
+		static_branch_enable(&have_crc32);
+	if (elf_hwcap2 & HWCAP2_PMULL)
+		static_branch_enable(&have_pmull);
+	return 0;
+}
+arch_initcall(crc32_arm_init);
+
+static void __exit crc32_arm_exit(void)
+{
+}
+module_exit(crc32_arm_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (elf_hwcap2 & (HWCAP2_CRC32 | HWCAP2_PMULL))
+		return CRC32_LE_OPTIMIZATION | CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel at linaro.org>");
+MODULE_DESCRIPTION("Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions");
+MODULE_LICENSE("GPL v2");
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:43 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:43 -0800
Subject: [PATCH v3 07/18] mips/crc32: expose CRC32 functions through lib
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-8-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the mips CRC32 assembly code into the lib directory and wire it up
to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/mips/crypto/crc32-mips.c to
arch/mips/lib/crc32-mips.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/mips/Kconfig                     |   5 +-
 arch/mips/configs/eyeq5_defconfig     |   1 -
 arch/mips/configs/eyeq6_defconfig     |   1 -
 arch/mips/configs/generic/32r6.config |   2 -
 arch/mips/configs/generic/64r6.config |   1 -
 arch/mips/crypto/Kconfig              |   9 -
 arch/mips/crypto/Makefile             |   2 -
 arch/mips/crypto/crc32-mips.c         | 354 --------------------------
 arch/mips/lib/Makefile                |   2 +
 arch/mips/lib/crc32-mips.c            | 192 ++++++++++++++
 10 files changed, 195 insertions(+), 374 deletions(-)
 delete mode 100644 arch/mips/crypto/crc32-mips.c
 create mode 100644 arch/mips/lib/crc32-mips.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 397edf05dd72..f80ea80d792f 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1993,15 +1993,15 @@ config CPU_MIPSR5
 	select MIPS_SPRAM
 
 config CPU_MIPSR6
 	bool
 	default y if CPU_MIPS32_R6 || CPU_MIPS64_R6
+	select ARCH_HAS_CRC32
 	select CPU_HAS_RIXI
 	select CPU_HAS_DIEI if !CPU_DIEI_BROKEN
 	select HAVE_ARCH_BITREVERSE
 	select MIPS_ASID_BITS_VARIABLE
-	select MIPS_CRC_SUPPORT
 	select MIPS_SPRAM
 
 config TARGET_ISA_REV
 	int
 	default 1 if CPU_MIPSR1
@@ -2473,13 +2473,10 @@ config MIPS_ASID_BITS
 	default 8
 
 config MIPS_ASID_BITS_VARIABLE
 	bool
 
-config MIPS_CRC_SUPPORT
-	bool
-
 # R4600 erratum.  Due to the lack of errata information the exact
 # technical details aren't known.  I've experimentally found that disabling
 # interrupts during indexed I-cache flushes seems to be sufficient to deal
 # with the issue.
 config WAR_R4600_V1_INDEX_ICACHEOP
diff --git a/arch/mips/configs/eyeq5_defconfig b/arch/mips/configs/eyeq5_defconfig
index ae9a09b16e40..ff7af5dc6d9d 100644
--- a/arch/mips/configs/eyeq5_defconfig
+++ b/arch/mips/configs/eyeq5_defconfig
@@ -97,11 +97,10 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_NFS_V4_1=y
 CONFIG_NFS_V4_2=y
 CONFIG_ROOT_NFS=y
-CONFIG_CRYPTO_CRC32_MIPS=y
 CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_RCU_TRACE is not set
 # CONFIG_FTRACE is not set
 CONFIG_CMDLINE_BOOL=y
diff --git a/arch/mips/configs/eyeq6_defconfig b/arch/mips/configs/eyeq6_defconfig
index 6597d5e88b33..0afbb45a78e8 100644
--- a/arch/mips/configs/eyeq6_defconfig
+++ b/arch/mips/configs/eyeq6_defconfig
@@ -100,11 +100,10 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_NFS_V4_1=y
 CONFIG_NFS_V4_2=y
 CONFIG_ROOT_NFS=y
-CONFIG_CRYPTO_CRC32_MIPS=y
 CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_RCU_TRACE is not set
 # CONFIG_FTRACE is not set
 CONFIG_CMDLINE_BOOL=y
diff --git a/arch/mips/configs/generic/32r6.config b/arch/mips/configs/generic/32r6.config
index 1a5d5ea4ab2b..ca606e71f4d0 100644
--- a/arch/mips/configs/generic/32r6.config
+++ b/arch/mips/configs/generic/32r6.config
@@ -1,4 +1,2 @@
 CONFIG_CPU_MIPS32_R6=y
 CONFIG_HIGHMEM=y
-
-CONFIG_CRYPTO_CRC32_MIPS=y
diff --git a/arch/mips/configs/generic/64r6.config b/arch/mips/configs/generic/64r6.config
index 63b4e95f303d..23a300914957 100644
--- a/arch/mips/configs/generic/64r6.config
+++ b/arch/mips/configs/generic/64r6.config
@@ -2,7 +2,6 @@ CONFIG_CPU_MIPS64_R6=y
 CONFIG_64BIT=y
 CONFIG_MIPS32_O32=y
 CONFIG_MIPS32_N32=y
 
 CONFIG_CPU_HAS_MSA=y
-CONFIG_CRYPTO_CRC32_MIPS=y
 CONFIG_VIRTUALIZATION=y
diff --git a/arch/mips/crypto/Kconfig b/arch/mips/crypto/Kconfig
index 9003a5c1e879..7decd40c4e20 100644
--- a/arch/mips/crypto/Kconfig
+++ b/arch/mips/crypto/Kconfig
@@ -1,18 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 
 menu "Accelerated Cryptographic Algorithms for CPU (mips)"
 
-config CRYPTO_CRC32_MIPS
-	tristate "CRC32c and CRC32"
-	depends on MIPS_CRC_SUPPORT
-	select CRYPTO_HASH
-	help
-	  CRC32c and CRC32 CRC algorithms
-
-	  Architecture: mips
-
 config CRYPTO_POLY1305_MIPS
 	tristate "Hash functions: Poly1305"
 	depends on MIPS
 	select CRYPTO_ARCH_HAVE_LIB_POLY1305
 	help
diff --git a/arch/mips/crypto/Makefile b/arch/mips/crypto/Makefile
index 5e4105cccf9f..fddc88281412 100644
--- a/arch/mips/crypto/Makefile
+++ b/arch/mips/crypto/Makefile
@@ -1,12 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
 #
 # Makefile for MIPS crypto files..
 #
 
-obj-$(CONFIG_CRYPTO_CRC32_MIPS) += crc32-mips.o
-
 obj-$(CONFIG_CRYPTO_CHACHA_MIPS) += chacha-mips.o
 chacha-mips-y := chacha-core.o chacha-glue.o
 AFLAGS_chacha-core.o += -O2 # needed to fill branch delay slots
 
 obj-$(CONFIG_CRYPTO_POLY1305_MIPS) += poly1305-mips.o
diff --git a/arch/mips/crypto/crc32-mips.c b/arch/mips/crypto/crc32-mips.c
deleted file mode 100644
index 90eacf00cfc3..000000000000
--- a/arch/mips/crypto/crc32-mips.c
+++ /dev/null
@@ -1,354 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * crc32-mips.c - CRC32 and CRC32C using optional MIPSr6 instructions
- *
- * Module based on arm64/crypto/crc32-arm.c
- *
- * Copyright (C) 2014 Linaro Ltd <yazen.ghannam at linaro.org>
- * Copyright (C) 2018 MIPS Tech, LLC
- */
-
-#include <linux/cpufeature.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <asm/mipsregs.h>
-#include <linux/unaligned.h>
-
-#include <crypto/internal/hash.h>
-
-enum crc_op_size {
-	b, h, w, d,
-};
-
-enum crc_type {
-	crc32,
-	crc32c,
-};
-
-#ifndef TOOLCHAIN_SUPPORTS_CRC
-#define _ASM_SET_CRC(OP, SZ, TYPE)					  \
-_ASM_MACRO_3R(OP, rt, rs, rt2,						  \
-	".ifnc	\\rt, \\rt2\n\t"					  \
-	".error	\"invalid operands \\\"" #OP " \\rt,\\rs,\\rt2\\\"\"\n\t" \
-	".endif\n\t"							  \
-	_ASM_INSN_IF_MIPS(0x7c00000f | (__rt << 16) | (__rs << 21) |	  \
-			  ((SZ) <<  6) | ((TYPE) << 8))			  \
-	_ASM_INSN32_IF_MM(0x00000030 | (__rs << 16) | (__rt << 21) |	  \
-			  ((SZ) << 14) | ((TYPE) << 3)))
-#define _ASM_UNSET_CRC(op, SZ, TYPE) ".purgem " #op "\n\t"
-#else /* !TOOLCHAIN_SUPPORTS_CRC */
-#define _ASM_SET_CRC(op, SZ, TYPE) ".set\tcrc\n\t"
-#define _ASM_UNSET_CRC(op, SZ, TYPE)
-#endif
-
-#define __CRC32(crc, value, op, SZ, TYPE)		\
-do {							\
-	__asm__ __volatile__(				\
-		".set	push\n\t"			\
-		_ASM_SET_CRC(op, SZ, TYPE)		\
-		#op "	%0, %1, %0\n\t"			\
-		_ASM_UNSET_CRC(op, SZ, TYPE)		\
-		".set	pop"				\
-		: "+r" (crc)				\
-		: "r" (value));				\
-} while (0)
-
-#define _CRC32_crc32b(crc, value)	__CRC32(crc, value, crc32b, 0, 0)
-#define _CRC32_crc32h(crc, value)	__CRC32(crc, value, crc32h, 1, 0)
-#define _CRC32_crc32w(crc, value)	__CRC32(crc, value, crc32w, 2, 0)
-#define _CRC32_crc32d(crc, value)	__CRC32(crc, value, crc32d, 3, 0)
-#define _CRC32_crc32cb(crc, value)	__CRC32(crc, value, crc32cb, 0, 1)
-#define _CRC32_crc32ch(crc, value)	__CRC32(crc, value, crc32ch, 1, 1)
-#define _CRC32_crc32cw(crc, value)	__CRC32(crc, value, crc32cw, 2, 1)
-#define _CRC32_crc32cd(crc, value)	__CRC32(crc, value, crc32cd, 3, 1)
-
-#define _CRC32(crc, value, size, op) \
-	_CRC32_##op##size(crc, value)
-
-#define CRC32(crc, value, size) \
-	_CRC32(crc, value, size, crc32)
-
-#define CRC32C(crc, value, size) \
-	_CRC32(crc, value, size, crc32c)
-
-static u32 crc32_mips_le_hw(u32 crc_, const u8 *p, unsigned int len)
-{
-	u32 crc = crc_;
-
-	if (IS_ENABLED(CONFIG_64BIT)) {
-		for (; len >= sizeof(u64); p += sizeof(u64), len -= sizeof(u64)) {
-			u64 value = get_unaligned_le64(p);
-
-			CRC32(crc, value, d);
-		}
-
-		if (len & sizeof(u32)) {
-			u32 value = get_unaligned_le32(p);
-
-			CRC32(crc, value, w);
-			p += sizeof(u32);
-		}
-	} else {
-		for (; len >= sizeof(u32); len -= sizeof(u32)) {
-			u32 value = get_unaligned_le32(p);
-
-			CRC32(crc, value, w);
-			p += sizeof(u32);
-		}
-	}
-
-	if (len & sizeof(u16)) {
-		u16 value = get_unaligned_le16(p);
-
-		CRC32(crc, value, h);
-		p += sizeof(u16);
-	}
-
-	if (len & sizeof(u8)) {
-		u8 value = *p++;
-
-		CRC32(crc, value, b);
-	}
-
-	return crc;
-}
-
-static u32 crc32c_mips_le_hw(u32 crc_, const u8 *p, unsigned int len)
-{
-	u32 crc = crc_;
-
-	if (IS_ENABLED(CONFIG_64BIT)) {
-		for (; len >= sizeof(u64); p += sizeof(u64), len -= sizeof(u64)) {
-			u64 value = get_unaligned_le64(p);
-
-			CRC32C(crc, value, d);
-		}
-
-		if (len & sizeof(u32)) {
-			u32 value = get_unaligned_le32(p);
-
-			CRC32C(crc, value, w);
-			p += sizeof(u32);
-		}
-	} else {
-		for (; len >= sizeof(u32); len -= sizeof(u32)) {
-			u32 value = get_unaligned_le32(p);
-
-			CRC32C(crc, value, w);
-			p += sizeof(u32);
-		}
-	}
-
-	if (len & sizeof(u16)) {
-		u16 value = get_unaligned_le16(p);
-
-		CRC32C(crc, value, h);
-		p += sizeof(u16);
-	}
-
-	if (len & sizeof(u8)) {
-		u8 value = *p++;
-
-		CRC32C(crc, value, b);
-	}
-	return crc;
-}
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-struct chksum_ctx {
-	u32 key;
-};
-
-struct chksum_desc_ctx {
-	u32 crc;
-};
-
-static int chksum_init(struct shash_desc *desc)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = mctx->key;
-
-	return 0;
-}
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set
- * the seed.
- */
-static int chksum_setkey(struct crypto_shash *tfm, const u8 *key,
-			 unsigned int keylen)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
-
-	if (keylen != sizeof(mctx->key))
-		return -EINVAL;
-	mctx->key = get_unaligned_le32(key);
-	return 0;
-}
-
-static int chksum_update(struct shash_desc *desc, const u8 *data,
-			 unsigned int length)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = crc32_mips_le_hw(ctx->crc, data, length);
-	return 0;
-}
-
-static int chksumc_update(struct shash_desc *desc, const u8 *data,
-			 unsigned int length)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = crc32c_mips_le_hw(ctx->crc, data, length);
-	return 0;
-}
-
-static int chksum_final(struct shash_desc *desc, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	put_unaligned_le32(ctx->crc, out);
-	return 0;
-}
-
-static int chksumc_final(struct shash_desc *desc, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	put_unaligned_le32(~ctx->crc, out);
-	return 0;
-}
-
-static int __chksum_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
-{
-	put_unaligned_le32(crc32_mips_le_hw(crc, data, len), out);
-	return 0;
-}
-
-static int __chksumc_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
-{
-	put_unaligned_le32(~crc32c_mips_le_hw(crc, data, len), out);
-	return 0;
-}
-
-static int chksum_finup(struct shash_desc *desc, const u8 *data,
-			unsigned int len, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	return __chksum_finup(ctx->crc, data, len, out);
-}
-
-static int chksumc_finup(struct shash_desc *desc, const u8 *data,
-			unsigned int len, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	return __chksumc_finup(ctx->crc, data, len, out);
-}
-
-static int chksum_digest(struct shash_desc *desc, const u8 *data,
-			 unsigned int length, u8 *out)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-
-	return __chksum_finup(mctx->key, data, length, out);
-}
-
-static int chksumc_digest(struct shash_desc *desc, const u8 *data,
-			 unsigned int length, u8 *out)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-
-	return __chksumc_finup(mctx->key, data, length, out);
-}
-
-static int chksum_cra_init(struct crypto_tfm *tfm)
-{
-	struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = ~0;
-	return 0;
-}
-
-static struct shash_alg crc32_alg = {
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.setkey			=	chksum_setkey,
-	.init			=	chksum_init,
-	.update			=	chksum_update,
-	.final			=	chksum_final,
-	.finup			=	chksum_finup,
-	.digest			=	chksum_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crc32",
-		.cra_driver_name	=	"crc32-mips-hw",
-		.cra_priority		=	300,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(struct chksum_ctx),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	chksum_cra_init,
-	}
-};
-
-static struct shash_alg crc32c_alg = {
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.setkey			=	chksum_setkey,
-	.init			=	chksum_init,
-	.update			=	chksumc_update,
-	.final			=	chksumc_final,
-	.finup			=	chksumc_finup,
-	.digest			=	chksumc_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crc32c",
-		.cra_driver_name	=	"crc32c-mips-hw",
-		.cra_priority		=	300,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(struct chksum_ctx),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	chksum_cra_init,
-	}
-};
-
-static int __init crc32_mod_init(void)
-{
-	int err;
-
-	err = crypto_register_shash(&crc32_alg);
-
-	if (err)
-		return err;
-
-	err = crypto_register_shash(&crc32c_alg);
-
-	if (err) {
-		crypto_unregister_shash(&crc32_alg);
-		return err;
-	}
-
-	return 0;
-}
-
-static void __exit crc32_mod_exit(void)
-{
-	crypto_unregister_shash(&crc32_alg);
-	crypto_unregister_shash(&crc32c_alg);
-}
-
-MODULE_AUTHOR("Marcin Nowakowski <marcin.nowakowski at mips.com");
-MODULE_DESCRIPTION("CRC32 and CRC32C using optional MIPS instructions");
-MODULE_LICENSE("GPL v2");
-
-module_cpu_feature_match(MIPS_CRC32, crc32_mod_init);
-module_exit(crc32_mod_exit);
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 5d5b993cbc2b..9c024e6d5e54 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -12,7 +12,9 @@ obj-$(CONFIG_PCI)	+= iomap-pci.o
 lib-$(CONFIG_GENERIC_CSUM)	:= $(filter-out csum_partial.o, $(lib-y))
 
 obj-$(CONFIG_CPU_GENERIC_DUMP_TLB) += dump_tlb.o
 obj-$(CONFIG_CPU_R3000)		+= r3k_dump_tlb.o
 
+obj-$(CONFIG_CRC32_ARCH)	+= crc32-mips.o
+
 # libgcc-style stuff needed in the kernel
 obj-y += bswapsi.o bswapdi.o multi3.o
diff --git a/arch/mips/lib/crc32-mips.c b/arch/mips/lib/crc32-mips.c
new file mode 100644
index 000000000000..083e5d693a16
--- /dev/null
+++ b/arch/mips/lib/crc32-mips.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * crc32-mips.c - CRC32 and CRC32C using optional MIPSr6 instructions
+ *
+ * Module based on arm64/crypto/crc32-arm.c
+ *
+ * Copyright (C) 2014 Linaro Ltd <yazen.ghannam at linaro.org>
+ * Copyright (C) 2018 MIPS Tech, LLC
+ */
+
+#include <linux/cpufeature.h>
+#include <linux/crc32.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/mipsregs.h>
+#include <linux/unaligned.h>
+
+enum crc_op_size {
+	b, h, w, d,
+};
+
+enum crc_type {
+	crc32,
+	crc32c,
+};
+
+#ifndef TOOLCHAIN_SUPPORTS_CRC
+#define _ASM_SET_CRC(OP, SZ, TYPE)					  \
+_ASM_MACRO_3R(OP, rt, rs, rt2,						  \
+	".ifnc	\\rt, \\rt2\n\t"					  \
+	".error	\"invalid operands \\\"" #OP " \\rt,\\rs,\\rt2\\\"\"\n\t" \
+	".endif\n\t"							  \
+	_ASM_INSN_IF_MIPS(0x7c00000f | (__rt << 16) | (__rs << 21) |	  \
+			  ((SZ) <<  6) | ((TYPE) << 8))			  \
+	_ASM_INSN32_IF_MM(0x00000030 | (__rs << 16) | (__rt << 21) |	  \
+			  ((SZ) << 14) | ((TYPE) << 3)))
+#define _ASM_UNSET_CRC(op, SZ, TYPE) ".purgem " #op "\n\t"
+#else /* !TOOLCHAIN_SUPPORTS_CRC */
+#define _ASM_SET_CRC(op, SZ, TYPE) ".set\tcrc\n\t"
+#define _ASM_UNSET_CRC(op, SZ, TYPE)
+#endif
+
+#define __CRC32(crc, value, op, SZ, TYPE)		\
+do {							\
+	__asm__ __volatile__(				\
+		".set	push\n\t"			\
+		_ASM_SET_CRC(op, SZ, TYPE)		\
+		#op "	%0, %1, %0\n\t"			\
+		_ASM_UNSET_CRC(op, SZ, TYPE)		\
+		".set	pop"				\
+		: "+r" (crc)				\
+		: "r" (value));				\
+} while (0)
+
+#define _CRC32_crc32b(crc, value)	__CRC32(crc, value, crc32b, 0, 0)
+#define _CRC32_crc32h(crc, value)	__CRC32(crc, value, crc32h, 1, 0)
+#define _CRC32_crc32w(crc, value)	__CRC32(crc, value, crc32w, 2, 0)
+#define _CRC32_crc32d(crc, value)	__CRC32(crc, value, crc32d, 3, 0)
+#define _CRC32_crc32cb(crc, value)	__CRC32(crc, value, crc32cb, 0, 1)
+#define _CRC32_crc32ch(crc, value)	__CRC32(crc, value, crc32ch, 1, 1)
+#define _CRC32_crc32cw(crc, value)	__CRC32(crc, value, crc32cw, 2, 1)
+#define _CRC32_crc32cd(crc, value)	__CRC32(crc, value, crc32cd, 3, 1)
+
+#define _CRC32(crc, value, size, op) \
+	_CRC32_##op##size(crc, value)
+
+#define CRC32(crc, value, size) \
+	_CRC32(crc, value, size, crc32)
+
+#define CRC32C(crc, value, size) \
+	_CRC32(crc, value, size, crc32c)
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32);
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (!static_branch_likely(&have_crc32))
+		return crc32_le_base(crc, p, len);
+
+	if (IS_ENABLED(CONFIG_64BIT)) {
+		for (; len >= sizeof(u64); p += sizeof(u64), len -= sizeof(u64)) {
+			u64 value = get_unaligned_le64(p);
+
+			CRC32(crc, value, d);
+		}
+
+		if (len & sizeof(u32)) {
+			u32 value = get_unaligned_le32(p);
+
+			CRC32(crc, value, w);
+			p += sizeof(u32);
+		}
+	} else {
+		for (; len >= sizeof(u32); len -= sizeof(u32)) {
+			u32 value = get_unaligned_le32(p);
+
+			CRC32(crc, value, w);
+			p += sizeof(u32);
+		}
+	}
+
+	if (len & sizeof(u16)) {
+		u16 value = get_unaligned_le16(p);
+
+		CRC32(crc, value, h);
+		p += sizeof(u16);
+	}
+
+	if (len & sizeof(u8)) {
+		u8 value = *p++;
+
+		CRC32(crc, value, b);
+	}
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (!static_branch_likely(&have_crc32))
+		return crc32c_le_base(crc, p, len);
+
+	if (IS_ENABLED(CONFIG_64BIT)) {
+		for (; len >= sizeof(u64); p += sizeof(u64), len -= sizeof(u64)) {
+			u64 value = get_unaligned_le64(p);
+
+			CRC32C(crc, value, d);
+		}
+
+		if (len & sizeof(u32)) {
+			u32 value = get_unaligned_le32(p);
+
+			CRC32C(crc, value, w);
+			p += sizeof(u32);
+		}
+	} else {
+		for (; len >= sizeof(u32); len -= sizeof(u32)) {
+			u32 value = get_unaligned_le32(p);
+
+			CRC32C(crc, value, w);
+			p += sizeof(u32);
+		}
+	}
+
+	if (len & sizeof(u16)) {
+		u16 value = get_unaligned_le16(p);
+
+		CRC32C(crc, value, h);
+		p += sizeof(u16);
+	}
+
+	if (len & sizeof(u8)) {
+		u8 value = *p++;
+
+		CRC32C(crc, value, b);
+	}
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_mips_init(void)
+{
+	if (cpu_have_feature(cpu_feature(MIPS_CRC32)))
+		static_branch_enable(&have_crc32);
+	return 0;
+}
+arch_initcall(crc32_mips_init);
+
+static void __exit crc32_mips_exit(void)
+{
+}
+module_exit(crc32_mips_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_crc32))
+		return CRC32_LE_OPTIMIZATION | CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Marcin Nowakowski <marcin.nowakowski at mips.com");
+MODULE_DESCRIPTION("CRC32 and CRC32C using optional MIPS instructions");
+MODULE_LICENSE("GPL v2");
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:42 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:42 -0800
Subject: [PATCH v3 06/18] loongarch/crc32: expose CRC32 functions through lib
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-7-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the loongarch CRC32 assembly code into the lib directory and wire
it up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/loongarch/crypto/crc32-loongarch.c to
arch/loongarch/lib/crc32-loongarch.c, view this commit with
'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/loongarch/Kconfig                     |   1 +
 arch/loongarch/configs/loongson3_defconfig |   1 -
 arch/loongarch/crypto/Kconfig              |   9 -
 arch/loongarch/crypto/Makefile             |   2 -
 arch/loongarch/crypto/crc32-loongarch.c    | 300 ---------------------
 arch/loongarch/lib/Makefile                |   2 +
 arch/loongarch/lib/crc32-loongarch.c       | 135 ++++++++++
 7 files changed, 138 insertions(+), 312 deletions(-)
 delete mode 100644 arch/loongarch/crypto/crc32-loongarch.c
 create mode 100644 arch/loongarch/lib/crc32-loongarch.c

diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index bb35c34f86d2..455f1af0bf88 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -13,10 +13,11 @@ config LOONGARCH
 	select ARCH_ENABLE_MEMORY_HOTPLUG
 	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
 	select ARCH_HAS_ACPI_TABLE_UPGRADE	if ACPI
 	select ARCH_HAS_CPU_FINALIZE_INIT
+	select ARCH_HAS_CRC32
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_FAST_MULTIPLIER
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_KCOV
diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig
index 75b366407a60..0487ac21b38b 100644
--- a/arch/loongarch/configs/loongson3_defconfig
+++ b/arch/loongarch/configs/loongson3_defconfig
@@ -967,11 +967,10 @@ CONFIG_CRYPTO_LZ4=m
 CONFIG_CRYPTO_LZ4HC=m
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_CRC32_LOONGARCH=m
 CONFIG_CRYPTO_DEV_VIRTIO=m
 CONFIG_DMA_CMA=y
 CONFIG_DMA_NUMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=0
 CONFIG_PRINTK_TIME=y
diff --git a/arch/loongarch/crypto/Kconfig b/arch/loongarch/crypto/Kconfig
index 200a6e8b43b1..a0270b3e5b30 100644
--- a/arch/loongarch/crypto/Kconfig
+++ b/arch/loongarch/crypto/Kconfig
@@ -1,14 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
 menu "Accelerated Cryptographic Algorithms for CPU (loongarch)"
 
-config CRYPTO_CRC32_LOONGARCH
-	tristate "CRC32c and CRC32"
-	select CRC32
-	select CRYPTO_HASH
-	help
-	  CRC32c and CRC32 CRC algorithms
-
-	  Architecture: LoongArch with CRC32 instructions
-
 endmenu
diff --git a/arch/loongarch/crypto/Makefile b/arch/loongarch/crypto/Makefile
index d22613d27ce9..ba83755dde2b 100644
--- a/arch/loongarch/crypto/Makefile
+++ b/arch/loongarch/crypto/Makefile
@@ -1,6 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 #
 # Makefile for LoongArch crypto files..
 #
-
-obj-$(CONFIG_CRYPTO_CRC32_LOONGARCH) += crc32-loongarch.o
diff --git a/arch/loongarch/crypto/crc32-loongarch.c b/arch/loongarch/crypto/crc32-loongarch.c
deleted file mode 100644
index b7d9782827f5..000000000000
--- a/arch/loongarch/crypto/crc32-loongarch.c
+++ /dev/null
@@ -1,300 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * crc32.c - CRC32 and CRC32C using LoongArch crc* instructions
- *
- * Module based on mips/crypto/crc32-mips.c
- *
- * Copyright (C) 2014 Linaro Ltd <yazen.ghannam at linaro.org>
- * Copyright (C) 2018 MIPS Tech, LLC
- * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
- */
-
-#include <linux/module.h>
-#include <crypto/internal/hash.h>
-
-#include <asm/cpu-features.h>
-#include <linux/unaligned.h>
-
-#define _CRC32(crc, value, size, type)			\
-do {							\
-	__asm__ __volatile__(				\
-		#type ".w." #size ".w" " %0, %1, %0\n\t"\
-		: "+r" (crc)				\
-		: "r" (value)				\
-		: "memory");				\
-} while (0)
-
-#define CRC32(crc, value, size)		_CRC32(crc, value, size, crc)
-#define CRC32C(crc, value, size)	_CRC32(crc, value, size, crcc)
-
-static u32 crc32_loongarch_hw(u32 crc_, const u8 *p, unsigned int len)
-{
-	u32 crc = crc_;
-
-	while (len >= sizeof(u64)) {
-		u64 value = get_unaligned_le64(p);
-
-		CRC32(crc, value, d);
-		p += sizeof(u64);
-		len -= sizeof(u64);
-	}
-
-	if (len & sizeof(u32)) {
-		u32 value = get_unaligned_le32(p);
-
-		CRC32(crc, value, w);
-		p += sizeof(u32);
-	}
-
-	if (len & sizeof(u16)) {
-		u16 value = get_unaligned_le16(p);
-
-		CRC32(crc, value, h);
-		p += sizeof(u16);
-	}
-
-	if (len & sizeof(u8)) {
-		u8 value = *p++;
-
-		CRC32(crc, value, b);
-	}
-
-	return crc;
-}
-
-static u32 crc32c_loongarch_hw(u32 crc_, const u8 *p, unsigned int len)
-{
-	u32 crc = crc_;
-
-	while (len >= sizeof(u64)) {
-		u64 value = get_unaligned_le64(p);
-
-		CRC32C(crc, value, d);
-		p += sizeof(u64);
-		len -= sizeof(u64);
-	}
-
-	if (len & sizeof(u32)) {
-		u32 value = get_unaligned_le32(p);
-
-		CRC32C(crc, value, w);
-		p += sizeof(u32);
-	}
-
-	if (len & sizeof(u16)) {
-		u16 value = get_unaligned_le16(p);
-
-		CRC32C(crc, value, h);
-		p += sizeof(u16);
-	}
-
-	if (len & sizeof(u8)) {
-		u8 value = *p++;
-
-		CRC32C(crc, value, b);
-	}
-
-	return crc;
-}
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-struct chksum_ctx {
-	u32 key;
-};
-
-struct chksum_desc_ctx {
-	u32 crc;
-};
-
-static int chksum_init(struct shash_desc *desc)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = mctx->key;
-
-	return 0;
-}
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set the seed.
- */
-static int chksum_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
-
-	if (keylen != sizeof(mctx->key))
-		return -EINVAL;
-
-	mctx->key = get_unaligned_le32(key);
-
-	return 0;
-}
-
-static int chksum_update(struct shash_desc *desc, const u8 *data, unsigned int length)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = crc32_loongarch_hw(ctx->crc, data, length);
-	return 0;
-}
-
-static int chksumc_update(struct shash_desc *desc, const u8 *data, unsigned int length)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = crc32c_loongarch_hw(ctx->crc, data, length);
-	return 0;
-}
-
-static int chksum_final(struct shash_desc *desc, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	put_unaligned_le32(ctx->crc, out);
-	return 0;
-}
-
-static int chksumc_final(struct shash_desc *desc, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	put_unaligned_le32(~ctx->crc, out);
-	return 0;
-}
-
-static int __chksum_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
-{
-	put_unaligned_le32(crc32_loongarch_hw(crc, data, len), out);
-	return 0;
-}
-
-static int __chksumc_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
-{
-	put_unaligned_le32(~crc32c_loongarch_hw(crc, data, len), out);
-	return 0;
-}
-
-static int chksum_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	return __chksum_finup(ctx->crc, data, len, out);
-}
-
-static int chksumc_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
-{
-	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	return __chksumc_finup(ctx->crc, data, len, out);
-}
-
-static int chksum_digest(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-
-	return __chksum_finup(mctx->key, data, length, out);
-}
-
-static int chksumc_digest(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out)
-{
-	struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
-
-	return __chksumc_finup(mctx->key, data, length, out);
-}
-
-static int chksum_cra_init(struct crypto_tfm *tfm)
-{
-	struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = 0;
-	return 0;
-}
-
-static int chksumc_cra_init(struct crypto_tfm *tfm)
-{
-	struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = ~0;
-	return 0;
-}
-
-static struct shash_alg crc32_alg = {
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.setkey			=	chksum_setkey,
-	.init			=	chksum_init,
-	.update			=	chksum_update,
-	.final			=	chksum_final,
-	.finup			=	chksum_finup,
-	.digest			=	chksum_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crc32",
-		.cra_driver_name	=	"crc32-loongarch",
-		.cra_priority		=	300,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(struct chksum_ctx),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	chksum_cra_init,
-	}
-};
-
-static struct shash_alg crc32c_alg = {
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.setkey			=	chksum_setkey,
-	.init			=	chksum_init,
-	.update			=	chksumc_update,
-	.final			=	chksumc_final,
-	.finup			=	chksumc_finup,
-	.digest			=	chksumc_digest,
-	.descsize		=	sizeof(struct chksum_desc_ctx),
-	.base			=	{
-		.cra_name		=	"crc32c",
-		.cra_driver_name	=	"crc32c-loongarch",
-		.cra_priority		=	300,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(struct chksum_ctx),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	chksumc_cra_init,
-	}
-};
-
-static int __init crc32_mod_init(void)
-{
-	int err;
-
-	if (!cpu_has(CPU_FEATURE_CRC32))
-		return 0;
-
-	err = crypto_register_shash(&crc32_alg);
-	if (err)
-		return err;
-
-	err = crypto_register_shash(&crc32c_alg);
-	if (err)
-		return err;
-
-	return 0;
-}
-
-static void __exit crc32_mod_exit(void)
-{
-	if (!cpu_has(CPU_FEATURE_CRC32))
-		return;
-
-	crypto_unregister_shash(&crc32_alg);
-	crypto_unregister_shash(&crc32c_alg);
-}
-
-module_init(crc32_mod_init);
-module_exit(crc32_mod_exit);
-
-MODULE_AUTHOR("Min Zhou <zhoumin at loongson.cn>");
-MODULE_AUTHOR("Huacai Chen <chenhuacai at loongson.cn>");
-MODULE_DESCRIPTION("CRC32 and CRC32C using LoongArch crc* instructions");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
index ccea3bbd4353..fae77809048b 100644
--- a/arch/loongarch/lib/Makefile
+++ b/arch/loongarch/lib/Makefile
@@ -9,5 +9,7 @@ lib-y	+= delay.o memset.o memcpy.o memmove.o \
 obj-$(CONFIG_ARCH_SUPPORTS_INT128) += tishift.o
 
 obj-$(CONFIG_CPU_HAS_LSX) += xor_simd.o xor_simd_glue.o
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
+
+obj-$(CONFIG_CRC32_ARCH) += crc32-loongarch.o
diff --git a/arch/loongarch/lib/crc32-loongarch.c b/arch/loongarch/lib/crc32-loongarch.c
new file mode 100644
index 000000000000..ce862e398eb3
--- /dev/null
+++ b/arch/loongarch/lib/crc32-loongarch.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CRC32 and CRC32C using LoongArch crc* instructions
+ *
+ * Module based on mips/crypto/crc32-mips.c
+ *
+ * Copyright (C) 2014 Linaro Ltd <yazen.ghannam at linaro.org>
+ * Copyright (C) 2018 MIPS Tech, LLC
+ * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
+ */
+
+#include <asm/cpu-features.h>
+#include <linux/crc32.h>
+#include <linux/module.h>
+#include <linux/unaligned.h>
+
+#define _CRC32(crc, value, size, type)			\
+do {							\
+	__asm__ __volatile__(				\
+		#type ".w." #size ".w" " %0, %1, %0\n\t"\
+		: "+r" (crc)				\
+		: "r" (value)				\
+		: "memory");				\
+} while (0)
+
+#define CRC32(crc, value, size)		_CRC32(crc, value, size, crc)
+#define CRC32C(crc, value, size)	_CRC32(crc, value, size, crcc)
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32);
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (!static_branch_likely(&have_crc32))
+		return crc32_le_base(crc, p, len);
+
+	while (len >= sizeof(u64)) {
+		u64 value = get_unaligned_le64(p);
+
+		CRC32(crc, value, d);
+		p += sizeof(u64);
+		len -= sizeof(u64);
+	}
+
+	if (len & sizeof(u32)) {
+		u32 value = get_unaligned_le32(p);
+
+		CRC32(crc, value, w);
+		p += sizeof(u32);
+	}
+
+	if (len & sizeof(u16)) {
+		u16 value = get_unaligned_le16(p);
+
+		CRC32(crc, value, h);
+		p += sizeof(u16);
+	}
+
+	if (len & sizeof(u8)) {
+		u8 value = *p++;
+
+		CRC32(crc, value, b);
+	}
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (!static_branch_likely(&have_crc32))
+		return crc32c_le_base(crc, p, len);
+
+	while (len >= sizeof(u64)) {
+		u64 value = get_unaligned_le64(p);
+
+		CRC32C(crc, value, d);
+		p += sizeof(u64);
+		len -= sizeof(u64);
+	}
+
+	if (len & sizeof(u32)) {
+		u32 value = get_unaligned_le32(p);
+
+		CRC32C(crc, value, w);
+		p += sizeof(u32);
+	}
+
+	if (len & sizeof(u16)) {
+		u16 value = get_unaligned_le16(p);
+
+		CRC32C(crc, value, h);
+		p += sizeof(u16);
+	}
+
+	if (len & sizeof(u8)) {
+		u8 value = *p++;
+
+		CRC32C(crc, value, b);
+	}
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_loongarch_init(void)
+{
+	if (cpu_has(CPU_FEATURE_CRC32))
+		static_branch_enable(&have_crc32);
+	return 0;
+}
+arch_initcall(crc32_loongarch_init);
+
+static void __exit crc32_loongarch_exit(void)
+{
+}
+module_exit(crc32_loongarch_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_crc32))
+		return CRC32_LE_OPTIMIZATION | CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Min Zhou <zhoumin at loongson.cn>");
+MODULE_AUTHOR("Huacai Chen <chenhuacai at loongson.cn>");
+MODULE_DESCRIPTION("CRC32 and CRC32C using LoongArch crc* instructions");
+MODULE_LICENSE("GPL v2");
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:45 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:45 -0800
Subject: [PATCH v3 09/18] s390/crc32: expose CRC32 functions through lib
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-10-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the s390 CRC32 assembly code into the lib directory and wire it up
to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/s390/crypto/crc32-vx.c to
arch/s390/lib/crc32-glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/s390/Kconfig                      |   1 +
 arch/s390/configs/debug_defconfig      |   1 -
 arch/s390/configs/defconfig            |   1 -
 arch/s390/crypto/Kconfig               |  12 -
 arch/s390/crypto/Makefile              |   2 -
 arch/s390/crypto/crc32-vx.c            | 306 -------------------------
 arch/s390/lib/Makefile                 |   3 +
 arch/s390/lib/crc32-glue.c             |  92 ++++++++
 arch/s390/{crypto => lib}/crc32-vx.h   |   0
 arch/s390/{crypto => lib}/crc32be-vx.c |   0
 arch/s390/{crypto => lib}/crc32le-vx.c |   0
 11 files changed, 96 insertions(+), 322 deletions(-)
 delete mode 100644 arch/s390/crypto/crc32-vx.c
 create mode 100644 arch/s390/lib/crc32-glue.c
 rename arch/s390/{crypto => lib}/crc32-vx.h (100%)
 rename arch/s390/{crypto => lib}/crc32be-vx.c (100%)
 rename arch/s390/{crypto => lib}/crc32le-vx.c (100%)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index d339fe4fdedf..d1fde8b941d2 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -63,10 +63,11 @@ config S390
 	select ARCH_BINFMT_ELF_STATE
 	select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
 	select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM
 	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
+	select ARCH_HAS_CRC32
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEBUG_WX
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index fb0e9a1d9be2..fd83d8958f0b 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -792,11 +792,10 @@ CONFIG_CRYPTO_ZSTD=m
 CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_CRC32_S390=y
 CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_SHA1_S390=m
 CONFIG_CRYPTO_SHA256_S390=m
 CONFIG_CRYPTO_SHA3_256_S390=m
 CONFIG_CRYPTO_SHA3_512_S390=m
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index 88be0a734b60..3bdeb6d5cbd9 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -779,11 +779,10 @@ CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_JITTERENTROPY_OSR=1
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_CRYPTO_CRC32_S390=y
 CONFIG_CRYPTO_SHA512_S390=m
 CONFIG_CRYPTO_SHA1_S390=m
 CONFIG_CRYPTO_SHA256_S390=m
 CONFIG_CRYPTO_SHA3_256_S390=m
 CONFIG_CRYPTO_SHA3_512_S390=m
diff --git a/arch/s390/crypto/Kconfig b/arch/s390/crypto/Kconfig
index d3eb3a233693..b760232537f1 100644
--- a/arch/s390/crypto/Kconfig
+++ b/arch/s390/crypto/Kconfig
@@ -1,21 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 
 menu "Accelerated Cryptographic Algorithms for CPU (s390)"
 
-config CRYPTO_CRC32_S390
-	tristate "CRC32c and CRC32"
-	depends on S390
-	select CRYPTO_HASH
-	select CRC32
-	help
-	  CRC32c and CRC32 CRC algorithms
-
-	  Architecture: s390
-
-	  It is available with IBM z13 or later.
-
 config CRYPTO_SHA512_S390
 	tristate "Hash functions: SHA-384 and SHA-512"
 	depends on S390
 	select CRYPTO_HASH
 	help
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile
index a0cb96937c3d..14dafadbcbed 100644
--- a/arch/s390/crypto/Makefile
+++ b/arch/s390/crypto/Makefile
@@ -12,11 +12,9 @@ obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o
 obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
 obj-$(CONFIG_CRYPTO_PAES_S390) += paes_s390.o
 obj-$(CONFIG_CRYPTO_CHACHA_S390) += chacha_s390.o
 obj-$(CONFIG_S390_PRNG) += prng.o
 obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o
-obj-$(CONFIG_CRYPTO_CRC32_S390) += crc32-vx_s390.o
 obj-$(CONFIG_CRYPTO_HMAC_S390) += hmac_s390.o
 obj-y += arch_random.o
 
-crc32-vx_s390-y := crc32-vx.o crc32le-vx.o crc32be-vx.o
 chacha_s390-y := chacha-glue.o chacha-s390.o
diff --git a/arch/s390/crypto/crc32-vx.c b/arch/s390/crypto/crc32-vx.c
deleted file mode 100644
index 89a10337e6ea..000000000000
--- a/arch/s390/crypto/crc32-vx.c
+++ /dev/null
@@ -1,306 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Crypto-API module for CRC-32 algorithms implemented with the
- * z/Architecture Vector Extension Facility.
- *
- * Copyright IBM Corp. 2015
- * Author(s): Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
- */
-#define KMSG_COMPONENT	"crc32-vx"
-#define pr_fmt(fmt)	KMSG_COMPONENT ": " fmt
-
-#include <linux/module.h>
-#include <linux/cpufeature.h>
-#include <linux/crc32.h>
-#include <crypto/internal/hash.h>
-#include <asm/fpu.h>
-#include "crc32-vx.h"
-
-#define CRC32_BLOCK_SIZE	1
-#define CRC32_DIGEST_SIZE	4
-
-#define VX_MIN_LEN		64
-#define VX_ALIGNMENT		16L
-#define VX_ALIGN_MASK		(VX_ALIGNMENT - 1)
-
-struct crc_ctx {
-	u32 key;
-};
-
-struct crc_desc_ctx {
-	u32 crc;
-};
-
-/*
- * DEFINE_CRC32_VX() - Define a CRC-32 function using the vector extension
- *
- * Creates a function to perform a particular CRC-32 computation. Depending
- * on the message buffer, the hardware-accelerated or software implementation
- * is used.   Note that the message buffer is aligned to improve fetch
- * operations of VECTOR LOAD MULTIPLE instructions.
- *
- */
-#define DEFINE_CRC32_VX(___fname, ___crc32_vx, ___crc32_sw)		    \
-	static u32 __pure ___fname(u32 crc,				    \
-				unsigned char const *data, size_t datalen)  \
-	{								    \
-		unsigned long prealign, aligned, remaining;		    \
-		DECLARE_KERNEL_FPU_ONSTACK16(vxstate);			    \
-									    \
-		if (datalen < VX_MIN_LEN + VX_ALIGN_MASK)		    \
-			return ___crc32_sw(crc, data, datalen);		    \
-									    \
-		if ((unsigned long)data & VX_ALIGN_MASK) {		    \
-			prealign = VX_ALIGNMENT -			    \
-				  ((unsigned long)data & VX_ALIGN_MASK);    \
-			datalen -= prealign;				    \
-			crc = ___crc32_sw(crc, data, prealign);		    \
-			data = (void *)((unsigned long)data + prealign);    \
-		}							    \
-									    \
-		aligned = datalen & ~VX_ALIGN_MASK;			    \
-		remaining = datalen & VX_ALIGN_MASK;			    \
-									    \
-		kernel_fpu_begin(&vxstate, KERNEL_VXR_LOW);		    \
-		crc = ___crc32_vx(crc, data, aligned);			    \
-		kernel_fpu_end(&vxstate, KERNEL_VXR_LOW);		    \
-									    \
-		if (remaining)						    \
-			crc = ___crc32_sw(crc, data + aligned, remaining);  \
-									    \
-		return crc;						    \
-	}
-
-DEFINE_CRC32_VX(crc32_le_vx, crc32_le_vgfm_16, crc32_le)
-DEFINE_CRC32_VX(crc32_be_vx, crc32_be_vgfm_16, crc32_be)
-DEFINE_CRC32_VX(crc32c_le_vx, crc32c_le_vgfm_16, __crc32c_le)
-
-
-static int crc32_vx_cra_init_zero(struct crypto_tfm *tfm)
-{
-	struct crc_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = 0;
-	return 0;
-}
-
-static int crc32_vx_cra_init_invert(struct crypto_tfm *tfm)
-{
-	struct crc_ctx *mctx = crypto_tfm_ctx(tfm);
-
-	mctx->key = ~0;
-	return 0;
-}
-
-static int crc32_vx_init(struct shash_desc *desc)
-{
-	struct crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
-	struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	ctx->crc = mctx->key;
-	return 0;
-}
-
-static int crc32_vx_setkey(struct crypto_shash *tfm, const u8 *newkey,
-			   unsigned int newkeylen)
-{
-	struct crc_ctx *mctx = crypto_shash_ctx(tfm);
-
-	if (newkeylen != sizeof(mctx->key))
-		return -EINVAL;
-	mctx->key = le32_to_cpu(*(__le32 *)newkey);
-	return 0;
-}
-
-static int crc32be_vx_setkey(struct crypto_shash *tfm, const u8 *newkey,
-			     unsigned int newkeylen)
-{
-	struct crc_ctx *mctx = crypto_shash_ctx(tfm);
-
-	if (newkeylen != sizeof(mctx->key))
-		return -EINVAL;
-	mctx->key = be32_to_cpu(*(__be32 *)newkey);
-	return 0;
-}
-
-static int crc32le_vx_final(struct shash_desc *desc, u8 *out)
-{
-	struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	*(__le32 *)out = cpu_to_le32p(&ctx->crc);
-	return 0;
-}
-
-static int crc32be_vx_final(struct shash_desc *desc, u8 *out)
-{
-	struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	*(__be32 *)out = cpu_to_be32p(&ctx->crc);
-	return 0;
-}
-
-static int crc32c_vx_final(struct shash_desc *desc, u8 *out)
-{
-	struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
-
-	/*
-	 * Perform a final XOR with 0xFFFFFFFF to be in sync
-	 * with the generic crc32c shash implementation.
-	 */
-	*(__le32 *)out = ~cpu_to_le32p(&ctx->crc);
-	return 0;
-}
-
-static int __crc32le_vx_finup(u32 *crc, const u8 *data, unsigned int len,
-			      u8 *out)
-{
-	*(__le32 *)out = cpu_to_le32(crc32_le_vx(*crc, data, len));
-	return 0;
-}
-
-static int __crc32be_vx_finup(u32 *crc, const u8 *data, unsigned int len,
-			      u8 *out)
-{
-	*(__be32 *)out = cpu_to_be32(crc32_be_vx(*crc, data, len));
-	return 0;
-}
-
-static int __crc32c_vx_finup(u32 *crc, const u8 *data, unsigned int len,
-			     u8 *out)
-{
-	/*
-	 * Perform a final XOR with 0xFFFFFFFF to be in sync
-	 * with the generic crc32c shash implementation.
-	 */
-	*(__le32 *)out = ~cpu_to_le32(crc32c_le_vx(*crc, data, len));
-	return 0;
-}
-
-
-#define CRC32_VX_FINUP(alg, func)					      \
-	static int alg ## _vx_finup(struct shash_desc *desc, const u8 *data,  \
-				   unsigned int datalen, u8 *out)	      \
-	{								      \
-		return __ ## alg ## _vx_finup(shash_desc_ctx(desc),	      \
-					      data, datalen, out);	      \
-	}
-
-CRC32_VX_FINUP(crc32le, crc32_le_vx)
-CRC32_VX_FINUP(crc32be, crc32_be_vx)
-CRC32_VX_FINUP(crc32c, crc32c_le_vx)
-
-#define CRC32_VX_DIGEST(alg, func)					      \
-	static int alg ## _vx_digest(struct shash_desc *desc, const u8 *data, \
-				     unsigned int len, u8 *out)		      \
-	{								      \
-		return __ ## alg ## _vx_finup(crypto_shash_ctx(desc->tfm),    \
-					      data, len, out);		      \
-	}
-
-CRC32_VX_DIGEST(crc32le, crc32_le_vx)
-CRC32_VX_DIGEST(crc32be, crc32_be_vx)
-CRC32_VX_DIGEST(crc32c, crc32c_le_vx)
-
-#define CRC32_VX_UPDATE(alg, func)					      \
-	static int alg ## _vx_update(struct shash_desc *desc, const u8 *data, \
-				     unsigned int datalen)		      \
-	{								      \
-		struct crc_desc_ctx *ctx = shash_desc_ctx(desc);	      \
-		ctx->crc = func(ctx->crc, data, datalen);		      \
-		return 0;						      \
-	}
-
-CRC32_VX_UPDATE(crc32le, crc32_le_vx)
-CRC32_VX_UPDATE(crc32be, crc32_be_vx)
-CRC32_VX_UPDATE(crc32c, crc32c_le_vx)
-
-
-static struct shash_alg crc32_vx_algs[] = {
-	/* CRC-32 LE */
-	{
-		.init		=	crc32_vx_init,
-		.setkey		=	crc32_vx_setkey,
-		.update		=	crc32le_vx_update,
-		.final		=	crc32le_vx_final,
-		.finup		=	crc32le_vx_finup,
-		.digest		=	crc32le_vx_digest,
-		.descsize	=	sizeof(struct crc_desc_ctx),
-		.digestsize	=	CRC32_DIGEST_SIZE,
-		.base		=	{
-			.cra_name	 = "crc32",
-			.cra_driver_name = "crc32-vx",
-			.cra_priority	 = 200,
-			.cra_flags	 = CRYPTO_ALG_OPTIONAL_KEY,
-			.cra_blocksize	 = CRC32_BLOCK_SIZE,
-			.cra_ctxsize	 = sizeof(struct crc_ctx),
-			.cra_module	 = THIS_MODULE,
-			.cra_init	 = crc32_vx_cra_init_zero,
-		},
-	},
-	/* CRC-32 BE */
-	{
-		.init		=	crc32_vx_init,
-		.setkey		=	crc32be_vx_setkey,
-		.update		=	crc32be_vx_update,
-		.final		=	crc32be_vx_final,
-		.finup		=	crc32be_vx_finup,
-		.digest		=	crc32be_vx_digest,
-		.descsize	=	sizeof(struct crc_desc_ctx),
-		.digestsize	=	CRC32_DIGEST_SIZE,
-		.base		=	{
-			.cra_name	 = "crc32be",
-			.cra_driver_name = "crc32be-vx",
-			.cra_priority	 = 200,
-			.cra_flags	 = CRYPTO_ALG_OPTIONAL_KEY,
-			.cra_blocksize	 = CRC32_BLOCK_SIZE,
-			.cra_ctxsize	 = sizeof(struct crc_ctx),
-			.cra_module	 = THIS_MODULE,
-			.cra_init	 = crc32_vx_cra_init_zero,
-		},
-	},
-	/* CRC-32C LE */
-	{
-		.init		=	crc32_vx_init,
-		.setkey		=	crc32_vx_setkey,
-		.update		=	crc32c_vx_update,
-		.final		=	crc32c_vx_final,
-		.finup		=	crc32c_vx_finup,
-		.digest		=	crc32c_vx_digest,
-		.descsize	=	sizeof(struct crc_desc_ctx),
-		.digestsize	=	CRC32_DIGEST_SIZE,
-		.base		=	{
-			.cra_name	 = "crc32c",
-			.cra_driver_name = "crc32c-vx",
-			.cra_priority	 = 200,
-			.cra_flags	 = CRYPTO_ALG_OPTIONAL_KEY,
-			.cra_blocksize	 = CRC32_BLOCK_SIZE,
-			.cra_ctxsize	 = sizeof(struct crc_ctx),
-			.cra_module	 = THIS_MODULE,
-			.cra_init	 = crc32_vx_cra_init_invert,
-		},
-	},
-};
-
-
-static int __init crc_vx_mod_init(void)
-{
-	return crypto_register_shashes(crc32_vx_algs,
-				       ARRAY_SIZE(crc32_vx_algs));
-}
-
-static void __exit crc_vx_mod_exit(void)
-{
-	crypto_unregister_shashes(crc32_vx_algs, ARRAY_SIZE(crc32_vx_algs));
-}
-
-module_cpu_feature_match(S390_CPU_FEATURE_VXRS, crc_vx_mod_init);
-module_exit(crc_vx_mod_exit);
-
-MODULE_AUTHOR("Hendrik Brueckner <brueckner at linux.vnet.ibm.com>");
-MODULE_DESCRIPTION("CRC-32 algorithms using z/Architecture Vector Extension Facility");
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS_CRYPTO("crc32");
-MODULE_ALIAS_CRYPTO("crc32-vx");
-MODULE_ALIAS_CRYPTO("crc32c");
-MODULE_ALIAS_CRYPTO("crc32c-vx");
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index f43f897d3fc0..14bbfe50033c 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -22,5 +22,8 @@ obj-$(CONFIG_S390_MODULES_SANITY_TEST) += test_modules.o
 obj-$(CONFIG_S390_MODULES_SANITY_TEST_HELPERS) += test_modules_helpers.o
 
 lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 
 obj-$(CONFIG_EXPOLINE_EXTERN) += expoline.o
+
+obj-$(CONFIG_CRC32_ARCH) += crc32-s390.o
+crc32-s390-y := crc32-glue.o crc32le-vx.o crc32be-vx.o
diff --git a/arch/s390/lib/crc32-glue.c b/arch/s390/lib/crc32-glue.c
new file mode 100644
index 000000000000..137080e61f90
--- /dev/null
+++ b/arch/s390/lib/crc32-glue.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CRC-32 implemented with the z/Architecture Vector Extension Facility.
+ *
+ * Copyright IBM Corp. 2015
+ * Author(s): Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
+ */
+#define KMSG_COMPONENT	"crc32-vx"
+#define pr_fmt(fmt)	KMSG_COMPONENT ": " fmt
+
+#include <linux/module.h>
+#include <linux/cpufeature.h>
+#include <linux/crc32.h>
+#include <asm/fpu.h>
+#include "crc32-vx.h"
+
+#define VX_MIN_LEN		64
+#define VX_ALIGNMENT		16L
+#define VX_ALIGN_MASK		(VX_ALIGNMENT - 1)
+
+static DEFINE_STATIC_KEY_FALSE(have_vxrs);
+
+/*
+ * DEFINE_CRC32_VX() - Define a CRC-32 function using the vector extension
+ *
+ * Creates a function to perform a particular CRC-32 computation. Depending
+ * on the message buffer, the hardware-accelerated or software implementation
+ * is used.   Note that the message buffer is aligned to improve fetch
+ * operations of VECTOR LOAD MULTIPLE instructions.
+ */
+#define DEFINE_CRC32_VX(___fname, ___crc32_vx, ___crc32_sw)		    \
+	u32 ___fname(u32 crc, const u8 *data, size_t datalen)		    \
+	{								    \
+		unsigned long prealign, aligned, remaining;		    \
+		DECLARE_KERNEL_FPU_ONSTACK16(vxstate);			    \
+									    \
+		if (datalen < VX_MIN_LEN + VX_ALIGN_MASK ||		    \
+		    !static_branch_likely(&have_vxrs))			    \
+			return ___crc32_sw(crc, data, datalen);		    \
+									    \
+		if ((unsigned long)data & VX_ALIGN_MASK) {		    \
+			prealign = VX_ALIGNMENT -			    \
+				  ((unsigned long)data & VX_ALIGN_MASK);    \
+			datalen -= prealign;				    \
+			crc = ___crc32_sw(crc, data, prealign);		    \
+			data = (void *)((unsigned long)data + prealign);    \
+		}							    \
+									    \
+		aligned = datalen & ~VX_ALIGN_MASK;			    \
+		remaining = datalen & VX_ALIGN_MASK;			    \
+									    \
+		kernel_fpu_begin(&vxstate, KERNEL_VXR_LOW);		    \
+		crc = ___crc32_vx(crc, data, aligned);			    \
+		kernel_fpu_end(&vxstate, KERNEL_VXR_LOW);		    \
+									    \
+		if (remaining)						    \
+			crc = ___crc32_sw(crc, data + aligned, remaining);  \
+									    \
+		return crc;						    \
+	}								    \
+	EXPORT_SYMBOL(___fname);
+
+DEFINE_CRC32_VX(crc32_le_arch, crc32_le_vgfm_16, crc32_le_base)
+DEFINE_CRC32_VX(crc32_be_arch, crc32_be_vgfm_16, crc32_be_base)
+DEFINE_CRC32_VX(crc32c_le_arch, crc32c_le_vgfm_16, crc32c_le_base)
+
+static int __init crc32_s390_init(void)
+{
+	if (cpu_have_feature(S390_CPU_FEATURE_VXRS))
+		static_branch_enable(&have_vxrs);
+	return 0;
+}
+arch_initcall(crc32_s390_init);
+
+static void __exit crc32_s390_exit(void)
+{
+}
+module_exit(crc32_s390_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_vxrs))
+		return CRC32_LE_OPTIMIZATION |
+		       CRC32_BE_OPTIMIZATION |
+		       CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Hendrik Brueckner <brueckner at linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("CRC-32 algorithms using z/Architecture Vector Extension Facility");
+MODULE_LICENSE("GPL");
diff --git a/arch/s390/crypto/crc32-vx.h b/arch/s390/lib/crc32-vx.h
similarity index 100%
rename from arch/s390/crypto/crc32-vx.h
rename to arch/s390/lib/crc32-vx.h
diff --git a/arch/s390/crypto/crc32be-vx.c b/arch/s390/lib/crc32be-vx.c
similarity index 100%
rename from arch/s390/crypto/crc32be-vx.c
rename to arch/s390/lib/crc32be-vx.c
diff --git a/arch/s390/crypto/crc32le-vx.c b/arch/s390/lib/crc32le-vx.c
similarity index 100%
rename from arch/s390/crypto/crc32le-vx.c
rename to arch/s390/lib/crc32le-vx.c
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:46 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:46 -0800
Subject: [PATCH v3 10/18] sparc/crc32: expose CRC32 functions through lib
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-11-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the sparc CRC32C assembly code into the lib directory and wire it
up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/sparc/crypto/crc32c_glue.c to
arch/sparc/lib/crc32_glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/sparc/Kconfig                      |   1 +
 arch/sparc/crypto/Kconfig               |  10 --
 arch/sparc/crypto/Makefile              |   4 -
 arch/sparc/crypto/crc32c_glue.c         | 184 ------------------------
 arch/sparc/lib/Makefile                 |   2 +
 arch/sparc/lib/crc32_glue.c             |  93 ++++++++++++
 arch/sparc/{crypto => lib}/crc32c_asm.S |   2 +-
 7 files changed, 97 insertions(+), 199 deletions(-)
 delete mode 100644 arch/sparc/crypto/crc32c_glue.c
 create mode 100644 arch/sparc/lib/crc32_glue.c
 rename arch/sparc/{crypto => lib}/crc32c_asm.S (92%)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index dcfdb7f1dae9..0f88123925a4 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -108,10 +108,11 @@ config SPARC64
 	select ARCH_HAS_GIGANTIC_PAGE
 	select HAVE_SOFTIRQ_ON_OWN_STACK
 	select HAVE_SETUP_PER_CPU_AREA
 	select NEED_PER_CPU_EMBED_FIRST_CHUNK
 	select NEED_PER_CPU_PAGE_FIRST_CHUNK
+	select ARCH_HAS_CRC32
 
 config ARCH_PROC_KCORE_TEXT
 	def_bool y
 
 config CPU_BIG_ENDIAN
diff --git a/arch/sparc/crypto/Kconfig b/arch/sparc/crypto/Kconfig
index cfe5102b1c68..e858597de89d 100644
--- a/arch/sparc/crypto/Kconfig
+++ b/arch/sparc/crypto/Kconfig
@@ -14,20 +14,10 @@ config CRYPTO_DES_SPARC64
 	  Length-preserving ciphers: DES with ECB and CBC modes
 	  Length-preserving ciphers: Tripe DES EDE with ECB and CBC modes
 
 	  Architecture: sparc64
 
-config CRYPTO_CRC32C_SPARC64
-	tristate "CRC32c"
-	depends on SPARC64
-	select CRYPTO_HASH
-	select CRC32
-	help
-	  CRC32c CRC algorithm with the iSCSI polynomial (RFC 3385 and RFC 3720)
-
-	  Architecture: sparc64
-
 config CRYPTO_MD5_SPARC64
 	tristate "Digests: MD5"
 	depends on SPARC64
 	select CRYPTO_MD5
 	select CRYPTO_HASH
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile
index d257186c27d1..a2d7fca40cb4 100644
--- a/arch/sparc/crypto/Makefile
+++ b/arch/sparc/crypto/Makefile
@@ -10,17 +10,13 @@ obj-$(CONFIG_CRYPTO_MD5_SPARC64) += md5-sparc64.o
 
 obj-$(CONFIG_CRYPTO_AES_SPARC64) += aes-sparc64.o
 obj-$(CONFIG_CRYPTO_DES_SPARC64) += des-sparc64.o
 obj-$(CONFIG_CRYPTO_CAMELLIA_SPARC64) += camellia-sparc64.o
 
-obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o
-
 sha1-sparc64-y := sha1_asm.o sha1_glue.o
 sha256-sparc64-y := sha256_asm.o sha256_glue.o
 sha512-sparc64-y := sha512_asm.o sha512_glue.o
 md5-sparc64-y := md5_asm.o md5_glue.o
 
 aes-sparc64-y := aes_asm.o aes_glue.o
 des-sparc64-y := des_asm.o des_glue.o
 camellia-sparc64-y := camellia_asm.o camellia_glue.o
-
-crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o
diff --git a/arch/sparc/crypto/crc32c_glue.c b/arch/sparc/crypto/crc32c_glue.c
deleted file mode 100644
index 913b9a09e885..000000000000
--- a/arch/sparc/crypto/crc32c_glue.c
+++ /dev/null
@@ -1,184 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Glue code for CRC32C optimized for sparc64 crypto opcodes.
- *
- * This is based largely upon arch/x86/crypto/crc32c-intel.c
- *
- * Copyright (C) 2008 Intel Corporation
- * Authors: Austin Zhang <austin_zhang at linux.intel.com>
- *          Kent Liu <kent.liu at intel.com>
- */
-
-#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/crc32.h>
-
-#include <crypto/internal/hash.h>
-
-#include <asm/pstate.h>
-#include <asm/elf.h>
-#include <linux/unaligned.h>
-
-#include "opcodes.h"
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set
- * the seed.
- */
-static int crc32c_sparc64_setkey(struct crypto_shash *hash, const u8 *key,
-				 unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = get_unaligned_le32(key);
-	return 0;
-}
-
-static int crc32c_sparc64_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = *mctx;
-
-	return 0;
-}
-
-extern void crc32c_sparc64(u32 *crcp, const u64 *data, unsigned int len);
-
-static u32 crc32c_compute(u32 crc, const u8 *data, unsigned int len)
-{
-	unsigned int n = -(uintptr_t)data & 7;
-
-	if (n) {
-		/* Data isn't 8-byte aligned.  Align it. */
-		n = min(n, len);
-		crc = __crc32c_le(crc, data, n);
-		data += n;
-		len -= n;
-	}
-	n = len & ~7U;
-	if (n) {
-		crc32c_sparc64(&crc, (const u64 *)data, n);
-		data += n;
-		len -= n;
-	}
-	if (len)
-		crc = __crc32c_le(crc, data, len);
-	return crc;
-}
-
-static int crc32c_sparc64_update(struct shash_desc *desc, const u8 *data,
-				 unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = crc32c_compute(*crcp, data, len);
-	return 0;
-}
-
-static int __crc32c_sparc64_finup(const u32 *crcp, const u8 *data,
-				  unsigned int len, u8 *out)
-{
-	put_unaligned_le32(~crc32c_compute(*crcp, data, len), out);
-	return 0;
-}
-
-static int crc32c_sparc64_finup(struct shash_desc *desc, const u8 *data,
-				unsigned int len, u8 *out)
-{
-	return __crc32c_sparc64_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32c_sparc64_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	put_unaligned_le32(~*crcp, out);
-	return 0;
-}
-
-static int crc32c_sparc64_digest(struct shash_desc *desc, const u8 *data,
-				 unsigned int len, u8 *out)
-{
-	return __crc32c_sparc64_finup(crypto_shash_ctx(desc->tfm), data, len,
-				      out);
-}
-
-static int crc32c_sparc64_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = ~0;
-
-	return 0;
-}
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-static struct shash_alg alg = {
-	.setkey			=	crc32c_sparc64_setkey,
-	.init			=	crc32c_sparc64_init,
-	.update			=	crc32c_sparc64_update,
-	.final			=	crc32c_sparc64_final,
-	.finup			=	crc32c_sparc64_finup,
-	.digest			=	crc32c_sparc64_digest,
-	.descsize		=	sizeof(u32),
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.base			=	{
-		.cra_name		=	"crc32c",
-		.cra_driver_name	=	"crc32c-sparc64",
-		.cra_priority		=	SPARC_CR_OPCODE_PRIORITY,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(u32),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	crc32c_sparc64_cra_init,
-	}
-};
-
-static bool __init sparc64_has_crc32c_opcode(void)
-{
-	unsigned long cfr;
-
-	if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
-		return false;
-
-	__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
-	if (!(cfr & CFR_CRC32C))
-		return false;
-
-	return true;
-}
-
-static int __init crc32c_sparc64_mod_init(void)
-{
-	if (sparc64_has_crc32c_opcode()) {
-		pr_info("Using sparc64 crc32c opcode optimized CRC32C implementation\n");
-		return crypto_register_shash(&alg);
-	}
-	pr_info("sparc64 crc32c opcode not available.\n");
-	return -ENODEV;
-}
-
-static void __exit crc32c_sparc64_mod_fini(void)
-{
-	crypto_unregister_shash(&alg);
-}
-
-module_init(crc32c_sparc64_mod_init);
-module_exit(crc32c_sparc64_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated");
-
-MODULE_ALIAS_CRYPTO("crc32c");
-
-#include "crop_devid.c"
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index ee5091dd67ed..5724d0f356eb 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -51,5 +51,7 @@ lib-$(CONFIG_SPARC64) += copy_in_user.o memmove.o
 lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o
 
 obj-$(CONFIG_SPARC64) += iomap.o
 obj-$(CONFIG_SPARC32) += atomic32.o
 obj-$(CONFIG_SPARC64) += PeeCeeI.o
+obj-$(CONFIG_CRC32_ARCH) += crc32-sparc.o
+crc32-sparc-y := crc32_glue.o crc32c_asm.o
diff --git a/arch/sparc/lib/crc32_glue.c b/arch/sparc/lib/crc32_glue.c
new file mode 100644
index 000000000000..41076d2b1fd2
--- /dev/null
+++ b/arch/sparc/lib/crc32_glue.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Glue code for CRC32C optimized for sparc64 crypto opcodes.
+ *
+ * This is based largely upon arch/x86/crypto/crc32c-intel.c
+ *
+ * Copyright (C) 2008 Intel Corporation
+ * Authors: Austin Zhang <austin_zhang at linux.intel.com>
+ *          Kent Liu <kent.liu at intel.com>
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/crc32.h>
+#include <asm/pstate.h>
+#include <asm/elf.h>
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32c_opcode);
+
+u32 crc32_le_arch(u32 crc, const u8 *data, size_t len)
+{
+	return crc32_le_base(crc, data, len);
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+void crc32c_sparc64(u32 *crcp, const u64 *data, size_t len);
+
+u32 crc32c_le_arch(u32 crc, const u8 *data, size_t len)
+{
+	size_t n = -(uintptr_t)data & 7;
+
+	if (!static_branch_likely(&have_crc32c_opcode))
+		return crc32c_le_base(crc, data, len);
+
+	if (n) {
+		/* Data isn't 8-byte aligned.  Align it. */
+		n = min(n, len);
+		crc = crc32c_le_base(crc, data, n);
+		data += n;
+		len -= n;
+	}
+	n = len & ~7U;
+	if (n) {
+		crc32c_sparc64(&crc, (const u64 *)data, n);
+		data += n;
+		len -= n;
+	}
+	if (len)
+		crc = crc32c_le_base(crc, data, len);
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *data, size_t len)
+{
+	return crc32_be_base(crc, data, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_sparc_init(void)
+{
+	unsigned long cfr;
+
+	if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
+		return 0;
+
+	__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
+	if (!(cfr & CFR_CRC32C))
+		return 0;
+
+	static_branch_enable(&have_crc32c_opcode);
+	pr_info("Using sparc64 crc32c opcode optimized CRC32C implementation\n");
+	return 0;
+}
+arch_initcall(crc32_sparc_init);
+
+static void __exit crc32_sparc_exit(void)
+{
+}
+module_exit(crc32_sparc_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_crc32c_opcode))
+		return CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated");
diff --git a/arch/sparc/crypto/crc32c_asm.S b/arch/sparc/lib/crc32c_asm.S
similarity index 92%
rename from arch/sparc/crypto/crc32c_asm.S
rename to arch/sparc/lib/crc32c_asm.S
index b8659a479242..ee454fa6aed6 100644
--- a/arch/sparc/crypto/crc32c_asm.S
+++ b/arch/sparc/lib/crc32c_asm.S
@@ -1,11 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #include <linux/linkage.h>
 #include <asm/visasm.h>
 #include <asm/asi.h>
 
-#include "opcodes.h"
+#include "../crypto/opcodes.h"
 
 ENTRY(crc32c_sparc64)
 	/* %o0=crc32p, %o1=data_ptr, %o2=len */
 	VISEntryHalf
 	lda	[%o0] ASI_PL, %f1
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:48 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:48 -0800
Subject: [PATCH v3 12/18] x86/crc32: update prototype for crc32_pclmul_le_16()
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-13-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

- Change the len parameter from unsigned int to size_t, so that the
  library function which takes a size_t can safely use this code.

- Move the crc parameter to the front, as this is the usual convention.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/x86/crypto/crc32-pclmul_asm.S  | 19 +++++++++----------
 arch/x86/crypto/crc32-pclmul_glue.c |  4 ++--
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/arch/x86/crypto/crc32-pclmul_asm.S b/arch/x86/crypto/crc32-pclmul_asm.S
index 5d31137e2c7d..f9637789cac1 100644
--- a/arch/x86/crypto/crc32-pclmul_asm.S
+++ b/arch/x86/crypto/crc32-pclmul_asm.S
@@ -56,30 +56,29 @@
 	.octa 0x00000001F701164100000001DB710641
 
 #define CONSTANT %xmm0
 
 #ifdef __x86_64__
-#define BUF     %rdi
-#define LEN     %rsi
-#define CRC     %edx
+#define CRC     %edi
+#define BUF     %rsi
+#define LEN     %rdx
 #else
-#define BUF     %eax
-#define LEN     %edx
-#define CRC     %ecx
+#define CRC     %eax
+#define BUF     %edx
+#define LEN     %ecx
 #endif
 
 
 
 .text
 /**
  *      Calculate crc32
- *      BUF - buffer (16 bytes aligned)
- *      LEN - sizeof buffer (16 bytes aligned), LEN should be grater than 63
  *      CRC - initial crc32
+ *      BUF - buffer (16 bytes aligned)
+ *      LEN - sizeof buffer (16 bytes aligned), LEN should be greater than 63
  *      return %eax crc32
- *      uint crc32_pclmul_le_16(unsigned char const *buffer,
- *	                     size_t len, uint crc32)
+ *      u32 crc32_pclmul_le_16(u32 crc, const u8 *buffer, size_t len);
  */
 
 SYM_FUNC_START(crc32_pclmul_le_16) /* buffer and buffer size are 16 bytes aligned */
 	movdqa  (BUF), %xmm1
 	movdqa  0x10(BUF), %xmm2
diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c
index 9f5e342b9845..9d14eac51c5b 100644
--- a/arch/x86/crypto/crc32-pclmul_glue.c
+++ b/arch/x86/crypto/crc32-pclmul_glue.c
@@ -44,11 +44,11 @@
 #define PCLMUL_MIN_LEN		64L     /* minimum size of buffer
 					 * for crc32_pclmul_le_16 */
 #define SCALE_F			16L	/* size of xmm register */
 #define SCALE_F_MASK		(SCALE_F - 1)
 
-u32 crc32_pclmul_le_16(unsigned char const *buffer, size_t len, u32 crc32);
+u32 crc32_pclmul_le_16(u32 crc, const u8 *buffer, size_t len);
 
 static u32 __attribute__((pure))
 	crc32_pclmul_le(u32 crc, unsigned char const *p, size_t len)
 {
 	unsigned int iquotient;
@@ -69,11 +69,11 @@ static u32 __attribute__((pure))
 	}
 	iquotient = len & (~SCALE_F_MASK);
 	iremainder = len & SCALE_F_MASK;
 
 	kernel_fpu_begin();
-	crc = crc32_pclmul_le_16(p, iquotient, crc);
+	crc = crc32_pclmul_le_16(crc, p, iquotient);
 	kernel_fpu_end();
 
 	if (iremainder)
 		crc = crc32_le(crc, p + iquotient, iremainder);
 
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:52 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:52 -0800
Subject: [PATCH v3 16/18] jbd2: switch to using the crc32c library
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-17-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the crc32c() library function directly takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32c().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/jbd2/Kconfig      |  2 --
 fs/jbd2/journal.c    | 25 ++-----------------------
 include/linux/jbd2.h | 31 +++----------------------------
 3 files changed, 5 insertions(+), 53 deletions(-)

diff --git a/fs/jbd2/Kconfig b/fs/jbd2/Kconfig
index 4ad2c67f93f1..9c19e1512101 100644
--- a/fs/jbd2/Kconfig
+++ b/fs/jbd2/Kconfig
@@ -1,11 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config JBD2
 	tristate
 	select CRC32
-	select CRYPTO
-	select CRYPTO_CRC32C
 	help
 	  This is a generic journaling layer for block devices that support
 	  both 32-bit and 64-bit block numbers.  It is currently used by
 	  the ext4 and OCFS2 filesystems, but it could also be used to add
 	  journal support to other file systems or block devices such
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 97f487c3d8fc..56cea5a738a7 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1373,24 +1373,16 @@ static int journal_check_superblock(journal_t *journal)
 		printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2/3 "
 		       "at the same time!\n");
 		return err;
 	}
 
-	/* Load the checksum driver */
 	if (jbd2_journal_has_csum_v2or3_feature(journal)) {
 		if (sb->s_checksum_type != JBD2_CRC32C_CHKSUM) {
 			printk(KERN_ERR "JBD2: Unknown checksum type\n");
 			return err;
 		}
 
-		journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
-		if (IS_ERR(journal->j_chksum_driver)) {
-			printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
-			err = PTR_ERR(journal->j_chksum_driver);
-			journal->j_chksum_driver = NULL;
-			return err;
-		}
 		/* Check superblock checksum */
 		if (sb->s_checksum != jbd2_superblock_csum(journal, sb)) {
 			printk(KERN_ERR "JBD2: journal checksum error\n");
 			err = -EFSBADCRC;
 			return err;
@@ -1611,12 +1603,10 @@ static journal_t *journal_init_common(struct block_device *bdev,
 
 	return journal;
 
 err_cleanup:
 	percpu_counter_destroy(&journal->j_checkpoint_jh_count);
-	if (journal->j_chksum_driver)
-		crypto_free_shash(journal->j_chksum_driver);
 	kfree(journal->j_wbuf);
 	jbd2_journal_destroy_revoke(journal);
 	journal_fail_superblock(journal);
 	kfree(journal);
 	return ERR_PTR(err);
@@ -2194,12 +2184,10 @@ int jbd2_journal_destroy(journal_t *journal)
 	if (journal->j_proc_entry)
 		jbd2_stats_proc_exit(journal);
 	iput(journal->j_inode);
 	if (journal->j_revoke)
 		jbd2_journal_destroy_revoke(journal);
-	if (journal->j_chksum_driver)
-		crypto_free_shash(journal->j_chksum_driver);
 	kfree(journal->j_fc_wbuf);
 	kfree(journal->j_wbuf);
 	kfree(journal);
 
 	return err;
@@ -2340,23 +2328,14 @@ int jbd2_journal_set_features(journal_t *journal, unsigned long compat,
 			pr_err("JBD2: Cannot enable fast commits.\n");
 			return 0;
 		}
 	}
 
-	/* Load the checksum driver if necessary */
-	if ((journal->j_chksum_driver == NULL) &&
-	    INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
-		journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
-		if (IS_ERR(journal->j_chksum_driver)) {
-			printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
-			journal->j_chksum_driver = NULL;
-			return 0;
-		}
-		/* Precompute checksum seed for all metadata */
+	/* Precompute checksum seed for all metadata */
+	if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3))
 		journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid,
 						   sizeof(sb->s_uuid));
-	}
 
 	lock_buffer(journal->j_sb_buffer);
 
 	/* If enabling v3 checksums, update superblock */
 	if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 8aef9bb6ad57..33d25a3d15f1 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -26,11 +26,11 @@
 #include <linux/mutex.h>
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <linux/bit_spinlock.h>
 #include <linux/blkdev.h>
-#include <crypto/hash.h>
+#include <linux/crc32c.h>
 #endif
 
 #define journal_oom_retry 1
 
 /*
@@ -1239,17 +1239,10 @@ struct journal_s
 	 * An opaque pointer to fs-private information.  ext3 puts its
 	 * superblock pointer here.
 	 */
 	void *j_private;
 
-	/**
-	 * @j_chksum_driver:
-	 *
-	 * Reference to checksum algorithm driver via cryptoapi.
-	 */
-	struct crypto_shash *j_chksum_driver;
-
 	/**
 	 * @j_csum_seed:
 	 *
 	 * Precomputed journal UUID checksum for seeding other checksums.
 	 */
@@ -1748,14 +1741,11 @@ static inline bool jbd2_journal_has_csum_v2or3_feature(journal_t *j)
 	return jbd2_has_feature_csum2(j) || jbd2_has_feature_csum3(j);
 }
 
 static inline int jbd2_journal_has_csum_v2or3(journal_t *journal)
 {
-	WARN_ON_ONCE(jbd2_journal_has_csum_v2or3_feature(journal) &&
-		     journal->j_chksum_driver == NULL);
-
-	return journal->j_chksum_driver != NULL;
+	return jbd2_journal_has_csum_v2or3_feature(journal);
 }
 
 static inline int jbd2_journal_get_num_fc_blks(journal_superblock_t *jsb)
 {
 	int num_fc_blocks = be32_to_cpu(jsb->s_num_fc_blks);
@@ -1794,26 +1784,11 @@ static inline unsigned long jbd2_log_space_left(journal_t *journal)
 #define JBD_MAX_CHECKSUM_SIZE 4
 
 static inline u32 jbd2_chksum(journal_t *journal, u32 crc,
 			      const void *address, unsigned int length)
 {
-	struct {
-		struct shash_desc shash;
-		char ctx[JBD_MAX_CHECKSUM_SIZE];
-	} desc;
-	int err;
-
-	BUG_ON(crypto_shash_descsize(journal->j_chksum_driver) >
-		JBD_MAX_CHECKSUM_SIZE);
-
-	desc.shash.tfm = journal->j_chksum_driver;
-	*(u32 *)desc.ctx = crc;
-
-	err = crypto_shash_update(&desc.shash, address, length);
-	BUG_ON(err);
-
-	return *(u32 *)desc.ctx;
+	return crc32c(crc, address, length);
 }
 
 /* Return most recent uncommitted transaction */
 static inline tid_t  jbd2_get_latest_transaction(journal_t *journal)
 {
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:53 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:53 -0800
Subject: [PATCH v3 17/18] f2fs: switch to using the crc32 library
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-18-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the crc32() library function takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/f2fs/Kconfig |  3 +--
 fs/f2fs/f2fs.h  | 19 +------------------
 fs/f2fs/super.c | 15 ---------------
 3 files changed, 2 insertions(+), 35 deletions(-)

diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
index 68a1e23e1557..5916a02fb46d 100644
--- a/fs/f2fs/Kconfig
+++ b/fs/f2fs/Kconfig
@@ -2,12 +2,11 @@
 config F2FS_FS
 	tristate "F2FS filesystem support"
 	depends on BLOCK
 	select BUFFER_HEAD
 	select NLS
-	select CRYPTO
-	select CRYPTO_CRC32
+	select CRC32
 	select F2FS_FS_XATTR if FS_ENCRYPTION
 	select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
 	select FS_IOMAP
 	select LZ4_COMPRESS if F2FS_FS_LZ4
 	select LZ4_DECOMPRESS if F2FS_FS_LZ4
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 33f5449dc22d..1fc5c2743c8d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1761,13 +1761,10 @@ struct f2fs_sb_info {
 
 	/* For write statistics */
 	u64 sectors_written_start;
 	u64 kbytes_written;
 
-	/* Reference to checksum algorithm driver via cryptoapi */
-	struct crypto_shash *s_chksum_driver;
-
 	/* Precomputed FS UUID checksum for seeding other checksums */
 	__u32 s_chksum_seed;
 
 	struct workqueue_struct *post_read_wq;	/* post read workqueue */
 
@@ -1941,25 +1938,11 @@ static inline unsigned int f2fs_time_to_wait(struct f2fs_sb_info *sbi,
  * Inline functions
  */
 static inline u32 __f2fs_crc32(struct f2fs_sb_info *sbi, u32 crc,
 			      const void *address, unsigned int length)
 {
-	struct {
-		struct shash_desc shash;
-		char ctx[4];
-	} desc;
-	int err;
-
-	BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver) != sizeof(desc.ctx));
-
-	desc.shash.tfm = sbi->s_chksum_driver;
-	*(u32 *)desc.ctx = crc;
-
-	err = crypto_shash_update(&desc.shash, address, length);
-	BUG_ON(err);
-
-	return *(u32 *)desc.ctx;
+	return crc32(crc, address, length);
 }
 
 static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address,
 			   unsigned int length)
 {
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 87ab5696bd48..003d3bcb0caa 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1670,12 +1670,10 @@ static void f2fs_put_super(struct super_block *sb)
 
 	f2fs_destroy_post_read_wq(sbi);
 
 	kvfree(sbi->ckpt);
 
-	if (sbi->s_chksum_driver)
-		crypto_free_shash(sbi->s_chksum_driver);
 	kfree(sbi->raw_super);
 
 	f2fs_destroy_page_array_cache(sbi);
 	f2fs_destroy_xattr_caches(sbi);
 #ifdef CONFIG_QUOTA
@@ -4419,19 +4417,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 		INIT_LIST_HEAD(&sbi->inode_list[i]);
 		spin_lock_init(&sbi->inode_lock[i]);
 	}
 	mutex_init(&sbi->flush_lock);
 
-	/* Load the checksum driver */
-	sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0);
-	if (IS_ERR(sbi->s_chksum_driver)) {
-		f2fs_err(sbi, "Cannot load crc32 driver.");
-		err = PTR_ERR(sbi->s_chksum_driver);
-		sbi->s_chksum_driver = NULL;
-		goto free_sbi;
-	}
-
 	/* set a block size */
 	if (unlikely(!sb_set_blocksize(sb, F2FS_BLKSIZE))) {
 		f2fs_err(sbi, "unable to set blocksize");
 		goto free_sbi;
 	}
@@ -4872,12 +4861,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
 	fscrypt_free_dummy_policy(&F2FS_OPTION(sbi).dummy_enc_policy);
 	kvfree(options);
 free_sb_buf:
 	kfree(raw_super);
 free_sbi:
-	if (sbi->s_chksum_driver)
-		crypto_free_shash(sbi->s_chksum_driver);
 	kfree(sbi);
 	sb->s_fs_info = NULL;
 
 	/* give only one another chance */
 	if (retry_cnt > 0 && skip_recovery) {
@@ -5080,7 +5067,5 @@ module_init(init_f2fs_fs)
 module_exit(exit_f2fs_fs)
 
 MODULE_AUTHOR("Samsung Electronics's Praesto Team");
 MODULE_DESCRIPTION("Flash Friendly File System");
 MODULE_LICENSE("GPL");
-MODULE_SOFTDEP("pre: crc32");
-
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:50 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:50 -0800
Subject: [PATCH v3 14/18] lib/crc32: make crc32c() go directly to lib
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-15-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the lower level __crc32c_le() library function is optimized for
each architecture, make crc32c() just call that instead of taking an
inefficient and error-prone detour through the shash API.

Note: a future cleanup should make crc32c_le() be the actual library
function instead of __crc32c_le().  That will require updating callers
of __crc32c_le() to use crc32c_le() instead, and updating callers of
crc32c_le() that expect a 'const void *' arg to expect 'const u8 *'
instead.  Similarly, a future cleanup should remove LIBCRC32C by making
everyone who is selecting it just select CRC32 directly instead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 include/linux/crc32c.h |  7 ++--
 lib/Kconfig            | 10 ++----
 lib/Makefile           |  1 -
 lib/libcrc32c.c        | 74 ------------------------------------------
 4 files changed, 8 insertions(+), 84 deletions(-)
 delete mode 100644 lib/libcrc32c.c

diff --git a/include/linux/crc32c.h b/include/linux/crc32c.h
index 357ae4611a45..47eb78003c26 100644
--- a/include/linux/crc32c.h
+++ b/include/linux/crc32c.h
@@ -1,12 +1,15 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _LINUX_CRC32C_H
 #define _LINUX_CRC32C_H
 
-#include <linux/types.h>
+#include <linux/crc32.h>
 
-extern u32 crc32c(u32 crc, const void *address, unsigned int length);
+static inline u32 crc32c(u32 crc, const void *address, unsigned int length)
+{
+	return __crc32c_le(crc, address, length);
+}
 
 /* This macro exists for backwards-compatibility. */
 #define crc32c_le crc32c
 
 #endif	/* _LINUX_CRC32C_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 07afcf214f35..b894ee64ff95 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -296,18 +296,14 @@ config CRC7
 	  the kernel tree does. Such modules that use library CRC7
 	  functions require M here.
 
 config LIBCRC32C
 	tristate "CRC32c (Castagnoli, et al) Cyclic Redundancy-Check"
-	select CRYPTO
-	select CRYPTO_CRC32C
+	select CRC32
 	help
-	  This option is provided for the case where no in-kernel-tree
-	  modules require CRC32c functions, but a module built outside the
-	  kernel tree does. Such modules that use library CRC32c functions
-	  require M here.  See Castagnoli93.
-	  Module will be libcrc32c.
+	  This option just selects CRC32 and is provided for compatibility
+	  purposes until the users are updated to select CRC32 directly.
 
 config CRC8
 	tristate "CRC8 function"
 	help
 	  This option provides CRC8 function. Drivers may select this
diff --git a/lib/Makefile b/lib/Makefile
index 773adf88af41..15646679aee2 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -161,11 +161,10 @@ obj-$(CONFIG_CRC_ITU_T)	+= crc-itu-t.o
 obj-$(CONFIG_CRC32)	+= crc32.o
 obj-$(CONFIG_CRC64)     += crc64.o
 obj-$(CONFIG_CRC32_SELFTEST)	+= crc32test.o
 obj-$(CONFIG_CRC4)	+= crc4.o
 obj-$(CONFIG_CRC7)	+= crc7.o
-obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
 obj-$(CONFIG_CRC8)	+= crc8.o
 obj-$(CONFIG_CRC64_ROCKSOFT) += crc64-rocksoft.o
 obj-$(CONFIG_XXHASH)	+= xxhash.o
 obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
 
diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c
deleted file mode 100644
index 649e687413a0..000000000000
--- a/lib/libcrc32c.c
+++ /dev/null
@@ -1,74 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* 
- * CRC32C
- *@Article{castagnoli-crc,
- * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
- * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
- *                 and 32 Parity Bits}},
- * journal =      IEEE Transactions on Communication,
- * year =         {1993},
- * volume =       {41},
- * number =       {6},
- * pages =        {},
- * month =        {June},
- *}
- * Used by the iSCSI driver, possibly others, and derived from
- * the iscsi-crc.c module of the linux-iscsi driver at
- * http://linux-iscsi.sourceforge.net.
- *
- * Following the example of lib/crc32, this function is intended to be
- * flexible and useful for all users.  Modules that currently have their
- * own crc32c, but hopefully may be able to use this one are:
- *  net/sctp (please add all your doco to here if you change to
- *            use this one!)
- *  <endoflist>
- *
- * Copyright (c) 2004 Cisco Systems, Inc.
- */
-
-#include <crypto/hash.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/crc32c.h>
-
-static struct crypto_shash *tfm;
-
-u32 crc32c(u32 crc, const void *address, unsigned int length)
-{
-	SHASH_DESC_ON_STACK(shash, tfm);
-	u32 ret, *ctx = (u32 *)shash_desc_ctx(shash);
-	int err;
-
-	shash->tfm = tfm;
-	*ctx = crc;
-
-	err = crypto_shash_update(shash, address, length);
-	BUG_ON(err);
-
-	ret = *ctx;
-	barrier_data(ctx);
-	return ret;
-}
-
-EXPORT_SYMBOL(crc32c);
-
-static int __init libcrc32c_mod_init(void)
-{
-	tfm = crypto_alloc_shash("crc32c", 0, 0);
-	return PTR_ERR_OR_ZERO(tfm);
-}
-
-static void __exit libcrc32c_mod_fini(void)
-{
-	crypto_free_shash(tfm);
-}
-
-module_init(libcrc32c_mod_init);
-module_exit(libcrc32c_mod_fini);
-
-MODULE_AUTHOR("Clay Haapala <chaapala at cisco.com>");
-MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
-MODULE_LICENSE("GPL");
-MODULE_SOFTDEP("pre: crc32c");
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:47 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:47 -0800
Subject: [PATCH v3 11/18] x86/crc32: update prototype for crc_pcl()
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-12-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

- Change the len parameter from unsigned int to size_t, so that the
  library function which takes a size_t can safely use this code.

- Rename to crc32c_x86_3way() which is much clearer.

- Move the crc parameter to the front, as this is the usual convention.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/x86/crypto/crc32c-intel_glue.c       |  7 ++-
 arch/x86/crypto/crc32c-pcl-intel-asm_64.S | 63 ++++++++++++-----------
 2 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c
index 52c5d47ef5a1..603d159de400 100644
--- a/arch/x86/crypto/crc32c-intel_glue.c
+++ b/arch/x86/crypto/crc32c-intel_glue.c
@@ -39,12 +39,11 @@
  * size is >= 512 to account
  * for fpu state save/restore overhead.
  */
 #define CRC32C_PCL_BREAKEVEN	512
 
-asmlinkage unsigned int crc_pcl(const u8 *buffer, unsigned int len,
-				unsigned int crc_init);
+asmlinkage u32 crc32c_x86_3way(u32 crc, const u8 *buffer, size_t len);
 #endif /* CONFIG_X86_64 */
 
 static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length)
 {
 	while (length--) {
@@ -157,11 +156,11 @@ static int crc32c_pcl_intel_update(struct shash_desc *desc, const u8 *data,
 	 * use faster PCL version if datasize is large enough to
 	 * overcome kernel fpu state save/restore overhead
 	 */
 	if (len >= CRC32C_PCL_BREAKEVEN && crypto_simd_usable()) {
 		kernel_fpu_begin();
-		*crcp = crc_pcl(data, len, *crcp);
+		*crcp = crc32c_x86_3way(*crcp, data, len);
 		kernel_fpu_end();
 	} else
 		*crcp = crc32c_intel_le_hw(*crcp, data, len);
 	return 0;
 }
@@ -169,11 +168,11 @@ static int crc32c_pcl_intel_update(struct shash_desc *desc, const u8 *data,
 static int __crc32c_pcl_intel_finup(u32 *crcp, const u8 *data, unsigned int len,
 				u8 *out)
 {
 	if (len >= CRC32C_PCL_BREAKEVEN && crypto_simd_usable()) {
 		kernel_fpu_begin();
-		*(__le32 *)out = ~cpu_to_le32(crc_pcl(data, len, *crcp));
+		*(__le32 *)out = ~cpu_to_le32(crc32c_x86_3way(*crcp, data, len));
 		kernel_fpu_end();
 	} else
 		*(__le32 *)out =
 			~cpu_to_le32(crc32c_intel_le_hw(*crcp, data, len));
 	return 0;
diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
index 752812bc4991..9b8770503bbc 100644
--- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
@@ -50,19 +50,20 @@
 
 # Define threshold below which buffers are considered "small" and routed to
 # regular CRC code that does not interleave the CRC instructions.
 #define SMALL_SIZE 200
 
-# unsigned int crc_pcl(const u8 *buffer, unsigned int len, unsigned int crc_init);
+# u32 crc32c_x86_3way(u32 crc, const u8 *buffer, size_t len);
 
 .text
-SYM_FUNC_START(crc_pcl)
-#define    bufp		  %rdi
-#define    bufp_d	  %edi
-#define    len		  %esi
-#define    crc_init	  %edx
-#define    crc_init_q	  %rdx
+SYM_FUNC_START(crc32c_x86_3way)
+#define    crc0		  %edi
+#define    crc0_q	  %rdi
+#define    bufp		  %rsi
+#define    bufp_d	  %esi
+#define    len		  %rdx
+#define    len_dw	  %edx
 #define    n_misaligned	  %ecx /* overlaps chunk_bytes! */
 #define    n_misaligned_q %rcx
 #define    chunk_bytes	  %ecx /* overlaps n_misaligned! */
 #define    chunk_bytes_q  %rcx
 #define    crc1		  %r8
@@ -83,13 +84,13 @@ SYM_FUNC_START(crc_pcl)
 	# Process 1 <= n_misaligned <= 7 bytes individually in order to align
 	# the remaining data to an 8-byte boundary.
 .Ldo_align:
 	movq	(bufp), %rax
 	add	n_misaligned_q, bufp
-	sub	n_misaligned, len
+	sub	n_misaligned_q, len
 .Lalign_loop:
-	crc32b	%al, crc_init		# compute crc32 of 1-byte
+	crc32b	%al, crc0		# compute crc32 of 1-byte
 	shr	$8, %rax		# get next byte
 	dec	n_misaligned
 	jne     .Lalign_loop
 .Laligned:
 
@@ -100,11 +101,11 @@ SYM_FUNC_START(crc_pcl)
 	cmp	$128*24, len
 	jae     .Lfull_block
 
 .Lpartial_block:
 	# Compute floor(len / 24) to get num qwords to process from each lane.
-	imul	$2731, len, %eax	# 2731 = ceil(2^16 / 24)
+	imul	$2731, len_dw, %eax	# 2731 = ceil(2^16 / 24)
 	shr	$16, %eax
 	jmp	.Lcrc_3lanes
 
 .Lfull_block:
 	# Processing 128 qwords from each lane.
@@ -123,20 +124,20 @@ SYM_FUNC_START(crc_pcl)
 	jl	.Lcrc_3lanes_4x_done
 
 	# Unroll the loop by a factor of 4 to reduce the overhead of the loop
 	# bookkeeping instructions, which can compete with crc32q for the ALUs.
 .Lcrc_3lanes_4x_loop:
-	crc32q	(bufp), crc_init_q
+	crc32q	(bufp), crc0_q
 	crc32q	(bufp,chunk_bytes_q), crc1
 	crc32q	(bufp,chunk_bytes_q,2), crc2
-	crc32q	8(bufp), crc_init_q
+	crc32q	8(bufp), crc0_q
 	crc32q	8(bufp,chunk_bytes_q), crc1
 	crc32q	8(bufp,chunk_bytes_q,2), crc2
-	crc32q	16(bufp), crc_init_q
+	crc32q	16(bufp), crc0_q
 	crc32q	16(bufp,chunk_bytes_q), crc1
 	crc32q	16(bufp,chunk_bytes_q,2), crc2
-	crc32q	24(bufp), crc_init_q
+	crc32q	24(bufp), crc0_q
 	crc32q	24(bufp,chunk_bytes_q), crc1
 	crc32q	24(bufp,chunk_bytes_q,2), crc2
 	add	$32, bufp
 	sub	$4, %eax
 	jge	.Lcrc_3lanes_4x_loop
@@ -144,42 +145,42 @@ SYM_FUNC_START(crc_pcl)
 .Lcrc_3lanes_4x_done:
 	add	$4, %eax
 	jz	.Lcrc_3lanes_last_qword
 
 .Lcrc_3lanes_1x_loop:
-	crc32q	(bufp), crc_init_q
+	crc32q	(bufp), crc0_q
 	crc32q	(bufp,chunk_bytes_q), crc1
 	crc32q	(bufp,chunk_bytes_q,2), crc2
 	add	$8, bufp
 	dec	%eax
 	jnz	.Lcrc_3lanes_1x_loop
 
 .Lcrc_3lanes_last_qword:
-	crc32q	(bufp), crc_init_q
+	crc32q	(bufp), crc0_q
 	crc32q	(bufp,chunk_bytes_q), crc1
 # SKIP  crc32q	(bufp,chunk_bytes_q,2), crc2	; Don't do this one yet
 
 	################################################################
 	## 4) Combine three results:
 	################################################################
 
 	lea	(K_table-8)(%rip), %rax		# first entry is for idx 1
 	pmovzxdq (%rax,chunk_bytes_q), %xmm0	# 2 consts: K1:K2
 	lea	(chunk_bytes,chunk_bytes,2), %eax # chunk_bytes * 3
-	sub	%eax, len			# len -= chunk_bytes * 3
+	sub	%rax, len			# len -= chunk_bytes * 3
 
-	movq	crc_init_q, %xmm1		# CRC for block 1
+	movq	crc0_q, %xmm1			# CRC for block 1
 	pclmulqdq $0x00, %xmm0, %xmm1		# Multiply by K2
 
 	movq    crc1, %xmm2			# CRC for block 2
 	pclmulqdq $0x10, %xmm0, %xmm2		# Multiply by K1
 
 	pxor    %xmm2,%xmm1
 	movq    %xmm1, %rax
 	xor	(bufp,chunk_bytes_q,2), %rax
-	mov	crc2, crc_init_q
-	crc32	%rax, crc_init_q
+	mov	crc2, crc0_q
+	crc32	%rax, crc0_q
 	lea	8(bufp,chunk_bytes_q,2), bufp
 
 	################################################################
 	## 5) If more blocks remain, goto (2):
 	################################################################
@@ -191,38 +192,38 @@ SYM_FUNC_START(crc_pcl)
 
 	#######################################################################
 	## 6) Process any remainder without interleaving:
 	#######################################################################
 .Lsmall:
-	test	len, len
+	test	len_dw, len_dw
 	jz	.Ldone
-	mov	len, %eax
+	mov	len_dw, %eax
 	shr	$3, %eax
 	jz	.Ldo_dword
 .Ldo_qwords:
-	crc32q	(bufp), crc_init_q
+	crc32q	(bufp), crc0_q
 	add	$8, bufp
 	dec	%eax
 	jnz	.Ldo_qwords
 .Ldo_dword:
-	test	$4, len
+	test	$4, len_dw
 	jz	.Ldo_word
-	crc32l	(bufp), crc_init
+	crc32l	(bufp), crc0
 	add	$4, bufp
 .Ldo_word:
-	test	$2, len
+	test	$2, len_dw
 	jz	.Ldo_byte
-	crc32w	(bufp), crc_init
+	crc32w	(bufp), crc0
 	add	$2, bufp
 .Ldo_byte:
-	test	$1, len
+	test	$1, len_dw
 	jz	.Ldone
-	crc32b	(bufp), crc_init
+	crc32b	(bufp), crc0
 .Ldone:
-	mov	crc_init, %eax
+	mov	crc0, %eax
         RET
-SYM_FUNC_END(crc_pcl)
+SYM_FUNC_END(crc32c_x86_3way)
 
 .section	.rodata, "a", @progbits
 	################################################################
 	## PCLMULQDQ tables
 	## Table is 128 entries x 2 words (8 bytes) each
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:44 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:44 -0800
Subject: [PATCH v3 08/18] powerpc/crc32: expose CRC32 functions through lib
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-9-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the powerpc CRC32C assembly code into the lib directory and wire it
up to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Note: to see the diff from arch/powerpc/crypto/crc32c-vpmsum_glue.c to
arch/powerpc/lib/crc32-glue.c, view this commit with 'git show -M10'.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/powerpc/Kconfig                          |   1 +
 arch/powerpc/configs/powernv_defconfig        |   1 -
 arch/powerpc/configs/ppc64_defconfig          |   1 -
 arch/powerpc/crypto/Kconfig                   |  15 +-
 arch/powerpc/crypto/Makefile                  |   2 -
 arch/powerpc/crypto/crc32c-vpmsum_glue.c      | 173 ------------------
 arch/powerpc/crypto/crct10dif-vpmsum_asm.S    |   2 +-
 arch/powerpc/lib/Makefile                     |   3 +
 arch/powerpc/lib/crc32-glue.c                 |  92 ++++++++++
 .../{crypto => lib}/crc32-vpmsum_core.S       |   0
 .../{crypto => lib}/crc32c-vpmsum_asm.S       |   0
 11 files changed, 98 insertions(+), 192 deletions(-)
 delete mode 100644 arch/powerpc/crypto/crc32c-vpmsum_glue.c
 create mode 100644 arch/powerpc/lib/crc32-glue.c
 rename arch/powerpc/{crypto => lib}/crc32-vpmsum_core.S (100%)
 rename arch/powerpc/{crypto => lib}/crc32c-vpmsum_asm.S (100%)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 8094a01974cc..b05889400b04 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -125,10 +125,11 @@ config PPC
 	select ARCH_DISABLE_KASAN_INLINE	if PPC_RADIX_MMU
 	select ARCH_DMA_DEFAULT_COHERENT	if !NOT_COHERENT_CACHE
 	select ARCH_ENABLE_MEMORY_HOTPLUG
 	select ARCH_ENABLE_MEMORY_HOTREMOVE
 	select ARCH_HAS_COPY_MC			if PPC64
+	select ARCH_HAS_CRC32			if PPC64 && ALTIVEC
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select ARCH_HAS_DEBUG_WX		if STRICT_KERNEL_RWX
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
index ee84ade7a033..4a7ddea05b4d 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -318,11 +318,10 @@ CONFIG_FTR_FIXUP_SELFTEST=y
 CONFIG_MSI_BITMAP_SELFTEST=y
 CONFIG_XMON=y
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_CRC32C_VPMSUM=m
 CONFIG_CRYPTO_CRCT10DIF_VPMSUM=m
 CONFIG_CRYPTO_MD5_PPC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA1_PPC=m
 CONFIG_CRYPTO_SHA256=y
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index a5e3e7f97f4d..ea01c0d6705f 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -388,11 +388,10 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_LZO=m
-CONFIG_CRYPTO_CRC32C_VPMSUM=m
 CONFIG_CRYPTO_CRCT10DIF_VPMSUM=m
 CONFIG_CRYPTO_VPMSUM_TESTER=m
 CONFIG_CRYPTO_MD5_PPC=m
 CONFIG_CRYPTO_SHA1_PPC=m
 CONFIG_CRYPTO_AES_GCM_P10=m
diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig
index 46a4c85e85e2..5c016ec39530 100644
--- a/arch/powerpc/crypto/Kconfig
+++ b/arch/powerpc/crypto/Kconfig
@@ -11,23 +11,10 @@ config CRYPTO_CURVE25519_PPC64
 	  Curve25519 algorithm
 
 	  Architecture: PowerPC64
 	  - Little-endian
 
-config CRYPTO_CRC32C_VPMSUM
-	tristate "CRC32c"
-	depends on PPC64 && ALTIVEC
-	select CRYPTO_HASH
-	select CRC32
-	help
-	  CRC32c CRC algorithm with the iSCSI polynomial (RFC 3385 and RFC 3720)
-
-	  Architecture: powerpc64 using
-	  - AltiVec extensions
-
-	  Enable on POWER8 and newer processors for improved performance.
-
 config CRYPTO_CRCT10DIF_VPMSUM
 	tristate "CRC32T10DIF"
 	depends on PPC64 && ALTIVEC && CRC_T10DIF
 	select CRYPTO_HASH
 	help
@@ -38,11 +25,11 @@ config CRYPTO_CRCT10DIF_VPMSUM
 
 	  Enable on POWER8 and newer processors for improved performance.
 
 config CRYPTO_VPMSUM_TESTER
 	tristate "CRC32c and CRC32T10DIF hardware acceleration tester"
-	depends on CRYPTO_CRCT10DIF_VPMSUM && CRYPTO_CRC32C_VPMSUM
+	depends on CRYPTO_CRCT10DIF_VPMSUM && CRC32_ARCH
 	help
 	  Stress test for CRC32c and CRCT10DIF algorithms implemented with
 	  powerpc64 AltiVec extensions (POWER8 vpmsum instructions).
 	  Unless you are testing these algorithms, you don't need this.
 
diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile
index 59808592f0a1..54486192273c 100644
--- a/arch/powerpc/crypto/Makefile
+++ b/arch/powerpc/crypto/Makefile
@@ -8,11 +8,10 @@
 obj-$(CONFIG_CRYPTO_AES_PPC_SPE) += aes-ppc-spe.o
 obj-$(CONFIG_CRYPTO_MD5_PPC) += md5-ppc.o
 obj-$(CONFIG_CRYPTO_SHA1_PPC) += sha1-powerpc.o
 obj-$(CONFIG_CRYPTO_SHA1_PPC_SPE) += sha1-ppc-spe.o
 obj-$(CONFIG_CRYPTO_SHA256_PPC_SPE) += sha256-ppc-spe.o
-obj-$(CONFIG_CRYPTO_CRC32C_VPMSUM) += crc32c-vpmsum.o
 obj-$(CONFIG_CRYPTO_CRCT10DIF_VPMSUM) += crct10dif-vpmsum.o
 obj-$(CONFIG_CRYPTO_VPMSUM_TESTER) += crc-vpmsum_test.o
 obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o
 obj-$(CONFIG_CRYPTO_CHACHA20_P10) += chacha-p10-crypto.o
 obj-$(CONFIG_CRYPTO_POLY1305_P10) += poly1305-p10-crypto.o
@@ -22,11 +21,10 @@ obj-$(CONFIG_CRYPTO_CURVE25519_PPC64) += curve25519-ppc64le.o
 aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o
 md5-ppc-y := md5-asm.o md5-glue.o
 sha1-powerpc-y := sha1-powerpc-asm.o sha1.o
 sha1-ppc-spe-y := sha1-spe-asm.o sha1-spe-glue.o
 sha256-ppc-spe-y := sha256-spe-asm.o sha256-spe-glue.o
-crc32c-vpmsum-y := crc32c-vpmsum_asm.o crc32c-vpmsum_glue.o
 crct10dif-vpmsum-y := crct10dif-vpmsum_asm.o crct10dif-vpmsum_glue.o
 aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-ppc.o
 chacha-p10-crypto-y := chacha-p10-glue.o chacha-p10le-8x.o
 poly1305-p10-crypto-y := poly1305-p10-glue.o poly1305-p10le_64.o
 vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o
diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c
deleted file mode 100644
index 63760b7dbb76..000000000000
--- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c
+++ /dev/null
@@ -1,173 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#include <linux/crc32.h>
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/cpufeature.h>
-#include <asm/simd.h>
-#include <asm/switch_to.h>
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-#define VMX_ALIGN		16
-#define VMX_ALIGN_MASK		(VMX_ALIGN-1)
-
-#define VECTOR_BREAKPOINT	512
-
-u32 __crc32c_vpmsum(u32 crc, unsigned char const *p, size_t len);
-
-static u32 crc32c_vpmsum(u32 crc, unsigned char const *p, size_t len)
-{
-	unsigned int prealign;
-	unsigned int tail;
-
-	if (len < (VECTOR_BREAKPOINT + VMX_ALIGN) || !crypto_simd_usable())
-		return __crc32c_le(crc, p, len);
-
-	if ((unsigned long)p & VMX_ALIGN_MASK) {
-		prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK);
-		crc = __crc32c_le(crc, p, prealign);
-		len -= prealign;
-		p += prealign;
-	}
-
-	if (len & ~VMX_ALIGN_MASK) {
-		preempt_disable();
-		pagefault_disable();
-		enable_kernel_altivec();
-		crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK);
-		disable_kernel_altivec();
-		pagefault_enable();
-		preempt_enable();
-	}
-
-	tail = len & VMX_ALIGN_MASK;
-	if (tail) {
-		p += len & ~VMX_ALIGN_MASK;
-		crc = __crc32c_le(crc, p, tail);
-	}
-
-	return crc;
-}
-
-static int crc32c_vpmsum_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = ~0;
-
-	return 0;
-}
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set
- * the seed.
- */
-static int crc32c_vpmsum_setkey(struct crypto_shash *hash, const u8 *key,
-			       unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = le32_to_cpup((__le32 *)key);
-	return 0;
-}
-
-static int crc32c_vpmsum_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = *mctx;
-
-	return 0;
-}
-
-static int crc32c_vpmsum_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = crc32c_vpmsum(*crcp, data, len);
-
-	return 0;
-}
-
-static int __crc32c_vpmsum_finup(u32 *crcp, const u8 *data, unsigned int len,
-				u8 *out)
-{
-	*(__le32 *)out = ~cpu_to_le32(crc32c_vpmsum(*crcp, data, len));
-
-	return 0;
-}
-
-static int crc32c_vpmsum_finup(struct shash_desc *desc, const u8 *data,
-			      unsigned int len, u8 *out)
-{
-	return __crc32c_vpmsum_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32c_vpmsum_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*(__le32 *)out = ~cpu_to_le32p(crcp);
-
-	return 0;
-}
-
-static int crc32c_vpmsum_digest(struct shash_desc *desc, const u8 *data,
-			       unsigned int len, u8 *out)
-{
-	return __crc32c_vpmsum_finup(crypto_shash_ctx(desc->tfm), data, len,
-				     out);
-}
-
-static struct shash_alg alg = {
-	.setkey		= crc32c_vpmsum_setkey,
-	.init		= crc32c_vpmsum_init,
-	.update		= crc32c_vpmsum_update,
-	.final		= crc32c_vpmsum_final,
-	.finup		= crc32c_vpmsum_finup,
-	.digest		= crc32c_vpmsum_digest,
-	.descsize	= sizeof(u32),
-	.digestsize	= CHKSUM_DIGEST_SIZE,
-	.base		= {
-		.cra_name		= "crc32c",
-		.cra_driver_name	= "crc32c-vpmsum",
-		.cra_priority		= 200,
-		.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		= CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		= sizeof(u32),
-		.cra_module		= THIS_MODULE,
-		.cra_init		= crc32c_vpmsum_cra_init,
-	}
-};
-
-static int __init crc32c_vpmsum_mod_init(void)
-{
-	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
-		return -ENODEV;
-
-	return crypto_register_shash(&alg);
-}
-
-static void __exit crc32c_vpmsum_mod_fini(void)
-{
-	crypto_unregister_shash(&alg);
-}
-
-module_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, crc32c_vpmsum_mod_init);
-module_exit(crc32c_vpmsum_mod_fini);
-
-MODULE_AUTHOR("Anton Blanchard <anton at samba.org>");
-MODULE_DESCRIPTION("CRC32C using vector polynomial multiply-sum instructions");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_CRYPTO("crc32c");
-MODULE_ALIAS_CRYPTO("crc32c-vpmsum");
diff --git a/arch/powerpc/crypto/crct10dif-vpmsum_asm.S b/arch/powerpc/crypto/crct10dif-vpmsum_asm.S
index f0b93a0fe168..0a52261bf859 100644
--- a/arch/powerpc/crypto/crct10dif-vpmsum_asm.S
+++ b/arch/powerpc/crypto/crct10dif-vpmsum_asm.S
@@ -840,6 +840,6 @@
 	.octa 0x000000000000000000000001f65a57f8	/* x^64 div p(x) */
 	/* Barrett constant n */
 	.octa 0x0000000000000000000000018bb70000
 
 #define CRC_FUNCTION_NAME __crct10dif_vpmsum
-#include "crc32-vpmsum_core.S"
+#include "../lib/crc32-vpmsum_core.S"
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index f14ecab674a3..da9381a1c95b 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -76,6 +76,9 @@ obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o
 obj-$(CONFIG_ALTIVEC)	+= xor_vmx.o xor_vmx_glue.o
 CFLAGS_xor_vmx.o += -mhard-float -maltivec $(call cc-option,-mabi=altivec)
 # Enable <altivec.h>
 CFLAGS_xor_vmx.o += -isystem $(shell $(CC) -print-file-name=include)
 
+obj-$(CONFIG_CRC32_ARCH) += crc32-powerpc.o
+crc32-powerpc-y := crc32-glue.o crc32c-vpmsum_asm.o
+
 obj-$(CONFIG_PPC64) += $(obj64-y)
diff --git a/arch/powerpc/lib/crc32-glue.c b/arch/powerpc/lib/crc32-glue.c
new file mode 100644
index 000000000000..e9730f028afb
--- /dev/null
+++ b/arch/powerpc/lib/crc32-glue.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/crc32.h>
+#include <crypto/internal/simd.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/cpufeature.h>
+#include <asm/simd.h>
+#include <asm/switch_to.h>
+
+#define VMX_ALIGN		16
+#define VMX_ALIGN_MASK		(VMX_ALIGN-1)
+
+#define VECTOR_BREAKPOINT	512
+
+static DEFINE_STATIC_KEY_FALSE(have_vec_crypto);
+
+u32 __crc32c_vpmsum(u32 crc, const u8 *p, size_t len);
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_le_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	unsigned int prealign;
+	unsigned int tail;
+
+	if (len < (VECTOR_BREAKPOINT + VMX_ALIGN) || !crypto_simd_usable() ||
+	    !static_branch_likely(&have_vec_crypto))
+		return crc32c_le_base(crc, p, len);
+
+	if ((unsigned long)p & VMX_ALIGN_MASK) {
+		prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK);
+		crc = crc32c_le_base(crc, p, prealign);
+		len -= prealign;
+		p += prealign;
+	}
+
+	if (len & ~VMX_ALIGN_MASK) {
+		preempt_disable();
+		pagefault_disable();
+		enable_kernel_altivec();
+		crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK);
+		disable_kernel_altivec();
+		pagefault_enable();
+		preempt_enable();
+	}
+
+	tail = len & VMX_ALIGN_MASK;
+	if (tail) {
+		p += len & ~VMX_ALIGN_MASK;
+		crc = crc32c_le_base(crc, p, tail);
+	}
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_powerpc_init(void)
+{
+	if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
+	    (cur_cpu_spec->cpu_user_features2 & PPC_FEATURE2_VEC_CRYPTO))
+		static_branch_enable(&have_vec_crypto);
+	return 0;
+}
+arch_initcall(crc32_powerpc_init);
+
+static void __exit crc32_powerpc_exit(void)
+{
+}
+module_exit(crc32_powerpc_exit);
+
+u32 crc32_optimizations(void)
+{
+	if (static_key_enabled(&have_vec_crypto))
+		return CRC32C_OPTIMIZATION;
+	return 0;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_AUTHOR("Anton Blanchard <anton at samba.org>");
+MODULE_DESCRIPTION("CRC32C using vector polynomial multiply-sum instructions");
+MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/crypto/crc32-vpmsum_core.S b/arch/powerpc/lib/crc32-vpmsum_core.S
similarity index 100%
rename from arch/powerpc/crypto/crc32-vpmsum_core.S
rename to arch/powerpc/lib/crc32-vpmsum_core.S
diff --git a/arch/powerpc/crypto/crc32c-vpmsum_asm.S b/arch/powerpc/lib/crc32c-vpmsum_asm.S
similarity index 100%
rename from arch/powerpc/crypto/crc32c-vpmsum_asm.S
rename to arch/powerpc/lib/crc32c-vpmsum_asm.S
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:49 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:49 -0800
Subject: [PATCH v3 13/18] x86/crc32: expose CRC32 functions through lib
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-14-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Move the x86 CRC32 assembly code into the lib directory and wire it up
to the library interface.  This allows it to be used without going
through the crypto API.  It remains usable via the crypto API too via
the shash algorithms that use the library interface.  Thus all the
arch-specific "shash" code becomes unnecessary and is removed.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 arch/x86/Kconfig                              |   1 +
 arch/x86/crypto/Kconfig                       |  22 --
 arch/x86/crypto/Makefile                      |   7 -
 arch/x86/crypto/crc32-pclmul_glue.c           | 202 --------------
 arch/x86/crypto/crc32c-intel_glue.c           | 249 ------------------
 arch/x86/lib/Makefile                         |   4 +
 arch/x86/lib/crc32-glue.c                     | 124 +++++++++
 .../crc32-pclmul_asm.S => lib/crc32-pclmul.S} |   0
 .../crc32c-3way.S}                            |   0
 drivers/target/iscsi/Kconfig                  |   1 -
 10 files changed, 129 insertions(+), 481 deletions(-)
 delete mode 100644 arch/x86/crypto/crc32-pclmul_glue.c
 delete mode 100644 arch/x86/crypto/crc32c-intel_glue.c
 create mode 100644 arch/x86/lib/crc32-glue.c
 rename arch/x86/{crypto/crc32-pclmul_asm.S => lib/crc32-pclmul.S} (100%)
 rename arch/x86/{crypto/crc32c-pcl-intel-asm_64.S => lib/crc32c-3way.S} (100%)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 16354dfa6d96..e7470de11cec 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -74,10 +74,11 @@ config X86
 	select ARCH_HAS_ACPI_TABLE_UPGRADE	if ACPI
 	select ARCH_HAS_CACHE_LINE_SIZE
 	select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
 	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_CPU_PASID		if IOMMU_SVA
+	select ARCH_HAS_CRC32
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEBUG_VM_PGTABLE	if !X86_PAE
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_DMA_OPS			if GART_IOMMU || XEN
diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
index 7b1bebed879d..1ca53e847966 100644
--- a/arch/x86/crypto/Kconfig
+++ b/arch/x86/crypto/Kconfig
@@ -490,32 +490,10 @@ config CRYPTO_GHASH_CLMUL_NI_INTEL
 	  GCM GHASH hash function (NIST SP800-38D)
 
 	  Architecture: x86_64 using:
 	  - CLMUL-NI (carry-less multiplication new instructions)
 
-config CRYPTO_CRC32C_INTEL
-	tristate "CRC32c (SSE4.2/PCLMULQDQ)"
-	depends on X86
-	select CRYPTO_HASH
-	help
-	  CRC32c CRC algorithm with the iSCSI polynomial (RFC 3385 and RFC 3720)
-
-	  Architecture: x86 (32-bit and 64-bit) using:
-	  - SSE4.2 (Streaming SIMD Extensions 4.2) CRC32 instruction
-	  - PCLMULQDQ (carry-less multiplication)
-
-config CRYPTO_CRC32_PCLMUL
-	tristate "CRC32 (PCLMULQDQ)"
-	depends on X86
-	select CRYPTO_HASH
-	select CRC32
-	help
-	  CRC32 CRC algorithm (IEEE 802.3)
-
-	  Architecture: x86 (32-bit and 64-bit) using:
-	  - PCLMULQDQ (carry-less multiplication)
-
 config CRYPTO_CRCT10DIF_PCLMUL
 	tristate "CRCT10DIF (PCLMULQDQ)"
 	depends on X86 && 64BIT && CRC_T10DIF
 	select CRYPTO_HASH
 	help
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 53b4a277809e..030b925ca4e2 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -73,17 +73,10 @@ obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
 ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o
 
 obj-$(CONFIG_CRYPTO_POLYVAL_CLMUL_NI) += polyval-clmulni.o
 polyval-clmulni-y := polyval-clmulni_asm.o polyval-clmulni_glue.o
 
-obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
-crc32c-intel-y := crc32c-intel_glue.o
-crc32c-intel-$(CONFIG_64BIT) += crc32c-pcl-intel-asm_64.o
-
-obj-$(CONFIG_CRYPTO_CRC32_PCLMUL) += crc32-pclmul.o
-crc32-pclmul-y := crc32-pclmul_asm.o crc32-pclmul_glue.o
-
 obj-$(CONFIG_CRYPTO_CRCT10DIF_PCLMUL) += crct10dif-pclmul.o
 crct10dif-pclmul-y := crct10dif-pcl-asm_64.o crct10dif-pclmul_glue.o
 
 obj-$(CONFIG_CRYPTO_POLY1305_X86_64) += poly1305-x86_64.o
 poly1305-x86_64-y := poly1305-x86_64-cryptogams.o poly1305_glue.o
diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c
deleted file mode 100644
index 9d14eac51c5b..000000000000
--- a/arch/x86/crypto/crc32-pclmul_glue.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please  visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
-/*
- * Copyright 2012 Xyratex Technology Limited
- *
- * Wrappers for kernel crypto shash api to pclmulqdq crc32 implementation.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/crc32.h>
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-
-#include <asm/cpufeatures.h>
-#include <asm/cpu_device_id.h>
-#include <asm/simd.h>
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-#define PCLMUL_MIN_LEN		64L     /* minimum size of buffer
-					 * for crc32_pclmul_le_16 */
-#define SCALE_F			16L	/* size of xmm register */
-#define SCALE_F_MASK		(SCALE_F - 1)
-
-u32 crc32_pclmul_le_16(u32 crc, const u8 *buffer, size_t len);
-
-static u32 __attribute__((pure))
-	crc32_pclmul_le(u32 crc, unsigned char const *p, size_t len)
-{
-	unsigned int iquotient;
-	unsigned int iremainder;
-	unsigned int prealign;
-
-	if (len < PCLMUL_MIN_LEN + SCALE_F_MASK || !crypto_simd_usable())
-		return crc32_le(crc, p, len);
-
-	if ((long)p & SCALE_F_MASK) {
-		/* align p to 16 byte */
-		prealign = SCALE_F - ((long)p & SCALE_F_MASK);
-
-		crc = crc32_le(crc, p, prealign);
-		len -= prealign;
-		p = (unsigned char *)(((unsigned long)p + SCALE_F_MASK) &
-				     ~SCALE_F_MASK);
-	}
-	iquotient = len & (~SCALE_F_MASK);
-	iremainder = len & SCALE_F_MASK;
-
-	kernel_fpu_begin();
-	crc = crc32_pclmul_le_16(crc, p, iquotient);
-	kernel_fpu_end();
-
-	if (iremainder)
-		crc = crc32_le(crc, p + iquotient, iremainder);
-
-	return crc;
-}
-
-static int crc32_pclmul_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = 0;
-
-	return 0;
-}
-
-static int crc32_pclmul_setkey(struct crypto_shash *hash, const u8 *key,
-			unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = le32_to_cpup((__le32 *)key);
-	return 0;
-}
-
-static int crc32_pclmul_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = *mctx;
-
-	return 0;
-}
-
-static int crc32_pclmul_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = crc32_pclmul_le(*crcp, data, len);
-	return 0;
-}
-
-/* No final XOR 0xFFFFFFFF, like crc32_le */
-static int __crc32_pclmul_finup(u32 *crcp, const u8 *data, unsigned int len,
-				u8 *out)
-{
-	*(__le32 *)out = cpu_to_le32(crc32_pclmul_le(*crcp, data, len));
-	return 0;
-}
-
-static int crc32_pclmul_finup(struct shash_desc *desc, const u8 *data,
-			      unsigned int len, u8 *out)
-{
-	return __crc32_pclmul_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32_pclmul_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*(__le32 *)out = cpu_to_le32p(crcp);
-	return 0;
-}
-
-static int crc32_pclmul_digest(struct shash_desc *desc, const u8 *data,
-			       unsigned int len, u8 *out)
-{
-	return __crc32_pclmul_finup(crypto_shash_ctx(desc->tfm), data, len,
-				    out);
-}
-
-static struct shash_alg alg = {
-	.setkey		= crc32_pclmul_setkey,
-	.init		= crc32_pclmul_init,
-	.update		= crc32_pclmul_update,
-	.final		= crc32_pclmul_final,
-	.finup		= crc32_pclmul_finup,
-	.digest		= crc32_pclmul_digest,
-	.descsize	= sizeof(u32),
-	.digestsize	= CHKSUM_DIGEST_SIZE,
-	.base		= {
-			.cra_name		= "crc32",
-			.cra_driver_name	= "crc32-pclmul",
-			.cra_priority		= 200,
-			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
-			.cra_blocksize		= CHKSUM_BLOCK_SIZE,
-			.cra_ctxsize		= sizeof(u32),
-			.cra_module		= THIS_MODULE,
-			.cra_init		= crc32_pclmul_cra_init,
-	}
-};
-
-static const struct x86_cpu_id crc32pclmul_cpu_id[] = {
-	X86_MATCH_FEATURE(X86_FEATURE_PCLMULQDQ, NULL),
-	{}
-};
-MODULE_DEVICE_TABLE(x86cpu, crc32pclmul_cpu_id);
-
-
-static int __init crc32_pclmul_mod_init(void)
-{
-
-	if (!x86_match_cpu(crc32pclmul_cpu_id)) {
-		pr_info("PCLMULQDQ-NI instructions are not detected.\n");
-		return -ENODEV;
-	}
-	return crypto_register_shash(&alg);
-}
-
-static void __exit crc32_pclmul_mod_fini(void)
-{
-	crypto_unregister_shash(&alg);
-}
-
-module_init(crc32_pclmul_mod_init);
-module_exit(crc32_pclmul_mod_fini);
-
-MODULE_AUTHOR("Alexander Boyko <alexander_boyko at xyratex.com>");
-MODULE_DESCRIPTION("CRC32 algorithm (IEEE 802.3) accelerated with PCLMULQDQ");
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS_CRYPTO("crc32");
-MODULE_ALIAS_CRYPTO("crc32-pclmul");
diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c
deleted file mode 100644
index 603d159de400..000000000000
--- a/arch/x86/crypto/crc32c-intel_glue.c
+++ /dev/null
@@ -1,249 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Using hardware provided CRC32 instruction to accelerate the CRC32 disposal.
- * CRC32C polynomial:0x1EDC6F41(BE)/0x82F63B78(LE)
- * CRC32 is a new instruction in Intel SSE4.2, the reference can be found at:
- * http://www.intel.com/products/processor/manuals/
- * Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- * Volume 2A: Instruction Set Reference, A-M
- *
- * Copyright (C) 2008 Intel Corporation
- * Authors: Austin Zhang <austin_zhang at linux.intel.com>
- *          Kent Liu <kent.liu at intel.com>
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <crypto/internal/hash.h>
-#include <crypto/internal/simd.h>
-
-#include <asm/cpufeatures.h>
-#include <asm/cpu_device_id.h>
-#include <asm/simd.h>
-
-#define CHKSUM_BLOCK_SIZE	1
-#define CHKSUM_DIGEST_SIZE	4
-
-#define SCALE_F	sizeof(unsigned long)
-
-#ifdef CONFIG_X86_64
-#define CRC32_INST "crc32q %1, %q0"
-#else
-#define CRC32_INST "crc32l %1, %0"
-#endif
-
-#ifdef CONFIG_X86_64
-/*
- * use carryless multiply version of crc32c when buffer
- * size is >= 512 to account
- * for fpu state save/restore overhead.
- */
-#define CRC32C_PCL_BREAKEVEN	512
-
-asmlinkage u32 crc32c_x86_3way(u32 crc, const u8 *buffer, size_t len);
-#endif /* CONFIG_X86_64 */
-
-static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length)
-{
-	while (length--) {
-		asm("crc32b %1, %0"
-		    : "+r" (crc) : "rm" (*data));
-		data++;
-	}
-
-	return crc;
-}
-
-static u32 __pure crc32c_intel_le_hw(u32 crc, unsigned char const *p, size_t len)
-{
-	unsigned int iquotient = len / SCALE_F;
-	unsigned int iremainder = len % SCALE_F;
-	unsigned long *ptmp = (unsigned long *)p;
-
-	while (iquotient--) {
-		asm(CRC32_INST
-		    : "+r" (crc) : "rm" (*ptmp));
-		ptmp++;
-	}
-
-	if (iremainder)
-		crc = crc32c_intel_le_hw_byte(crc, (unsigned char *)ptmp,
-				 iremainder);
-
-	return crc;
-}
-
-/*
- * Setting the seed allows arbitrary accumulators and flexible XOR policy
- * If your algorithm starts with ~0, then XOR with ~0 before you set
- * the seed.
- */
-static int crc32c_intel_setkey(struct crypto_shash *hash, const u8 *key,
-			unsigned int keylen)
-{
-	u32 *mctx = crypto_shash_ctx(hash);
-
-	if (keylen != sizeof(u32))
-		return -EINVAL;
-	*mctx = le32_to_cpup((__le32 *)key);
-	return 0;
-}
-
-static int crc32c_intel_init(struct shash_desc *desc)
-{
-	u32 *mctx = crypto_shash_ctx(desc->tfm);
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = *mctx;
-
-	return 0;
-}
-
-static int crc32c_intel_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*crcp = crc32c_intel_le_hw(*crcp, data, len);
-	return 0;
-}
-
-static int __crc32c_intel_finup(u32 *crcp, const u8 *data, unsigned int len,
-				u8 *out)
-{
-	*(__le32 *)out = ~cpu_to_le32(crc32c_intel_le_hw(*crcp, data, len));
-	return 0;
-}
-
-static int crc32c_intel_finup(struct shash_desc *desc, const u8 *data,
-			      unsigned int len, u8 *out)
-{
-	return __crc32c_intel_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32c_intel_final(struct shash_desc *desc, u8 *out)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	*(__le32 *)out = ~cpu_to_le32p(crcp);
-	return 0;
-}
-
-static int crc32c_intel_digest(struct shash_desc *desc, const u8 *data,
-			       unsigned int len, u8 *out)
-{
-	return __crc32c_intel_finup(crypto_shash_ctx(desc->tfm), data, len,
-				    out);
-}
-
-static int crc32c_intel_cra_init(struct crypto_tfm *tfm)
-{
-	u32 *key = crypto_tfm_ctx(tfm);
-
-	*key = ~0;
-
-	return 0;
-}
-
-#ifdef CONFIG_X86_64
-static int crc32c_pcl_intel_update(struct shash_desc *desc, const u8 *data,
-			       unsigned int len)
-{
-	u32 *crcp = shash_desc_ctx(desc);
-
-	/*
-	 * use faster PCL version if datasize is large enough to
-	 * overcome kernel fpu state save/restore overhead
-	 */
-	if (len >= CRC32C_PCL_BREAKEVEN && crypto_simd_usable()) {
-		kernel_fpu_begin();
-		*crcp = crc32c_x86_3way(*crcp, data, len);
-		kernel_fpu_end();
-	} else
-		*crcp = crc32c_intel_le_hw(*crcp, data, len);
-	return 0;
-}
-
-static int __crc32c_pcl_intel_finup(u32 *crcp, const u8 *data, unsigned int len,
-				u8 *out)
-{
-	if (len >= CRC32C_PCL_BREAKEVEN && crypto_simd_usable()) {
-		kernel_fpu_begin();
-		*(__le32 *)out = ~cpu_to_le32(crc32c_x86_3way(*crcp, data, len));
-		kernel_fpu_end();
-	} else
-		*(__le32 *)out =
-			~cpu_to_le32(crc32c_intel_le_hw(*crcp, data, len));
-	return 0;
-}
-
-static int crc32c_pcl_intel_finup(struct shash_desc *desc, const u8 *data,
-			      unsigned int len, u8 *out)
-{
-	return __crc32c_pcl_intel_finup(shash_desc_ctx(desc), data, len, out);
-}
-
-static int crc32c_pcl_intel_digest(struct shash_desc *desc, const u8 *data,
-			       unsigned int len, u8 *out)
-{
-	return __crc32c_pcl_intel_finup(crypto_shash_ctx(desc->tfm), data, len,
-				    out);
-}
-#endif /* CONFIG_X86_64 */
-
-static struct shash_alg alg = {
-	.setkey			=	crc32c_intel_setkey,
-	.init			=	crc32c_intel_init,
-	.update			=	crc32c_intel_update,
-	.final			=	crc32c_intel_final,
-	.finup			=	crc32c_intel_finup,
-	.digest			=	crc32c_intel_digest,
-	.descsize		=	sizeof(u32),
-	.digestsize		=	CHKSUM_DIGEST_SIZE,
-	.base			=	{
-		.cra_name		=	"crc32c",
-		.cra_driver_name	=	"crc32c-intel",
-		.cra_priority		=	200,
-		.cra_flags		=	CRYPTO_ALG_OPTIONAL_KEY,
-		.cra_blocksize		=	CHKSUM_BLOCK_SIZE,
-		.cra_ctxsize		=	sizeof(u32),
-		.cra_module		=	THIS_MODULE,
-		.cra_init		=	crc32c_intel_cra_init,
-	}
-};
-
-static const struct x86_cpu_id crc32c_cpu_id[] = {
-	X86_MATCH_FEATURE(X86_FEATURE_XMM4_2, NULL),
-	{}
-};
-MODULE_DEVICE_TABLE(x86cpu, crc32c_cpu_id);
-
-static int __init crc32c_intel_mod_init(void)
-{
-	if (!x86_match_cpu(crc32c_cpu_id))
-		return -ENODEV;
-#ifdef CONFIG_X86_64
-	if (boot_cpu_has(X86_FEATURE_PCLMULQDQ)) {
-		alg.update = crc32c_pcl_intel_update;
-		alg.finup = crc32c_pcl_intel_finup;
-		alg.digest = crc32c_pcl_intel_digest;
-	}
-#endif
-	return crypto_register_shash(&alg);
-}
-
-static void __exit crc32c_intel_mod_fini(void)
-{
-	crypto_unregister_shash(&alg);
-}
-
-module_init(crc32c_intel_mod_init);
-module_exit(crc32c_intel_mod_fini);
-
-MODULE_AUTHOR("Austin Zhang <austin.zhang at intel.com>, Kent Liu <kent.liu at intel.com>");
-MODULE_DESCRIPTION("CRC32c (Castagnoli) optimization using Intel Hardware.");
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS_CRYPTO("crc32c");
-MODULE_ALIAS_CRYPTO("crc32c-intel");
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 98583a9dbab3..17510da06c9f 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -36,10 +36,14 @@ lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc.o copy_mc_64.o
 lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o
 lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
 lib-$(CONFIG_FUNCTION_ERROR_INJECTION)	+= error-inject.o
 lib-$(CONFIG_MITIGATION_RETPOLINE) += retpoline.o
 
+obj-$(CONFIG_CRC32_ARCH) += crc32-x86.o
+crc32-x86-y := crc32-glue.o crc32-pclmul.o
+crc32-x86-$(CONFIG_64BIT) += crc32c-3way.o
+
 obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o
 obj-y += iomem.o
 
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
diff --git a/arch/x86/lib/crc32-glue.c b/arch/x86/lib/crc32-glue.c
new file mode 100644
index 000000000000..9fcc65db6cb5
--- /dev/null
+++ b/arch/x86/lib/crc32-glue.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * x86-optimized CRC32 functions
+ *
+ * Copyright (C) 2008 Intel Corporation
+ * Copyright 2012 Xyratex Technology Limited
+ * Copyright 2024 Google LLC
+ */
+
+#include <asm/cpufeatures.h>
+#include <asm/simd.h>
+#include <crypto/internal/simd.h>
+#include <linux/crc32.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+/* minimum size of buffer for crc32_pclmul_le_16 */
+#define CRC32_PCLMUL_MIN_LEN	64
+
+static DEFINE_STATIC_KEY_FALSE(have_crc32);
+static DEFINE_STATIC_KEY_FALSE(have_pclmulqdq);
+
+u32 crc32_pclmul_le_16(u32 crc, const u8 *buffer, size_t len);
+
+u32 crc32_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	if (len >= CRC32_PCLMUL_MIN_LEN + 15 &&
+	    crypto_simd_usable() && static_branch_likely(&have_pclmulqdq)) {
+		size_t n = -(uintptr_t)p & 15;
+
+		/* align p to 16-byte boundary */
+		if (n) {
+			crc = crc32_le_base(crc, p, n);
+			p += n;
+			len -= n;
+		}
+		n = round_down(len, 16);
+		kernel_fpu_begin();
+		crc = crc32_pclmul_le_16(crc, p, n);
+		kernel_fpu_end();
+		p += n;
+		len -= n;
+	}
+	if (len)
+		crc = crc32_le_base(crc, p, len);
+	return crc;
+}
+EXPORT_SYMBOL(crc32_le_arch);
+
+#ifdef CONFIG_X86_64
+#define CRC32_INST "crc32q %1, %q0"
+#else
+#define CRC32_INST "crc32l %1, %0"
+#endif
+
+/*
+ * Use carryless multiply version of crc32c when buffer size is >= 512 to
+ * account for FPU state save/restore overhead.
+ */
+#define CRC32C_PCLMUL_BREAKEVEN	512
+
+asmlinkage u32 crc32c_x86_3way(u32 crc, const u8 *buffer, size_t len);
+
+u32 crc32c_le_arch(u32 crc, const u8 *p, size_t len)
+{
+	size_t num_longs;
+
+	if (!static_branch_likely(&have_crc32))
+		return crc32c_le_base(crc, p, len);
+
+	if (IS_ENABLED(CONFIG_X86_64) && len >= CRC32C_PCLMUL_BREAKEVEN &&
+	    crypto_simd_usable() && static_branch_likely(&have_pclmulqdq)) {
+		kernel_fpu_begin();
+		crc = crc32c_x86_3way(crc, p, len);
+		kernel_fpu_end();
+		return crc;
+	}
+
+	for (num_longs = len / sizeof(unsigned long);
+	     num_longs != 0; num_longs--, p += sizeof(unsigned long))
+		asm(CRC32_INST : "+r" (crc) : "rm" (*(unsigned long *)p));
+
+	for (len %= sizeof(unsigned long); len; len--, p++)
+		asm("crc32b %1, %0" : "+r" (crc) : "rm" (*p));
+
+	return crc;
+}
+EXPORT_SYMBOL(crc32c_le_arch);
+
+u32 crc32_be_arch(u32 crc, const u8 *p, size_t len)
+{
+	return crc32_be_base(crc, p, len);
+}
+EXPORT_SYMBOL(crc32_be_arch);
+
+static int __init crc32_x86_init(void)
+{
+	if (boot_cpu_has(X86_FEATURE_XMM4_2))
+		static_branch_enable(&have_crc32);
+	if (boot_cpu_has(X86_FEATURE_PCLMULQDQ))
+		static_branch_enable(&have_pclmulqdq);
+	return 0;
+}
+arch_initcall(crc32_x86_init);
+
+static void __exit crc32_x86_exit(void)
+{
+}
+module_exit(crc32_x86_exit);
+
+u32 crc32_optimizations(void)
+{
+	u32 optimizations = 0;
+
+	if (static_key_enabled(&have_crc32))
+		optimizations |= CRC32C_OPTIMIZATION;
+	if (static_key_enabled(&have_pclmulqdq))
+		optimizations |= CRC32_LE_OPTIMIZATION;
+	return optimizations;
+}
+EXPORT_SYMBOL(crc32_optimizations);
+
+MODULE_DESCRIPTION("x86-optimized CRC32 functions");
+MODULE_LICENSE("GPL");
diff --git a/arch/x86/crypto/crc32-pclmul_asm.S b/arch/x86/lib/crc32-pclmul.S
similarity index 100%
rename from arch/x86/crypto/crc32-pclmul_asm.S
rename to arch/x86/lib/crc32-pclmul.S
diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/lib/crc32c-3way.S
similarity index 100%
rename from arch/x86/crypto/crc32c-pcl-intel-asm_64.S
rename to arch/x86/lib/crc32c-3way.S
diff --git a/drivers/target/iscsi/Kconfig b/drivers/target/iscsi/Kconfig
index 922b207bc69d..1c0517a12571 100644
--- a/drivers/target/iscsi/Kconfig
+++ b/drivers/target/iscsi/Kconfig
@@ -2,11 +2,10 @@
 config ISCSI_TARGET
 	tristate "SCSI Target Mode Stack"
 	depends on INET
 	select CRYPTO
 	select CRYPTO_CRC32C
-	select CRYPTO_CRC32C_INTEL if X86
 	help
 	Say M to enable the SCSI target mode stack. A SCSI target mode stack
 	is software that makes local storage available over a storage network
 	to a SCSI initiator system. The supported storage network technologies
 	include iSCSI, Fibre Channel and the SCSI RDMA Protocol (SRP).
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:51 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:51 -0800
Subject: [PATCH v3 15/18] ext4: switch to using the crc32c library
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-16-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the crc32c() library function directly takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32c().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/ext4/Kconfig |  3 +--
 fs/ext4/ext4.h  | 25 +++----------------------
 fs/ext4/super.c | 15 ---------------
 3 files changed, 4 insertions(+), 39 deletions(-)

diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index e20d59221fc0..c9ca41d91a6c 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -29,12 +29,11 @@ config EXT3_FS_SECURITY
 config EXT4_FS
 	tristate "The Extended 4 (ext4) filesystem"
 	select BUFFER_HEAD
 	select JBD2
 	select CRC16
-	select CRYPTO
-	select CRYPTO_CRC32C
+	select CRC32
 	select FS_IOMAP
 	select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
 	help
 	  This is the next generation of the ext3 filesystem.
 
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 44b0d418143c..99aa512a7de1 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -31,11 +31,11 @@
 #include <linux/wait.h>
 #include <linux/sched/signal.h>
 #include <linux/blockgroup_lock.h>
 #include <linux/percpu_counter.h>
 #include <linux/ratelimit.h>
-#include <crypto/hash.h>
+#include <linux/crc32c.h>
 #include <linux/falloc.h>
 #include <linux/percpu-rwsem.h>
 #include <linux/fiemap.h>
 #ifdef __KERNEL__
 #include <linux/compat.h>
@@ -1660,13 +1660,10 @@ struct ext4_sb_info {
 	struct task_struct *s_mmp_tsk;
 
 	/* record the last minlen when FITRIM is called. */
 	unsigned long s_last_trim_minblks;
 
-	/* Reference to checksum algorithm driver via cryptoapi */
-	struct crypto_shash *s_chksum_driver;
-
 	/* Precomputed FS UUID checksum for seeding other checksums */
 	__u32 s_csum_seed;
 
 	/* Reclaim extents from extent status tree */
 	struct shrinker *s_es_shrinker;
@@ -2465,23 +2462,11 @@ static inline __le16 ext4_rec_len_to_disk(unsigned len, unsigned blocksize)
 #define DX_HASH_LAST 			DX_HASH_SIPHASH
 
 static inline u32 ext4_chksum(struct ext4_sb_info *sbi, u32 crc,
 			      const void *address, unsigned int length)
 {
-	struct {
-		struct shash_desc shash;
-		char ctx[4];
-	} desc;
-
-	BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver)!=sizeof(desc.ctx));
-
-	desc.shash.tfm = sbi->s_chksum_driver;
-	*(u32 *)desc.ctx = crc;
-
-	BUG_ON(crypto_shash_update(&desc.shash, address, length));
-
-	return *(u32 *)desc.ctx;
+	return crc32c(crc, address, length);
 }
 
 #ifdef __KERNEL__
 
 /* hash info structure used by the directory hash */
@@ -3278,15 +3263,11 @@ extern void ext4_group_desc_csum_set(struct super_block *sb, __u32 group,
 extern int ext4_register_li_request(struct super_block *sb,
 				    ext4_group_t first_not_zeroed);
 
 static inline int ext4_has_metadata_csum(struct super_block *sb)
 {
-	WARN_ON_ONCE(ext4_has_feature_metadata_csum(sb) &&
-		     !EXT4_SB(sb)->s_chksum_driver);
-
-	return ext4_has_feature_metadata_csum(sb) &&
-	       (EXT4_SB(sb)->s_chksum_driver != NULL);
+	return ext4_has_feature_metadata_csum(sb);
 }
 
 static inline int ext4_has_group_desc_csum(struct super_block *sb)
 {
 	return ext4_has_feature_gdt_csum(sb) || ext4_has_metadata_csum(sb);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 16a4ce704460..1a821093cc0d 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1371,12 +1371,10 @@ static void ext4_put_super(struct super_block *sb)
 	 * Now that we are completely done shutting down the
 	 * superblock, we need to actually destroy the kobject.
 	 */
 	kobject_put(&sbi->s_kobj);
 	wait_for_completion(&sbi->s_kobj_unregister);
-	if (sbi->s_chksum_driver)
-		crypto_free_shash(sbi->s_chksum_driver);
 	kfree(sbi->s_blockgroup_lock);
 	fs_put_dax(sbi->s_daxdev, NULL);
 	fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
 #if IS_ENABLED(CONFIG_UNICODE)
 	utf8_unload(sb->s_encoding);
@@ -4586,19 +4584,10 @@ static int ext4_init_metadata_csum(struct super_block *sb, struct ext4_super_blo
 		return -EINVAL;
 	}
 	ext4_setup_csum_trigger(sb, EXT4_JTR_ORPHAN_FILE,
 				ext4_orphan_file_block_trigger);
 
-	/* Load the checksum driver */
-	sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
-	if (IS_ERR(sbi->s_chksum_driver)) {
-		int ret = PTR_ERR(sbi->s_chksum_driver);
-		ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
-		sbi->s_chksum_driver = NULL;
-		return ret;
-	}
-
 	/* Check superblock checksum */
 	if (!ext4_superblock_csum_verify(sb, es)) {
 		ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
 			 "invalid superblock checksum.  Run e2fsck?");
 		return -EFSBADCRC;
@@ -5638,13 +5627,10 @@ failed_mount8: __maybe_unused
 	flush_work(&sbi->s_sb_upd_work);
 	ext4_stop_mmpd(sbi);
 	del_timer_sync(&sbi->s_err_report);
 	ext4_group_desc_free(sbi);
 failed_mount:
-	if (sbi->s_chksum_driver)
-		crypto_free_shash(sbi->s_chksum_driver);
-
 #if IS_ENABLED(CONFIG_UNICODE)
 	utf8_unload(sb->s_encoding);
 #endif
 
 #ifdef CONFIG_QUOTA
@@ -7433,8 +7419,7 @@ static void __exit ext4_exit_fs(void)
 }
 
 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
 MODULE_DESCRIPTION("Fourth Extended Filesystem");
 MODULE_LICENSE("GPL");
-MODULE_SOFTDEP("pre: crc32c");
 module_init(ext4_init_fs)
 module_exit(ext4_exit_fs)
-- 
2.47.0



From ebiggers at kernel.org  Sun Nov  3 14:31:54 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Sun,  3 Nov 2024 14:31:54 -0800
Subject: [PATCH v3 18/18] scsi: target: iscsi: switch to using the crc32c library
In-Reply-To: <20241103223154.136127-1-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
Message-ID: <20241103223154.136127-19-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

Now that the crc32c() library function directly takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32c().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 drivers/target/iscsi/Kconfig              |   3 +-
 drivers/target/iscsi/iscsi_target.c       | 153 +++++++---------------
 drivers/target/iscsi/iscsi_target_login.c |  50 -------
 drivers/target/iscsi/iscsi_target_login.h |   1 -
 drivers/target/iscsi/iscsi_target_nego.c  |  21 +--
 include/target/iscsi/iscsi_target_core.h  |   3 -
 6 files changed, 49 insertions(+), 182 deletions(-)

diff --git a/drivers/target/iscsi/Kconfig b/drivers/target/iscsi/Kconfig
index 1c0517a12571..70d76f3dd693 100644
--- a/drivers/target/iscsi/Kconfig
+++ b/drivers/target/iscsi/Kconfig
@@ -1,11 +1,12 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config ISCSI_TARGET
 	tristate "SCSI Target Mode Stack"
 	depends on INET
+	select CRC32
 	select CRYPTO
-	select CRYPTO_CRC32C
+	select CRYPTO_HASH
 	help
 	Say M to enable the SCSI target mode stack. A SCSI target mode stack
 	is software that makes local storage available over a storage network
 	to a SCSI initiator system. The supported storage network technologies
 	include iSCSI, Fibre Channel and the SCSI RDMA Protocol (SRP).
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 6002283cbeba..091c1efccfb7 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -6,11 +6,11 @@
  *
  * Author: Nicholas A. Bellinger <nab at linux-iscsi.org>
  *
  ******************************************************************************/
 
-#include <crypto/hash.h>
+#include <linux/crc32c.h>
 #include <linux/string.h>
 #include <linux/kthread.h>
 #include <linux/completion.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
@@ -488,12 +488,12 @@ void iscsit_aborted_task(struct iscsit_conn *conn, struct iscsit_cmd *cmd)
 
 	__iscsit_free_cmd(cmd, true);
 }
 EXPORT_SYMBOL(iscsit_aborted_task);
 
-static void iscsit_do_crypto_hash_buf(struct ahash_request *, const void *,
-				      u32, u32, const void *, void *);
+static u32 iscsit_crc_buf(const void *buf, u32 payload_length,
+			  u32 padding, const void *pad_bytes);
 static void iscsit_tx_thread_wait_for_tcp(struct iscsit_conn *);
 
 static int
 iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 			  const void *data_buf, u32 data_buf_len)
@@ -508,13 +508,11 @@ iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 	iov[niov++].iov_len	= ISCSI_HDR_LEN;
 
 	if (conn->conn_ops->HeaderDigest) {
 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-		iscsit_do_crypto_hash_buf(conn->conn_tx_hash, hdr,
-					  ISCSI_HDR_LEN, 0, NULL,
-					  header_digest);
+		*header_digest = iscsit_crc_buf(hdr, ISCSI_HDR_LEN, 0, NULL);
 
 		iov[0].iov_len += ISCSI_CRC_LEN;
 		tx_size += ISCSI_CRC_LEN;
 		pr_debug("Attaching CRC32C HeaderDigest"
 			 " to opcode 0x%x 0x%08x\n",
@@ -535,15 +533,13 @@ iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 			pr_debug("Attaching %u additional"
 				 " padding bytes.\n", padding);
 		}
 
 		if (conn->conn_ops->DataDigest) {
-			iscsit_do_crypto_hash_buf(conn->conn_tx_hash,
-						  data_buf, data_buf_len,
-						  padding, &cmd->pad_bytes,
-						  &cmd->data_crc);
-
+			cmd->data_crc = iscsit_crc_buf(data_buf, data_buf_len,
+						       padding,
+						       &cmd->pad_bytes);
 			iov[niov].iov_base = &cmd->data_crc;
 			iov[niov++].iov_len = ISCSI_CRC_LEN;
 			tx_size += ISCSI_CRC_LEN;
 			pr_debug("Attached DataDigest for %u"
 				 " bytes opcode 0x%x, CRC 0x%08x\n",
@@ -564,12 +560,12 @@ iscsit_xmit_nondatain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 }
 
 static int iscsit_map_iovec(struct iscsit_cmd *cmd, struct kvec *iov, int nvec,
 			    u32 data_offset, u32 data_length);
 static void iscsit_unmap_iovec(struct iscsit_cmd *);
-static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsit_cmd *,
-				    u32, u32, u32, u8 *);
+static u32 iscsit_crc_sglist(const struct iscsit_cmd *cmd, u32 data_length,
+			     u32 padding, const u8 *pad_bytes);
 static int
 iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 		       const struct iscsi_datain *datain)
 {
 	struct kvec *iov;
@@ -582,14 +578,12 @@ iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 	tx_size += ISCSI_HDR_LEN;
 
 	if (conn->conn_ops->HeaderDigest) {
 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
 
-		iscsit_do_crypto_hash_buf(conn->conn_tx_hash, cmd->pdu,
-					  ISCSI_HDR_LEN, 0, NULL,
-					  header_digest);
-
+		*header_digest = iscsit_crc_buf(cmd->pdu, ISCSI_HDR_LEN, 0,
+						NULL);
 		iov[0].iov_len += ISCSI_CRC_LEN;
 		tx_size += ISCSI_CRC_LEN;
 
 		pr_debug("Attaching CRC32 HeaderDigest for DataIN PDU 0x%08x\n",
 			 *header_digest);
@@ -612,16 +606,12 @@ iscsit_xmit_datain_pdu(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 
 		pr_debug("Attaching %u padding bytes\n", cmd->padding);
 	}
 
 	if (conn->conn_ops->DataDigest) {
-		cmd->data_crc = iscsit_do_crypto_hash_sg(conn->conn_tx_hash,
-							 cmd, datain->offset,
-							 datain->length,
-							 cmd->padding,
-							 cmd->pad_bytes);
-
+		cmd->data_crc = iscsit_crc_sglist(cmd, datain->length,
+						  cmd->padding, cmd->pad_bytes);
 		iov[iov_count].iov_base	= &cmd->data_crc;
 		iov[iov_count++].iov_len = ISCSI_CRC_LEN;
 		tx_size += ISCSI_CRC_LEN;
 
 		pr_debug("Attached CRC32C DataDigest %d bytes, crc 0x%08x\n",
@@ -1402,81 +1392,49 @@ iscsit_handle_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 		return 0;
 
 	return iscsit_get_immediate_data(cmd, hdr, dump_payload);
 }
 
-static u32 iscsit_do_crypto_hash_sg(
-	struct ahash_request *hash,
-	struct iscsit_cmd *cmd,
-	u32 data_offset,
-	u32 data_length,
-	u32 padding,
-	u8 *pad_bytes)
+static u32 iscsit_crc_sglist(const struct iscsit_cmd *cmd, u32 data_length,
+			     u32 padding, const u8 *pad_bytes)
 {
-	u32 data_crc;
-	struct scatterlist *sg;
-	unsigned int page_off;
-
-	crypto_ahash_init(hash);
-
-	sg = cmd->first_data_sg;
-	page_off = cmd->first_data_sg_off;
-
-	if (data_length && page_off) {
-		struct scatterlist first_sg;
-		u32 len = min_t(u32, data_length, sg->length - page_off);
-
-		sg_init_table(&first_sg, 1);
-		sg_set_page(&first_sg, sg_page(sg), len, sg->offset + page_off);
-
-		ahash_request_set_crypt(hash, &first_sg, NULL, len);
-		crypto_ahash_update(hash);
-
-		data_length -= len;
-		sg = sg_next(sg);
-	}
+	struct scatterlist *sg = cmd->first_data_sg;
+	unsigned int page_off = cmd->first_data_sg_off;
+	u32 crc = ~0;
 
 	while (data_length) {
-		u32 cur_len = min_t(u32, data_length, sg->length);
+		u32 cur_len = min_t(u32, data_length, sg->length - page_off);
+		const void *virt;
 
-		ahash_request_set_crypt(hash, sg, NULL, cur_len);
-		crypto_ahash_update(hash);
+		virt = kmap_local_page(sg_page(sg)) + sg->offset + page_off;
+		crc = crc32c(crc, virt, cur_len);
+		kunmap_local(virt);
 
-		data_length -= cur_len;
 		/* iscsit_map_iovec has already checked for invalid sg pointers */
 		sg = sg_next(sg);
-	}
 
-	if (padding) {
-		struct scatterlist pad_sg;
-
-		sg_init_one(&pad_sg, pad_bytes, padding);
-		ahash_request_set_crypt(hash, &pad_sg, (u8 *)&data_crc,
-					padding);
-		crypto_ahash_finup(hash);
-	} else {
-		ahash_request_set_crypt(hash, NULL, (u8 *)&data_crc, 0);
-		crypto_ahash_final(hash);
+		page_off = 0;
+		data_length -= cur_len;
 	}
 
-	return data_crc;
+	if (padding)
+		crc = crc32c(crc, pad_bytes, padding);
+
+	return ~crc;
 }
 
-static void iscsit_do_crypto_hash_buf(struct ahash_request *hash,
-	const void *buf, u32 payload_length, u32 padding,
-	const void *pad_bytes, void *data_crc)
+static u32 iscsit_crc_buf(const void *buf, u32 payload_length,
+			  u32 padding, const void *pad_bytes)
 {
-	struct scatterlist sg[2];
+	u32 crc = ~0;
 
-	sg_init_table(sg, ARRAY_SIZE(sg));
-	sg_set_buf(sg, buf, payload_length);
-	if (padding)
-		sg_set_buf(sg + 1, pad_bytes, padding);
+	crc = crc32c(crc, buf, payload_length);
 
-	ahash_request_set_crypt(hash, sg, data_crc, payload_length + padding);
+	if (padding)
+		crc = crc32c(crc, pad_bytes, padding);
 
-	crypto_ahash_digest(hash);
+	return ~crc;
 }
 
 int
 __iscsit_check_dataout_hdr(struct iscsit_conn *conn, void *buf,
 			   struct iscsit_cmd *cmd, u32 payload_length,
@@ -1660,15 +1618,12 @@ iscsit_get_dataout(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 		return -1;
 
 	if (conn->conn_ops->DataDigest) {
 		u32 data_crc;
 
-		data_crc = iscsit_do_crypto_hash_sg(conn->conn_rx_hash, cmd,
-						    be32_to_cpu(hdr->offset),
-						    payload_length, padding,
-						    cmd->pad_bytes);
-
+		data_crc = iscsit_crc_sglist(cmd, payload_length, padding,
+					     cmd->pad_bytes);
 		if (checksum != data_crc) {
 			pr_err("ITT: 0x%08x, Offset: %u, Length: %u,"
 				" DataSN: 0x%08x, CRC32C DataDigest 0x%08x"
 				" does not match computed 0x%08x\n",
 				hdr->itt, hdr->offset, payload_length,
@@ -1923,14 +1878,12 @@ static int iscsit_handle_nop_out(struct iscsit_conn *conn, struct iscsit_cmd *cm
 			ret = -1;
 			goto out;
 		}
 
 		if (conn->conn_ops->DataDigest) {
-			iscsit_do_crypto_hash_buf(conn->conn_rx_hash, ping_data,
-						  payload_length, padding,
-						  cmd->pad_bytes, &data_crc);
-
+			data_crc = iscsit_crc_buf(ping_data, payload_length,
+						  padding, cmd->pad_bytes);
 			if (checksum != data_crc) {
 				pr_err("Ping data CRC32C DataDigest"
 				" 0x%08x does not match computed 0x%08x\n",
 					checksum, data_crc);
 				if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
@@ -2326,14 +2279,11 @@ iscsit_handle_text_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
 		rx_got = rx_data(conn, &iov[0], niov, rx_size);
 		if (rx_got != rx_size)
 			goto reject;
 
 		if (conn->conn_ops->DataDigest) {
-			iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
-						  text_in, rx_size, 0, NULL,
-						  &data_crc);
-
+			data_crc = iscsit_crc_buf(text_in, rx_size, 0, NULL);
 			if (checksum != data_crc) {
 				pr_err("Text data CRC32C DataDigest"
 					" 0x%08x does not match computed"
 					" 0x%08x\n", checksum, data_crc);
 				if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
@@ -2686,14 +2636,12 @@ static int iscsit_handle_immediate_data(
 	}
 
 	if (conn->conn_ops->DataDigest) {
 		u32 data_crc;
 
-		data_crc = iscsit_do_crypto_hash_sg(conn->conn_rx_hash, cmd,
-						    cmd->write_data_done, length, padding,
-						    cmd->pad_bytes);
-
+		data_crc = iscsit_crc_sglist(cmd, length, padding,
+					     cmd->pad_bytes);
 		if (checksum != data_crc) {
 			pr_err("ImmediateData CRC32C DataDigest 0x%08x"
 				" does not match computed 0x%08x\n", checksum,
 				data_crc);
 
@@ -4114,14 +4062,12 @@ static void iscsit_get_rx_pdu(struct iscsit_conn *conn)
 			if (ret != ISCSI_CRC_LEN) {
 				iscsit_rx_thread_wait_for_tcp(conn);
 				break;
 			}
 
-			iscsit_do_crypto_hash_buf(conn->conn_rx_hash, buffer,
-						  ISCSI_HDR_LEN, 0, NULL,
-						  &checksum);
-
+			checksum = iscsit_crc_buf(buffer, ISCSI_HDR_LEN, 0,
+						  NULL);
 			if (digest != checksum) {
 				pr_err("HeaderDigest CRC32C failed,"
 					" received 0x%08x, computed 0x%08x\n",
 					digest, checksum);
 				/*
@@ -4404,19 +4350,10 @@ int iscsit_close_connection(
 	 * If any other processes are accessing this connection pointer we
 	 * must wait until they have completed.
 	 */
 	iscsit_check_conn_usage_count(conn);
 
-	ahash_request_free(conn->conn_tx_hash);
-	if (conn->conn_rx_hash) {
-		struct crypto_ahash *tfm;
-
-		tfm = crypto_ahash_reqtfm(conn->conn_rx_hash);
-		ahash_request_free(conn->conn_rx_hash);
-		crypto_free_ahash(tfm);
-	}
-
 	if (conn->sock)
 		sock_release(conn->sock);
 
 	if (conn->conn_transport->iscsit_free_conn)
 		conn->conn_transport->iscsit_free_conn(conn);
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 90b870f234f0..c2ac9a99ebbb 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -6,11 +6,10 @@
  *
  * Author: Nicholas A. Bellinger <nab at linux-iscsi.org>
  *
  ******************************************************************************/
 
-#include <crypto/hash.h>
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/kthread.h>
 #include <linux/sched/signal.h>
 #include <linux/idr.h>
@@ -69,50 +68,10 @@ static struct iscsi_login *iscsi_login_init_conn(struct iscsit_conn *conn)
 out_login:
 	kfree(login);
 	return NULL;
 }
 
-/*
- * Used by iscsi_target_nego.c:iscsi_target_locate_portal() to setup
- * per struct iscsit_conn libcrypto contexts for crc32c and crc32-intel
- */
-int iscsi_login_setup_crypto(struct iscsit_conn *conn)
-{
-	struct crypto_ahash *tfm;
-
-	/*
-	 * Setup slicing by CRC32C algorithm for RX and TX libcrypto contexts
-	 * which will default to crc32c_intel.ko for cpu_has_xmm4_2, or fallback
-	 * to software 1x8 byte slicing from crc32c.ko
-	 */
-	tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC);
-	if (IS_ERR(tfm)) {
-		pr_err("crypto_alloc_ahash() failed\n");
-		return -ENOMEM;
-	}
-
-	conn->conn_rx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
-	if (!conn->conn_rx_hash) {
-		pr_err("ahash_request_alloc() failed for conn_rx_hash\n");
-		crypto_free_ahash(tfm);
-		return -ENOMEM;
-	}
-	ahash_request_set_callback(conn->conn_rx_hash, 0, NULL, NULL);
-
-	conn->conn_tx_hash = ahash_request_alloc(tfm, GFP_KERNEL);
-	if (!conn->conn_tx_hash) {
-		pr_err("ahash_request_alloc() failed for conn_tx_hash\n");
-		ahash_request_free(conn->conn_rx_hash);
-		conn->conn_rx_hash = NULL;
-		crypto_free_ahash(tfm);
-		return -ENOMEM;
-	}
-	ahash_request_set_callback(conn->conn_tx_hash, 0, NULL, NULL);
-
-	return 0;
-}
-
 static int iscsi_login_check_initiator_version(
 	struct iscsit_conn *conn,
 	u8 version_max,
 	u8 version_min)
 {
@@ -1163,19 +1122,10 @@ void iscsi_target_login_sess_out(struct iscsit_conn *conn,
 		} else
 			spin_unlock_bh(&conn->sess->conn_lock);
 		iscsit_dec_session_usage_count(conn->sess);
 	}
 
-	ahash_request_free(conn->conn_tx_hash);
-	if (conn->conn_rx_hash) {
-		struct crypto_ahash *tfm;
-
-		tfm = crypto_ahash_reqtfm(conn->conn_rx_hash);
-		ahash_request_free(conn->conn_rx_hash);
-		crypto_free_ahash(tfm);
-	}
-
 	if (conn->param_list) {
 		iscsi_release_param_list(conn->param_list);
 		conn->param_list = NULL;
 	}
 	iscsi_target_nego_release(conn);
diff --git a/drivers/target/iscsi/iscsi_target_login.h b/drivers/target/iscsi/iscsi_target_login.h
index e8760735486b..03c7d695d58f 100644
--- a/drivers/target/iscsi/iscsi_target_login.h
+++ b/drivers/target/iscsi/iscsi_target_login.h
@@ -7,11 +7,10 @@
 struct iscsit_conn;
 struct iscsi_login;
 struct iscsi_np;
 struct sockaddr_storage;
 
-extern int iscsi_login_setup_crypto(struct iscsit_conn *);
 extern int iscsi_check_for_session_reinstatement(struct iscsit_conn *);
 extern int iscsi_login_post_auth_non_zero_tsih(struct iscsit_conn *, u16, u32);
 extern int iscsit_setup_np(struct iscsi_np *,
 				struct sockaddr_storage *);
 extern int iscsi_target_setup_login_socket(struct iscsi_np *,
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index fa3fb5f4e6bc..16e3ded98c32 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -1192,18 +1192,11 @@ int iscsi_target_locate_portal(
 	if (!sessiontype) {
 		if (!login->leading_connection)
 			goto get_target;
 
 		sess->sess_ops->SessionType = 1;
-		/*
-		 * Setup crc32c modules from libcrypto
-		 */
-		if (iscsi_login_setup_crypto(conn) < 0) {
-			pr_err("iscsi_login_setup_crypto() failed\n");
-			ret = -1;
-			goto out;
-		}
+
 		/*
 		 * Serialize access across the discovery struct iscsi_portal_group to
 		 * process login attempt.
 		 */
 		conn->tpg = iscsit_global->discovery_tpg;
@@ -1256,21 +1249,11 @@ int iscsi_target_locate_portal(
 		ret = -1;
 		goto out;
 	}
 	conn->tpg_np = tpg_np;
 	pr_debug("Located Portal Group Object: %hu\n", conn->tpg->tpgt);
-	/*
-	 * Setup crc32c modules from libcrypto
-	 */
-	if (iscsi_login_setup_crypto(conn) < 0) {
-		pr_err("iscsi_login_setup_crypto() failed\n");
-		kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put);
-		iscsit_put_tiqn_for_login(tiqn);
-		conn->tpg = NULL;
-		ret = -1;
-		goto out;
-	}
+
 	/*
 	 * Serialize access across the struct iscsi_portal_group to
 	 * process login attempt.
 	 */
 	if (iscsit_access_np(np, conn->tpg) < 0) {
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h
index 60af7c63b34e..51ca80abacf7 100644
--- a/include/target/iscsi/iscsi_target_core.h
+++ b/include/target/iscsi/iscsi_target_core.h
@@ -574,13 +574,10 @@ struct iscsit_conn {
 	spinlock_t		nopin_timer_lock;
 	spinlock_t		response_queue_lock;
 	spinlock_t		state_lock;
 	spinlock_t		login_timer_lock;
 	spinlock_t		login_worker_lock;
-	/* libcrypto RX and TX contexts for crc32c */
-	struct ahash_request	*conn_rx_hash;
-	struct ahash_request	*conn_tx_hash;
 	/* Used for scheduling TX and RX connection kthreads */
 	cpumask_var_t		conn_cpumask;
 	cpumask_var_t		allowed_cpumask;
 	unsigned int		conn_rx_reset_cpumask:1;
 	unsigned int		conn_tx_reset_cpumask:1;
-- 
2.47.0



From unicorn_wang at outlook.com  Sun Nov  3 17:52:16 2024
From: unicorn_wang at outlook.com (Chen Wang)
Date: Mon, 4 Nov 2024 09:52:16 +0800
Subject: [PATCH] dt-bindings: pinctrl: correct typo of description for
 cv1800
In-Reply-To: <20241029012312.3448287-1-unicornxw@gmail.com>
References: <20241029012312.3448287-1-unicornxw@gmail.com>
Message-ID: <MA0P287MB282298E7A00528040BBEC5DEFE512@MA0P287MB2822.INDP287.PROD.OUTLOOK.COM>

Hi, Linus Walleij,

Will you pick this fixes and PR for 6.12?

Or I will take this over and PR this for 6.13 due to it is a minor text 
change.

Thanks,

Chen

On 2024/10/29 9:23, Chen Wang wrote:
> From: Chen Wang <unicorn_wang at outlook.com>
>
> It should be PINMUX/PINMUX2, not GPIOMUX/GPIOMUX2, see
> <dt-bindings/pinctrl/pinctrl-cv1800b.h>.
>
> Fixes: 64aa494de6fa ("dt-bindings: pinctrl: Add pinctrl for Sophgo CV1800 series SoC.")
> Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
> ---
>   .../devicetree/bindings/pinctrl/sophgo,cv1800-pinctrl.yaml      | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/sophgo,cv1800-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/sophgo,cv1800-pinctrl.yaml
> index 1e6a55afe26a..feb4785a3fac 100644
> --- a/Documentation/devicetree/bindings/pinctrl/sophgo,cv1800-pinctrl.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/sophgo,cv1800-pinctrl.yaml
> @@ -58,7 +58,7 @@ patternProperties:
>             pinmux:
>               description: |
>                 The list of GPIOs and their mux settings that properties in the
> -              node apply to. This should be set using the GPIOMUX or GPIOMUX2
> +              node apply to. This should be set using the PINMUX or PINMUX2
>                 macro.
>   
>             bias-pull-up:
>
> base-commit: 81983758430957d9a5cb3333fe324fd70cf63e7e


From si.yanteng at linux.dev  Sun Nov  3 18:12:23 2024
From: si.yanteng at linux.dev (Yanteng Si)
Date: Mon, 4 Nov 2024 10:12:23 +0800
Subject: [PATCH] docs/zh_CN: add the translation of kbuild/llvm.rst
In-Reply-To: <20241023153235.1291567-1-dzm91@hust.edu.cn>
References: <20241023153235.1291567-1-dzm91@hust.edu.cn>
Message-ID: <07a5170b-8a7b-44c6-8ad1-af8d4c361661@linux.dev>




? 2024/10/23 23:32, Dongliang Mu ??:
> Finish the translation of kbuild/llvm.rst and move llvm from TODO
> to the main body.
>
> Update to commit 145082ebfcf0 ("Documentation/llvm: turn make command
> for ccache into code block")
>
> Signed-off-by: Dongliang Mu <dzm91 at hust.edu.cn>
Reviewed-by: Yanteng Si <si.yanteng at linux.dev>


Thanks,
Yanteng
> ---
>   .../translations/zh_CN/kbuild/index.rst       |   3 +-
>   .../translations/zh_CN/kbuild/llvm.rst        | 203 ++++++++++++++++++
>   2 files changed, 205 insertions(+), 1 deletion(-)
>   create mode 100644 Documentation/translations/zh_CN/kbuild/llvm.rst
>
> diff --git a/Documentation/translations/zh_CN/kbuild/index.rst b/Documentation/translations/zh_CN/kbuild/index.rst
> index 0ba96aecb13a..3f9ab52fa5bb 100644
> --- a/Documentation/translations/zh_CN/kbuild/index.rst
> +++ b/Documentation/translations/zh_CN/kbuild/index.rst
> @@ -17,6 +17,7 @@
>       gcc-plugins
>       kbuild
>       reproducible-builds
> +    llvm
>   
>   TODO:
>   
> @@ -25,7 +26,7 @@ TODO:
>   - makefiles
>   - modules
>   - issues
> -- llvm
> +
>   
>   .. only::  subproject and html
>   
> diff --git a/Documentation/translations/zh_CN/kbuild/llvm.rst b/Documentation/translations/zh_CN/kbuild/llvm.rst
> new file mode 100644
> index 000000000000..f71092144a26
> --- /dev/null
> +++ b/Documentation/translations/zh_CN/kbuild/llvm.rst
> @@ -0,0 +1,203 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +.. include:: ../disclaimer-zh_CN.rst
> +
> +:Original: Documentation/kbuild/llvm.rst
> +:Translator: ??? Dongliang Mu <dzm91 at hust.edu.cn>
> +
> +==========================
> +?? Clang/LLVM ?? Linux
> +==========================
> +
> +????????? Clang ? LLVM ???? Linux ???
> +
> +??
> +----
> +
> +Linux ????????? GNU ????? GCC ? binutils?????????????
> +`Clang <https://clang.llvm.org/>`_ ? `LLVM <https://llvm.org/>`_ ???
> +???????????????? `Android <https://www.android.com/>`_?
> +`ChromeOS <https://www.chromium.org/chromium-os>`_?`OpenMandriva
> +<https://www.openmandriva.org/>`_ ? `Chimera Linux
> +<https://chimera-linux.org/>`_ ?? Clang ????????? Meta ?????
> +?????? Clang ??????
> +
> +`LLVM ?? C++ ???????????? <https://www.aosabook.org/en/llvm.html>`_?
> +Clang ? LLVM ?????? C ???????? GNU C ??????? "klang"???
> +"see-lang"?
> +
> +?? LLVM ??
> +--------------
> +
> +???????? ``make``::
> +
> +	make LLVM=1
> +
> +????????????????::
> +
> +	make LLVM=1 ARCH=arm64
> +
> +LLVM= ??
> +----------
> +
> +LLVM ? GNU binutils ???????????????????????? make ??
> +????::
> +
> +	make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip \
> +	  OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump READELF=llvm-readelf \
> +	  HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld
> +
> +``LLVM=1`` ????????
> +
> +???? LLVM ???? PATH ????????????? LLVM ?????????::
> +
> +	make LLVM=/path/to/llvm/
> +
> +???? ``/path/to/llvm/clang``?``/path/to/llvm/ld.lld`` ???????
> +??????::
> +
> +	PATH=/path/to/llvm:$PATH make LLVM=1
> +
> +???? LLVM ?????????????????????????????????
> +??? ``LLVM=1``?????? ``LLVM`` ???????::
> +
> +	make LLVM=-14
> +
> +???? ``clang-14``?``ld.lld-14`` ??????????????????????
> +????::
> +
> +	PATH=/path/to/llvm/:$PATH make LLVM=-14
> +
> +``LLVM=0`` ??? ``LLVM`` ??????????? ``LLVM=1``?????????
> +?? LLVM ??????????? make ???
> +
> +???????????????????? ``make`` ????? ``LLVM=`` ????
> +?????????? ``make``????? ``LLVM=`` ????????
> +
> +????
> +--------
> +
> +?? Clang ?????????????? LLVM ???????????????????
> +???????????? ``LLVM=1`` ??????? LLVM ???``CROSS_COMPILE``
> +?????????????????::
> +
> +	make LLVM=1 ARCH=arm64
> +
> +???? LLVM ? GNU ????????? ``ARCH=s390`` ????????
> +``ld.lld`` ? ``llvm-objcopy`` ??????????????? ``make``::
> +
> +	make LLVM=1 ARCH=s390 LD=s390x-linux-gnu-ld.bfd \
> +	  OBJCOPY=s390x-linux-gnu-objcopy
> +
> +?????? ``s390x-linux-gnu-ld.bfd`` ??????
> +``s390x-linux-gnu-objcopy``??????????? ``$PATH`` ??
> +
> +? ``LLVM=1`` ?????``CROSS_COMPILE`` ????? Clang ????????
> +????? LLVM ????????? GNU ?????????
> +
> +LLVM_IAS= ??
> +--------------
> +
> +Clang ?????????????? ``LLVM_IAS=0`` ??????? Clang ??
> +????????????::
> +
> +	make LLVM=1 LLVM_IAS=0
> +
> +???????????? ``CROSS_COMPILE`` ? ``LLVM_IAS=0``?????
> +``--prefix=`` ??????????????????????????????
> +??????????????::
> +
> +	make LLVM=1 ARCH=arm LLVM_IAS=0 CROSS_COMPILE=arm-linux-gnueabi-
> +
> +Ccache
> +------
> +
> +``ccache`` ??? ``clang`` ??????????????????????
> +KBUILD_BUILD_TIMESTAMP_ ????????????? 100% ???????
> +?? Reproducible_builds_ ???????::
> +
> +	KBUILD_BUILD_TIMESTAMP='' make LLVM=1 CC="ccache clang"
> +
> +.. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp
> +.. _Reproducible_builds: reproducible-builds.html#timestamps
> +
> +?????
> +----------
> +
> +LLVM ???? Linux ???????????????? LLVM ??????????????
> +????????????????????? ``CC=clang`` ? ``LLVM=1`` ????????
> +??????? MAINTAINERS ???? "S" ??????????????? LLVM ????
> +???????????????? LLVM ??????????????????????
> +``defconfig`` ?????????????????????????????????
> +?????????????
> +
> +.. list-table::
> +   :widths: 10 10 10
> +   :header-rows: 1
> +
> +   * - ??
> +     - ????
> +     - ``make`` ??
> +   * - arm
> +     - ??
> +     - ``LLVM=1``
> +   * - arm64
> +     - ??
> +     - ``LLVM=1``
> +   * - hexagon
> +     - ??
> +     - ``LLVM=1``
> +   * - loongarch
> +     - ??
> +     - ``LLVM=1``
> +   * - mips
> +     - ??
> +     - ``LLVM=1``
> +   * - powerpc
> +     - ??
> +     - ``LLVM=1``
> +   * - riscv
> +     - ??
> +     - ``LLVM=1``
> +   * - s390
> +     - ??
> +     - ``LLVM=1`` ?LLVM >= 18.1.0??``CC=clang`` ?LLVM < 18.1.0?
> +   * - um (????)
> +     - ??
> +     - ``LLVM=1``
> +   * - x86
> +     - ??
> +     - ``LLVM=1``
> +
> +????
> +--------
> +
> +- `?? <https://clangbuiltlinux.github.io/>`_
> +- `???? <https://lore.kernel.org/llvm/>`_: <llvm at lists.linux.dev>
> +- `??????? <https://groups.google.com/g/clang-built-linux>`_
> +- `????? <https://github.com/ClangBuiltLinux/linux/issues>`_
> +- IRC: #clangbuiltlinux ? irc.libera.chat
> +- `Telegram <https://t.me/ClangBuiltLinux>`_: @ClangBuiltLinux
> +- `?? <https://github.com/ClangBuiltLinux/linux/wiki>`_
> +- `????? <https://github.com/ClangBuiltLinux/linux/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22>`_
> +
> +.. _zh_cn_getting_llvm:
> +
> +?? LLVM
> +---------
> +
> +??? `kernel.org <https://kernel.org/pub/tools/llvm/>`_ ????????? LLVM?
> +???????? Linux ???????????????????????????? LLVM?????
> +??????????
> +
> +?????????????? LLVM ????????????? LLVM ????
> +
> +- https://releases.llvm.org/download.html
> +- https://github.com/llvm/llvm-project
> +- https://llvm.org/docs/GettingStarted.html
> +- https://llvm.org/docs/CMake.html
> +- https://apt.llvm.org/
> +- https://www.archlinux.org/packages/extra/x86_64/llvm/
> +- https://github.com/ClangBuiltLinux/tc-build
> +- https://github.com/ClangBuiltLinux/linux/wiki/Building-Clang-from-source
> +- https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/



From wangyuli at uniontech.com  Sun Nov  3 18:34:18 2024
From: wangyuli at uniontech.com (WangYuli)
Date: Mon, 4 Nov 2024 10:34:18 +0800
Subject: [PATCH v2 06/18] loongarch/crc32: expose CRC32 functions through
 lib
In-Reply-To: <20241103135730.GA813@quark.localdomain>
References: <20241025191454.72616-7-ebiggers@kernel.org>
 <DA8BCDFFEACDA1C6+20241103133655.217375-1-wangyuli@uniontech.com>
 <20241103135730.GA813@quark.localdomain>
Message-ID: <E7AED86A89FD886F+263304da-0529-4b4c-9e23-ea2e5e3cef2c@uniontech.com>


On 2024/11/3 21:57, Eric Biggers wrote:
> On Sun, Nov 03, 2024 at 09:36:55PM +0800, WangYuli wrote:
>> Even though the narrower CRC instructions doesn't require GRLEN=64, they still *aren't* part of LA32 (LoongArch reference manual v1.10, Volume 1, Table 2-1).
>> Link: https://lore.kernel.org/all/0a7d0a9e-c56e-4ee2-a83b-00164a450abe at xen0n.name/
>>
>> Therefore, we could not directly add ARCH_HAS_CRC32 to config LOONGARCH.
>>
> There's still a runtime CPU feature check of cpu_has(CPU_FEATURE_CRC32).
> See arch/loongarch/lib/crc32-loongarch.c.  So it's the same as before.
> ARCH_HAS_CRC32 just means that the file will be compiled.
>
> If you're trying to say that you think this file should be built only when
> CONFIG_64BIT=y, then that would be an existing bug since the existing file
> arch/loongarch/crypto/crc32-loongarch.c was built for both 32-bit and 64-bit.
> But if you think this is a bug, I can fix this too.
>
> - Eric
>

Actually, my originally mean is that directly declaring LoongArch 
ARCH_HAS_CRC32 without distinguishing between 32-bit and 64-bit might 
mislead those reading the code. And it's not rigorous.
However, according to Huacai Chen's recent reply, there are many similar 
issues and they won't cause build errors for now.
Link: 
https://lore.kernel.org/all/CAAhV-H5KaXBr-TdpDbJwcr_L0_mbSw=4J30uwQ2xn2YDs=Hg2Q at mail.gmail.com/
So, this change should be fine for now.

Reviewed-by: WangYuli <wangyuli at uniontech.com>

Thanks,
-- 
WangYuli
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0xC5DA1F3046F40BEE.asc
Type: application/pgp-keys
Size: 632 bytes
Desc: OpenPGP public key
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241104/205b7840/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 236 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241104/205b7840/attachment.sig>

From cuiyunhui at bytedance.com  Sun Nov  3 19:43:48 2024
From: cuiyunhui at bytedance.com (yunhui cui)
Date: Mon, 4 Nov 2024 11:43:48 +0800
Subject: [External] Re: [PATCH] RISC-V: ACPI: fix early_ioremap to early_memremap
In-Reply-To: <ZyBfvfvyry6Wb89H@sunil-laptop>
References: <20241014094705.71775-1-cuiyunhui@bytedance.com>
 <d39e4832-50f3-4fc8-ba95-a2d6eefa5abe@ghiti.fr> <CAEEQ3wk6K52RdCat+L91KvfNVkxbj1-3zxjubkn9xy89wK_-bA@mail.gmail.com>
 <c05e09d0-d996-4712-a6e5-ef77f1f2ff0a@ghiti.fr> <CAEEQ3wmw8B_cOs54H4Z8e2QTGyeE2cAYQwDRyk7KgUUKTFhZ-g@mail.gmail.com>
 <CAHVXubjDhM6NEF6uf981Y2fNA1Dw=Bu_SNtpso6P1=3Np6BUDw@mail.gmail.com>
 <CAEEQ3wndPwdaNrJZaqqrbyMBeWTVnV3m8KEehdijtTfXWjuYsw@mail.gmail.com> <ZyBfvfvyry6Wb89H@sunil-laptop>
Message-ID: <CAEEQ3wkwUx1ySYRXZZP3vO2r5+1zd1PqFrUidkU11tnnzR+MnQ@mail.gmail.com>

Hi Sunil, Alex

On Tue, Oct 29, 2024 at 12:08?PM Sunil V L <sunilvl at ventanamicro.com> wrote:
>
> On Tue, Oct 29, 2024 at 11:04:49AM +0800, yunhui cui wrote:
> > Hi Alex,
> >
> >
> > On Mon, Oct 28, 2024 at 9:37?PM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
> > >
> > > Hi Yunhui,
> > >
> > > Sorry for the late reply, I was on vacation last week.
> > >
> > > On Mon, Oct 21, 2024 at 8:45?AM yunhui cui <cuiyunhui at bytedance.com> wrote:
> > > >
> > > > Hi Alex,
> > > >
> > > > On Mon, Oct 14, 2024 at 9:01?PM Alexandre Ghiti <alex at ghiti.fr> wrote:
> > > > >
> > > > > On 14/10/2024 14:30, yunhui cui wrote:
> > > > > > Hi Alex,
> > > > > >
> > > > > > On Mon, Oct 14, 2024 at 8:12?PM Alexandre Ghiti <alex at ghiti.fr> wrote:
> > > > > >> Hi Yunhui,
> > > > > >>
> > > > > >> On 14/10/2024 11:47, Yunhui Cui wrote:
> > > > > >>> When SVPBMT is enabled, __acpi_map_table() will directly access the
> > > > > >>> data in DDR through the IO attribute, rather than through hardware
> > > > > >>> cache consistency, resulting in incorrect data in the obtained ACPI
> > > > > >>> table.
> > > > > >>>
> > > > > >>> The log: ACPI: [ACPI:0x18] Invalid zero length.
> > > > > >>>
> > > > > >>> We do not assume whether the bootloader flushes or not. We should
> > > > > >>> access in a cacheable way instead of maintaining cache consistency
> > > > > >>> by software.
> > > > > >>>
> > > > > >>> Signed-off-by: Yunhui Cui <cuiyunhui at bytedance.com>
> > > > > >>> ---
> > > > > >>>    arch/riscv/kernel/acpi.c | 2 +-
> > > > > >>>    1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > >>>
> > > > > >>> diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
> > > > > >>> index 6e0d333f57e5..3177c9af8764 100644
> > > > > >>> --- a/arch/riscv/kernel/acpi.c
> > > > > >>> +++ b/arch/riscv/kernel/acpi.c
> > > > > >>> @@ -210,7 +210,7 @@ void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size)
> > > > > >>>        if (!size)
> > > > > >>>                return NULL;
> > > > > >>>
> > > > > >>> -     return early_ioremap(phys, size);
> > > > > >>> +     return early_memremap(phys, size);
> > > > > >>>    }
> > > > > >>>
> > > > > >>>    void __init __acpi_unmap_table(void __iomem *map, unsigned long size)
> > > > > >>
> > > > > >> It makes sense to me since with this, we don't have to care about how
> > > > > >> the firmware mapped the table. And it mimics all other architectures
> > > > > >> (arm64, loongarch and x86).
> > > > > >>
> > > > > >> Here is the corresponding fixes tag:
> > > > > >>
> > > > > >> Fixes: 3b426d4b5b14 ("RISC-V: ACPI : Fix for usage of pointers in
> > > > > >> different address space")
> > > > > >>
> > > > > >> With the corresponding fix in __acpi_unmap_table() as pointed by Sunil,
> > > > > >> you can add:
> > > > > >>
> > > > > >> Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > >>
> > > > > >> And regarding the sparse error, I don't see any other architecture
> > > > > >> casting to __iomem, so maybe that's not necessary anymore?
> > > > > > OK. I will make the changes in v2. Regarding the sparse error, I will
> > > > > > use another patch specifically to solve it. Is that okay?
> > > > >
> > > > >
> > > > > If the second patch only consists in casting, I would not use another
> > > > > patch since the patch 2 would fix something introduced in patch 1.
> > > > >
> > > > > But if patch 2 is more complicated,  it may make sense to do as you
> > > > > suggest, the goal is to merge patch 1 asap.
> > > >
> > > > Regarding patch 2, I executed "make & make install" for sparse of the
> > > > riscv arch. I "git cloned" from
> > > > https://github.com/ConchuOD/sparse.git.
> > > > Then when compiling the kernel, the following error was reported:
> > > >
> > > > cd /data00/cyh/linux-next/
> > > > make defconfig
> > > > cp .config build-riscv64/
> > > >
> > > > make O=build-riscv64/ C=1 W=1 arch/riscv/kernel/ drivers/acpi/
> > > > drivers/mailbox/ -j
> > > > make[1]: Entering directory '/data00/cyh/linux-next/build-riscv64'
> > > >   GEN     Makefile
> > > >   CC      scripts/mod/empty.o
> > > >   CC      scripts/mod/devicetable-offsets.s
> > > >   CHECK   ../scripts/mod/empty.c
> > > > invalid argument to '-march': '_zicsr_zifencei'
> > > >
> > > > make[3]: *** [../scripts/Makefile.build:229: scripts/mod/empty.o] Error 1
> > > > make[3]: *** Deleting file 'scripts/mod/empty.o'
> > > > make[3]: *** Waiting for unfinished jobs....
> > > > make[2]: *** [/data00/cyh/linux-next/Makefile:1215: prepare0] Error 2
> > > > make[1]: *** [/data00/cyh/linux-next/Makefile:224: __sub-make] Error 2
> > > >
> > > > Do you know the solution?
> > >
> > > In case you did not find the solution yet, I would say that your
> > > toolchain is too old.
> > >
> > > Let me know if I can help,
> > It may not be a problem of an old compiler. The version of the
> > compiler I am using is 13.2.
> > It is a problem with sparse. When running "sparse --arch=riscv
> > -march=rv64imac_zicsr_zifencei scripts/mod/empty.c", there is an
> > invalid argument for '-march': '_zicsr_zifencei'.
> >
> Hi Yunhui,
>
> I think you need latest sparse. I remember building sparse from latest
> sources to avoid this error.
>
> https://www.kernel.org/doc/html/v4.11/dev-tools/sparse.html
>
> Thanks,
> Sunil

Thank you for your suggestions on sparse. The patch has been sent to
the community. Please refer to:
https://lore.kernel.org/linux-arm-kernel/20241031112030.72647-1-cuiyunhui at bytedance.com/T/.


Thanks,
Yunhui


From u.kleine-koenig at baylibre.com  Sun Nov  3 22:46:50 2024
From: u.kleine-koenig at baylibre.com (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Mon,  4 Nov 2024 07:46:50 +0100
Subject: [PATCH] iommu: Switch back to struct platform_driver::remove()
Message-ID: <20241104064650.799122-2-u.kleine-koenig@baylibre.com>

After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
return void") .remove() is (again) the right callback to implement for
platform drivers.

Convert all platform drivers below drivers/iommu to use .remove(), with
the eventual goal to drop struct platform_driver::remove_new(). As
.remove() and .remove_new() have the same prototypes, conversion is done
by just changing the structure member name in the driver initializer.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>
---
Hello,

I did a single patch for all of drivers/iommu. While I usually prefer to
do one logical change per patch, this seems to be overengineering here
as the individual changes are really trivial and shouldn't be much in
the way for stable backports. But I'll happily split the patch if you
prefer it split.

This is based on today's next, if conflicts arise when you apply it at
some later time and don't want to resolve them, feel free to just drop
the changes to the conflicting files. I'll notice and followup at a
later time then. Or ask me for a fixed resend. (Having said that, I
recommend b4 am -3 + git am -3 which should resolve most conflicts just
fine.)

Best regards
Uwe

 drivers/iommu/apple-dart.c                  | 2 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 2 +-
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     | 4 ++--
 drivers/iommu/ipmmu-vmsa.c                  | 2 +-
 drivers/iommu/msm_iommu.c                   | 2 +-
 drivers/iommu/mtk_iommu.c                   | 2 +-
 drivers/iommu/mtk_iommu_v1.c                | 2 +-
 drivers/iommu/omap-iommu.c                  | 2 +-
 drivers/iommu/riscv/iommu-platform.c        | 2 +-
 drivers/iommu/sprd-iommu.c                  | 2 +-
 11 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index eb1e62cd499a..c5bde50d1c42 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -1352,7 +1352,7 @@ static struct platform_driver apple_dart_driver = {
 		.pm			= pm_sleep_ptr(&apple_dart_pm_ops),
 	},
 	.probe	= apple_dart_probe,
-	.remove_new = apple_dart_remove,
+	.remove	= apple_dart_remove,
 };
 
 module_platform_driver(apple_dart_driver);
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 826db8894fb7..efbc78bffd33 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4679,7 +4679,7 @@ static struct platform_driver arm_smmu_driver = {
 		.suppress_bind_attrs	= true,
 	},
 	.probe	= arm_smmu_device_probe,
-	.remove_new = arm_smmu_device_remove,
+	.remove	= arm_smmu_device_remove,
 	.shutdown = arm_smmu_device_shutdown,
 };
 module_driver(arm_smmu_driver, platform_driver_register,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 8321962b3714..4e9bb9f4c4bd 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -2372,7 +2372,7 @@ static struct platform_driver arm_smmu_driver = {
 		.suppress_bind_attrs    = true,
 	},
 	.probe	= arm_smmu_device_probe,
-	.remove_new = arm_smmu_device_remove,
+	.remove = arm_smmu_device_remove,
 	.shutdown = arm_smmu_device_shutdown,
 };
 module_platform_driver(arm_smmu_driver);
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index b98a7a598b89..9ce2fe50b22c 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -759,7 +759,7 @@ static struct platform_driver qcom_iommu_ctx_driver = {
 		.of_match_table	= ctx_of_match,
 	},
 	.probe	= qcom_iommu_ctx_probe,
-	.remove_new = qcom_iommu_ctx_remove,
+	.remove	= qcom_iommu_ctx_remove,
 };
 
 static bool qcom_iommu_has_secure_context(struct qcom_iommu_dev *qcom_iommu)
@@ -931,7 +931,7 @@ static struct platform_driver qcom_iommu_driver = {
 		.pm		= &qcom_iommu_pm_ops,
 	},
 	.probe	= qcom_iommu_device_probe,
-	.remove_new = qcom_iommu_device_remove,
+	.remove	= qcom_iommu_device_remove,
 };
 
 static int __init qcom_iommu_init(void)
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index ff55b8c30712..074daf1aac4e 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -1159,6 +1159,6 @@ static struct platform_driver ipmmu_driver = {
 		.pm = pm_sleep_ptr(&ipmmu_pm),
 	},
 	.probe = ipmmu_probe,
-	.remove_new = ipmmu_remove,
+	.remove = ipmmu_remove,
 };
 builtin_platform_driver(ipmmu_driver);
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 989e0869d805..ce40f0a419ea 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -838,6 +838,6 @@ static struct platform_driver msm_iommu_driver = {
 		.of_match_table = msm_iommu_dt_match,
 	},
 	.probe		= msm_iommu_probe,
-	.remove_new	= msm_iommu_remove,
+	.remove		= msm_iommu_remove,
 };
 builtin_platform_driver(msm_iommu_driver);
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index c45313c43b9e..72b68d037b95 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1794,7 +1794,7 @@ MODULE_DEVICE_TABLE(of, mtk_iommu_of_ids);
 
 static struct platform_driver mtk_iommu_driver = {
 	.probe	= mtk_iommu_probe,
-	.remove_new = mtk_iommu_remove,
+	.remove	= mtk_iommu_remove,
 	.driver	= {
 		.name = "mtk-iommu",
 		.of_match_table = mtk_iommu_of_ids,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index ee4e55b6b190..480e57ea6635 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -745,7 +745,7 @@ static const struct dev_pm_ops mtk_iommu_v1_pm_ops = {
 
 static struct platform_driver mtk_iommu_v1_driver = {
 	.probe	= mtk_iommu_v1_probe,
-	.remove_new = mtk_iommu_v1_remove,
+	.remove	= mtk_iommu_v1_remove,
 	.driver	= {
 		.name = "mtk-iommu-v1",
 		.of_match_table = mtk_iommu_v1_of_ids,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 3f72aef8bd5b..b8ced5d0581c 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1285,7 +1285,7 @@ static const struct of_device_id omap_iommu_of_match[] = {
 
 static struct platform_driver omap_iommu_driver = {
 	.probe	= omap_iommu_probe,
-	.remove_new = omap_iommu_remove,
+	.remove	= omap_iommu_remove,
 	.driver	= {
 		.name	= "omap-iommu",
 		.pm	= &omap_iommu_pm_ops,
diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
index da336863f152..382ba2841849 100644
--- a/drivers/iommu/riscv/iommu-platform.c
+++ b/drivers/iommu/riscv/iommu-platform.c
@@ -81,7 +81,7 @@ static const struct of_device_id riscv_iommu_of_match[] = {
 
 static struct platform_driver riscv_iommu_platform_driver = {
 	.probe = riscv_iommu_platform_probe,
-	.remove_new = riscv_iommu_platform_remove,
+	.remove = riscv_iommu_platform_remove,
 	.driver = {
 		.name = "riscv,iommu",
 		.of_match_table = riscv_iommu_of_match,
diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
index a2f4ffe6d949..e84806eee281 100644
--- a/drivers/iommu/sprd-iommu.c
+++ b/drivers/iommu/sprd-iommu.c
@@ -531,7 +531,7 @@ static struct platform_driver sprd_iommu_driver = {
 		.suppress_bind_attrs = true,
 	},
 	.probe	= sprd_iommu_probe,
-	.remove_new = sprd_iommu_remove,
+	.remove	= sprd_iommu_remove,
 };
 module_platform_driver(sprd_iommu_driver);
 
base-commit: c88416ba074a8913cf6d61b789dd834bbca6681c
-- 
2.45.2



From parri.andrea at gmail.com  Sun Nov  3 23:13:19 2024
From: parri.andrea at gmail.com (Andrea Parri)
Date: Mon, 4 Nov 2024 09:13:19 +0200
Subject: [PATCH v6 00/13] Zacas/Zabha support and qspinlocks
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <Zyh0D9N8SgQd_zne@andrea>

> Alexandre Ghiti (11):
>   riscv: Move cpufeature.h macros into their own header
>   riscv: Do not fail to build on byte/halfword operations with Zawrs
>   riscv: Implement cmpxchg32/64() using Zacas
>   dt-bindings: riscv: Add Zabha ISA extension description
>   riscv: Implement cmpxchg8/16() using Zabha
>   riscv: Improve zacas fully-ordered cmpxchg()
>   riscv: Implement arch_cmpxchg128() using Zacas
>   riscv: Implement xchg8/16() using Zabha
>   riscv: Add ISA extension parsing for Ziccrse
>   dt-bindings: riscv: Add Ziccrse ISA extension description
>   riscv: Add qspinlock support
> 
> Guo Ren (2):
>   asm-generic: ticket-lock: Reuse arch_spinlock_t of qspinlock
>   asm-generic: ticket-lock: Add separate ticket-lock.h

For the series,

Reviewed-by: Andrea Parri <parri.andrea at gmail.com>

  Andrea


From max.hsu at sifive.com  Sun Nov  3 23:44:21 2024
From: max.hsu at sifive.com (Max Hsu)
Date: Mon, 4 Nov 2024 15:44:21 +0800
Subject: [PATCH RFC v2 3/3] riscv: KVM: Add Svukte extension support for Guest/VM
In-Reply-To: <CAAhSdy0ncLTAjEE1s-GWL95sscxwQFsKn1rXyA1_VVfk1bQBiw@mail.gmail.com>
References: <20240927-dev-maxh-svukte-rebase-2-v2-0-9afe57c33aee@sifive.com>
 <20240927-dev-maxh-svukte-rebase-2-v2-3-9afe57c33aee@sifive.com> <CAAhSdy0ncLTAjEE1s-GWL95sscxwQFsKn1rXyA1_VVfk1bQBiw@mail.gmail.com>
Message-ID: <CAHibDywpKUE7r4UfcudDSBZCM=JAC5s40uf+PwQE+oMvZy4aVA@mail.gmail.com>

Hi Anup,

Thank you for the suggestion.

I?m not entirely sure if I fully understand it, but I believe the
hypervisor should be able to disable the Svukte extension.

Inside the switch-case of kvm_riscv_vcpu_isa_disable_allowed(),
the default case breaks and returns true.

So that means when the KVM_RISCV_ISA_EXT_SVUKTE passed into
kvm_riscv_vcpu_isa_disable_allowed() it will return true.

If I've misunderstood, please let me know.

Best regards,
Max Hsu

On Fri, Oct 25, 2024 at 3:17?AM Anup Patel <anup at brainfault.org> wrote:
>
> On Fri, Sep 27, 2024 at 7:12?PM Max Hsu <max.hsu at sifive.com> wrote:
> >
> > Add KVM ISA extension ONE_REG interface to allow VMM tools to
> > detect and enable Svukte extension for Guest/VM.
> >
> > Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
> > Signed-off-by: Max Hsu <max.hsu at sifive.com>
> > ---
> >  arch/riscv/include/uapi/asm/kvm.h | 1 +
> >  arch/riscv/kvm/vcpu_onereg.c      | 1 +
> >  2 files changed, 2 insertions(+)
> >
> > diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
> > index e97db3296456e19f79ca02e4c4f70ae1b4abb48b..41b466b7ffaec421e8389d3f5b178580091a2c98 100644
> > --- a/arch/riscv/include/uapi/asm/kvm.h
> > +++ b/arch/riscv/include/uapi/asm/kvm.h
> > @@ -175,6 +175,7 @@ enum KVM_RISCV_ISA_EXT_ID {
> >         KVM_RISCV_ISA_EXT_ZCF,
> >         KVM_RISCV_ISA_EXT_ZCMOP,
> >         KVM_RISCV_ISA_EXT_ZAWRS,
> > +       KVM_RISCV_ISA_EXT_SVUKTE,
> >         KVM_RISCV_ISA_EXT_MAX,
> >  };
> >
> > diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
> > index b319c4c13c54ce22d2a7552f4c9f256a0c50780e..67237d6e53882a9fcd2cf265aa1704f25cc4a701 100644
> > --- a/arch/riscv/kvm/vcpu_onereg.c
> > +++ b/arch/riscv/kvm/vcpu_onereg.c
> > @@ -41,6 +41,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
> >         KVM_ISA_EXT_ARR(SVINVAL),
> >         KVM_ISA_EXT_ARR(SVNAPOT),
> >         KVM_ISA_EXT_ARR(SVPBMT),
> > +       KVM_ISA_EXT_ARR(SVUKTE),
> >         KVM_ISA_EXT_ARR(ZACAS),
> >         KVM_ISA_EXT_ARR(ZAWRS),
> >         KVM_ISA_EXT_ARR(ZBA),
>
> The KVM_RISCV_ISA_EXT_SVUKTE should be added to the
> switch-case in kvm_riscv_vcpu_isa_disable_allowed() because
> hypervisor seems to have no way to disable Svukte for the Guest
> when it's available on the Host.
>
> Regards,
> Anup


From elena.reshetova at intel.com  Mon Nov  4 00:33:06 2024
From: elena.reshetova at intel.com (Reshetova, Elena)
Date: Mon, 4 Nov 2024 08:33:06 +0000
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <7bd627df-0303-4ded-b8c8-ceb84fb20f0d@amazon.com>
References: <784d1522-0451-4844-a334-8b7d49019437@intel.com>
 <7bd627df-0303-4ded-b8c8-ceb84fb20f0d@amazon.com>
Message-ID: <DM8PR11MB57509ED04CB0730680735AC9E7512@DM8PR11MB5750.namprd11.prod.outlook.com>

> 
> +Elena
> 
> On 2024-11-01 at 16:06+0000, Dave Hansen wrote:
> > On 10/31/24 17:10, Manwaring, Derek wrote:
> > > TDX and SEV encryption happens between the core and main memory, so
> > > cached guest data we're most concerned about for transient execution
> > > attacks isn't necessarily inaccessible.
> > >
> > > I'd be interested what Intel, AMD, and other folks think on this, but I
> > > think direct map removal is worthwhile for CoCo cases as well.
> >
> > I'm not sure specifically which attacks you have in mind.? [...]
> >
> > I _think_ you might be thinking of attacks like MDS where some random
> > microarchitectural buffer contains guest data after a VM exit and then
> > an attacker extracts it.? Direct map removal doesn't affect these
> > buffers and doesn't mitigate an attacker getting the data out.
> 
> Right, the only attacks we can thwart with direct map removal are
> transient execution attacks on the host kernel whose leak origin is
> "Mapped memory" in Table 1 of the Quarantine paper [2]. Maybe the
> simplest hypothetical to consider here is a new spectre v1 gadget in the
> host kernel.
> 
> > The main thing I think you want to keep in mind is mentioned in the "TDX
> > Module v1.5 Base Architecture Specification"[1]:
> >
> > > Any software except guest TD or TDX module must not be able to
> > > speculatively or non-speculatively access TD private memory,
> >
> > That's a pretty broad claim and it involves mitigations in hardware and
> > the TDX module.
> >
> > 1. https://cdrdv2.intel.com/v1/dl/getContent/733575
> 
> Thank you, I hadn't seen that. That is a very strong claim as far as
> preventing speculative access; I didn't realize Intel claimed that about
> TDX. The comma followed by "to detect if a prior corruption attempt was
> successful" makes me wonder a bit if the statement is not quite as broad
> as it sounds, but maybe that's just meant to relate it to the integrity
> section?

This statement *is* for integrity section. We have a separate TDX guidance
on side-channels (including speculative) [3] and some speculative attacks
that affect confidentiality (for example spectre v1) are listed as not covered
by TDX but remaining SW responsibility (as they are now). 

[3] https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/best-practices/trusted-domain-security-guidance-for-developers.html

Best Regards,
Elena.

From lkp at intel.com  Mon Nov  4 01:04:10 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 4 Nov 2024 17:04:10 +0800
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241103145153.105097-14-alexghiti@rivosinc.com>
References: <20241103145153.105097-14-alexghiti@rivosinc.com>
Message-ID: <202411041609.gxjI2dsw-lkp@intel.com>

Hi Alexandre,

kernel test robot noticed the following build warnings:

[auto build test WARNING on arnd-asm-generic/master]
[also build test WARNING on robh/for-next tip/locking/core linus/master v6.12-rc6]
[cannot apply to next-20241101]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Alexandre-Ghiti/riscv-Move-cpufeature-h-macros-into-their-own-header/20241103-230614
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
patch link:    https://lore.kernel.org/r/20241103145153.105097-14-alexghiti%40rivosinc.com
patch subject: [PATCH v6 13/13] riscv: Add qspinlock support
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411041609.gxjI2dsw-lkp at intel.com/

includecheck warnings: (new ones prefixed by >>)
>> arch/riscv/include/asm/spinlock.h: asm/ticket_spinlock.h is included more than once.
>> arch/riscv/include/asm/spinlock.h: asm/qspinlock.h is included more than once.

vim +10 arch/riscv/include/asm/spinlock.h

     8	
     9	#define __no_arch_spinlock_redefine
  > 10	#include <asm/ticket_spinlock.h>
    11	#include <asm/qspinlock.h>
    12	#include <asm/jump_label.h>
    13	
    14	/*
    15	 * TODO: Use an alternative instead of a static key when we are able to parse
    16	 * the extensions string earlier in the boot process.
    17	 */
    18	DECLARE_STATIC_KEY_TRUE(qspinlock_key);
    19	
    20	#define SPINLOCK_BASE_DECLARE(op, type, type_lock)			\
    21	static __always_inline type arch_spin_##op(type_lock lock)		\
    22	{									\
    23		if (static_branch_unlikely(&qspinlock_key))			\
    24			return queued_spin_##op(lock);				\
    25		return ticket_spin_##op(lock);					\
    26	}
    27	
    28	SPINLOCK_BASE_DECLARE(lock, void, arch_spinlock_t *)
    29	SPINLOCK_BASE_DECLARE(unlock, void, arch_spinlock_t *)
    30	SPINLOCK_BASE_DECLARE(is_locked, int, arch_spinlock_t *)
    31	SPINLOCK_BASE_DECLARE(is_contended, int, arch_spinlock_t *)
    32	SPINLOCK_BASE_DECLARE(trylock, bool, arch_spinlock_t *)
    33	SPINLOCK_BASE_DECLARE(value_unlocked, int, arch_spinlock_t)
    34	
    35	#elif defined(CONFIG_RISCV_QUEUED_SPINLOCKS)
    36	
    37	#include <asm/qspinlock.h>
    38	
    39	#else
    40	
  > 41	#include <asm/ticket_spinlock.h>
    42	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From alexghiti at rivosinc.com  Mon Nov  4 01:09:07 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Mon, 4 Nov 2024 10:09:07 +0100
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <202411041609.gxjI2dsw-lkp@intel.com>
References: <20241103145153.105097-14-alexghiti@rivosinc.com> <202411041609.gxjI2dsw-lkp@intel.com>
Message-ID: <CAHVXubj8EXCXNPuJ+hqrHwyujjz3GDcqqMjQ4ZFC5VbmZurV3w@mail.gmail.com>

On Mon, Nov 4, 2024 at 10:05?AM kernel test robot <lkp at intel.com> wrote:
>
> Hi Alexandre,
>
> kernel test robot noticed the following build warnings:
>
> [auto build test WARNING on arnd-asm-generic/master]
> [also build test WARNING on robh/for-next tip/locking/core linus/master v6.12-rc6]
> [cannot apply to next-20241101]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url:    https://github.com/intel-lab-lkp/linux/commits/Alexandre-Ghiti/riscv-Move-cpufeature-h-macros-into-their-own-header/20241103-230614
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
> patch link:    https://lore.kernel.org/r/20241103145153.105097-14-alexghiti%40rivosinc.com
> patch subject: [PATCH v6 13/13] riscv: Add qspinlock support
> compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp at intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202411041609.gxjI2dsw-lkp at intel.com/
>
> includecheck warnings: (new ones prefixed by >>)
> >> arch/riscv/include/asm/spinlock.h: asm/ticket_spinlock.h is included more than once.
> >> arch/riscv/include/asm/spinlock.h: asm/qspinlock.h is included more than once.

Yes but that's in a #ifdef/#elif#else clause so nothing to do here!

>
> vim +10 arch/riscv/include/asm/spinlock.h
>
>      8
>      9  #define __no_arch_spinlock_redefine
>   > 10  #include <asm/ticket_spinlock.h>
>     11  #include <asm/qspinlock.h>
>     12  #include <asm/jump_label.h>
>     13
>     14  /*
>     15   * TODO: Use an alternative instead of a static key when we are able to parse
>     16   * the extensions string earlier in the boot process.
>     17   */
>     18  DECLARE_STATIC_KEY_TRUE(qspinlock_key);
>     19
>     20  #define SPINLOCK_BASE_DECLARE(op, type, type_lock)                      \
>     21  static __always_inline type arch_spin_##op(type_lock lock)              \
>     22  {                                                                       \
>     23          if (static_branch_unlikely(&qspinlock_key))                     \
>     24                  return queued_spin_##op(lock);                          \
>     25          return ticket_spin_##op(lock);                                  \
>     26  }
>     27
>     28  SPINLOCK_BASE_DECLARE(lock, void, arch_spinlock_t *)
>     29  SPINLOCK_BASE_DECLARE(unlock, void, arch_spinlock_t *)
>     30  SPINLOCK_BASE_DECLARE(is_locked, int, arch_spinlock_t *)
>     31  SPINLOCK_BASE_DECLARE(is_contended, int, arch_spinlock_t *)
>     32  SPINLOCK_BASE_DECLARE(trylock, bool, arch_spinlock_t *)
>     33  SPINLOCK_BASE_DECLARE(value_unlocked, int, arch_spinlock_t)
>     34
>     35  #elif defined(CONFIG_RISCV_QUEUED_SPINLOCKS)
>     36
>     37  #include <asm/qspinlock.h>
>     38
>     39  #else
>     40
>   > 41  #include <asm/ticket_spinlock.h>
>     42
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki


From cleger at rivosinc.com  Mon Nov  4 01:15:56 2024
From: cleger at rivosinc.com (=?UTF-8?B?Q2zDqW1lbnQgTMOpZ2Vy?=)
Date: Mon, 4 Nov 2024 10:15:56 +0100
Subject: [PATCH v2 2/3] riscv: add ISA extension parsing for bfloat16 ISA
 extension
In-Reply-To: <20241103074959.1135240-3-inochiama@gmail.com>
References: <20241103074959.1135240-1-inochiama@gmail.com>
 <20241103074959.1135240-3-inochiama@gmail.com>
Message-ID: <2e775421-0c3e-48ef-8a8c-6734f7fcf298@rivosinc.com>



On 03/11/2024 08:49, Inochi Amaoto wrote:
> Add parsing for Zfbmin, Zvfbfmin, Zvfbfwma ISA extension which
> were ratified in 4dc23d62 ("Added Chapter title to BF16") of
> the riscv-isa-manual.
> 
> Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
> ---
>  arch/riscv/include/asm/hwcap.h | 3 +++
>  arch/riscv/kernel/cpufeature.c | 3 +++
>  2 files changed, 6 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
> index 46d9de54179e..97657fb63af6 100644
> --- a/arch/riscv/include/asm/hwcap.h
> +++ b/arch/riscv/include/asm/hwcap.h
> @@ -93,6 +93,9 @@
>  #define RISCV_ISA_EXT_ZCMOP		84
>  #define RISCV_ISA_EXT_ZAWRS		85
>  #define RISCV_ISA_EXT_SVVPTC		86
> +#define RISCV_ISA_EXT_ZFBFMIN		87
> +#define RISCV_ISA_EXT_ZVFBFMIN		88
> +#define RISCV_ISA_EXT_ZVFBFWMA		89
>  
>  #define RISCV_ISA_EXT_XLINUXENVCFG	127
>  
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 3a8eeaa9310c..1b286f5bc591 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -325,6 +325,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
>  	__RISCV_ISA_EXT_DATA(zacas, RISCV_ISA_EXT_ZACAS),
>  	__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
>  	__RISCV_ISA_EXT_DATA(zfa, RISCV_ISA_EXT_ZFA),
> +	__RISCV_ISA_EXT_DATA(zfbfmin, RISCV_ISA_EXT_ZFBFMIN),
>  	__RISCV_ISA_EXT_DATA(zfh, RISCV_ISA_EXT_ZFH),
>  	__RISCV_ISA_EXT_DATA(zfhmin, RISCV_ISA_EXT_ZFHMIN),
>  	__RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA),
> @@ -357,6 +358,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
>  	__RISCV_ISA_EXT_SUPERSET(zve64d, RISCV_ISA_EXT_ZVE64D, riscv_zve64d_exts),
>  	__RISCV_ISA_EXT_SUPERSET(zve64f, RISCV_ISA_EXT_ZVE64F, riscv_zve64f_exts),
>  	__RISCV_ISA_EXT_SUPERSET(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts),
> +	__RISCV_ISA_EXT_DATA(zvfbfmin, RISCV_ISA_EXT_ZVFBFMIN),
> +	__RISCV_ISA_EXT_DATA(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA),

@Conor,

Should we wait for your V/F validation support to be merged before this
one ?

Thanks,

Cl?ment


>  	__RISCV_ISA_EXT_DATA(zvfh, RISCV_ISA_EXT_ZVFH),
>  	__RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN),
>  	__RISCV_ISA_EXT_DATA(zvkb, RISCV_ISA_EXT_ZVKB),



From alex at ghiti.fr  Mon Nov  4 02:02:14 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Mon, 4 Nov 2024 11:02:14 +0100
Subject: [PATCH] tools: add forwarding header for
 arch/riscv/include/asm/fence.h
In-Reply-To: <mvm5xq44bqh.fsf@suse.de>
References: <mvm5xq44bqh.fsf@suse.de>
Message-ID: <d380fd10-ebc4-4d66-becb-13995372d41a@ghiti.fr>

Hi Andreas,

On 07/10/2024 09:24, Andreas Schwab wrote:
> This is needed so that <asm/barrier.h> can find <asm/fence.h> on riscv.
>
> Fixes: 6d74d178fe6e ("tools: Add riscv barrier implementation")
> Signed-off-by: Andreas Schwab <schwab at suse.de>
> ---
>   tools/include/asm/fence.h | 3 +++
>   1 file changed, 3 insertions(+)
>   create mode 100644 tools/include/asm/fence.h
>
> diff --git a/tools/include/asm/fence.h b/tools/include/asm/fence.h
> new file mode 100644
> index 000000000000..917a173059a4
> --- /dev/null
> +++ b/tools/include/asm/fence.h
> @@ -0,0 +1,3 @@
> +#if defined(__riscv)
> +#include "../../arch/riscv/include/asm/fence.h"
> +#endif


After a discussion with Bjorn, it appears that he had already solved 
this issue with the following patch: 
https://lore.kernel.org/linux-riscv/20240927131355.350918-1-bjorn at kernel.org/ 
which we find cleaner. I have just tested his, and it indeed fixes the 
build error.

Unless you have any objection, we'll try to make Bjorn's patch into 
6.12-rc7 instead of yours.

Thanks,

Alex



From alex at ghiti.fr  Mon Nov  4 02:04:56 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Mon, 4 Nov 2024 11:04:56 +0100
Subject: [PATCH bpf-next 1/2] libbpf: Add missing per-arch include path
In-Reply-To: <20240927131355.350918-1-bjorn@kernel.org>
References: <20240927131355.350918-1-bjorn@kernel.org>
Message-ID: <a48514dc-6fe0-4f06-a5ee-10b1cf0f55e1@ghiti.fr>

Hi Bjorn,

On 27/09/2024 15:13, Bj?rn T?pel wrote:
> From: Bj?rn T?pel <bjorn at rivosinc.com>
>
> libbpf does not include the per-arch tools include path, e.g.
> tools/arch/riscv/include. Some architectures depend those files to
> build properly.
>
> Include tools/arch/$(SUBARCH)/include in the libbpf build.
>
> Fixes: 6d74d178fe6e ("tools: Add riscv barrier implementation")
> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
> ---
>   tools/lib/bpf/Makefile | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
> index 1b22f0f37288..857a5f7b413d 100644
> --- a/tools/lib/bpf/Makefile
> +++ b/tools/lib/bpf/Makefile
> @@ -61,7 +61,8 @@ ifndef VERBOSE
>   endif
>   
>   INCLUDES = -I$(or $(OUTPUT),.) \
> -	   -I$(srctree)/tools/include -I$(srctree)/tools/include/uapi
> +	   -I$(srctree)/tools/include -I$(srctree)/tools/include/uapi \
> +	   -I$(srctree)/tools/arch/$(SRCARCH)/include
>   
>   export prefix libdir src obj
>   
>
> base-commit: db5ca265e3334b48c4e3fa07eef79e8bc578c430


You can add:

Tested-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From m.wilczynski at samsung.com  Mon Nov  4 02:07:31 2024
From: m.wilczynski at samsung.com (Michal Wilczynski)
Date: Mon,  4 Nov 2024 11:07:31 +0100
Subject: [PATCH v6 0/3] Introduce support for T-head TH1520 Mailbox
References: <CGME20241104100757eucas1p15156cbe4466b785095cfb788192a7077@eucas1p1.samsung.com>
Message-ID: <20241104100734.1276116-1-m.wilczynski@samsung.com>

The T-head TH1520 SoC supports a hardware mailbox that enables two cores
within the SoC to communicate and coordinate [1]. One example of such
coordination would be cooperation with the T-Head E902 core, which is
responsible for power, clock, and resource management. For example, in
the specific case of the BXM-4-64 GPU, it needs to be powered on by the
E902 core, and the kernel running on the E910 needs to 'ask' the
firmware running on the E902 core to enable power to the GPU island.
Given recent advancements in work on the upstream GPU driver [2], there
is an emerging need to get this code in the mainline kernel.

Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf [1]
Link: https://gitlab.freedesktop.org/imagination/linux-firmware/-/issues/1 [2]

Thanks everyone for taking the time to review this series !

To test this, I've prepared a diff that includes the missing drivers
utilizing the mailbox and enabled the GPU node in the device tree to use
the drm/imagination driver.

I?ve created two branches. Both contain the same code, including this
patch series and some extra commits with mailbox consumers. The only
difference is that one branch has an additional commit that switches ON
calls to OFF calls (and vice versa) to observe the behavior when the GPU
is turned off via the mailbox.

To reproduce, simply clone the repository, add the following extra options
in the config:

CONFIG_THEAD_TH1520_MBOX=y #(this series)
CONFIG_DRM_POWERVR=y
CONFIG_LIGHT_AON=y
CONFIG_LIGHT_AON_PD=y

Then build and deploy on the target.

In case [1], the output should be:
[    2.478394] light_aon_probe: virtual_log_mem=0x000000005faf564a, phy base=0x33600000, size:2097152
[    2.488589] succeed to create power domain debugfs direntry
[    2.494987] powervr ffef400000.gpu: Before reading BVNC
At this point, the system will hang because the driver is trying to read
memory-mapped registers while the GPU isn?t powered on.

In case [2], the GPU powers on correctly, and the BVNC can be read
without issues. If the specific firmware file isn?t available, the
output would look like this:
root at revyos-lpi4a:~# dmesg | grep gpu
[    2.408207] powervr ffef400000.gpu: Before reading BVNC
[    2.413533] powervr ffef400000.gpu: After reading BVNC
[    2.418930] powervr ffef400000.gpu: Direct firmware load for powervr/rogue_36.52.104.182_v1.fw failed with error -2
[    2.429568] powervr ffef400000.gpu: [drm] *ERROR* failed to load firmware powervr/rogue_36.52.104.182_v1.fw (err=-2)
[    2.440403] powervr ffef400000.gpu: probe with driver powervr failed with error -2

Here are the links:
[1] - https://github.com/mwilczy/linux/tree/31_october_demonstrate_mailbox_not_working
[2] - https://github.com/mwilczy/linux/tree/31_october_demonstrate_mailbox_working

Note: U-Boot must load the AON firmware at startup to the address mapped
for AON for this to work properly.

v6:
 - added a devm_ action callback to disable the clocks if the probe fails

v5:
 - removed 'type' mbox-cell, which isn't really necessary for the use-cases of
   the series, but desribes SW protocol instead of the HW, adjust driver code
   logic to account for this, simplifying it
 - change the register mappings in the device tree node to reflect the manual
 - adjust the driver code to compensate for irregularities in the mappings, do
   this by modifying th1520_map_mmio() with extra argument 'offset'
 - add support for enabling/disabling MBOX clocks in the driver
 - add clocks in the dt-binding/device tree node
 - rebase and retest

v4:
- fixed warning of unused variable
- added Reviewed-by from Krzysztof
- fixed minor cosmetic issues in dt-binding

v3:
- added a comment about mixing devm_ and non-devm resources in the context
  of shared interrupts and explained why it's safe to do so in this
  particular case
- changed the order of resource freeing in the .shutdown callback
- used a wrapper function for register mapping
- since the only conceivable use case for this mailbox driver is
  communication with cores not managed by the kernel, I?ve hard-coded
  this by removing the thead,icu-cpu-id property and adjusted the mailbox
  driver code accordingly.
- added a more detailed description for mbox-cells.
- made some cosmetic changes.
- retested by applying the patch with non-yet-upstreamed patches,
  confirming that the drm/imagination driver can read the registers
  correctly.

v2:
 - fixed thead,th1520-mbox.yaml binding file by dropping redundant
   descriptions, renaming reg-names, removing unnecessary clocks,
   providing constraints and defining ICU's
 - fixed the mailbox driver code to work well with updated binding-file,
   removed clocks support, as it's not necessary for mailbox to work
 - adjusted the device tree node instance of mbox_910t so it will work
   with updated bindings file

Michal Wilczynski (3):
  mailbox: Introduce support for T-head TH1520 Mailbox driver
  dt-bindings: mailbox: Add thead,th1520-mailbox bindings
  riscv: dts: thead: Add mailbox node

 .../bindings/mailbox/thead,th1520-mbox.yaml   |  89 +++
 MAINTAINERS                                   |   2 +
 arch/riscv/boot/dts/thead/th1520.dtsi         |  16 +
 drivers/mailbox/Kconfig                       |  10 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mailbox-th1520.c              | 597 ++++++++++++++++++
 6 files changed, 716 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/thead,th1520-mbox.yaml
 create mode 100644 drivers/mailbox/mailbox-th1520.c

-- 
2.34.1



From m.wilczynski at samsung.com  Mon Nov  4 02:07:33 2024
From: m.wilczynski at samsung.com (Michal Wilczynski)
Date: Mon,  4 Nov 2024 11:07:33 +0100
Subject: [PATCH v6 2/3] dt-bindings: mailbox: Add thead,th1520-mailbox
 bindings
In-Reply-To: <20241104100734.1276116-1-m.wilczynski@samsung.com>
References: <20241104100734.1276116-1-m.wilczynski@samsung.com>
	<CGME20241104100800eucas1p15817779e9a030e74878ae39a8a99dc1e@eucas1p1.samsung.com>
Message-ID: <20241104100734.1276116-3-m.wilczynski@samsung.com>

Add bindings for the mailbox controller. This work is based on the vendor
kernel. [1]

Link: https://github.com/revyos/thead-kernel.git [1]

Signed-off-by: Michal Wilczynski <m.wilczynski at samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 .../bindings/mailbox/thead,th1520-mbox.yaml   | 89 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 90 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/thead,th1520-mbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/thead,th1520-mbox.yaml b/Documentation/devicetree/bindings/mailbox/thead,th1520-mbox.yaml
new file mode 100644
index 000000000000..0971fb97896e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/thead,th1520-mbox.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/thead,th1520-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: T-head TH1520 Mailbox Controller
+
+description:
+  The T-head mailbox controller enables communication and coordination between
+  cores within the SoC by passing messages (e.g., data, status, and control)
+  through mailbox channels. It also allows one core to signal another processor
+  using interrupts via the Interrupt Controller Unit (ICU).
+
+maintainers:
+  - Michal Wilczynski <m.wilczynski at samsung.com>
+
+properties:
+  compatible:
+    const: thead,th1520-mbox
+
+  clocks:
+    items:
+      - description: Clock for the local mailbox
+      - description: Clock for remote ICU 0
+      - description: Clock for remote ICU 1
+      - description: Clock for remote ICU 2
+
+  clock-names:
+    items:
+      - const: clk-local
+      - const: clk-remote-icu0
+      - const: clk-remote-icu1
+      - const: clk-remote-icu2
+
+  reg:
+    items:
+      - description: Mailbox local base address
+      - description: Remote ICU 0 base address
+      - description: Remote ICU 1 base address
+      - description: Remote ICU 2 base address
+
+  reg-names:
+    items:
+      - const: local
+      - const: remote-icu0
+      - const: remote-icu1
+      - const: remote-icu2
+
+  interrupts:
+    maxItems: 1
+
+  '#mbox-cells':
+    const: 1
+    description:
+      The one and only cell describes destination CPU ID.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - reg
+  - reg-names
+  - interrupts
+  - '#mbox-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/thead,th1520-clk-ap.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+      mailbox at ffffc38000 {
+        compatible = "thead,th1520-mbox";
+        reg = <0xff 0xffc38000 0x0 0x4000>,
+              <0xff 0xffc44000 0x0 0x1000>,
+              <0xff 0xffc4c000 0x0 0x1000>,
+              <0xff 0xffc54000 0x0 0x1000>;
+        reg-names = "local", "remote-icu0", "remote-icu1", "remote-icu2";
+        clocks = <&clk CLK_MBOX0>, <&clk CLK_MBOX1>, <&clk CLK_MBOX2>,
+                 <&clk CLK_MBOX3>;
+        clock-names = "clk-local", "clk-remote-icu0", "clk-remote-icu1",
+                      "clk-remote-icu2";
+        interrupts = <28>;
+        #mbox-cells = <1>;
+      };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index df36684221ff..506cdea74694 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19816,6 +19816,7 @@ L:	linux-riscv at lists.infradead.org
 S:	Maintained
 T:	git https://github.com/pdp7/linux.git
 F:	Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml
+F:	Documentation/devicetree/bindings/mailbox/thead,th1520-mbox.yaml
 F:	arch/riscv/boot/dts/thead/
 F:	drivers/clk/thead/clk-th1520-ap.c
 F:	drivers/mailbox/mailbox-th1520.c
-- 
2.34.1



From m.wilczynski at samsung.com  Mon Nov  4 02:07:34 2024
From: m.wilczynski at samsung.com (Michal Wilczynski)
Date: Mon,  4 Nov 2024 11:07:34 +0100
Subject: [PATCH v6 3/3] riscv: dts: thead: Add mailbox node
In-Reply-To: <20241104100734.1276116-1-m.wilczynski@samsung.com>
References: <20241104100734.1276116-1-m.wilczynski@samsung.com>
	<CGME20241104100801eucas1p27cd0d7b9b5b4500604470664884c42fb@eucas1p2.samsung.com>
Message-ID: <20241104100734.1276116-4-m.wilczynski@samsung.com>

Add mailbox device tree node. This work is based on the vendor kernel [1].

Link: https://github.com/revyos/thead-kernel.git [1]

Signed-off-by: Michal Wilczynski <m.wilczynski at samsung.com>
---
 arch/riscv/boot/dts/thead/th1520.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
index 6992060e6a54..89de5634d3d3 100644
--- a/arch/riscv/boot/dts/thead/th1520.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520.dtsi
@@ -520,6 +520,22 @@ timer7: timer at ffffc3303c {
 			status = "disabled";
 		};
 
+		mbox_910t: mailbox at ffffc38000 {
+			compatible = "thead,th1520-mbox";
+			reg = <0xff 0xffc38000 0x0 0x6000>,
+			      <0xff 0xffc40000 0x0 0x6000>,
+			      <0xff 0xffc4c000 0x0 0x2000>,
+			      <0xff 0xffc54000 0x0 0x2000>;
+			reg-names = "local", "remote-icu0", "remote-icu1", "remote-icu2";
+			clocks = <&clk CLK_MBOX0>, <&clk CLK_MBOX1>, <&clk CLK_MBOX2>,
+				 <&clk CLK_MBOX3>;
+			clock-names = "clk-local", "clk-remote-icu0", "clk-remote-icu1",
+				      "clk-remote-icu2";
+			interrupt-parent = <&plic>;
+			interrupts = <28 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <1>;
+		};
+
 		ao_gpio0: gpio at fffff41000 {
 			compatible = "snps,dw-apb-gpio";
 			reg = <0xff 0xfff41000 0x0 0x1000>;
-- 
2.34.1



From m.wilczynski at samsung.com  Mon Nov  4 02:07:32 2024
From: m.wilczynski at samsung.com (Michal Wilczynski)
Date: Mon,  4 Nov 2024 11:07:32 +0100
Subject: [PATCH v6 1/3] mailbox: Introduce support for T-head TH1520 Mailbox
 driver
In-Reply-To: <20241104100734.1276116-1-m.wilczynski@samsung.com>
References: <20241104100734.1276116-1-m.wilczynski@samsung.com>
	<CGME20241104100759eucas1p1251cb0bc0a3c4d621479170a29c454e7@eucas1p1.samsung.com>
Message-ID: <20241104100734.1276116-2-m.wilczynski@samsung.com>

This driver was tested using the drm/imagination GPU driver. It was able
to successfully power on the GPU, by passing a command through mailbox
from E910 core to E902 that's responsible for powering up the GPU. The
GPU driver was able to read the BVNC version from control registers,
which confirms it was successfully powered on.

[   33.957467] powervr ffef400000.gpu: [drm] loaded firmware
powervr/rogue_36.52.104.182_v1.fw
[   33.966008] powervr ffef400000.gpu: [drm] FW version v1.0 (build
6621747 OS)
[   38.978542] powervr ffef400000.gpu: [drm] *ERROR* Firmware failed to
boot

Though the driver still fails to boot the firmware, the mailbox driver
works when used with the not-yet-upstreamed firmware AON driver. There
is ongoing work to get the BXM-4-64 supported with the drm/imagination
driver [1], though it's not completed yet.

This work is based on the driver from the vendor kernel [2].

Link: https://gitlab.freedesktop.org/imagination/linux-firmware/-/issues/2 [1]
Link: https://github.com/revyos/thead-kernel.git [2]

Signed-off-by: Michal Wilczynski <m.wilczynski at samsung.com>
---
 MAINTAINERS                      |   1 +
 drivers/mailbox/Kconfig          |  10 +
 drivers/mailbox/Makefile         |   2 +
 drivers/mailbox/mailbox-th1520.c | 597 +++++++++++++++++++++++++++++++
 4 files changed, 610 insertions(+)
 create mode 100644 drivers/mailbox/mailbox-th1520.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a27407950242..df36684221ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19818,6 +19818,7 @@ T:	git https://github.com/pdp7/linux.git
 F:	Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml
 F:	arch/riscv/boot/dts/thead/
 F:	drivers/clk/thead/clk-th1520-ap.c
+F:	drivers/mailbox/mailbox-th1520.c
 F:	include/dt-bindings/clock/thead,th1520-clk-ap.h
 
 RNBD BLOCK DRIVERS
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 6fb995778636..52f8162896f5 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -295,4 +295,14 @@ config QCOM_IPCC
 	  acts as an interrupt controller for receiving interrupts from clients.
 	  Say Y here if you want to build this driver.
 
+config THEAD_TH1520_MBOX
+	tristate "T-head TH1520 Mailbox"
+	depends on ARCH_THEAD || COMPILE_TEST
+	help
+	  Mailbox driver implementation for the Thead TH-1520 platform. Enables
+	  two cores within the SoC to communicate and coordinate by passing
+	  messages. Could be used to communicate between E910 core, on which the
+	  kernel is running, and E902 core used for power management among other
+	  things.
+
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 3c3c27d54c13..5f4f5b0ce2cc 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -64,3 +64,5 @@ obj-$(CONFIG_SPRD_MBOX)		+= sprd-mailbox.o
 obj-$(CONFIG_QCOM_CPUCP_MBOX)	+= qcom-cpucp-mbox.o
 
 obj-$(CONFIG_QCOM_IPCC)		+= qcom-ipcc.o
+
+obj-$(CONFIG_THEAD_TH1520_MBOX)	+= mailbox-th1520.o
diff --git a/drivers/mailbox/mailbox-th1520.c b/drivers/mailbox/mailbox-th1520.c
new file mode 100644
index 000000000000..4e84640ac3b8
--- /dev/null
+++ b/drivers/mailbox/mailbox-th1520.c
@@ -0,0 +1,597 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* Status Register */
+#define TH_1520_MBOX_STA 0x0
+#define TH_1520_MBOX_CLR 0x4
+#define TH_1520_MBOX_MASK 0xc
+
+/* Transmit/receive data register:
+ * INFO0 ~ INFO6
+ */
+#define TH_1520_MBOX_INFO_NUM 8
+#define TH_1520_MBOX_DATA_INFO_NUM 7
+#define TH_1520_MBOX_INFO0 0x14
+/* Transmit ack register: INFO7 */
+#define TH_1520_MBOX_INFO7 0x30
+
+/* Generate remote icu IRQ Register */
+#define TH_1520_MBOX_GEN 0x10
+#define TH_1520_MBOX_GEN_RX_DATA BIT(6)
+#define TH_1520_MBOX_GEN_TX_ACK BIT(7)
+
+#define TH_1520_MBOX_CHAN_RES_SIZE 0x1000
+#define TH_1520_MBOX_CHANS 4
+#define TH_1520_MBOX_CHAN_NAME_SIZE 20
+
+#define TH_1520_MBOX_ACK_MAGIC 0xdeadbeaf
+
+#ifdef CONFIG_PM_SLEEP
+/* store MBOX context across system-wide suspend/resume transitions */
+struct th1520_mbox_context {
+	u32 intr_mask[TH_1520_MBOX_CHANS - 1];
+};
+#endif
+
+enum th1520_mbox_icu_cpu_id {
+	TH_1520_MBOX_ICU_KERNEL_CPU0, /* 910T */
+	TH_1520_MBOX_ICU_CPU1, /* 902 */
+	TH_1520_MBOX_ICU_CPU2, /* 906 */
+	TH_1520_MBOX_ICU_CPU3, /* 910R */
+};
+
+struct th1520_mbox_con_priv {
+	enum th1520_mbox_icu_cpu_id idx;
+	void __iomem *comm_local_base;
+	void __iomem *comm_remote_base;
+	char irq_desc[TH_1520_MBOX_CHAN_NAME_SIZE];
+	struct mbox_chan *chan;
+};
+
+struct th1520_mbox_priv {
+	struct device *dev;
+	void __iomem *local_icu[TH_1520_MBOX_CHANS];
+	void __iomem *remote_icu[TH_1520_MBOX_CHANS - 1];
+	void __iomem *cur_cpu_ch_base;
+	spinlock_t mbox_lock; /* control register lock */
+
+	struct mbox_controller mbox;
+	struct mbox_chan mbox_chans[TH_1520_MBOX_CHANS];
+	struct clk_bulk_data clocks[TH_1520_MBOX_CHANS];
+	struct th1520_mbox_con_priv con_priv[TH_1520_MBOX_CHANS];
+	int irq;
+#ifdef CONFIG_PM_SLEEP
+	struct th1520_mbox_context *ctx;
+#endif
+};
+
+static struct th1520_mbox_priv *
+to_th1520_mbox_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct th1520_mbox_priv, mbox);
+}
+
+static void th1520_mbox_write(struct th1520_mbox_priv *priv, u32 val, u32 offs)
+{
+	iowrite32(val, priv->cur_cpu_ch_base + offs);
+}
+
+static u32 th1520_mbox_read(struct th1520_mbox_priv *priv, u32 offs)
+{
+	return ioread32(priv->cur_cpu_ch_base + offs);
+}
+
+static u32 th1520_mbox_rmw(struct th1520_mbox_priv *priv, u32 off, u32 set,
+			   u32 clr)
+{
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&priv->mbox_lock, flags);
+	val = th1520_mbox_read(priv, off);
+	val &= ~clr;
+	val |= set;
+	th1520_mbox_write(priv, val, off);
+	spin_unlock_irqrestore(&priv->mbox_lock, flags);
+
+	return val;
+}
+
+static void th1520_mbox_chan_write(struct th1520_mbox_con_priv *cp, u32 val,
+				   u32 offs, bool is_remote)
+{
+	if (is_remote)
+		iowrite32(val, cp->comm_remote_base + offs);
+	else
+		iowrite32(val, cp->comm_local_base + offs);
+}
+
+static u32 th1520_mbox_chan_read(struct th1520_mbox_con_priv *cp, u32 offs,
+				 bool is_remote)
+{
+	if (is_remote)
+		return ioread32(cp->comm_remote_base + offs);
+	else
+		return ioread32(cp->comm_local_base + offs);
+}
+
+static void th1520_mbox_chan_rmw(struct th1520_mbox_con_priv *cp, u32 off,
+				 u32 set, u32 clr, bool is_remote)
+{
+	struct th1520_mbox_priv *priv = to_th1520_mbox_priv(cp->chan->mbox);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&priv->mbox_lock, flags);
+	val = th1520_mbox_chan_read(cp, off, is_remote);
+	val &= ~clr;
+	val |= set;
+	th1520_mbox_chan_write(cp, val, off, is_remote);
+	spin_unlock_irqrestore(&priv->mbox_lock, flags);
+}
+
+static void th1520_mbox_chan_rd_data(struct th1520_mbox_con_priv *cp,
+				     void *data, bool is_remote)
+{
+	u32 off = TH_1520_MBOX_INFO0;
+	u32 *arg = data;
+	u32 i;
+
+	/* read info0 ~ info6, totally 28 bytes
+	 * requires data memory size is 28 bytes
+	 */
+	for (i = 0; i < TH_1520_MBOX_DATA_INFO_NUM; i++) {
+		*arg = th1520_mbox_chan_read(cp, off, is_remote);
+		off += 4;
+		arg++;
+	}
+}
+
+static void th1520_mbox_chan_wr_data(struct th1520_mbox_con_priv *cp,
+				     void *data, bool is_remote)
+{
+	u32 off = TH_1520_MBOX_INFO0;
+	u32 *arg = data;
+	u32 i;
+
+	/* write info0 ~ info6, totally 28 bytes
+	 * requires data memory is 28 bytes valid data
+	 */
+	for (i = 0; i < TH_1520_MBOX_DATA_INFO_NUM; i++) {
+		th1520_mbox_chan_write(cp, *arg, off, is_remote);
+		off += 4;
+		arg++;
+	}
+}
+
+static void th1520_mbox_chan_wr_ack(struct th1520_mbox_con_priv *cp, void *data,
+				    bool is_remote)
+{
+	u32 off = TH_1520_MBOX_INFO7;
+	u32 *arg = data;
+
+	th1520_mbox_chan_write(cp, *arg, off, is_remote);
+}
+
+static int th1520_mbox_chan_id_to_mapbit(struct th1520_mbox_con_priv *cp)
+{
+	int mapbit = 0;
+	int i;
+
+	for (i = 0; i < TH_1520_MBOX_CHANS; i++) {
+		if (i == cp->idx)
+			return mapbit;
+
+		if (i != TH_1520_MBOX_ICU_KERNEL_CPU0)
+			mapbit++;
+	}
+
+	if (i == TH_1520_MBOX_CHANS)
+		dev_err(cp->chan->mbox->dev, "convert to mapbit failed\n");
+
+	return 0;
+}
+
+static irqreturn_t th1520_mbox_isr(int irq, void *p)
+{
+	struct mbox_chan *chan = p;
+	struct th1520_mbox_priv *priv = to_th1520_mbox_priv(chan->mbox);
+	struct th1520_mbox_con_priv *cp = chan->con_priv;
+	int mapbit = th1520_mbox_chan_id_to_mapbit(cp);
+	u32 sta, dat[TH_1520_MBOX_DATA_INFO_NUM];
+	u32 ack_magic = TH_1520_MBOX_ACK_MAGIC;
+	u32 info0_data, info7_data;
+
+	sta = th1520_mbox_read(priv, TH_1520_MBOX_STA);
+	if (!(sta & BIT(mapbit)))
+		return IRQ_NONE;
+
+	/* clear chan irq bit in STA register */
+	th1520_mbox_rmw(priv, TH_1520_MBOX_CLR, BIT(mapbit), 0);
+
+	/* info0 is the protocol word, should not be zero! */
+	info0_data = th1520_mbox_chan_read(cp, TH_1520_MBOX_INFO0, false);
+	if (info0_data) {
+		/* read info0~info6 data */
+		th1520_mbox_chan_rd_data(cp, dat, false);
+
+		/* clear local info0 */
+		th1520_mbox_chan_write(cp, 0x0, TH_1520_MBOX_INFO0, false);
+
+		/* notify remote cpu */
+		th1520_mbox_chan_wr_ack(cp, &ack_magic, true);
+		/* CPU1 902/906 use polling mode to monitor info7 */
+		if (cp->idx != TH_1520_MBOX_ICU_CPU1 &&
+		    cp->idx != TH_1520_MBOX_ICU_CPU2)
+			th1520_mbox_chan_rmw(cp, TH_1520_MBOX_GEN,
+					     TH_1520_MBOX_GEN_TX_ACK, 0, true);
+
+		/* transfer the data to client */
+		mbox_chan_received_data(chan, (void *)dat);
+	}
+
+	/* info7 magic value mean the real ack signal, not generate bit7 */
+	info7_data = th1520_mbox_chan_read(cp, TH_1520_MBOX_INFO7, false);
+	if (info7_data == TH_1520_MBOX_ACK_MAGIC) {
+		/* clear local info7 */
+		th1520_mbox_chan_write(cp, 0x0, TH_1520_MBOX_INFO7, false);
+
+		/* notify framework the last TX has completed */
+		mbox_chan_txdone(chan, 0);
+	}
+
+	if (!info0_data && !info7_data)
+		return IRQ_NONE;
+
+	return IRQ_HANDLED;
+}
+
+static int th1520_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct th1520_mbox_con_priv *cp = chan->con_priv;
+
+	th1520_mbox_chan_wr_data(cp, data, true);
+	th1520_mbox_chan_rmw(cp, TH_1520_MBOX_GEN, TH_1520_MBOX_GEN_RX_DATA, 0,
+			     true);
+	return 0;
+}
+
+static int th1520_mbox_startup(struct mbox_chan *chan)
+{
+	struct th1520_mbox_priv *priv = to_th1520_mbox_priv(chan->mbox);
+	struct th1520_mbox_con_priv *cp = chan->con_priv;
+	u32 data[8] = {};
+	int mask_bit;
+	int ret;
+
+	/* clear local and remote generate and info0~info7 */
+	th1520_mbox_chan_rmw(cp, TH_1520_MBOX_GEN, 0x0, 0xff, true);
+	th1520_mbox_chan_rmw(cp, TH_1520_MBOX_GEN, 0x0, 0xff, false);
+	th1520_mbox_chan_wr_ack(cp, &data[7], true);
+	th1520_mbox_chan_wr_ack(cp, &data[7], false);
+	th1520_mbox_chan_wr_data(cp, &data[0], true);
+	th1520_mbox_chan_wr_data(cp, &data[0], false);
+
+	/* enable the chan mask */
+	mask_bit = th1520_mbox_chan_id_to_mapbit(cp);
+	th1520_mbox_rmw(priv, TH_1520_MBOX_MASK, BIT(mask_bit), 0);
+
+	/*
+	 * Mixing devm_ managed resources with manual IRQ handling is generally
+	 * discouraged due to potential complexities with resource management,
+	 * especially when dealing with shared interrupts. However, in this case,
+	 * the approach is safe and effective because:
+	 *
+	 * 1. Each mailbox channel requests its IRQ within the .startup() callback
+	 *    and frees it within the .shutdown() callback.
+	 * 2. During device unbinding, the devm_ managed mailbox controller first
+	 *    iterates through all channels, ensuring that their IRQs are freed before
+	 *    any other devm_ resources are released.
+	 *
+	 * This ordering guarantees that no interrupts can be triggered from the device
+	 * while it is being unbound, preventing race conditions and ensuring system
+	 * stability.
+	 */
+	ret = request_irq(priv->irq, th1520_mbox_isr,
+			  IRQF_SHARED | IRQF_NO_SUSPEND, cp->irq_desc, chan);
+	if (ret) {
+		dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void th1520_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct th1520_mbox_priv *priv = to_th1520_mbox_priv(chan->mbox);
+	struct th1520_mbox_con_priv *cp = chan->con_priv;
+	int mask_bit;
+
+	free_irq(priv->irq, chan);
+
+	/* clear the chan mask */
+	mask_bit = th1520_mbox_chan_id_to_mapbit(cp);
+	th1520_mbox_rmw(priv, TH_1520_MBOX_MASK, 0, BIT(mask_bit));
+}
+
+static const struct mbox_chan_ops th1520_mbox_ops = {
+	.send_data = th1520_mbox_send_data,
+	.startup = th1520_mbox_startup,
+	.shutdown = th1520_mbox_shutdown,
+};
+
+static int th1520_mbox_init_generic(struct th1520_mbox_priv *priv)
+{
+#ifdef CONFIG_PM_SLEEP
+	priv->ctx = devm_kzalloc(priv->dev, sizeof(*priv->ctx), GFP_KERNEL);
+	if (!priv->ctx)
+		return -ENOMEM;
+#endif
+	/* Set default configuration */
+	th1520_mbox_write(priv, 0xff, TH_1520_MBOX_CLR);
+	th1520_mbox_write(priv, 0x0, TH_1520_MBOX_MASK);
+	return 0;
+}
+
+static struct mbox_chan *th1520_mbox_xlate(struct mbox_controller *mbox,
+					   const struct of_phandle_args *sp)
+{
+	u32 chan;
+
+	if (sp->args_count != 1) {
+		dev_err(mbox->dev, "Invalid argument count %d\n",
+			sp->args_count);
+		return ERR_PTR(-EINVAL);
+	}
+
+	chan = sp->args[0]; /* comm remote channel */
+
+	if (chan >= mbox->num_chans) {
+		dev_err(mbox->dev, "Not supported channel number: %d\n", chan);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (chan == TH_1520_MBOX_ICU_KERNEL_CPU0) {
+		dev_err(mbox->dev, "Cannot communicate with yourself\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	return &mbox->chans[chan];
+}
+
+static void __iomem *th1520_map_mmio(struct platform_device *pdev,
+				     char *res_name, size_t offset)
+{
+	void __iomem *mapped;
+	struct resource *res;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
+
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get resource: %s\n", res_name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	mapped = devm_ioremap(&pdev->dev, res->start + offset,
+			      resource_size(res) - offset);
+	if (IS_ERR(mapped))
+		dev_err(&pdev->dev, "Failed to map resource: %s\n", res_name);
+
+	return mapped;
+}
+
+static void th1520_disable_clk(void *data)
+{
+	struct th1520_mbox_priv *priv = data;
+
+	clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
+}
+
+static int th1520_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct th1520_mbox_priv *priv;
+	unsigned int remote_idx = 0;
+	unsigned int i;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = dev;
+
+	priv->clocks[0].id = "clk-local";
+	priv->clocks[1].id = "clk-remote-icu0";
+	priv->clocks[2].id = "clk-remote-icu1";
+	priv->clocks[3].id = "clk-remote-icu2";
+
+	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks),
+				priv->clocks);
+	if (ret) {
+		dev_err(dev, "Failed to get clocks\n");
+		return ret;
+	}
+
+	ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks);
+	if (ret) {
+		dev_err(dev, "Failed to enable clocks\n");
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(dev, th1520_disable_clk, priv);
+	if (ret) {
+		clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
+		return ret;
+	}
+
+	/*
+	 * The address mappings in the device tree align precisely with those
+	 * outlined in the manual. However, register offsets within these
+	 * mapped regions are irregular, particularly for remote-icu0.
+	 * Consequently, th1520_map_mmio() requires an additional parameter to
+	 * handle this quirk.
+	 */
+	priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0] =
+		th1520_map_mmio(pdev, "local", 0x0);
+	if (IS_ERR(priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0]))
+		return PTR_ERR(priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0]);
+
+	priv->remote_icu[0] = th1520_map_mmio(pdev, "remote-icu0", 0x4000);
+	if (IS_ERR(priv->remote_icu[0]))
+		return PTR_ERR(priv->remote_icu[0]);
+
+	priv->remote_icu[1] = th1520_map_mmio(pdev, "remote-icu1", 0x0);
+	if (IS_ERR(priv->remote_icu[1]))
+		return PTR_ERR(priv->remote_icu[1]);
+
+	priv->remote_icu[2] = th1520_map_mmio(pdev, "remote-icu2", 0x0);
+	if (IS_ERR(priv->remote_icu[2]))
+		return PTR_ERR(priv->remote_icu[2]);
+
+	priv->local_icu[TH_1520_MBOX_ICU_CPU1] =
+		priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0] +
+		TH_1520_MBOX_CHAN_RES_SIZE;
+	priv->local_icu[TH_1520_MBOX_ICU_CPU2] =
+		priv->local_icu[TH_1520_MBOX_ICU_CPU1] +
+		TH_1520_MBOX_CHAN_RES_SIZE;
+	priv->local_icu[TH_1520_MBOX_ICU_CPU3] =
+		priv->local_icu[TH_1520_MBOX_ICU_CPU2] +
+		TH_1520_MBOX_CHAN_RES_SIZE;
+
+	priv->cur_cpu_ch_base = priv->local_icu[TH_1520_MBOX_ICU_KERNEL_CPU0];
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (priv->irq < 0)
+		return priv->irq;
+
+	/* init the chans */
+	for (i = 0; i < TH_1520_MBOX_CHANS; i++) {
+		struct th1520_mbox_con_priv *cp = &priv->con_priv[i];
+
+		cp->idx = i;
+		cp->chan = &priv->mbox_chans[i];
+		priv->mbox_chans[i].con_priv = cp;
+		snprintf(cp->irq_desc, sizeof(cp->irq_desc),
+			 "th1520_mbox_chan[%i]", cp->idx);
+
+		cp->comm_local_base = priv->local_icu[i];
+		if (i != TH_1520_MBOX_ICU_KERNEL_CPU0) {
+			cp->comm_remote_base = priv->remote_icu[remote_idx];
+			remote_idx++;
+		}
+	}
+
+	spin_lock_init(&priv->mbox_lock);
+
+	priv->mbox.dev = dev;
+	priv->mbox.ops = &th1520_mbox_ops;
+	priv->mbox.chans = priv->mbox_chans;
+	priv->mbox.num_chans = TH_1520_MBOX_CHANS;
+	priv->mbox.of_xlate = th1520_mbox_xlate;
+	priv->mbox.txdone_irq = true;
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = th1520_mbox_init_generic(priv);
+	if (ret) {
+		dev_err(dev, "Failed to init mailbox context\n");
+		return ret;
+	}
+
+	return devm_mbox_controller_register(dev, &priv->mbox);
+}
+
+static const struct of_device_id th1520_mbox_dt_ids[] = {
+	{ .compatible = "thead,th1520-mbox" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, th1520_mbox_dt_ids);
+
+#ifdef CONFIG_PM_SLEEP
+static int __maybe_unused th1520_mbox_suspend_noirq(struct device *dev)
+{
+	struct th1520_mbox_priv *priv = dev_get_drvdata(dev);
+	struct th1520_mbox_context *ctx = priv->ctx;
+	u32 i;
+	/*
+	 * ONLY interrupt mask bit should be stored and restores.
+	 * INFO data all assumed to be lost.
+	 */
+	for (i = 0; i < TH_1520_MBOX_CHANS; i++) {
+		ctx->intr_mask[i] =
+			ioread32(priv->local_icu[i] + TH_1520_MBOX_MASK);
+	}
+	return 0;
+}
+
+static int __maybe_unused th1520_mbox_resume_noirq(struct device *dev)
+{
+	struct th1520_mbox_priv *priv = dev_get_drvdata(dev);
+	struct th1520_mbox_context *ctx = priv->ctx;
+	u32 i;
+
+	for (i = 0; i < TH_1520_MBOX_CHANS; i++) {
+		iowrite32(ctx->intr_mask[i],
+			  priv->local_icu[i] + TH_1520_MBOX_MASK);
+	}
+
+	return 0;
+}
+#endif
+
+static int  __maybe_unused th1520_mbox_runtime_suspend(struct device *dev)
+{
+	struct th1520_mbox_priv *priv = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
+
+	return 0;
+}
+
+static int __maybe_unused th1520_mbox_runtime_resume(struct device *dev)
+{
+	struct th1520_mbox_priv *priv = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks);
+	if (ret)
+		dev_err(dev, "Failed to enable clocks in runtime resume\n");
+
+	return ret;
+}
+
+static const struct dev_pm_ops th1520_mbox_pm_ops = {
+#ifdef CONFIG_PM_SLEEP
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(th1520_mbox_suspend_noirq,
+				      th1520_mbox_resume_noirq)
+#endif
+	SET_RUNTIME_PM_OPS(th1520_mbox_runtime_suspend,
+			   th1520_mbox_runtime_resume, NULL)
+};
+
+static struct platform_driver th1520_mbox_driver = {
+	.probe		= th1520_mbox_probe,
+	.driver = {
+		.name	= "th1520-mbox",
+		.of_match_table = th1520_mbox_dt_ids,
+		.pm = &th1520_mbox_pm_ops,
+	},
+};
+module_platform_driver(th1520_mbox_driver);
+
+MODULE_DESCRIPTION("Thead TH-1520 mailbox IPC driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From bjorn at kernel.org  Mon Nov  4 02:25:58 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Mon, 04 Nov 2024 11:25:58 +0100
Subject: [PATCH bpf-next 1/2] libbpf: Add missing per-arch include path
In-Reply-To: <172835823300.66789.3704854116445399222.git-patchwork-notify@kernel.org>
References: <20240927131355.350918-1-bjorn@kernel.org>
 <172835823300.66789.3704854116445399222.git-patchwork-notify@kernel.org>
Message-ID: <87bjyvpa6h.fsf@all.your.base.are.belong.to.us>

patchwork-bot+netdevbpf at kernel.org writes:

> Hello:
>
> This series was applied to bpf/bpf-next.git (master)
> by Andrii Nakryiko <andrii at kernel.org>:
>
> On Fri, 27 Sep 2024 15:13:52 +0200 you wrote:
>> From: Bj?rn T?pel <bjorn at rivosinc.com>
>> 
>> libbpf does not include the per-arch tools include path, e.g.
>> tools/arch/riscv/include. Some architectures depend those files to
>> build properly.
>> 
>> Include tools/arch/$(SUBARCH)/include in the libbpf build.
>> 
>> [...]
>
> Here is the summary with links:
>   - [bpf-next,1/2] libbpf: Add missing per-arch include path
>     https://git.kernel.org/bpf/bpf-next/c/710fbca820c7
>   - [bpf-next,2/2] selftests: bpf: Add missing per-arch include path
>     https://git.kernel.org/bpf/bpf-next/c/19090f0306f1

Andrii, I just noted that this landed into bpf-next, and not bpf
(fixes).

RISC-V libbpf/perf needs this fix in 6.12 to properly build. Would it be
possible to have it in the bpf tree, and have it land in 6.12-rc7?

Andreas that has a similar fix [1].


Bj?rn

[1] https://lore.kernel.org/linux-riscv/mvm5xq44bqh.fsf at suse.de/


From robin.murphy at arm.com  Mon Nov  4 02:32:10 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 4 Nov 2024 10:32:10 +0000
Subject: [PATCH] iommu: Switch back to struct platform_driver::remove()
In-Reply-To: <20241104064650.799122-2-u.kleine-koenig@baylibre.com>
References: <20241104064650.799122-2-u.kleine-koenig@baylibre.com>
Message-ID: <6b5b4f25-0f42-4f83-b6b5-82c1adbefe83@arm.com>

On 2024-11-04 6:46 am, Uwe Kleine-K?nig wrote:
> After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
> return void") .remove() is (again) the right callback to implement for
> platform drivers.
> 
> Convert all platform drivers below drivers/iommu to use .remove(), with
> the eventual goal to drop struct platform_driver::remove_new(). As
> .remove() and .remove_new() have the same prototypes, conversion is done
> by just changing the structure member name in the driver initializer.

I dont see any major concern with doing it this way. FWIW,

Acked-by: Robin Murphy <robin.murphy at arm.com>

> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>
> ---
> Hello,
> 
> I did a single patch for all of drivers/iommu. While I usually prefer to
> do one logical change per patch, this seems to be overengineering here
> as the individual changes are really trivial and shouldn't be much in
> the way for stable backports. But I'll happily split the patch if you
> prefer it split.
> 
> This is based on today's next, if conflicts arise when you apply it at
> some later time and don't want to resolve them, feel free to just drop
> the changes to the conflicting files. I'll notice and followup at a
> later time then. Or ask me for a fixed resend. (Having said that, I
> recommend b4 am -3 + git am -3 which should resolve most conflicts just
> fine.)
> 
> Best regards
> Uwe
> 
>   drivers/iommu/apple-dart.c                  | 2 +-
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +-
>   drivers/iommu/arm/arm-smmu/arm-smmu.c       | 2 +-
>   drivers/iommu/arm/arm-smmu/qcom_iommu.c     | 4 ++--
>   drivers/iommu/ipmmu-vmsa.c                  | 2 +-
>   drivers/iommu/msm_iommu.c                   | 2 +-
>   drivers/iommu/mtk_iommu.c                   | 2 +-
>   drivers/iommu/mtk_iommu_v1.c                | 2 +-
>   drivers/iommu/omap-iommu.c                  | 2 +-
>   drivers/iommu/riscv/iommu-platform.c        | 2 +-
>   drivers/iommu/sprd-iommu.c                  | 2 +-
>   11 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
> index eb1e62cd499a..c5bde50d1c42 100644
> --- a/drivers/iommu/apple-dart.c
> +++ b/drivers/iommu/apple-dart.c
> @@ -1352,7 +1352,7 @@ static struct platform_driver apple_dart_driver = {
>   		.pm			= pm_sleep_ptr(&apple_dart_pm_ops),
>   	},
>   	.probe	= apple_dart_probe,
> -	.remove_new = apple_dart_remove,
> +	.remove	= apple_dart_remove,
>   };
>   
>   module_platform_driver(apple_dart_driver);
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 826db8894fb7..efbc78bffd33 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -4679,7 +4679,7 @@ static struct platform_driver arm_smmu_driver = {
>   		.suppress_bind_attrs	= true,
>   	},
>   	.probe	= arm_smmu_device_probe,
> -	.remove_new = arm_smmu_device_remove,
> +	.remove	= arm_smmu_device_remove,
>   	.shutdown = arm_smmu_device_shutdown,
>   };
>   module_driver(arm_smmu_driver, platform_driver_register,
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index 8321962b3714..4e9bb9f4c4bd 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -2372,7 +2372,7 @@ static struct platform_driver arm_smmu_driver = {
>   		.suppress_bind_attrs    = true,
>   	},
>   	.probe	= arm_smmu_device_probe,
> -	.remove_new = arm_smmu_device_remove,
> +	.remove = arm_smmu_device_remove,
>   	.shutdown = arm_smmu_device_shutdown,
>   };
>   module_platform_driver(arm_smmu_driver);
> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> index b98a7a598b89..9ce2fe50b22c 100644
> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> @@ -759,7 +759,7 @@ static struct platform_driver qcom_iommu_ctx_driver = {
>   		.of_match_table	= ctx_of_match,
>   	},
>   	.probe	= qcom_iommu_ctx_probe,
> -	.remove_new = qcom_iommu_ctx_remove,
> +	.remove	= qcom_iommu_ctx_remove,
>   };
>   
>   static bool qcom_iommu_has_secure_context(struct qcom_iommu_dev *qcom_iommu)
> @@ -931,7 +931,7 @@ static struct platform_driver qcom_iommu_driver = {
>   		.pm		= &qcom_iommu_pm_ops,
>   	},
>   	.probe	= qcom_iommu_device_probe,
> -	.remove_new = qcom_iommu_device_remove,
> +	.remove	= qcom_iommu_device_remove,
>   };
>   
>   static int __init qcom_iommu_init(void)
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index ff55b8c30712..074daf1aac4e 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -1159,6 +1159,6 @@ static struct platform_driver ipmmu_driver = {
>   		.pm = pm_sleep_ptr(&ipmmu_pm),
>   	},
>   	.probe = ipmmu_probe,
> -	.remove_new = ipmmu_remove,
> +	.remove = ipmmu_remove,
>   };
>   builtin_platform_driver(ipmmu_driver);
> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index 989e0869d805..ce40f0a419ea 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -838,6 +838,6 @@ static struct platform_driver msm_iommu_driver = {
>   		.of_match_table = msm_iommu_dt_match,
>   	},
>   	.probe		= msm_iommu_probe,
> -	.remove_new	= msm_iommu_remove,
> +	.remove		= msm_iommu_remove,
>   };
>   builtin_platform_driver(msm_iommu_driver);
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index c45313c43b9e..72b68d037b95 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -1794,7 +1794,7 @@ MODULE_DEVICE_TABLE(of, mtk_iommu_of_ids);
>   
>   static struct platform_driver mtk_iommu_driver = {
>   	.probe	= mtk_iommu_probe,
> -	.remove_new = mtk_iommu_remove,
> +	.remove	= mtk_iommu_remove,
>   	.driver	= {
>   		.name = "mtk-iommu",
>   		.of_match_table = mtk_iommu_of_ids,
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index ee4e55b6b190..480e57ea6635 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -745,7 +745,7 @@ static const struct dev_pm_ops mtk_iommu_v1_pm_ops = {
>   
>   static struct platform_driver mtk_iommu_v1_driver = {
>   	.probe	= mtk_iommu_v1_probe,
> -	.remove_new = mtk_iommu_v1_remove,
> +	.remove	= mtk_iommu_v1_remove,
>   	.driver	= {
>   		.name = "mtk-iommu-v1",
>   		.of_match_table = mtk_iommu_v1_of_ids,
> diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
> index 3f72aef8bd5b..b8ced5d0581c 100644
> --- a/drivers/iommu/omap-iommu.c
> +++ b/drivers/iommu/omap-iommu.c
> @@ -1285,7 +1285,7 @@ static const struct of_device_id omap_iommu_of_match[] = {
>   
>   static struct platform_driver omap_iommu_driver = {
>   	.probe	= omap_iommu_probe,
> -	.remove_new = omap_iommu_remove,
> +	.remove	= omap_iommu_remove,
>   	.driver	= {
>   		.name	= "omap-iommu",
>   		.pm	= &omap_iommu_pm_ops,
> diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
> index da336863f152..382ba2841849 100644
> --- a/drivers/iommu/riscv/iommu-platform.c
> +++ b/drivers/iommu/riscv/iommu-platform.c
> @@ -81,7 +81,7 @@ static const struct of_device_id riscv_iommu_of_match[] = {
>   
>   static struct platform_driver riscv_iommu_platform_driver = {
>   	.probe = riscv_iommu_platform_probe,
> -	.remove_new = riscv_iommu_platform_remove,
> +	.remove = riscv_iommu_platform_remove,
>   	.driver = {
>   		.name = "riscv,iommu",
>   		.of_match_table = riscv_iommu_of_match,
> diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
> index a2f4ffe6d949..e84806eee281 100644
> --- a/drivers/iommu/sprd-iommu.c
> +++ b/drivers/iommu/sprd-iommu.c
> @@ -531,7 +531,7 @@ static struct platform_driver sprd_iommu_driver = {
>   		.suppress_bind_attrs = true,
>   	},
>   	.probe	= sprd_iommu_probe,
> -	.remove_new = sprd_iommu_remove,
> +	.remove	= sprd_iommu_remove,
>   };
>   module_platform_driver(sprd_iommu_driver);
>   
> base-commit: c88416ba074a8913cf6d61b789dd834bbca6681c



From ardb at kernel.org  Mon Nov  4 02:55:08 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 4 Nov 2024 11:55:08 +0100
Subject: [PATCH v3 03/18] lib/crc32: expose whether the lib is really
 optimized at runtime
In-Reply-To: <20241103223154.136127-4-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org> <20241103223154.136127-4-ebiggers@kernel.org>
Message-ID: <CAMj1kXErAGvJ+ZK1SMQQKVbbZVhjxaWzn0gmV-xxtsoWSuwT9g@mail.gmail.com>

On Sun, 3 Nov 2024 at 23:34, Eric Biggers <ebiggers at kernel.org> wrote:
>
> From: Eric Biggers <ebiggers at google.com>
>
> Make the CRC32 library export a function crc32_optimizations() which
> returns flags that indicate which CRC32 functions are actually executing
> optimized code at runtime.
>
> This will be used to determine whether the crc32[c]-$arch shash
> algorithms should be registered in the crypto API.  btrfs could also
> start using these flags instead of the hack that it currently uses where
> it parses the crypto_shash_driver_name.
>
> Signed-off-by: Eric Biggers <ebiggers at google.com>

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>

> ---
>  arch/arm64/lib/crc32-glue.c  | 10 ++++++++++
>  arch/riscv/lib/crc32-riscv.c | 10 ++++++++++
>  include/linux/crc32.h        | 15 +++++++++++++++
>  3 files changed, 35 insertions(+)
>
> diff --git a/arch/arm64/lib/crc32-glue.c b/arch/arm64/lib/crc32-glue.c
> index d7f6e1cbf0d2..15c4c9db573e 100644
> --- a/arch/arm64/lib/crc32-glue.c
> +++ b/arch/arm64/lib/crc32-glue.c
> @@ -83,7 +83,17 @@ u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
>
>         return crc32_be_arm64(crc, p, len);
>  }
>  EXPORT_SYMBOL(crc32_be_arch);
>
> +u32 crc32_optimizations(void)
> +{
> +       if (alternative_has_cap_likely(ARM64_HAS_CRC32))
> +               return CRC32_LE_OPTIMIZATION |
> +                      CRC32_BE_OPTIMIZATION |
> +                      CRC32C_OPTIMIZATION;
> +       return 0;
> +}
> +EXPORT_SYMBOL(crc32_optimizations);
> +
>  MODULE_LICENSE("GPL");
>  MODULE_DESCRIPTION("arm64-optimized CRC32 functions");
> diff --git a/arch/riscv/lib/crc32-riscv.c b/arch/riscv/lib/crc32-riscv.c
> index a3ff7db2a1ce..53d56ab422c7 100644
> --- a/arch/riscv/lib/crc32-riscv.c
> +++ b/arch/riscv/lib/crc32-riscv.c
> @@ -295,7 +295,17 @@ u32 __pure crc32_be_arch(u32 crc, const u8 *p, size_t len)
>  legacy:
>         return crc32_be_base(crc, p, len);
>  }
>  EXPORT_SYMBOL(crc32_be_arch);
>
> +u32 crc32_optimizations(void)
> +{
> +       if (riscv_has_extension_likely(RISCV_ISA_EXT_ZBC))
> +               return CRC32_LE_OPTIMIZATION |
> +                      CRC32_BE_OPTIMIZATION |
> +                      CRC32C_OPTIMIZATION;
> +       return 0;
> +}
> +EXPORT_SYMBOL(crc32_optimizations);
> +
>  MODULE_LICENSE("GPL");
>  MODULE_DESCRIPTION("Accelerated CRC32 implementation with Zbc extension");
> diff --git a/include/linux/crc32.h b/include/linux/crc32.h
> index 58c632533b08..e9bd40056687 100644
> --- a/include/linux/crc32.h
> +++ b/include/linux/crc32.h
> @@ -35,10 +35,25 @@ static inline u32 __pure __crc32c_le(u32 crc, const u8 *p, size_t len)
>         if (IS_ENABLED(CONFIG_CRC32_ARCH))
>                 return crc32c_le_arch(crc, p, len);
>         return crc32c_le_base(crc, p, len);
>  }
>
> +/*
> + * crc32_optimizations() returns flags that indicate which CRC32 library
> + * functions are using architecture-specific optimizations.  Unlike
> + * IS_ENABLED(CONFIG_CRC32_ARCH) it takes into account the different CRC32
> + * variants and also whether any needed CPU features are available at runtime.
> + */
> +#define CRC32_LE_OPTIMIZATION  BIT(0) /* crc32_le() is optimized */
> +#define CRC32_BE_OPTIMIZATION  BIT(1) /* crc32_be() is optimized */
> +#define CRC32C_OPTIMIZATION    BIT(2) /* __crc32c_le() is optimized */
> +#if IS_ENABLED(CONFIG_CRC32_ARCH)
> +u32 crc32_optimizations(void);
> +#else
> +static inline u32 crc32_optimizations(void) { return 0; }
> +#endif
> +
>  /**
>   * crc32_le_combine - Combine two crc32 check values into one. For two
>   *                   sequences of bytes, seq1 and seq2 with lengths len1
>   *                   and len2, crc32_le() check values were calculated
>   *                   for each, crc1 and crc2.
> --
> 2.47.0
>
>


From ardb at kernel.org  Mon Nov  4 02:56:45 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 4 Nov 2024 11:56:45 +0100
Subject: [PATCH v3 04/18] crypto: crc32 - don't unnecessarily register
 arch algorithms
In-Reply-To: <20241103223154.136127-5-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org> <20241103223154.136127-5-ebiggers@kernel.org>
Message-ID: <CAMj1kXH3C1xP7865V-mJ+3=FDHTR-df909=7jift_Z6dmp58Gw@mail.gmail.com>

On Sun, 3 Nov 2024 at 23:32, Eric Biggers <ebiggers at kernel.org> wrote:
>
> From: Eric Biggers <ebiggers at google.com>
>
> Instead of registering the crc32-$arch and crc32c-$arch algorithms if
> the arch-specific code was built, only register them when that code was
> built *and* is not falling back to the base implementation at runtime.
>
> This avoids confusing users like btrfs which checks the shash driver
> name to determine whether it is crc32c-generic.
>
> (It would also make sense to change btrfs to test the crc32_optimization
> flags itself, so that it doesn't have to use the weird hack of parsing
> the driver name.  This change still makes sense either way though.)
>
> Signed-off-by: Eric Biggers <ebiggers at google.com>

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>

> ---
>  crypto/crc32_generic.c  | 8 ++++++--
>  crypto/crc32c_generic.c | 8 ++++++--
>  2 files changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/crypto/crc32_generic.c b/crypto/crc32_generic.c
> index cc064ea8240e..783a30b27398 100644
> --- a/crypto/crc32_generic.c
> +++ b/crypto/crc32_generic.c
> @@ -155,19 +155,23 @@ static struct shash_alg algs[] = {{
>         .base.cra_ctxsize       = sizeof(u32),
>         .base.cra_module        = THIS_MODULE,
>         .base.cra_init          = crc32_cra_init,
>  }};
>
> +static int num_algs;
> +
>  static int __init crc32_mod_init(void)
>  {
>         /* register the arch flavor only if it differs from the generic one */
> -       return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
> +       num_algs = 1 + ((crc32_optimizations() & CRC32_LE_OPTIMIZATION) != 0);
> +
> +       return crypto_register_shashes(algs, num_algs);
>  }
>
>  static void __exit crc32_mod_fini(void)
>  {
> -       crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
> +       crypto_unregister_shashes(algs, num_algs);
>  }
>
>  subsys_initcall(crc32_mod_init);
>  module_exit(crc32_mod_fini);
>
> diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c
> index 04b03d825cf4..985da981d6e2 100644
> --- a/crypto/crc32c_generic.c
> +++ b/crypto/crc32c_generic.c
> @@ -195,19 +195,23 @@ static struct shash_alg algs[] = {{
>         .base.cra_ctxsize       = sizeof(struct chksum_ctx),
>         .base.cra_module        = THIS_MODULE,
>         .base.cra_init          = crc32c_cra_init,
>  }};
>
> +static int num_algs;
> +
>  static int __init crc32c_mod_init(void)
>  {
>         /* register the arch flavor only if it differs from the generic one */
> -       return crypto_register_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
> +       num_algs = 1 + ((crc32_optimizations() & CRC32C_OPTIMIZATION) != 0);
> +
> +       return crypto_register_shashes(algs, num_algs);
>  }
>
>  static void __exit crc32c_mod_fini(void)
>  {
> -       crypto_unregister_shashes(algs, 1 + IS_ENABLED(CONFIG_CRC32_ARCH));
> +       crypto_unregister_shashes(algs, num_algs);
>  }
>
>  subsys_initcall(crc32c_mod_init);
>  module_exit(crc32c_mod_fini);
>
> --
> 2.47.0
>
>


From conor at kernel.org  Mon Nov  4 03:18:43 2024
From: conor at kernel.org (Conor Dooley)
Date: Mon, 4 Nov 2024 11:18:43 +0000
Subject: [PATCH v5 2/2] PCI: microchip: rework reg region handing to
 support using either instance 1 or 2
In-Reply-To: <20241101195129.GA1318063@bhelgaas>
References: <20240814-outmost-untainted-cedd4adcd551@spud>
 <20241101195129.GA1318063@bhelgaas>
Message-ID: <20241104-stabilize-friday-94705c3dc244@spud>

On Fri, Nov 01, 2024 at 02:51:29PM -0500, Bjorn Helgaas wrote:
> On Wed, Aug 14, 2024 at 09:08:42AM +0100, Conor Dooley wrote:
> > From: Conor Dooley <conor.dooley at microchip.com>
> > 
> > The PCI host controller on PolarFire SoC has multiple "instances", each
> > with their own bridge and ctrl address spaces. The original binding has
> > an "apb" register region, and it is expected to be set to the base
> > address of the host controllers register space. Defines in the driver
> > were used to compute the addresses of the bridge and ctrl address ranges
> > corresponding to instance1. Some customers want to use instance0 however
> > and that requires changing the defines in the driver, which is clearly
> > not a portable solution.
> 
> The subject mentions "instance 1 or 2".
> 
> This paragraph implies adding support for "instance0" ("customers want
> to use instance0").
> 
> The DT patch suggests that we're adding support for "instance2"
> ("customers want to use instance2").
> 
> Both patches suggest that the existing support is for "instance 1".
> 
> Maybe what's being added is "instance 2", and this commit log should
> s/instance0/instance 2/ ?  And probably s/instance1/instance 1/ so the
> style is consistent?

Hmm no, it would be s/instance1/instance 2/ & s/instance0/instance 1/.
The indices are 1-based, not 0-based.

> Is this a "pick one or the other but not both" situation, or does this
> device support two independent PCIe controllers?
> 
> I first thought this driver supported a single PCIe controller, and
> you were adding support for a second independent controller.
> 

I don't know if they are fully independent (Daire would have to confirm)
but as far as the driver in linux is concerned they are. As far as I
know, you could operate both instances at the same time, but I've not
heard of any customer that is actually doing that nor tested it myself.
Operating both instances would require another node in the devicetree,
which should work fine given the private data structs are allocated at
runtime. I think the config space is shared.

> But the fact that you say "the [singular] host controller on
> PolarFire", and you're not changing mc_host_probe() to call
> pci_host_common_probe() more than once makes me think there is only a
> single PCIe controller, and for some reason you can choose to operate
> it using either register set 1 or register set 2.

The wording I've used mostly stems from conversations with Daire. We've
kinda been saying that there's a single controller with two root port
instances. Each root port instance is connected to different IOs,
they're more than just different registers for accessing the same thing.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241104/3dbd31e7/attachment.sig>

From conor at kernel.org  Mon Nov  4 04:07:49 2024
From: conor at kernel.org (Conor Dooley)
Date: Mon, 4 Nov 2024 12:07:49 +0000
Subject: [PATCH v2 2/3] riscv: add ISA extension parsing for bfloat16 ISA
 extension
In-Reply-To: <2e775421-0c3e-48ef-8a8c-6734f7fcf298@rivosinc.com>
References: <20241103074959.1135240-1-inochiama@gmail.com>
 <20241103074959.1135240-3-inochiama@gmail.com>
 <2e775421-0c3e-48ef-8a8c-6734f7fcf298@rivosinc.com>
Message-ID: <20241104-number-recall-85e044c9b72d@spud>

On Mon, Nov 04, 2024 at 10:15:56AM +0100, Cl?ment L?ger wrote:
> 
> 
> On 03/11/2024 08:49, Inochi Amaoto wrote:
> > Add parsing for Zfbmin, Zvfbfmin, Zvfbfwma ISA extension which
> > were ratified in 4dc23d62 ("Added Chapter title to BF16") of
> > the riscv-isa-manual.
> > 
> > Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
> > ---
> >  arch/riscv/include/asm/hwcap.h | 3 +++
> >  arch/riscv/kernel/cpufeature.c | 3 +++
> >  2 files changed, 6 insertions(+)
> > 
> > diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
> > index 46d9de54179e..97657fb63af6 100644
> > --- a/arch/riscv/include/asm/hwcap.h
> > +++ b/arch/riscv/include/asm/hwcap.h
> > @@ -93,6 +93,9 @@
> >  #define RISCV_ISA_EXT_ZCMOP		84
> >  #define RISCV_ISA_EXT_ZAWRS		85
> >  #define RISCV_ISA_EXT_SVVPTC		86
> > +#define RISCV_ISA_EXT_ZFBFMIN		87
> > +#define RISCV_ISA_EXT_ZVFBFMIN		88
> > +#define RISCV_ISA_EXT_ZVFBFWMA		89
> >  
> >  #define RISCV_ISA_EXT_XLINUXENVCFG	127
> >  
> > diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> > index 3a8eeaa9310c..1b286f5bc591 100644
> > --- a/arch/riscv/kernel/cpufeature.c
> > +++ b/arch/riscv/kernel/cpufeature.c
> > @@ -325,6 +325,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
> >  	__RISCV_ISA_EXT_DATA(zacas, RISCV_ISA_EXT_ZACAS),
> >  	__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
> >  	__RISCV_ISA_EXT_DATA(zfa, RISCV_ISA_EXT_ZFA),
> > +	__RISCV_ISA_EXT_DATA(zfbfmin, RISCV_ISA_EXT_ZFBFMIN),
> >  	__RISCV_ISA_EXT_DATA(zfh, RISCV_ISA_EXT_ZFH),
> >  	__RISCV_ISA_EXT_DATA(zfhmin, RISCV_ISA_EXT_ZFHMIN),
> >  	__RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA),
> > @@ -357,6 +358,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
> >  	__RISCV_ISA_EXT_SUPERSET(zve64d, RISCV_ISA_EXT_ZVE64D, riscv_zve64d_exts),
> >  	__RISCV_ISA_EXT_SUPERSET(zve64f, RISCV_ISA_EXT_ZVE64F, riscv_zve64f_exts),
> >  	__RISCV_ISA_EXT_SUPERSET(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts),
> > +	__RISCV_ISA_EXT_DATA(zvfbfmin, RISCV_ISA_EXT_ZVFBFMIN),
> > +	__RISCV_ISA_EXT_DATA(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA),
> 
> @Conor,
> 
> Should we wait for your V/F validation support to be merged before this
> one ?

Uh, I don't really see a reason to hold this up on my account. I can
easily rebase on top when I get the motivation to do more work on that
series.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241104/98f6b957/attachment.sig>

From conor at kernel.org  Mon Nov  4 04:08:51 2024
From: conor at kernel.org (Conor Dooley)
Date: Mon, 4 Nov 2024 12:08:51 +0000
Subject: [PATCH v2 1/3] dt-bindings: riscv: add bfloat16 ISA extension
 description
In-Reply-To: <20241103074959.1135240-2-inochiama@gmail.com>
References: <20241103074959.1135240-1-inochiama@gmail.com>
 <20241103074959.1135240-2-inochiama@gmail.com>
Message-ID: <20241104-clean-osmosis-680d64616712@spud>

On Sun, Nov 03, 2024 at 03:49:55PM +0800, Inochi Amaoto wrote:
> @@ -605,6 +623,33 @@ properties:
>          then:
>            contains:
>              const: zca
> +      # Zfbfmin depends on F
> +      - if:
> +          contains:
> +            const: zfbfmin
> +        then:
> +          contains:
> +            const: f
> +      # Zvfbfmin depends on V or Zve32f
> +      - if:
> +          contains:
> +            const: zvfbfmin
> +        then:
> +          oneOf:
> +            - contains:
> +                const: v
> +            - contains:
> +                const: zve32f
> +      # Zvfbfwma depends on Zfbfmin and Zvfbfmin

IMO these contents are statements of the obvious and not needed, but I
wouldn't bother respinning for that alone.

Acked-by: Conor Dooley <conor.dooley at microchip.com>


> +      - if:
> +          contains:
> +            const: zvfbfwma
> +        then:
> +          allOf:
> +            - contains:
> +                const: zfbfmin
> +            - contains:
> +                const: zvfbfmin

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241104/3a1d731c/attachment.sig>

From cleger at rivosinc.com  Mon Nov  4 04:11:17 2024
From: cleger at rivosinc.com (=?UTF-8?B?Q2zDqW1lbnQgTMOpZ2Vy?=)
Date: Mon, 4 Nov 2024 13:11:17 +0100
Subject: [PATCH v2 3/3] riscv: hwprobe: export bfloat16 ISA extension
In-Reply-To: <20241103074959.1135240-4-inochiama@gmail.com>
References: <20241103074959.1135240-1-inochiama@gmail.com>
 <20241103074959.1135240-4-inochiama@gmail.com>
Message-ID: <b823ad91-af5c-43a7-bf16-78d683937e0e@rivosinc.com>



On 03/11/2024 08:49, Inochi Amaoto wrote:
> Export Zfbmin, Zvfbfmin, Zvfbfwma ISA extension through hwprobe.
> 
> Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
> ---
>  Documentation/arch/riscv/hwprobe.rst  | 12 ++++++++++++
>  arch/riscv/include/uapi/asm/hwprobe.h |  3 +++
>  arch/riscv/kernel/sys_hwprobe.c       |  3 +++
>  3 files changed, 18 insertions(+)
> 
> diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
> index 85b709257918..8c30dd06f3c0 100644
> --- a/Documentation/arch/riscv/hwprobe.rst
> +++ b/Documentation/arch/riscv/hwprobe.rst
> @@ -239,6 +239,18 @@ The following keys are defined:
>         ratified in commit 98918c844281 ("Merge pull request #1217 from
>         riscv/zawrs") of riscv-isa-manual.
>  
> +  * :c:macro:`RISCV_HWPROBE_EXT_ZFBFMIN`: The Zfbfmin extension is supported as
> +       defined in the RISC-V ISA manual starting from commit 4dc23d6229de
> +       ("Added Chapter title to BF16").
> +
> +  * :c:macro:`RISCV_HWPROBE_EXT_ZVFBFMIN`: The Zvfbfmin extension is supported as
> +       defined in the RISC-V ISA manual starting from commit 4dc23d6229de
> +       ("Added Chapter title to BF16").
> +
> +  * :c:macro:`RISCV_HWPROBE_EXT_ZVFBFWMA`: The Zvfbfwma extension is supported as
> +       defined in the RISC-V ISA manual starting from commit 4dc23d6229de
> +       ("Added Chapter title to BF16").
> +
>  * :c:macro:`RISCV_HWPROBE_KEY_CPUPERF_0`: Deprecated.  Returns similar values to
>       :c:macro:`RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF`, but the key was
>       mistakenly classified as a bitmask rather than a value.
> diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
> index 1e153cda57db..95d00a065b4e 100644
> --- a/arch/riscv/include/uapi/asm/hwprobe.h
> +++ b/arch/riscv/include/uapi/asm/hwprobe.h
> @@ -72,6 +72,9 @@ struct riscv_hwprobe {
>  #define		RISCV_HWPROBE_EXT_ZCF		(1ULL << 46)
>  #define		RISCV_HWPROBE_EXT_ZCMOP		(1ULL << 47)
>  #define		RISCV_HWPROBE_EXT_ZAWRS		(1ULL << 48)
> +#define		RISCV_HWPROBE_EXT_ZFBFMIN	(1ULL << 49)
> +#define		RISCV_HWPROBE_EXT_ZVFBFMIN	(1ULL << 50)
> +#define		RISCV_HWPROBE_EXT_ZVFBFWMA	(1ULL << 51)
>  #define RISCV_HWPROBE_KEY_CPUPERF_0	5
>  #define		RISCV_HWPROBE_MISALIGNED_UNKNOWN	(0 << 0)
>  #define		RISCV_HWPROBE_MISALIGNED_EMULATED	(1 << 0)
> diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
> index cea0ca2bf2a2..de1966bd1776 100644
> --- a/arch/riscv/kernel/sys_hwprobe.c
> +++ b/arch/riscv/kernel/sys_hwprobe.c
> @@ -131,6 +131,8 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
>  			EXT_KEY(ZVE64D);
>  			EXT_KEY(ZVE64F);
>  			EXT_KEY(ZVE64X);
> +			EXT_KEY(ZVFBFMIN);
> +			EXT_KEY(ZVFBFWMA);
>  			EXT_KEY(ZVFH);
>  			EXT_KEY(ZVFHMIN);
>  			EXT_KEY(ZVKB);
> @@ -147,6 +149,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
>  			EXT_KEY(ZCD);
>  			EXT_KEY(ZCF);
>  			EXT_KEY(ZFA);
> +			EXT_KEY(ZFBFMIN);
>  			EXT_KEY(ZFH);
>  			EXT_KEY(ZFHMIN);
>  		}


Looks good to me !

Reviewed-by: Cl?ment L?ger <cleger at rivosinc.com>

Thanks


From david at redhat.com  Mon Nov  4 04:18:51 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 4 Nov 2024 13:18:51 +0100
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <4aa0ccf4-ebbe-4244-bc85-8bc8dcd14e74@redhat.com>
 <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
Message-ID: <d1a69eb7-85d5-4ffa-88e2-f4841713c1d7@redhat.com>

On 31.10.24 11:42, Patrick Roy wrote:
> On Thu, 2024-10-31 at 09:50 +0000, David Hildenbrand wrote:
>> On 30.10.24 14:49, Patrick Roy wrote:
>>> Unmapping virtual machine guest memory from the host kernel's direct map
>>> is a successful mitigation against Spectre-style transient execution
>>> issues: If the kernel page tables do not contain entries pointing to
>>> guest memory, then any attempted speculative read through the direct map
>>> will necessarily be blocked by the MMU before any observable
>>> microarchitectural side-effects happen. This means that Spectre-gadgets
>>> and similar cannot be used to target virtual machine memory. Roughly 60%
>>> of speculative execution issues fall into this category [1, Table 1].
>>>
>>> This patch series extends guest_memfd with the ability to remove its
>>> memory from the host kernel's direct map, to be able to attain the above
>>> protection for KVM guests running inside guest_memfd.
>>>
>>> === Changes to v2 ===
>>>
>>> - Handle direct map removal for physically contiguous pages in arch code
>>>     (Mike R.)
>>> - Track the direct map state in guest_memfd itself instead of at the
>>>     folio level, to prepare for huge pages support (Sean C.)
>>> - Allow configuring direct map state of not-yet faulted in memory
>>>     (Vishal A.)
>>> - Pay attention to alignment in ftrace structs (Steven R.)
>>>
>>> Most significantly, I've reduced the patch series to focus only on
>>> direct map removal for guest_memfd for now, leaving the whole "how to do
>>> non-CoCo VMs in guest_memfd" for later. If this separation is
>>> acceptable, then I think I can drop the RFC tag in the next revision
>>> (I've mainly kept it here because I'm not entirely sure what to do with
>>> patches 3 and 4).
>>
>> Hi,
>>
>> keeping upcoming "shared and private memory in guest_memfd" in mind, I
>> assume the focus would be to only remove the direct map for private memory?
>>
>> So in the current upstream state, you would only be removing the direct
>> map for private memory, currently translating to "encrypted"/"protected"
>> memory that is inaccessible either way already.
>>
>> Correct?
> 
> Yea, with the upcomming "shared and private" stuff, I would expect the
> the shared<->private conversions would call the routines from patch 3 to
> restore direct map entries on private->shared, and zap them on
> shared->private.

I wanted to follow-up to the discussion we had in the bi-weekly call.

We talked about shared (faultable) vs. private (unfaultable), and how it 
would interact with the directmap patches here.

As discussed, having private (unfaultable) memory with the direct-map 
removed and shared (faultable) memory with the direct-mapping can make 
sense for non-TDX/AMD-SEV/... non-CoCo use cases. Not sure about CoCo, 
the discussion here seems to indicate that it might currently not be 
required.

So one thing we could do is that shared (faultable) will have a direct 
mapping and be gup-able and private (unfaultable) memory will not have a 
direct mapping and is, by design, not gup-able.

Maybe it could make sense to not have a direct map for all guest_memfd 
memory, making it behave like secretmem (and it would be easy to 
implement)? But I'm not sure if that is really desirable in VM context.

Having a mixture of "has directmap" and "has no directmap" for shared 
(faultable) memory should not be done. Similarly, private memory really 
should stay "unfaultable".

I think one of the points raised during the bi-weekly call was that 
using a viommu/swiotlb might be the right call, such that all memory can 
be considered private (unfaultable) that is not explicitly 
shared/expected to be modified by the hypervisor (-> faultable, -> 
GUP-able).

Further, I think Sean had some good points why we should explore that 
direction, but I recall that there were some issue to be sorted out 
(interpreted instructions requiring direct map when accessing "private" 
memory?), not sure if that is already working/can be made working in KVM.

What's your opinion after the call and the next step for use cases like 
you have in mind (IIRC firecracker, which wants to not have the 
direct-map for guest memory where it can be avoided)?

-- 
Cheers,

David / dhildenb



From troymitchell988 at gmail.com  Mon Nov  4 04:23:23 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Mon, 4 Nov 2024 20:23:23 +0800
Subject: [PATCH v2 0/2] riscv: spacemit: add i2c support to K1 SoC
In-Reply-To: <stpzkggfwseaqy6kbppiog4xfbpq4r2jwix2nvredbmmjqzbsi@wkllt4jlingv>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <stpzkggfwseaqy6kbppiog4xfbpq4r2jwix2nvredbmmjqzbsi@wkllt4jlingv>
Message-ID: <edfaccd7-ac96-47fc-a174-912c8aaf0f5e@gmail.com>

On 2024/10/31 19:43, Andi Shyti wrote:
> Hi Tony,
> 
> On Mon, Oct 28, 2024 at 01:32:18PM +0800, Troy Mitchell wrote:
>> Hi all,
>>
>> This patch implements I2C driver for the SpacemiT K1 SoC,
>> providing basic support for I2C read/write communication which
>> compatible with standard I2C bus specifications.
>>
>> In this version, the driver defaults to use fast-speed-mode and
>> interrupts for transmission, and does not support DMA, high-speed mode, or FIFO.
>>
>> The docs of I2C can be found here, in chapter 16.1 I2C [1]
>>
>> Link: https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#part5 [1]
>>
>> Troy Mitchell (2):
>>   dt-bindings: i2c: spacemit: add support for K1 SoC
>>   i2c: spacemit: add support for SpacemiT K1 SoC
> 
> As Krzysztof has asked, please do provide the changelog, it's
> important to track the progress of your series.
I saw a compilation warning sent to me by the robot, and I've
fixed the warning. Should I resend V2 with the changelog
what I miss or send V3?

Thank for your response.
> 
> Thanks,
> Andi
> 
>>  .../bindings/i2c/spacemit,k1-i2c.yaml         |  51 ++
>>  drivers/i2c/busses/Kconfig                    |  18 +
>>  drivers/i2c/busses/Makefile                   |   1 +
>>  drivers/i2c/busses/i2c-k1.c                   | 658 ++++++++++++++++++
>>  4 files changed, 728 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>  create mode 100644 drivers/i2c/busses/i2c-k1.c
>>
>> -- 
>> 2.34.1
>>

-- 
Troy Mitchell


From troymitchell988 at gmail.com  Mon Nov  4 05:01:41 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Mon, 4 Nov 2024 21:01:41 +0800
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <ariqiukhztgziwwgaauqy6q3pghflnoeuwtag4izwkfmtvi2kh@gnlq4d7jsaw4>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <6zx3tqdc5bma2vutexwigzlir6nr6adp7arg4qwl5ieyd3avbu@5yyhv57ttwcl>
 <dbeea869-54cd-43fe-9021-783d641f1278@gmail.com>
 <ariqiukhztgziwwgaauqy6q3pghflnoeuwtag4izwkfmtvi2kh@gnlq4d7jsaw4>
Message-ID: <6cce463e-25cc-4a07-971f-6260347cb581@gmail.com>


On 2024/10/31 16:00, Krzysztof Kozlowski wrote:
> On Tue, Oct 29, 2024 at 04:36:00PM +0800, Troy Mitchell wrote:
>> On 2024/10/28 15:38, Krzysztof Kozlowski wrote:
>>> On Mon, Oct 28, 2024 at 01:32:19PM +0800, Troy Mitchell wrote:
>>>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
>>>> and supports FIFO transmission.
>>>>
>>>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>>>> ---
Change in v2:
 - Change the maxItems of reg from 1 to 2 in properties
 - Change 'i2c' to 'I2C' in the commit message.
 - Drop fifo-disable property
 - Drop alias in dts example
 - Move `unevaluatedProperties` after `required:` block

>>>
>>> Where is the changelog? Nothing here, nothing in cover letter.
>>>
>>> I asked for several changes, so now I don't know if you implemented
>>> them.
>>
>> I deleted the FIFO property because I believe your suggestion is correct.
>> this should be decided by the driver, even though the FIFO is provided
>> by the hardware.
>>
>> Apologies for missing the changelog. To correct this, should I send a v3 
>> version with the changelog or resend v2?
> 
> Reply now with changelog. Your binding has some other unrelated and
> incorrect changes, which I do not understand.
> 
> Best regards,
> Krzysztof
> 

-- 
Troy Mitchell


From troymitchell988 at gmail.com  Mon Nov  4 05:01:47 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Mon, 4 Nov 2024 21:01:47 +0800
Subject: [PATCH v2 2/2] i2c: spacemit: add support for SpacemiT K1 SoC
In-Reply-To: <20241028053220.346283-3-TroyMitchell988@gmail.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-3-TroyMitchell988@gmail.com>
Message-ID: <ff300296-daea-4113-8597-62f7a5f61d9c@gmail.com>


On 2024/10/28 13:32, Troy Mitchell wrote:
> This patch introduces basic I2C support for the SpacemiT K1 SoC,
> utilizing interrupts for transfers.
> 
> The driver has been tested using i2c-tools on a Bananapi-F3 board,
> and basic I2C read/write operations have been confirmed to work.
> 
> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
> --
Change in V2:
 - Alphabetize Makefile and Kconfig
 - Change `.remove_new` to `.remove` in `struct platform_driver`
 - Change `dev_alert` to `dev_warn_ratelimited` in `spacemit_i2c_bus_reset`
 - Change `spacemit_i2c_read/write_reg` to `read/writel`
 - Change `spacemit_i2c_dt_match` to `spacemit_i2c_of_match`
 - Clean up code flow
 - Fix unnecessary line wraps
 - Move `spacemit_i2c_handle_err` to a suitable location
 - Use `PTR_ERR(i2c->base)` directly as the `dev_err_probe` parameter instead of
   the intermediate variable
-- 
Troy Mitchell


From roypat at amazon.co.uk  Mon Nov  4 05:09:53 2024
From: roypat at amazon.co.uk (Patrick Roy)
Date: Mon, 4 Nov 2024 13:09:53 +0000
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <d1a69eb7-85d5-4ffa-88e2-f4841713c1d7@redhat.com>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <4aa0ccf4-ebbe-4244-bc85-8bc8dcd14e74@redhat.com>
 <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
 <d1a69eb7-85d5-4ffa-88e2-f4841713c1d7@redhat.com>
Message-ID: <90c9d8c0-814e-4c86-86ef-439cb5552cb6@amazon.co.uk>


Hi David,

On 11/4/24 12:18, David Hildenbrand wrote:
> On 31.10.24 11:42, Patrick Roy wrote:
>> On Thu, 2024-10-31 at 09:50 +0000, David Hildenbrand wrote:
>>> On 30.10.24 14:49, Patrick Roy wrote:
>>>> Unmapping virtual machine guest memory from the host kernel's direct map
>>>> is a successful mitigation against Spectre-style transient execution
>>>> issues: If the kernel page tables do not contain entries pointing to
>>>> guest memory, then any attempted speculative read through the direct map
>>>> will necessarily be blocked by the MMU before any observable
>>>> microarchitectural side-effects happen. This means that Spectre-gadgets
>>>> and similar cannot be used to target virtual machine memory. Roughly 60%
>>>> of speculative execution issues fall into this category [1, Table 1].
>>>>
>>>> This patch series extends guest_memfd with the ability to remove its
>>>> memory from the host kernel's direct map, to be able to attain the above
>>>> protection for KVM guests running inside guest_memfd.
>>>>
>>>> === Changes to v2 ===
>>>>
>>>> - Handle direct map removal for physically contiguous pages in arch code
>>>>     (Mike R.)
>>>> - Track the direct map state in guest_memfd itself instead of at the
>>>>     folio level, to prepare for huge pages support (Sean C.)
>>>> - Allow configuring direct map state of not-yet faulted in memory
>>>>     (Vishal A.)
>>>> - Pay attention to alignment in ftrace structs (Steven R.)
>>>>
>>>> Most significantly, I've reduced the patch series to focus only on
>>>> direct map removal for guest_memfd for now, leaving the whole "how to do
>>>> non-CoCo VMs in guest_memfd" for later. If this separation is
>>>> acceptable, then I think I can drop the RFC tag in the next revision
>>>> (I've mainly kept it here because I'm not entirely sure what to do with
>>>> patches 3 and 4).
>>>
>>> Hi,
>>>
>>> keeping upcoming "shared and private memory in guest_memfd" in mind, I
>>> assume the focus would be to only remove the direct map for private memory?
>>>
>>> So in the current upstream state, you would only be removing the direct
>>> map for private memory, currently translating to "encrypted"/"protected"
>>> memory that is inaccessible either way already.
>>>
>>> Correct?
>>
>> Yea, with the upcomming "shared and private" stuff, I would expect the
>> the shared<->private conversions would call the routines from patch 3 to
>> restore direct map entries on private->shared, and zap them on
>> shared->private.
> 
> I wanted to follow-up to the discussion we had in the bi-weekly call.

Thanks for summarizing!

> We talked about shared (faultable) vs. private (unfaultable), and how it
> would interact with the directmap patches here.
> 
> As discussed, having private (unfaultable) memory with the direct-map
> removed and shared (faultable) memory with the direct-mapping can make
> sense for non-TDX/AMD-SEV/... non-CoCo use cases. Not sure about CoCo,
> the discussion here seems to indicate that it might currently not be
> required.
>
> So one thing we could do is that shared (faultable) will have a direct
> mapping and be gup-able and private (unfaultable) memory will not have a
> direct mapping and is, by design, not gup-able.> 
> Maybe it could make sense to not have a direct map for all guest_memfd
> memory, making it behave like secretmem (and it would be easy to
> implement)? But I'm not sure if that is really desirable in VM context.

This would work for us (in this scenario, the swiotlb areas would be
"traditional" memory, e.g. set to shared via mem attributes instead of
"shared" inside KVM), it's kinda what I had prototyped in my v1 of this
series (well, we'd need to figure out how to get the mappings of gmem
back into KVM, since in this setup, short-circuiting it into
userspace_addr wouldn't work, unless we banish swiotlb into a different
memslot altogether somehow). But I don't think it'd work for pKVM, iirc
they need GUP on gmem, and also want direct map removal (... but maybe,
the gmem VMA for non-CoCo usecase and the gmem VMA for pKVM could be
behave differently?  non-CoCo gets essentially memfd_secret, pKVM gets
GUP+no faults of private mem).

> Having a mixture of "has directmap" and "has no directmap" for shared
> (faultable) memory should not be done. Similarly, private memory really
> should stay "unfaultable".

You've convinced me that having both GUP-able and non GUP-able
memory in the same VMA will be tricky. However, I'm less convinced on
why private memory should stay unfaultable; only that it shouldn't be
faultable into a VMA that also allows GUP. Can we have two VMAs? One
that disallows GUP, but allows userspace access to shared and private,
and one that allows GUP, but disallows accessing private memory? Maybe
via some `PROT_NOGUP` flag to `mmap`? I guess this is a slightly
different spin of the above idea.

> I think one of the points raised during the bi-weekly call was that
> using a viommu/swiotlb might be the right call, such that all memory can
> be considered private (unfaultable) that is not explicitly
> shared/expected to be modified by the hypervisor (-> faultable, ->
> GUP-able).
> 
> Further, I think Sean had some good points why we should explore that
> direction, but I recall that there were some issue to be sorted out
> (interpreted instructions requiring direct map when accessing "private"
> memory?), not sure if that is already working/can be made working in KVM.

Yeah, the big one is MMIO instruction emulation on x86, which does guest
page table walks and instruction fetch (and particularly the latter
cannot be known ahead-of-time by the guest, aka cannot be explicitly
"shared"). That's what the majority of my v2 series was about. For
traditional memslots, KVM handles these via get_user and friends, but if
we don't have a VMA that allows faulting all of gmem, then that's
impossible, and we're in "temporarily restore direct map" land. Which
comes with significantly performance penalties due to TLB flushes.

> What's your opinion after the call and the next step for use cases like
> you have in mind (IIRC firecracker, which wants to not have the
> direct-map for guest memory where it can be avoided)?

Yea, the usecase is for Firecracker to not have direct map entries for
guest memory, unless needed for I/O (-> swiotlb).

As for next steps, let's determine once and for all if we can do the
KVM-internal guest memory accesses for MMIO emulation through userspace
mappings (although if we can't I'll have some serious soul-searching to
do, because all other solutions we talked about so far also have fairly
big drawbacks; on-demand direct map reinsertion has terrible
performance, protection keys would limit us to 15 VMs on the host, and
the page table swapping runs into problems with NMIs if I understood
Sean correctly last Thursday :( ).

> -- 
> Cheers,
> 
> David / dhildenb

Best, 
Patrick


From apatel at ventanamicro.com  Mon Nov  4 05:19:15 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 4 Nov 2024 18:49:15 +0530
Subject: [PATCH RFC v2 3/3] riscv: KVM: Add Svukte extension support for Guest/VM
In-Reply-To: <CAHibDywpKUE7r4UfcudDSBZCM=JAC5s40uf+PwQE+oMvZy4aVA@mail.gmail.com>
References: <20240927-dev-maxh-svukte-rebase-2-v2-0-9afe57c33aee@sifive.com>
 <20240927-dev-maxh-svukte-rebase-2-v2-3-9afe57c33aee@sifive.com>
 <CAAhSdy0ncLTAjEE1s-GWL95sscxwQFsKn1rXyA1_VVfk1bQBiw@mail.gmail.com> <CAHibDywpKUE7r4UfcudDSBZCM=JAC5s40uf+PwQE+oMvZy4aVA@mail.gmail.com>
Message-ID: <CAK9=C2WEU53TD+tnWRLC1iLRf+j607s=bZXevkogTnr-cmhPGw@mail.gmail.com>

On Mon, Nov 4, 2024 at 1:14?PM Max Hsu <max.hsu at sifive.com> wrote:
>
> Hi Anup,
>
> Thank you for the suggestion.
>
> I?m not entirely sure if I fully understand it, but I believe the
> hypervisor should be able to disable the Svukte extension.
>
> Inside the switch-case of kvm_riscv_vcpu_isa_disable_allowed(),
> the default case breaks and returns true.
>
> So that means when the KVM_RISCV_ISA_EXT_SVUKTE passed into
> kvm_riscv_vcpu_isa_disable_allowed() it will return true.
>
> If I've misunderstood, please let me know.

I don't see any code in this patch which disables/enables Svukte for
Guest based on KVM ONE_REG interface.

Regards,
Anup

>
> Best regards,
> Max Hsu
>
> On Fri, Oct 25, 2024 at 3:17?AM Anup Patel <anup at brainfault.org> wrote:
> >
> > On Fri, Sep 27, 2024 at 7:12?PM Max Hsu <max.hsu at sifive.com> wrote:
> > >
> > > Add KVM ISA extension ONE_REG interface to allow VMM tools to
> > > detect and enable Svukte extension for Guest/VM.
> > >
> > > Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
> > > Signed-off-by: Max Hsu <max.hsu at sifive.com>
> > > ---
> > >  arch/riscv/include/uapi/asm/kvm.h | 1 +
> > >  arch/riscv/kvm/vcpu_onereg.c      | 1 +
> > >  2 files changed, 2 insertions(+)
> > >
> > > diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
> > > index e97db3296456e19f79ca02e4c4f70ae1b4abb48b..41b466b7ffaec421e8389d3f5b178580091a2c98 100644
> > > --- a/arch/riscv/include/uapi/asm/kvm.h
> > > +++ b/arch/riscv/include/uapi/asm/kvm.h
> > > @@ -175,6 +175,7 @@ enum KVM_RISCV_ISA_EXT_ID {
> > >         KVM_RISCV_ISA_EXT_ZCF,
> > >         KVM_RISCV_ISA_EXT_ZCMOP,
> > >         KVM_RISCV_ISA_EXT_ZAWRS,
> > > +       KVM_RISCV_ISA_EXT_SVUKTE,
> > >         KVM_RISCV_ISA_EXT_MAX,
> > >  };
> > >
> > > diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
> > > index b319c4c13c54ce22d2a7552f4c9f256a0c50780e..67237d6e53882a9fcd2cf265aa1704f25cc4a701 100644
> > > --- a/arch/riscv/kvm/vcpu_onereg.c
> > > +++ b/arch/riscv/kvm/vcpu_onereg.c
> > > @@ -41,6 +41,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
> > >         KVM_ISA_EXT_ARR(SVINVAL),
> > >         KVM_ISA_EXT_ARR(SVNAPOT),
> > >         KVM_ISA_EXT_ARR(SVPBMT),
> > > +       KVM_ISA_EXT_ARR(SVUKTE),
> > >         KVM_ISA_EXT_ARR(ZACAS),
> > >         KVM_ISA_EXT_ARR(ZAWRS),
> > >         KVM_ISA_EXT_ARR(ZBA),
> >
> > The KVM_RISCV_ISA_EXT_SVUKTE should be added to the
> > switch-case in kvm_riscv_vcpu_isa_disable_allowed() because
> > hypervisor seems to have no way to disable Svukte for the Guest
> > when it's available on the Host.
> >
> > Regards,
> > Anup
>


From krzk at kernel.org  Mon Nov  4 06:48:18 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 4 Nov 2024 15:48:18 +0100
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <6cce463e-25cc-4a07-971f-6260347cb581@gmail.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <6zx3tqdc5bma2vutexwigzlir6nr6adp7arg4qwl5ieyd3avbu@5yyhv57ttwcl>
 <dbeea869-54cd-43fe-9021-783d641f1278@gmail.com>
 <ariqiukhztgziwwgaauqy6q3pghflnoeuwtag4izwkfmtvi2kh@gnlq4d7jsaw4>
 <6cce463e-25cc-4a07-971f-6260347cb581@gmail.com>
Message-ID: <502b0b14-0e1f-4a59-85ad-7edeb9d3033d@kernel.org>

On 04/11/2024 14:01, Troy Mitchell wrote:
> 
> On 2024/10/31 16:00, Krzysztof Kozlowski wrote:
>> On Tue, Oct 29, 2024 at 04:36:00PM +0800, Troy Mitchell wrote:
>>> On 2024/10/28 15:38, Krzysztof Kozlowski wrote:
>>>> On Mon, Oct 28, 2024 at 01:32:19PM +0800, Troy Mitchell wrote:
>>>>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
>>>>> and supports FIFO transmission.
>>>>>
>>>>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>>>>> ---
> Change in v2:
>  - Change the maxItems of reg from 1 to 2 in properties

Why?

>  - Change 'i2c' to 'I2C' in the commit message.
>  - Drop fifo-disable property
>  - Drop alias in dts example
>  - Move `unevaluatedProperties` after `required:` block

Rest look ok.

Best regards,
Krzysztof



From emil.renner.berthing at canonical.com  Mon Nov  4 07:26:06 2024
From: emil.renner.berthing at canonical.com (Emil Renner Berthing)
Date: Mon, 4 Nov 2024 07:26:06 -0800
Subject: [PATCH 11/11] riscv: dts: starfive: jh7100: Use physical memory
 ranges for DMA
In-Reply-To: <20241102000843.1301099-12-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com> <20241102000843.1301099-12-samuel.holland@sifive.com>
Message-ID: <CAJM55Z-caGvqZXDTtbj0LknAJVgj1s5_p0SaN3kJog1950L0yg@mail.gmail.com>

Samuel Holland wrote:
> JH7100 provides a physical memory region which is a noncached alias of
> normal cacheable DRAM. Now that Linux can apply PMAs by selecting
> between aliases of a physical memory region, any page of DRAM can be
> marked as noncached for use with DMA, and the preallocated DMA pool is
> no longer needed. This allows portable kernels to boot on JH7100 boards.
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
>  arch/riscv/Kconfig.errata                     | 19 ------------
>  .../boot/dts/starfive/jh7100-common.dtsi      | 30 ++++---------------
>  2 files changed, 6 insertions(+), 43 deletions(-)
>
> diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
> index 2806ed7916c7..fc2c7fb2caff 100644
> --- a/arch/riscv/Kconfig.errata
> +++ b/arch/riscv/Kconfig.errata
> @@ -53,25 +53,6 @@ config ERRATA_SIFIVE_CIP_1200
>
>  	  If you don't know what to do here, say "Y".
>
> -config ERRATA_STARFIVE_JH7100
> -	bool "StarFive JH7100 support"
> -	depends on ARCH_STARFIVE
> -	depends on !DMA_DIRECT_REMAP
> -	depends on NONPORTABLE
> -	select DMA_GLOBAL_POOL

Hi Samuel,

Thank you for working on this!

The JH7100 still need the RISCV_NONSTANDARD_CACHE_OPS from the sifive-ccache
driver for streaming DMA, so if I just remove the 3 lines above instead of the
whole ERRATE_STARFIVE_JH7110 (and enable RISCV_ISA_SVPBMT) this series works on
my Starlight board.

> -	select RISCV_DMA_NONCOHERENT
> -	select RISCV_NONSTANDARD_CACHE_OPS
> -	select SIFIVE_CCACHE
> -	default n
> -	help
> -	  The StarFive JH7100 was a test chip for the JH7110 and has
> -	  caches that are non-coherent with respect to peripheral DMAs.
> -	  It was designed before the Zicbom extension so needs non-standard
> -	  cache operations through the SiFive cache controller.
> -
> -	  Say "Y" if you want to support the BeagleV Starlight and/or
> -	  StarFive VisionFive V1 boards.
> -
>  config ERRATA_THEAD
>  	bool "T-HEAD errata"
>  	depends on RISCV_ALTERNATIVE
> diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
> index ae1a6aeb0aea..34885fe40e2d 100644
> --- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
> +++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
> @@ -9,8 +9,14 @@
>  #include <dt-bindings/gpio/gpio.h>
>  #include <dt-bindings/leds/common.h>
>  #include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
> +#include <dt-bindings/riscv/physical-memory.h>
>
>  / {
> +	riscv,physical-memory-regions =
> +		<0x00 0x00000000 0x40 0x00000000 (PMA_RW | PMA_IO) 0x0>,
> +		<0x00 0x80000000 0x08 0x00000000 (PMA_RWXA | PMA_NONCOHERENT_MEMORY) 0x0>,
> +		<0x10 0x00000000 0x08 0x00000000 (PMA_RWX | PMA_NONCACHEABLE_MEMORY | PMR_ALIAS(1)) 0x0>;
> +

The size and placement of the DMA pool was kind of arbitrary but the above is
a feature of the SoC, so should be moved to jh7100.dtsi instead.

>  	aliases {
>  		mmc0 = &sdio0;
>  		mmc1 = &sdio1;
> @@ -42,30 +48,6 @@ led-ack {
>  		};
>  	};
>
> -	reserved-memory {
> -		#address-cells = <2>;
> -		#size-cells = <2>;
> -		ranges;
> -
> -		dma-reserved at fa000000 {
> -			reg = <0x0 0xfa000000 0x0 0x1000000>;
> -			no-map;
> -		};
> -
> -		linux,dma at 107a000000 {
> -			compatible = "shared-dma-pool";
> -			reg = <0x10 0x7a000000 0x0 0x1000000>;
> -			no-map;
> -			linux,dma-default;
> -		};
> -	};
> -
> -	soc {
> -		dma-ranges = <0x00 0x80000000 0x00 0x80000000 0x00 0x7a000000>,
> -			     <0x00 0xfa000000 0x10 0x7a000000 0x00 0x01000000>,
> -			     <0x00 0xfb000000 0x00 0xfb000000 0x07 0x85000000>;
> -	};
> -
>  	wifi_pwrseq: wifi-pwrseq {
>  		compatible = "mmc-pwrseq-simple";
>  		reset-gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
> --
> 2.45.1
>


From djwong at kernel.org  Mon Nov  4 07:59:00 2024
From: djwong at kernel.org (Darrick J. Wong)
Date: Mon, 4 Nov 2024 07:59:00 -0800
Subject: [PATCH v3 15/18] ext4: switch to using the crc32c library
In-Reply-To: <20241103223154.136127-16-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
 <20241103223154.136127-16-ebiggers@kernel.org>
Message-ID: <20241104155900.GH21832@frogsfrogsfrogs>

On Sun, Nov 03, 2024 at 02:31:51PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers at google.com>
> 
> Now that the crc32c() library function directly takes advantage of
> architecture-specific optimizations, it is unnecessary to go through the
> crypto API.  Just use crc32c().  This is much simpler, and it improves
> performance due to eliminating the crypto API overhead.
> 
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Eric Biggers <ebiggers at google.com>
> ---
>  fs/ext4/Kconfig |  3 +--
>  fs/ext4/ext4.h  | 25 +++----------------------
>  fs/ext4/super.c | 15 ---------------
>  3 files changed, 4 insertions(+), 39 deletions(-)
> 
> diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
> index e20d59221fc0..c9ca41d91a6c 100644
> --- a/fs/ext4/Kconfig
> +++ b/fs/ext4/Kconfig
> @@ -29,12 +29,11 @@ config EXT3_FS_SECURITY
>  config EXT4_FS
>  	tristate "The Extended 4 (ext4) filesystem"
>  	select BUFFER_HEAD
>  	select JBD2
>  	select CRC16
> -	select CRYPTO
> -	select CRYPTO_CRC32C
> +	select CRC32

Hmm.  Looking at your git branch (which was quite helpful to link to!) I
think for XFS we don't need to change the crc32c() calls, and the only
porting work that needs to be done is mirroring this Kconfig change?
And that doesn't even need to be done until someone wants to get rid of
CONFIG_LIBCRC32C, right?

>  	select FS_IOMAP
>  	select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
>  	help
>  	  This is the next generation of the ext3 filesystem.
>  
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 44b0d418143c..99aa512a7de1 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -31,11 +31,11 @@
>  #include <linux/wait.h>
>  #include <linux/sched/signal.h>
>  #include <linux/blockgroup_lock.h>
>  #include <linux/percpu_counter.h>
>  #include <linux/ratelimit.h>
> -#include <crypto/hash.h>
> +#include <linux/crc32c.h>
>  #include <linux/falloc.h>
>  #include <linux/percpu-rwsem.h>
>  #include <linux/fiemap.h>
>  #ifdef __KERNEL__
>  #include <linux/compat.h>
> @@ -1660,13 +1660,10 @@ struct ext4_sb_info {
>  	struct task_struct *s_mmp_tsk;
>  
>  	/* record the last minlen when FITRIM is called. */
>  	unsigned long s_last_trim_minblks;
>  
> -	/* Reference to checksum algorithm driver via cryptoapi */
> -	struct crypto_shash *s_chksum_driver;
> -
>  	/* Precomputed FS UUID checksum for seeding other checksums */
>  	__u32 s_csum_seed;
>  
>  	/* Reclaim extents from extent status tree */
>  	struct shrinker *s_es_shrinker;
> @@ -2465,23 +2462,11 @@ static inline __le16 ext4_rec_len_to_disk(unsigned len, unsigned blocksize)
>  #define DX_HASH_LAST 			DX_HASH_SIPHASH
>  
>  static inline u32 ext4_chksum(struct ext4_sb_info *sbi, u32 crc,
>  			      const void *address, unsigned int length)
>  {
> -	struct {
> -		struct shash_desc shash;
> -		char ctx[4];
> -	} desc;
> -
> -	BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver)!=sizeof(desc.ctx));
> -
> -	desc.shash.tfm = sbi->s_chksum_driver;
> -	*(u32 *)desc.ctx = crc;
> -
> -	BUG_ON(crypto_shash_update(&desc.shash, address, length));
> -
> -	return *(u32 *)desc.ctx;
> +	return crc32c(crc, address, length);
>  }
>  
>  #ifdef __KERNEL__
>  
>  /* hash info structure used by the directory hash */
> @@ -3278,15 +3263,11 @@ extern void ext4_group_desc_csum_set(struct super_block *sb, __u32 group,
>  extern int ext4_register_li_request(struct super_block *sb,
>  				    ext4_group_t first_not_zeroed);
>  
>  static inline int ext4_has_metadata_csum(struct super_block *sb)
>  {
> -	WARN_ON_ONCE(ext4_has_feature_metadata_csum(sb) &&
> -		     !EXT4_SB(sb)->s_chksum_driver);
> -
> -	return ext4_has_feature_metadata_csum(sb) &&
> -	       (EXT4_SB(sb)->s_chksum_driver != NULL);
> +	return ext4_has_feature_metadata_csum(sb);
>  }

Nit: Someone might want to
s/ext4_has_metadata_csum/ext4_has_feature_metadata_csum/ here to get rid
of the confusingly named trivial helper.

Otherwise this logic looks ok to me, so
Reviewed-by: Darrick J. Wong <djwong at kernel.org>

--D


>  
>  static inline int ext4_has_group_desc_csum(struct super_block *sb)
>  {
>  	return ext4_has_feature_gdt_csum(sb) || ext4_has_metadata_csum(sb);
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index 16a4ce704460..1a821093cc0d 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -1371,12 +1371,10 @@ static void ext4_put_super(struct super_block *sb)
>  	 * Now that we are completely done shutting down the
>  	 * superblock, we need to actually destroy the kobject.
>  	 */
>  	kobject_put(&sbi->s_kobj);
>  	wait_for_completion(&sbi->s_kobj_unregister);
> -	if (sbi->s_chksum_driver)
> -		crypto_free_shash(sbi->s_chksum_driver);
>  	kfree(sbi->s_blockgroup_lock);
>  	fs_put_dax(sbi->s_daxdev, NULL);
>  	fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
>  #if IS_ENABLED(CONFIG_UNICODE)
>  	utf8_unload(sb->s_encoding);
> @@ -4586,19 +4584,10 @@ static int ext4_init_metadata_csum(struct super_block *sb, struct ext4_super_blo
>  		return -EINVAL;
>  	}
>  	ext4_setup_csum_trigger(sb, EXT4_JTR_ORPHAN_FILE,
>  				ext4_orphan_file_block_trigger);
>  
> -	/* Load the checksum driver */
> -	sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
> -	if (IS_ERR(sbi->s_chksum_driver)) {
> -		int ret = PTR_ERR(sbi->s_chksum_driver);
> -		ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
> -		sbi->s_chksum_driver = NULL;
> -		return ret;
> -	}
> -
>  	/* Check superblock checksum */
>  	if (!ext4_superblock_csum_verify(sb, es)) {
>  		ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
>  			 "invalid superblock checksum.  Run e2fsck?");
>  		return -EFSBADCRC;
> @@ -5638,13 +5627,10 @@ failed_mount8: __maybe_unused
>  	flush_work(&sbi->s_sb_upd_work);
>  	ext4_stop_mmpd(sbi);
>  	del_timer_sync(&sbi->s_err_report);
>  	ext4_group_desc_free(sbi);
>  failed_mount:
> -	if (sbi->s_chksum_driver)
> -		crypto_free_shash(sbi->s_chksum_driver);
> -
>  #if IS_ENABLED(CONFIG_UNICODE)
>  	utf8_unload(sb->s_encoding);
>  #endif
>  
>  #ifdef CONFIG_QUOTA
> @@ -7433,8 +7419,7 @@ static void __exit ext4_exit_fs(void)
>  }
>  
>  MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
>  MODULE_DESCRIPTION("Fourth Extended Filesystem");
>  MODULE_LICENSE("GPL");
> -MODULE_SOFTDEP("pre: crc32c");
>  module_init(ext4_init_fs)
>  module_exit(ext4_exit_fs)
> -- 
> 2.47.0
> 
> 


From djwong at kernel.org  Mon Nov  4 08:01:36 2024
From: djwong at kernel.org (Darrick J. Wong)
Date: Mon, 4 Nov 2024 08:01:36 -0800
Subject: [PATCH v3 16/18] jbd2: switch to using the crc32c library
In-Reply-To: <20241103223154.136127-17-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
 <20241103223154.136127-17-ebiggers@kernel.org>
Message-ID: <20241104160136.GI21832@frogsfrogsfrogs>

On Sun, Nov 03, 2024 at 02:31:52PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers at google.com>
> 
> Now that the crc32c() library function directly takes advantage of
> architecture-specific optimizations, it is unnecessary to go through the
> crypto API.  Just use crc32c().  This is much simpler, and it improves
> performance due to eliminating the crypto API overhead.
> 
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Eric Biggers <ebiggers at google.com>
> ---
>  fs/jbd2/Kconfig      |  2 --
>  fs/jbd2/journal.c    | 25 ++-----------------------
>  include/linux/jbd2.h | 31 +++----------------------------
>  3 files changed, 5 insertions(+), 53 deletions(-)
> 
> diff --git a/fs/jbd2/Kconfig b/fs/jbd2/Kconfig
> index 4ad2c67f93f1..9c19e1512101 100644
> --- a/fs/jbd2/Kconfig
> +++ b/fs/jbd2/Kconfig
> @@ -1,11 +1,9 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  config JBD2
>  	tristate
>  	select CRC32
> -	select CRYPTO
> -	select CRYPTO_CRC32C
>  	help
>  	  This is a generic journaling layer for block devices that support
>  	  both 32-bit and 64-bit block numbers.  It is currently used by
>  	  the ext4 and OCFS2 filesystems, but it could also be used to add
>  	  journal support to other file systems or block devices such
> diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
> index 97f487c3d8fc..56cea5a738a7 100644
> --- a/fs/jbd2/journal.c
> +++ b/fs/jbd2/journal.c
> @@ -1373,24 +1373,16 @@ static int journal_check_superblock(journal_t *journal)
>  		printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2/3 "
>  		       "at the same time!\n");
>  		return err;
>  	}
>  
> -	/* Load the checksum driver */
>  	if (jbd2_journal_has_csum_v2or3_feature(journal)) {
>  		if (sb->s_checksum_type != JBD2_CRC32C_CHKSUM) {
>  			printk(KERN_ERR "JBD2: Unknown checksum type\n");
>  			return err;
>  		}
>  
> -		journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
> -		if (IS_ERR(journal->j_chksum_driver)) {
> -			printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
> -			err = PTR_ERR(journal->j_chksum_driver);
> -			journal->j_chksum_driver = NULL;
> -			return err;
> -		}
>  		/* Check superblock checksum */
>  		if (sb->s_checksum != jbd2_superblock_csum(journal, sb)) {
>  			printk(KERN_ERR "JBD2: journal checksum error\n");
>  			err = -EFSBADCRC;
>  			return err;
> @@ -1611,12 +1603,10 @@ static journal_t *journal_init_common(struct block_device *bdev,
>  
>  	return journal;
>  
>  err_cleanup:
>  	percpu_counter_destroy(&journal->j_checkpoint_jh_count);
> -	if (journal->j_chksum_driver)
> -		crypto_free_shash(journal->j_chksum_driver);
>  	kfree(journal->j_wbuf);
>  	jbd2_journal_destroy_revoke(journal);
>  	journal_fail_superblock(journal);
>  	kfree(journal);
>  	return ERR_PTR(err);
> @@ -2194,12 +2184,10 @@ int jbd2_journal_destroy(journal_t *journal)
>  	if (journal->j_proc_entry)
>  		jbd2_stats_proc_exit(journal);
>  	iput(journal->j_inode);
>  	if (journal->j_revoke)
>  		jbd2_journal_destroy_revoke(journal);
> -	if (journal->j_chksum_driver)
> -		crypto_free_shash(journal->j_chksum_driver);
>  	kfree(journal->j_fc_wbuf);
>  	kfree(journal->j_wbuf);
>  	kfree(journal);
>  
>  	return err;
> @@ -2340,23 +2328,14 @@ int jbd2_journal_set_features(journal_t *journal, unsigned long compat,
>  			pr_err("JBD2: Cannot enable fast commits.\n");
>  			return 0;
>  		}
>  	}
>  
> -	/* Load the checksum driver if necessary */
> -	if ((journal->j_chksum_driver == NULL) &&
> -	    INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
> -		journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
> -		if (IS_ERR(journal->j_chksum_driver)) {
> -			printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
> -			journal->j_chksum_driver = NULL;
> -			return 0;
> -		}
> -		/* Precompute checksum seed for all metadata */
> +	/* Precompute checksum seed for all metadata */
> +	if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3))
>  		journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid,
>  						   sizeof(sb->s_uuid));
> -	}
>  
>  	lock_buffer(journal->j_sb_buffer);
>  
>  	/* If enabling v3 checksums, update superblock */
>  	if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
> diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
> index 8aef9bb6ad57..33d25a3d15f1 100644
> --- a/include/linux/jbd2.h
> +++ b/include/linux/jbd2.h
> @@ -26,11 +26,11 @@
>  #include <linux/mutex.h>
>  #include <linux/timer.h>
>  #include <linux/slab.h>
>  #include <linux/bit_spinlock.h>
>  #include <linux/blkdev.h>
> -#include <crypto/hash.h>
> +#include <linux/crc32c.h>
>  #endif
>  
>  #define journal_oom_retry 1
>  
>  /*
> @@ -1239,17 +1239,10 @@ struct journal_s
>  	 * An opaque pointer to fs-private information.  ext3 puts its
>  	 * superblock pointer here.
>  	 */
>  	void *j_private;
>  
> -	/**
> -	 * @j_chksum_driver:
> -	 *
> -	 * Reference to checksum algorithm driver via cryptoapi.
> -	 */
> -	struct crypto_shash *j_chksum_driver;
> -
>  	/**
>  	 * @j_csum_seed:
>  	 *
>  	 * Precomputed journal UUID checksum for seeding other checksums.
>  	 */
> @@ -1748,14 +1741,11 @@ static inline bool jbd2_journal_has_csum_v2or3_feature(journal_t *j)
>  	return jbd2_has_feature_csum2(j) || jbd2_has_feature_csum3(j);
>  }
>  
>  static inline int jbd2_journal_has_csum_v2or3(journal_t *journal)
>  {
> -	WARN_ON_ONCE(jbd2_journal_has_csum_v2or3_feature(journal) &&
> -		     journal->j_chksum_driver == NULL);
> -
> -	return journal->j_chksum_driver != NULL;
> +	return jbd2_journal_has_csum_v2or3_feature(journal);

Same comment as my last reply about removing trivial helpers, but
otherwise
Reviewed-by: Darrick J. Wong <djwong at kernel.org>

If you push this for 6.13 I'd be happy that the shash junk finally went
away.  The onstack struct desc thing in the _chksum() functions was by
far the most sketchy part of the ext4/jbd2 metadata csum project. :)

--D

>  }
>  
>  static inline int jbd2_journal_get_num_fc_blks(journal_superblock_t *jsb)
>  {
>  	int num_fc_blocks = be32_to_cpu(jsb->s_num_fc_blks);
> @@ -1794,26 +1784,11 @@ static inline unsigned long jbd2_log_space_left(journal_t *journal)
>  #define JBD_MAX_CHECKSUM_SIZE 4
>  
>  static inline u32 jbd2_chksum(journal_t *journal, u32 crc,
>  			      const void *address, unsigned int length)
>  {
> -	struct {
> -		struct shash_desc shash;
> -		char ctx[JBD_MAX_CHECKSUM_SIZE];
> -	} desc;
> -	int err;
> -
> -	BUG_ON(crypto_shash_descsize(journal->j_chksum_driver) >
> -		JBD_MAX_CHECKSUM_SIZE);
> -
> -	desc.shash.tfm = journal->j_chksum_driver;
> -	*(u32 *)desc.ctx = crc;
> -
> -	err = crypto_shash_update(&desc.shash, address, length);
> -	BUG_ON(err);
> -
> -	return *(u32 *)desc.ctx;
> +	return crc32c(crc, address, length);
>  }
>  
>  /* Return most recent uncommitted transaction */
>  static inline tid_t  jbd2_get_latest_transaction(journal_t *journal)
>  {
> -- 
> 2.47.0
> 
> 


From tytso at mit.edu  Mon Nov  4 08:17:13 2024
From: tytso at mit.edu (Theodore Ts'o)
Date: Mon, 4 Nov 2024 11:17:13 -0500
Subject: [PATCH v3 15/18] ext4: switch to using the crc32c library
In-Reply-To: <20241103223154.136127-16-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
 <20241103223154.136127-16-ebiggers@kernel.org>
Message-ID: <20241104161713.GA43869@mit.edu>

On Sun, Nov 03, 2024 at 02:31:51PM -0800, Eric Biggers wrote:
> Now that the crc32c() library function directly takes advantage of
> architecture-specific optimizations, it is unnecessary to go through the
> crypto API.  Just use crc32c().  This is much simpler, and it improves
> performance due to eliminating the crypto API overhead.
> 
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Eric Biggers <ebiggers at google.com>

Acked-by: Theodore Ts'o <tytso at mit.edu>

Thanks for the cleanup!



From tytso at mit.edu  Mon Nov  4 08:17:40 2024
From: tytso at mit.edu (Theodore Ts'o)
Date: Mon, 4 Nov 2024 11:17:40 -0500
Subject: [PATCH v3 16/18] jbd2: switch to using the crc32c library
In-Reply-To: <20241103223154.136127-17-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
 <20241103223154.136127-17-ebiggers@kernel.org>
Message-ID: <20241104161740.GB43869@mit.edu>

On Sun, Nov 03, 2024 at 02:31:52PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers at google.com>
> 
> Now that the crc32c() library function directly takes advantage of
> architecture-specific optimizations, it is unnecessary to go through the
> crypto API.  Just use crc32c().  This is much simpler, and it improves
> performance due to eliminating the crypto API overhead.
> 
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Eric Biggers <ebiggers at google.com>

Acked-by: Theodore Ts'o <tytso at mit.edu>



From ebiggers at kernel.org  Mon Nov  4 09:48:39 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Mon, 4 Nov 2024 17:48:39 +0000
Subject: [PATCH v3 15/18] ext4: switch to using the crc32c library
In-Reply-To: <20241104155900.GH21832@frogsfrogsfrogs>
References: <20241103223154.136127-1-ebiggers@kernel.org>
 <20241103223154.136127-16-ebiggers@kernel.org>
 <20241104155900.GH21832@frogsfrogsfrogs>
Message-ID: <20241104174839.GA1049313@google.com>

On Mon, Nov 04, 2024 at 07:59:00AM -0800, Darrick J. Wong wrote:
> Hmm.  Looking at your git branch (which was quite helpful to link to!) I
> think for XFS we don't need to change the crc32c() calls, and the only
> porting work that needs to be done is mirroring this Kconfig change?
> And that doesn't even need to be done until someone wants to get rid of
> CONFIG_LIBCRC32C, right?

That's correct, no porting work is required now.  'select LIBCRC32C' should be
replaced with 'select CRC32', but that can be done later.

> > @@ -3278,15 +3263,11 @@ extern void ext4_group_desc_csum_set(struct super_block *sb, __u32 group,
> >  extern int ext4_register_li_request(struct super_block *sb,
> >  				    ext4_group_t first_not_zeroed);
> >  
> >  static inline int ext4_has_metadata_csum(struct super_block *sb)
> >  {
> > -	WARN_ON_ONCE(ext4_has_feature_metadata_csum(sb) &&
> > -		     !EXT4_SB(sb)->s_chksum_driver);
> > -
> > -	return ext4_has_feature_metadata_csum(sb) &&
> > -	       (EXT4_SB(sb)->s_chksum_driver != NULL);
> > +	return ext4_has_feature_metadata_csum(sb);
> >  }
> 
> Nit: Someone might want to
> s/ext4_has_metadata_csum/ext4_has_feature_metadata_csum/ here to get rid
> of the confusingly named trivial helper.
> 

Yes, that should be done as a follow-up patch.

> Otherwise this logic looks ok to me, so
> Reviewed-by: Darrick J. Wong <djwong at kernel.org>
> 
> --D

Thanks,

- Eric


From ebiggers at kernel.org  Mon Nov  4 10:02:35 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Mon, 4 Nov 2024 18:02:35 +0000
Subject: [PATCH v3 16/18] jbd2: switch to using the crc32c library
In-Reply-To: <20241104160136.GI21832@frogsfrogsfrogs>
References: <20241103223154.136127-1-ebiggers@kernel.org>
 <20241103223154.136127-17-ebiggers@kernel.org>
 <20241104160136.GI21832@frogsfrogsfrogs>
Message-ID: <20241104180235.GB1049313@google.com>

On Mon, Nov 04, 2024 at 08:01:36AM -0800, Darrick J. Wong wrote:
> Same comment as my last reply about removing trivial helpers, but
> otherwise
> Reviewed-by: Darrick J. Wong <djwong at kernel.org>
> 
> If you push this for 6.13 I'd be happy that the shash junk finally went
> away.  The onstack struct desc thing in the _chksum() functions was by
> far the most sketchy part of the ext4/jbd2 metadata csum project. :)

It will take a bit longer I'm afraid, since this patchset depends on patches
that are currently enqueued in three different trees for 6.13.  My current plan
is to target 6.14, and get this series into into linux-next shortly after the
6.13 merge window closes.

- Eric


From ebiggers at kernel.org  Mon Nov  4 10:10:26 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Mon, 4 Nov 2024 18:10:26 +0000
Subject: [PATCH v3 05/18] arm/crc32: expose CRC32 functions through lib
In-Reply-To: <20241103223154.136127-6-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
 <20241103223154.136127-6-ebiggers@kernel.org>
Message-ID: <20241104181026.GC1049313@google.com>

On Sun, Nov 03, 2024 at 02:31:41PM -0800, Eric Biggers wrote:
> -static int __init crc32_pmull_mod_init(void)
> -{
> -	if (elf_hwcap2 & HWCAP2_PMULL) {
> -		crc32_pmull_algs[0].update = crc32_pmull_update;
> -		crc32_pmull_algs[1].update = crc32c_pmull_update;
> -
> -		if (elf_hwcap2 & HWCAP2_CRC32) {
> -			fallback_crc32 = crc32_armv8_le;
> -			fallback_crc32c = crc32c_armv8_le;
> -		} else {
> -			fallback_crc32 = crc32_le;
> -			fallback_crc32c = __crc32c_le;
> -		}
> -	} else if (!(elf_hwcap2 & HWCAP2_CRC32)) {
> -		return -ENODEV;
> -	}
[...]
> +static u32 crc32_le_scalar(u32 crc, const u8 *p, size_t len)
> +{
> +	if (static_branch_likely(&have_crc32))
> +		return crc32_armv8_le(crc, p, len);
> +	return crc32_le_base(crc, p, len);
> +}

kernel test robot reported a build error on this patch,
"undefined symbol: __kcfi_typeid_crc32_armv8_le".  It's because crc32-core.S
uses SYM_TYPED_FUNC_START(crc32_armv8_le), and this patch makes crc32_armv8_le
be called only via direct calls, not indirect calls as it was before.  I will
fix this by replacing SYM_TYPED_FUNC_START by SYM_FUNC_START.

- Eric


From robh at kernel.org  Mon Nov  4 11:03:13 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon,  4 Nov 2024 13:03:13 -0600
Subject: [PATCH] riscv: cacheinfo: Use of_property_present() for non-boolean properties
Message-ID: <20241104190314.270095-1-robh@kernel.org>

The use of of_property_read_bool() for non-boolean properties is
deprecated in favor of of_property_present() when testing for property
presence.

Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
---
 arch/riscv/kernel/cacheinfo.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index b320b1d9aa01..0115051fa1e1 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -105,11 +105,11 @@ int populate_cache_leaves(unsigned int cpu)
 		return 0;
 	}
 
-	if (of_property_read_bool(np, "cache-size"))
+	if (of_property_present(np, "cache-size"))
 		ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
-	if (of_property_read_bool(np, "i-cache-size"))
+	if (of_property_present(np, "i-cache-size"))
 		ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
-	if (of_property_read_bool(np, "d-cache-size"))
+	if (of_property_present(np, "d-cache-size"))
 		ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
 
 	prev = np;
@@ -122,11 +122,11 @@ int populate_cache_leaves(unsigned int cpu)
 			break;
 		if (level <= levels)
 			break;
-		if (of_property_read_bool(np, "cache-size"))
+		if (of_property_present(np, "cache-size"))
 			ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
-		if (of_property_read_bool(np, "i-cache-size"))
+		if (of_property_present(np, "i-cache-size"))
 			ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
-		if (of_property_read_bool(np, "d-cache-size"))
+		if (of_property_present(np, "d-cache-size"))
 			ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
 		levels = level;
 	}
-- 
2.45.2



From bjorn at kernel.org  Mon Nov  4 11:15:01 2024
From: bjorn at kernel.org (=?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?=)
Date: Mon,  4 Nov 2024 20:15:01 +0100
Subject: [PATCH] riscv: kvm: Fix out-of-bounds array access
Message-ID: <20241104191503.74725-1-bjorn@kernel.org>

From: Bj?rn T?pel <bjorn at rivosinc.com>

In kvm_riscv_vcpu_sbi_init() the entry->ext_idx can contain an
out-of-bound index. This is used as a special marker for the base
extensions, that cannot be disabled. However, when traversing the
extensions, that special marker is not checked prior indexing the
array.

Add an out-of-bounds check to the function.

Fixes: 56d8a385b605 ("RISC-V: KVM: Allow some SBI extensions to be disabled by default")
Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
---
Don't know if it matters, but I hit this when trying kvmtool.


Bj?rn
---
arch/riscv/kvm/vcpu_sbi.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
index 7de128be8db9..6e704ed86a83 100644
--- a/arch/riscv/kvm/vcpu_sbi.c
+++ b/arch/riscv/kvm/vcpu_sbi.c
@@ -486,19 +486,22 @@ void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu)
 	struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
 	const struct kvm_riscv_sbi_extension_entry *entry;
 	const struct kvm_vcpu_sbi_extension *ext;
-	int i;
+	int idx, i;
 
 	for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) {
 		entry = &sbi_ext[i];
 		ext = entry->ext_ptr;
+		idx = entry->ext_idx;
+
+		if (idx < 0 || idx >= ARRAY_SIZE(scontext->ext_status))
+			continue;
 
 		if (ext->probe && !ext->probe(vcpu)) {
-			scontext->ext_status[entry->ext_idx] =
-				KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE;
+			scontext->ext_status[idx] = KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE;
 			continue;
 		}
 
-		scontext->ext_status[entry->ext_idx] = ext->default_disabled ?
+		scontext->ext_status[idx] = ext->default_disabled ?
 					KVM_RISCV_SBI_EXT_STATUS_DISABLED :
 					KVM_RISCV_SBI_EXT_STATUS_ENABLED;
 	}

base-commit: 59b723cd2adbac2a34fc8e12c74ae26ae45bf230
-- 
2.43.0



From bjorn at kernel.org  Mon Nov  4 11:21:19 2024
From: bjorn at kernel.org (=?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?=)
Date: Mon,  4 Nov 2024 20:21:19 +0100
Subject: [PATCH kvmtool] riscv: Pass correct size to snprintf()
Message-ID: <20241104192120.75841-1-bjorn@kernel.org>

From: Bj?rn T?pel <bjorn at rivosinc.com>

The snprintf() function does not get the correct size argument passed,
when the FDT ISA string is built. Instead of adjusting the size for
each extension, the full size is passed for every iteration. Doing so
will make __snprinf_chk() bail out on glibc.

Adjust size for each iteration.

Fixes: 8aff29e1dafe ("riscv: Append ISA extensions to the device tree")
Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
---
 riscv/fdt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/riscv/fdt.c b/riscv/fdt.c
index 8189601f46de..85c8f95604f6 100644
--- a/riscv/fdt.c
+++ b/riscv/fdt.c
@@ -157,7 +157,7 @@ static void generate_cpu_nodes(void *fdt, struct kvm *kvm)
 					   isa_info_arr[i].name);
 				break;
 			}
-			pos += snprintf(cpu_isa + pos, CPU_ISA_MAX_LEN, "_%s",
+			pos += snprintf(cpu_isa + pos, CPU_ISA_MAX_LEN - pos, "_%s",
 					isa_info_arr[i].name);
 		}
 		cpu_isa[pos] = '\0';

base-commit: 3040b298156e4e2a82b27ac8db5bd63a72b3785b
-- 
2.43.0



From jassisinghbrar at gmail.com  Mon Nov  4 11:28:11 2024
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Mon, 4 Nov 2024 13:28:11 -0600
Subject: [PATCH v2 3/3] mailbox: add Microchip IPC support
In-Reply-To: <ee8b10e3-ccd2-409e-82d0-612107f3fe26@microchip.com>
References: <20241025125110.1347757-1-valentina.fernandezalanis@microchip.com>
 <20241025125110.1347757-4-valentina.fernandezalanis@microchip.com>
 <CABb+yY3cDD-E-P1MPKQjdX7R2XVVKjwXUW-BANWcz-9aR6kskA@mail.gmail.com> <ee8b10e3-ccd2-409e-82d0-612107f3fe26@microchip.com>
Message-ID: <CABb+yY1Oy-vdXSQBQHoqzsK8xpXXfHw5ZQ5Q6gjv0gdFK2hwDA@mail.gmail.com>

On Mon, Nov 4, 2024 at 1:01?PM <Valentina.FernandezAlanis at microchip.com> wrote:
>
> On 03/11/2024 00:23, Jassi Brar wrote:

> Regarding the EXPORT function, I understand that it?s also possible to
> retrieve con_priv from mbox_chan in the client. However, I felt it would
> be cleaner to export the function to obtain the channel ID directly,
> rather than declaring the struct ipc_chan_info in a header file to make
> it accessible to the client.
>
> If necessary, I can remove the function and instead expose struct
> ipc_chan_info in linux/mailbox/mchp-ipc.h.
>
Yes please avoid EXPORT at any cost. They are only acceptable when no
other means exist.

> >
> >> +static struct platform_driver mchp_ipc_driver = {
> >> +       .driver = {
> >> +               .name = "microchip_ipc",
> >> +               .of_match_table = mchp_ipc_of_match,
> >> +       },
> >> +       .probe = mchp_ipc_probe,
> > The driver could be built as a module, so please provide .remove()
> > even if you never intend to unload it.
> In this particular case, there is nothing specific to implement in the
> .remove() function because all resources allocated in the .probe()
> function are managed using devm_*

OK.


From corbet at lwn.net  Mon Nov  4 11:41:25 2024
From: corbet at lwn.net (Jonathan Corbet)
Date: Mon, 04 Nov 2024 12:41:25 -0700
Subject: [PATCH] docs/zh_CN: add the translation of kbuild/llvm.rst
In-Reply-To: <20241023153235.1291567-1-dzm91@hust.edu.cn>
References: <20241023153235.1291567-1-dzm91@hust.edu.cn>
Message-ID: <87wmhi7pne.fsf@trenco.lwn.net>

Dongliang Mu <dzm91 at hust.edu.cn> writes:

> Finish the translation of kbuild/llvm.rst and move llvm from TODO
> to the main body.
>
> Update to commit 145082ebfcf0 ("Documentation/llvm: turn make command
> for ccache into code block")
>
> Signed-off-by: Dongliang Mu <dzm91 at hust.edu.cn>
> ---
>  .../translations/zh_CN/kbuild/index.rst       |   3 +-
>  .../translations/zh_CN/kbuild/llvm.rst        | 203 ++++++++++++++++++
>  2 files changed, 205 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/translations/zh_CN/kbuild/llvm.rst

Applied, thanks.

jon


From charlie at rivosinc.com  Mon Nov  4 13:06:02 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:02 -0800
Subject: [PATCH RFT 00/16] perf tools: Use generic syscall scripts for all
 archs
Message-ID: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>

Standardize the generation of syscall headers around syscall tables.
Previously each architecture independently selected how syscall headers
would be generated, or would not define a way and fallback onto
libaudit. Convert all architectures to use a standard syscall header
generation script and allow each architecture to override the syscall
table to use if they do not use the generic table.

As a result of these changes, no architecture will require libaudit, and
so the fallback case of using libaudit is removed by this series.

Testing:

I have tested that the syscall mappings of id to name generation works
as expected for every architecture, but I have only validated that perf
trace compiles and runs as expected on riscv, arm64, and x86_64.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
Charlie Jenkins (16):
      perf tools: Create generic syscall table support
      perf tools: arc: Support generic syscall headers
      perf tools: csky: Support generic syscall headers
      perf tools: arm: Support syscall headers
      perf tools: sh: Support syscall headers
      perf tools: sparc: Support syscall headers
      perf tools: xtensa: Support syscall header
      perf tools: x86: Use generic syscall scripts
      perf tools: alpha: Support syscall header
      perf tools: parisc: Support syscall header
      perf tools: arm64: Use syscall table
      perf tools: loongarch: Use syscall table
      perf tools: mips: Use generic syscall scripts
      perf tools: powerpc: Use generic syscall table scripts
      perf tools: s390: Use generic syscall table scripts
      perf tools: Remove dependency on libaudit

 Documentation/admin-guide/workload-tracing.rst     |   2 +-
 tools/build/feature/Makefile                       |   4 -
 tools/build/feature/test-libaudit.c                |  11 -
 tools/perf/Documentation/perf-check.txt            |   1 -
 tools/perf/Makefile.config                         |  28 +-
 tools/perf/Makefile.perf                           |  12 +-
 tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
 .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 ++++++++++++++++++++
 tools/perf/arch/alpha/include/syscall_table.h      |   2 +
 tools/perf/arch/arc/entry/syscalls/Kbuild          |   2 +
 .../perf/arch/arc/entry/syscalls/Makefile.syscalls |   3 +
 tools/perf/arch/arc/include/syscall_table.h        |   2 +
 tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
 .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
 tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 479 +++++++++++++++++++
 tools/perf/arch/arm/include/syscall_table.h        |   2 +
 tools/perf/arch/arm64/Makefile                     |  22 -
 tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
 .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
 .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++
 .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
 tools/perf/arch/arm64/include/syscall_table.h      |   8 +
 tools/perf/arch/csky/entry/syscalls/Kbuild         |   2 +
 .../arch/csky/entry/syscalls/Makefile.syscalls     |   3 +
 tools/perf/arch/csky/include/syscall_table.h       |   2 +
 tools/perf/arch/loongarch/Makefile                 |  22 -
 tools/perf/arch/loongarch/entry/syscalls/Kbuild    |   2 +
 .../loongarch/entry/syscalls/Makefile.syscalls     |   3 +
 .../arch/loongarch/entry/syscalls/mksyscalltbl     |  45 --
 tools/perf/arch/loongarch/include/syscall_table.h  |   2 +
 tools/perf/arch/mips/Makefile                      |  18 -
 tools/perf/arch/mips/entry/syscalls/Kbuild         |   2 +
 .../arch/mips/entry/syscalls/Makefile.syscalls     |   5 +
 tools/perf/arch/mips/entry/syscalls/mksyscalltbl   |  32 --
 tools/perf/arch/mips/include/syscall_table.h       |   2 +
 tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
 .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
 tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++
 tools/perf/arch/parisc/include/syscall_table.h     |   8 +
 tools/perf/arch/powerpc/Makefile                   |  25 -
 tools/perf/arch/powerpc/entry/syscalls/Kbuild      |   3 +
 .../arch/powerpc/entry/syscalls/Makefile.syscalls  |   6 +
 .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  |  39 --
 tools/perf/arch/powerpc/include/syscall_table.h    |   8 +
 tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
 .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
 tools/perf/arch/riscv/include/syscall_table.h      |   8 +
 tools/perf/arch/s390/Makefile                      |  21 -
 tools/perf/arch/s390/entry/syscalls/Kbuild         |   2 +
 .../arch/s390/entry/syscalls/Makefile.syscalls     |   5 +
 tools/perf/arch/s390/entry/syscalls/mksyscalltbl   |  32 --
 tools/perf/arch/s390/include/syscall_table.h       |   2 +
 tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
 .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
 tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 468 +++++++++++++++++++
 tools/perf/arch/sh/include/syscall_table.h         |   2 +
 tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
 .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 510 +++++++++++++++++++++
 tools/perf/arch/sparc/include/syscall_table.h      |   8 +
 tools/perf/arch/x86/Build                          |   1 -
 tools/perf/arch/x86/Makefile                       |  25 -
 tools/perf/arch/x86/entry/syscalls/Kbuild          |   3 +
 .../perf/arch/x86/entry/syscalls/Makefile.syscalls |   6 +
 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   |  42 --
 tools/perf/arch/x86/include/syscall_table.h        |   8 +
 tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
 .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 435 ++++++++++++++++++
 tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
 tools/perf/builtin-check.c                         |   1 -
 tools/perf/builtin-help.c                          |   2 -
 tools/perf/builtin-trace.c                         |  30 --
 tools/perf/check-headers.sh                        |   9 +
 tools/perf/perf.c                                  |   6 +-
 tools/perf/scripts/Makefile.syscalls               |  69 +++
 tools/perf/scripts/syscalltbl.sh                   |  86 ++++
 tools/perf/tests/make                              |   7 +-
 tools/perf/util/env.c                              |   4 +-
 tools/perf/util/generate-cmdlist.sh                |   4 +-
 tools/perf/util/syscalltbl.c                       |  87 +---
 tools/scripts/syscall.tbl                          | 405 ++++++++++++++++
 84 files changed, 4089 insertions(+), 555 deletions(-)
---
base-commit: 59b723cd2adbac2a34fc8e12c74ae26ae45bf230
change-id: 20240913-perf_syscalltbl-6f98defcc6f5
-- 
- Charlie



From charlie at rivosinc.com  Mon Nov  4 13:06:03 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:03 -0800
Subject: [PATCH RFT 01/16] perf tools: Create generic syscall table support
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-1-9adae5c761ef@rivosinc.com>

Currently each architecture in perf independently generates syscall
headers. Adapt the work that has gone into unifying syscall header
implementations in the kernel to work with perf tools. Introduce this
framework with riscv at first. riscv previously relied on libaudit, but
with this change, perf tools for riscv no longer needs this external
dependency.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   7 +
 tools/perf/Makefile.perf                           |   4 +
 tools/perf/arch/riscv/entry/syscalls/Kbuild        |   2 +
 .../arch/riscv/entry/syscalls/Makefile.syscalls    |   4 +
 tools/perf/arch/riscv/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   1 +
 tools/perf/scripts/Makefile.syscalls               |  69 ++++
 tools/perf/scripts/syscalltbl.sh                   |  86 +++++
 tools/perf/util/syscalltbl.c                       |   5 +-
 tools/scripts/syscall.tbl                          | 405 +++++++++++++++++++++
 10 files changed, 590 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index d4332675babb..6774b67d4668 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -35,6 +35,13 @@ ifneq ($(NO_SYSCALL_TABLE),1)
     NO_SYSCALL_TABLE := 0
   endif
 
+  # architectures that use the generic syscall table scripts
+  ifeq ($(SRCARCH),riscv)
+    NO_SYSCALL_TABLE := 0
+    CFLAGS += -DGENERIC_SYSCALL_TABLE
+    CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
+  endif
+
   ifneq ($(NO_SYSCALL_TABLE),1)
     CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
   endif
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 9dd2e8d3f3c9..18294b840121 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -310,6 +310,10 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
 FEATURE_TESTS := all
 endif
 endif
+# architectures that use the generic syscall table
+ifeq ($(SRCARCH),riscv)
+include $(srctree)/tools/perf/scripts/Makefile.syscalls
+endif
 include Makefile.config
 endif
 
diff --git a/tools/perf/arch/riscv/entry/syscalls/Kbuild b/tools/perf/arch/riscv/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..9a41e3572c3a
--- /dev/null
+++ b/tools/perf/arch/riscv/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..9668fd1faf60
--- /dev/null
+++ b/tools/perf/arch/riscv/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += riscv memfd_secret
+syscall_abis_64 += riscv rlimit memfd_secret
diff --git a/tools/perf/arch/riscv/include/syscall_table.h b/tools/perf/arch/riscv/include/syscall_table.h
new file mode 100644
index 000000000000..7ff51b783000
--- /dev/null
+++ b/tools/perf/arch/riscv/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index a05c1c105c51..692f48db810c 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -71,6 +71,7 @@ FILES=(
   "include/uapi/asm-generic/ioctls.h"
   "include/uapi/asm-generic/mman-common.h"
   "include/uapi/asm-generic/unistd.h"
+  "scripts/syscall.tbl"
 )
 
 declare -a SYNC_CHECK_FILES
diff --git a/tools/perf/scripts/Makefile.syscalls b/tools/perf/scripts/Makefile.syscalls
new file mode 100644
index 000000000000..41e1e938b1c1
--- /dev/null
+++ b/tools/perf/scripts/Makefile.syscalls
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: GPL-2.0
+# include/asm-generic contains a lot of files that are used
+# verbatim by several architectures.
+#
+# This Makefile generates arch/$(SRCARCH)/include/generated/(uapi/)/asm
+# headers from multiple sources:
+#  - a small wrapper to include the corresponding asm-generic/*.h
+#    is generated for each file listed as generic-y
+#  - uapi/asm/unistd_*.h files listed as syscalls-y are generated from
+#    syscall.tbl with the __NR_* macros
+#  - Corresponding asm/syscall_*.h are generated from the same input
+
+PHONY := all
+all:
+
+obj := $(srctree)/tools/perf/arch/$(SRCARCH)/include/generated/asm
+
+src := $(srctree)/$(subst /generated,,$(obj))
+
+syscall_abis_32  += common,32
+syscall_abis_64  += common,64
+syscalltbl := $(srctree)/tools/scripts/syscall.tbl
+
+# let architectures override $(syscall_abis_%) and $(syscalltbl)
+-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Makefile.syscalls
+include $(srctree)/scripts/Kbuild.include
+-include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Kbuild
+
+systbl := $(srctree)/tools/perf/scripts/syscalltbl.sh
+
+syscall-y   := $(addprefix $(obj)/, $(syscall-y))
+
+# Remove stale wrappers when the corresponding files are removed from generic-y
+old-headers := $(wildcard $(obj)/*.c)
+unwanted    := $(filter-out $(syscall-y),$(old-headers))
+
+quiet_cmd_remove = REMOVE  $(unwanted)
+      cmd_remove = rm -f $(unwanted)
+
+quiet_cmd_systbl = SYSTBL  $@
+      cmd_systbl = $(CONFIG_SHELL) $(systbl) \
+		   $(if $(systbl-args-$*),$(systbl-args-$*),$(systbl-args)) \
+		   --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \
+		   $< $@
+
+all: $(syscall-y)
+	$(if $(unwanted),$(call cmd,remove))
+	@:
+
+$(obj)/syscalls_%.h: $(syscalltbl) $(systbl) FORCE
+	$(call if_changed,systbl)
+
+targets := $(syscall-y)
+
+# Create output directory. Skip it if at least one old header exists
+# since we know the output directory already exists.
+ifeq ($(old-headers),)
+$(shell mkdir -p $(obj))
+endif
+
+PHONY += FORCE
+
+FORCE:
+
+existing-targets := $(wildcard $(sort $(targets)))
+
+-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
+
+.PHONY: $(PHONY)
diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh
new file mode 100755
index 000000000000..1ce0d5aa8b50
--- /dev/null
+++ b/tools/perf/scripts/syscalltbl.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generate a syscall table header.
+#
+# Each line of the syscall table should have the following format:
+#
+# NR ABI NAME [NATIVE] [COMPAT]
+#
+# NR       syscall number
+# ABI      ABI name
+# NAME     syscall name
+# NATIVE   native entry point (optional)
+# COMPAT   compat entry point (optional)
+
+set -e
+
+usage() {
+	echo >&2 "usage: $0 [--abis ABIS] INFILE OUTFILE" >&2
+	echo >&2
+	echo >&2 "  INFILE    input syscall table"
+	echo >&2 "  OUTFILE   output header file"
+	echo >&2
+	echo >&2 "options:"
+	echo >&2 "  --abis ABIS        ABI(s) to handle (By default, all lines are handled)"
+	exit 1
+}
+
+# default unless specified by options
+abis=
+
+while [ $# -gt 0 ]
+do
+	case $1 in
+	--abis)
+		abis=$(echo "($2)" | tr ',' '|')
+		shift 2;;
+	-*)
+		echo "$1: unknown option" >&2
+		usage;;
+	*)
+		break;;
+	esac
+done
+
+if [ $# -ne 2 ]; then
+	usage
+fi
+
+infile="$1"
+outfile="$2"
+
+nxt=0
+
+syscall_macro() {
+    nr="$1"
+    name="$2"
+
+    echo "	[$nr] = \"$name\","
+}
+
+emit() {
+    nr="$1"
+    entry="$2"
+
+    syscall_macro "$nr" "$entry"
+}
+
+echo "static const char *const syscalltbl[] = {" > $outfile
+
+sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
+grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table
+
+max_nr=0
+# the params are: nr abi name entry compat
+# use _ for intentionally unused variables according to SC2034
+while read nr _ name _ _; do
+    emit "$nr" "$name" >> $outfile
+    max_nr=$nr
+done < $sorted_table
+
+rm -f $sorted_table
+
+echo "};" >> $outfile
+
+echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 6c45ded922b6..229183e5c55f 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -9,7 +9,6 @@
 #include <stdlib.h>
 #include <linux/compiler.h>
 #include <linux/zalloc.h>
-
 #ifdef HAVE_SYSCALL_TABLE_SUPPORT
 #include <string.h>
 #include "string2.h"
@@ -46,6 +45,10 @@ static const char *const *syscalltbl_native = syscalltbl_mips_n64;
 #include <asm/syscalls.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_loongarch;
+#elif defined(GENERIC_SYSCALL_TABLE)
+#include <syscall_table.h>
+const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
+static const char *const *syscalltbl_native = syscalltbl;
 #else
 const int syscalltbl_native_max_id = 0;
 static const char *const syscalltbl_native[] = {
diff --git a/tools/scripts/syscall.tbl b/tools/scripts/syscall.tbl
new file mode 100644
index 000000000000..845e24eb372e
--- /dev/null
+++ b/tools/scripts/syscall.tbl
@@ -0,0 +1,405 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# This file contains the system call numbers for all of the
+# more recently added architectures.
+#
+# As a basic principle, no duplication of functionality
+# should be added, e.g. we don't use lseek when llseek
+# is present. New architectures should use this file
+# and implement the less feature-full calls in user space.
+#
+0	common	io_setup			sys_io_setup			compat_sys_io_setup
+1	common	io_destroy			sys_io_destroy
+2	common	io_submit			sys_io_submit			compat_sys_io_submit
+3	common	io_cancel			sys_io_cancel
+4	time32	io_getevents			sys_io_getevents_time32
+4	64	io_getevents			sys_io_getevents
+5	common	setxattr			sys_setxattr
+6	common	lsetxattr			sys_lsetxattr
+7	common	fsetxattr			sys_fsetxattr
+8	common	getxattr			sys_getxattr
+9	common	lgetxattr			sys_lgetxattr
+10	common	fgetxattr			sys_fgetxattr
+11	common	listxattr			sys_listxattr
+12	common	llistxattr			sys_llistxattr
+13	common	flistxattr			sys_flistxattr
+14	common	removexattr			sys_removexattr
+15	common	lremovexattr			sys_lremovexattr
+16	common	fremovexattr			sys_fremovexattr
+17	common	getcwd				sys_getcwd
+18	common	lookup_dcookie			sys_ni_syscall
+19	common	eventfd2			sys_eventfd2
+20	common	epoll_create1			sys_epoll_create1
+21	common	epoll_ctl			sys_epoll_ctl
+22	common	epoll_pwait			sys_epoll_pwait			compat_sys_epoll_pwait
+23	common	dup				sys_dup
+24	common	dup3				sys_dup3
+25	32	fcntl64				sys_fcntl64			compat_sys_fcntl64
+25	64	fcntl				sys_fcntl
+26	common	inotify_init1			sys_inotify_init1
+27	common	inotify_add_watch		sys_inotify_add_watch
+28	common	inotify_rm_watch		sys_inotify_rm_watch
+29	common	ioctl				sys_ioctl			compat_sys_ioctl
+30	common	ioprio_set			sys_ioprio_set
+31	common	ioprio_get			sys_ioprio_get
+32	common	flock				sys_flock
+33	common	mknodat				sys_mknodat
+34	common	mkdirat				sys_mkdirat
+35	common	unlinkat			sys_unlinkat
+36	common	symlinkat			sys_symlinkat
+37	common	linkat				sys_linkat
+# renameat is superseded with flags by renameat2
+38	renameat renameat			sys_renameat
+39	common	umount2				sys_umount
+40	common	mount				sys_mount
+41	common	pivot_root			sys_pivot_root
+42	common	nfsservctl			sys_ni_syscall
+43	32	statfs64			sys_statfs64			compat_sys_statfs64
+43	64	statfs				sys_statfs
+44	32	fstatfs64			sys_fstatfs64			compat_sys_fstatfs64
+44	64	fstatfs				sys_fstatfs
+45	32	truncate64			sys_truncate64			compat_sys_truncate64
+45	64	truncate			sys_truncate
+46	32	ftruncate64			sys_ftruncate64			compat_sys_ftruncate64
+46	64	ftruncate			sys_ftruncate
+47	common	fallocate			sys_fallocate			compat_sys_fallocate
+48	common	faccessat			sys_faccessat
+49	common	chdir				sys_chdir
+50	common	fchdir				sys_fchdir
+51	common	chroot				sys_chroot
+52	common	fchmod				sys_fchmod
+53	common	fchmodat			sys_fchmodat
+54	common	fchownat			sys_fchownat
+55	common	fchown				sys_fchown
+56	common	openat				sys_openat
+57	common	close				sys_close
+58	common	vhangup				sys_vhangup
+59	common	pipe2				sys_pipe2
+60	common	quotactl			sys_quotactl
+61	common	getdents64			sys_getdents64
+62	32	llseek				sys_llseek
+62	64	lseek				sys_lseek
+63	common	read				sys_read
+64	common	write				sys_write
+65	common	readv				sys_readv			sys_readv
+66	common	writev				sys_writev			sys_writev
+67	common	pread64				sys_pread64			compat_sys_pread64
+68	common	pwrite64			sys_pwrite64			compat_sys_pwrite64
+69	common	preadv				sys_preadv			compat_sys_preadv
+70	common	pwritev				sys_pwritev			compat_sys_pwritev
+71	32	sendfile64			sys_sendfile64
+71	64	sendfile			sys_sendfile64
+72	time32	pselect6			sys_pselect6_time32		compat_sys_pselect6_time32
+72	64	pselect6			sys_pselect6
+73	time32	ppoll				sys_ppoll_time32		compat_sys_ppoll_time32
+73	64	ppoll				sys_ppoll
+74	common	signalfd4			sys_signalfd4			compat_sys_signalfd4
+75	common	vmsplice			sys_vmsplice
+76	common	splice				sys_splice
+77	common	tee				sys_tee
+78	common	readlinkat			sys_readlinkat
+79	stat64	fstatat64			sys_fstatat64
+79	64	newfstatat			sys_newfstatat
+80	stat64	fstat64				sys_fstat64
+80	64	fstat				sys_newfstat
+81	common	sync				sys_sync
+82	common	fsync				sys_fsync
+83	common	fdatasync			sys_fdatasync
+84	common	sync_file_range			sys_sync_file_range		compat_sys_sync_file_range
+85	common	timerfd_create			sys_timerfd_create
+86	time32	timerfd_settime			sys_timerfd_settime32
+86	64	timerfd_settime			sys_timerfd_settime
+87	time32	timerfd_gettime			sys_timerfd_gettime32
+87	64	timerfd_gettime			sys_timerfd_gettime
+88	time32	utimensat			sys_utimensat_time32
+88	64	utimensat			sys_utimensat
+89	common	acct				sys_acct
+90	common	capget				sys_capget
+91	common	capset				sys_capset
+92	common	personality			sys_personality
+93	common	exit				sys_exit
+94	common	exit_group			sys_exit_group
+95	common	waitid				sys_waitid			compat_sys_waitid
+96	common	set_tid_address			sys_set_tid_address
+97	common	unshare				sys_unshare
+98	time32	futex				sys_futex_time32
+98	64	futex				sys_futex
+99	common	set_robust_list			sys_set_robust_list		compat_sys_set_robust_list
+100	common	get_robust_list			sys_get_robust_list		compat_sys_get_robust_list
+101	time32	nanosleep			sys_nanosleep_time32
+101	64	nanosleep			sys_nanosleep
+102	common	getitimer			sys_getitimer			compat_sys_getitimer
+103	common	setitimer			sys_setitimer			compat_sys_setitimer
+104	common	kexec_load			sys_kexec_load			compat_sys_kexec_load
+105	common	init_module			sys_init_module
+106	common	delete_module			sys_delete_module
+107	common	timer_create			sys_timer_create		compat_sys_timer_create
+108	time32	timer_gettime			sys_timer_gettime32
+108	64	timer_gettime			sys_timer_gettime
+109	common	timer_getoverrun		sys_timer_getoverrun
+110	time32	timer_settime			sys_timer_settime32
+110	64	timer_settime			sys_timer_settime
+111	common	timer_delete			sys_timer_delete
+112	time32	clock_settime			sys_clock_settime32
+112	64	clock_settime			sys_clock_settime
+113	time32	clock_gettime			sys_clock_gettime32
+113	64	clock_gettime			sys_clock_gettime
+114	time32	clock_getres			sys_clock_getres_time32
+114	64	clock_getres			sys_clock_getres
+115	time32	clock_nanosleep			sys_clock_nanosleep_time32
+115	64	clock_nanosleep			sys_clock_nanosleep
+116	common	syslog				sys_syslog
+117	common	ptrace				sys_ptrace			compat_sys_ptrace
+118	common	sched_setparam			sys_sched_setparam
+119	common	sched_setscheduler		sys_sched_setscheduler
+120	common	sched_getscheduler		sys_sched_getscheduler
+121	common	sched_getparam			sys_sched_getparam
+122	common	sched_setaffinity		sys_sched_setaffinity		compat_sys_sched_setaffinity
+123	common	sched_getaffinity		sys_sched_getaffinity		compat_sys_sched_getaffinity
+124	common	sched_yield			sys_sched_yield
+125	common	sched_get_priority_max		sys_sched_get_priority_max
+126	common	sched_get_priority_min		sys_sched_get_priority_min
+127	time32	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+127	64	sched_rr_get_interval		sys_sched_rr_get_interval
+128	common	restart_syscall			sys_restart_syscall
+129	common	kill				sys_kill
+130	common	tkill				sys_tkill
+131	common	tgkill				sys_tgkill
+132	common	sigaltstack			sys_sigaltstack			compat_sys_sigaltstack
+133	common	rt_sigsuspend			sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+134	common	rt_sigaction			sys_rt_sigaction		compat_sys_rt_sigaction
+135	common	rt_sigprocmask			sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+136	common	rt_sigpending			sys_rt_sigpending		compat_sys_rt_sigpending
+137	time32	rt_sigtimedwait			sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+137	64	rt_sigtimedwait			sys_rt_sigtimedwait
+138	common	rt_sigqueueinfo			sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+139	common	rt_sigreturn			sys_rt_sigreturn		compat_sys_rt_sigreturn
+140	common	setpriority			sys_setpriority
+141	common	getpriority			sys_getpriority
+142	common	reboot				sys_reboot
+143	common	setregid			sys_setregid
+144	common	setgid				sys_setgid
+145	common	setreuid			sys_setreuid
+146	common	setuid				sys_setuid
+147	common	setresuid			sys_setresuid
+148	common	getresuid			sys_getresuid
+149	common	setresgid			sys_setresgid
+150	common	getresgid			sys_getresgid
+151	common	setfsuid			sys_setfsuid
+152	common	setfsgid			sys_setfsgid
+153	common	times				sys_times			compat_sys_times
+154	common	setpgid				sys_setpgid
+155	common	getpgid				sys_getpgid
+156	common	getsid				sys_getsid
+157	common	setsid				sys_setsid
+158	common	getgroups			sys_getgroups
+159	common	setgroups			sys_setgroups
+160	common	uname				sys_newuname
+161	common	sethostname			sys_sethostname
+162	common	setdomainname			sys_setdomainname
+# getrlimit and setrlimit are superseded with prlimit64
+163	rlimit	getrlimit			sys_getrlimit			compat_sys_getrlimit
+164	rlimit	setrlimit			sys_setrlimit			compat_sys_setrlimit
+165	common	getrusage			sys_getrusage			compat_sys_getrusage
+166	common	umask				sys_umask
+167	common	prctl				sys_prctl
+168	common	getcpu				sys_getcpu
+169	time32	gettimeofday			sys_gettimeofday		compat_sys_gettimeofday
+169	64	gettimeofday			sys_gettimeofday
+170	time32	settimeofday			sys_settimeofday		compat_sys_settimeofday
+170	64	settimeofday			sys_settimeofday
+171	time32	adjtimex			sys_adjtimex_time32
+171	64	adjtimex			sys_adjtimex
+172	common	getpid				sys_getpid
+173	common	getppid				sys_getppid
+174	common	getuid				sys_getuid
+175	common	geteuid				sys_geteuid
+176	common	getgid				sys_getgid
+177	common	getegid				sys_getegid
+178	common	gettid				sys_gettid
+179	common	sysinfo				sys_sysinfo			compat_sys_sysinfo
+180	common	mq_open				sys_mq_open			compat_sys_mq_open
+181	common	mq_unlink			sys_mq_unlink
+182	time32	mq_timedsend			sys_mq_timedsend_time32
+182	64	mq_timedsend			sys_mq_timedsend
+183	time32	mq_timedreceive			sys_mq_timedreceive_time32
+183	64	mq_timedreceive			sys_mq_timedreceive
+184	common	mq_notify			sys_mq_notify			compat_sys_mq_notify
+185	common	mq_getsetattr			sys_mq_getsetattr		compat_sys_mq_getsetattr
+186	common	msgget				sys_msgget
+187	common	msgctl				sys_msgctl			compat_sys_msgctl
+188	common	msgrcv				sys_msgrcv			compat_sys_msgrcv
+189	common	msgsnd				sys_msgsnd			compat_sys_msgsnd
+190	common	semget				sys_semget
+191	common	semctl				sys_semctl			compat_sys_semctl
+192	time32	semtimedop			sys_semtimedop_time32
+192	64	semtimedop			sys_semtimedop
+193	common	semop				sys_semop
+194	common	shmget				sys_shmget
+195	common	shmctl				sys_shmctl			compat_sys_shmctl
+196	common	shmat				sys_shmat			compat_sys_shmat
+197	common	shmdt				sys_shmdt
+198	common	socket				sys_socket
+199	common	socketpair			sys_socketpair
+200	common	bind				sys_bind
+201	common	listen				sys_listen
+202	common	accept				sys_accept
+203	common	connect				sys_connect
+204	common	getsockname			sys_getsockname
+205	common	getpeername			sys_getpeername
+206	common	sendto				sys_sendto
+207	common	recvfrom			sys_recvfrom			compat_sys_recvfrom
+208	common	setsockopt			sys_setsockopt			sys_setsockopt
+209	common	getsockopt			sys_getsockopt			sys_getsockopt
+210	common	shutdown			sys_shutdown
+211	common	sendmsg				sys_sendmsg			compat_sys_sendmsg
+212	common	recvmsg				sys_recvmsg			compat_sys_recvmsg
+213	common	readahead			sys_readahead			compat_sys_readahead
+214	common	brk				sys_brk
+215	common	munmap				sys_munmap
+216	common	mremap				sys_mremap
+217	common	add_key				sys_add_key
+218	common	request_key			sys_request_key
+219	common	keyctl				sys_keyctl			compat_sys_keyctl
+220	common	clone				sys_clone
+221	common	execve				sys_execve			compat_sys_execve
+222	32	mmap2				sys_mmap2
+222	64	mmap				sys_mmap
+223	32	fadvise64_64			sys_fadvise64_64		compat_sys_fadvise64_64
+223	64	fadvise64			sys_fadvise64_64
+224	common	swapon				sys_swapon
+225	common	swapoff				sys_swapoff
+226	common	mprotect			sys_mprotect
+227	common	msync				sys_msync
+228	common	mlock				sys_mlock
+229	common	munlock				sys_munlock
+230	common	mlockall			sys_mlockall
+231	common	munlockall			sys_munlockall
+232	common	mincore				sys_mincore
+233	common	madvise				sys_madvise
+234	common	remap_file_pages		sys_remap_file_pages
+235	common	mbind				sys_mbind
+236	common	get_mempolicy			sys_get_mempolicy
+237	common	set_mempolicy			sys_set_mempolicy
+238	common	migrate_pages			sys_migrate_pages
+239	common	move_pages			sys_move_pages
+240	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+241	common	perf_event_open			sys_perf_event_open
+242	common	accept4				sys_accept4
+243	time32	recvmmsg			sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+243	64	recvmmsg			sys_recvmmsg
+# Architectures may provide up to 16 syscalls of their own between 244 and 259
+244	arc	cacheflush			sys_cacheflush
+245	arc	arc_settls			sys_arc_settls
+246	arc	arc_gettls			sys_arc_gettls
+247	arc	sysfs				sys_sysfs
+248	arc	arc_usr_cmpxchg			sys_arc_usr_cmpxchg
+
+244	csky	set_thread_area			sys_set_thread_area
+245	csky	cacheflush			sys_cacheflush
+
+244	nios2	cacheflush			sys_cacheflush
+
+244	or1k	or1k_atomic			sys_or1k_atomic
+
+258	riscv	riscv_hwprobe			sys_riscv_hwprobe
+259	riscv	riscv_flush_icache		sys_riscv_flush_icache
+
+260	time32	wait4				sys_wait4			compat_sys_wait4
+260	64	wait4				sys_wait4
+261	common	prlimit64			sys_prlimit64
+262	common	fanotify_init			sys_fanotify_init
+263	common	fanotify_mark			sys_fanotify_mark
+264	common	name_to_handle_at		sys_name_to_handle_at
+265	common	open_by_handle_at		sys_open_by_handle_at
+266	time32	clock_adjtime			sys_clock_adjtime32
+266	64	clock_adjtime			sys_clock_adjtime
+267	common	syncfs				sys_syncfs
+268	common	setns				sys_setns
+269	common	sendmmsg			sys_sendmmsg			compat_sys_sendmmsg
+270	common	process_vm_readv		sys_process_vm_readv
+271	common	process_vm_writev		sys_process_vm_writev
+272	common	kcmp				sys_kcmp
+273	common	finit_module			sys_finit_module
+274	common	sched_setattr			sys_sched_setattr
+275	common	sched_getattr			sys_sched_getattr
+276	common	renameat2			sys_renameat2
+277	common	seccomp				sys_seccomp
+278	common	getrandom			sys_getrandom
+279	common	memfd_create			sys_memfd_create
+280	common	bpf				sys_bpf
+281	common	execveat			sys_execveat			compat_sys_execveat
+282	common	userfaultfd			sys_userfaultfd
+283	common	membarrier			sys_membarrier
+284	common	mlock2				sys_mlock2
+285	common	copy_file_range			sys_copy_file_range
+286	common	preadv2				sys_preadv2			compat_sys_preadv2
+287	common	pwritev2			sys_pwritev2			compat_sys_pwritev2
+288	common	pkey_mprotect			sys_pkey_mprotect
+289	common	pkey_alloc			sys_pkey_alloc
+290	common	pkey_free			sys_pkey_free
+291	common	statx				sys_statx
+292	time32	io_pgetevents			sys_io_pgetevents_time32	compat_sys_io_pgetevents
+292	64	io_pgetevents			sys_io_pgetevents
+293	common	rseq				sys_rseq
+294	common	kexec_file_load			sys_kexec_file_load
+# 295 through 402 are unassigned to sync up with generic numbers don't use
+403	32	clock_gettime64			sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+447	memfd_secret	memfd_secret		sys_memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:04 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:04 -0800
Subject: [PATCH RFT 02/16] perf tools: arc: Support generic syscall headers
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-2-9adae5c761ef@rivosinc.com>

Arc uses the generic syscall table, use that in perf instead of
requiring libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                           | 2 +-
 tools/perf/Makefile.perf                             | 2 +-
 tools/perf/arch/arc/entry/syscalls/Kbuild            | 2 ++
 tools/perf/arch/arc/entry/syscalls/Makefile.syscalls | 3 +++
 tools/perf/arch/arc/include/syscall_table.h          | 2 ++
 5 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 6774b67d4668..504d762cc572 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),riscv)
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 18294b840121..02ff3f2fcf12 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),riscv)
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/arc/entry/syscalls/Kbuild b/tools/perf/arch/arc/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..11707c481a24
--- /dev/null
+++ b/tools/perf/arch/arc/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..391d30ab7a83
--- /dev/null
+++ b/tools/perf/arch/arc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += arc time32 renameat stat64 rlimit
diff --git a/tools/perf/arch/arc/include/syscall_table.h b/tools/perf/arch/arc/include/syscall_table.h
new file mode 100644
index 000000000000..4c942821662d
--- /dev/null
+++ b/tools/perf/arch/arc/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:05 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:05 -0800
Subject: [PATCH RFT 03/16] perf tools: csky: Support generic syscall
 headers
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-3-9adae5c761ef@rivosinc.com>

csky uses the generic syscall table, use that in perf instead of
requiring libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                            | 2 +-
 tools/perf/Makefile.perf                              | 2 +-
 tools/perf/arch/csky/entry/syscalls/Kbuild            | 2 ++
 tools/perf/arch/csky/entry/syscalls/Makefile.syscalls | 3 +++
 tools/perf/arch/csky/include/syscall_table.h          | 2 ++
 5 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 504d762cc572..a19c59c8cd3b 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 02ff3f2fcf12..7c5fba39d8e6 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/csky/entry/syscalls/Kbuild b/tools/perf/arch/csky/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..11707c481a24
--- /dev/null
+++ b/tools/perf/arch/csky/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls b/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..ea2dd10d0571
--- /dev/null
+++ b/tools/perf/arch/csky/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += csky time32 stat64 rlimit
diff --git a/tools/perf/arch/csky/include/syscall_table.h b/tools/perf/arch/csky/include/syscall_table.h
new file mode 100644
index 000000000000..4c942821662d
--- /dev/null
+++ b/tools/perf/arch/csky/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:06 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:06 -0800
Subject: [PATCH RFT 04/16] perf tools: arm: Support syscall headers
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-4-9adae5c761ef@rivosinc.com>

arm uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/arm/entry/syscalls/Kbuild          |   4 +
 .../perf/arch/arm/entry/syscalls/Makefile.syscalls |   2 +
 tools/perf/arch/arm/entry/syscalls/syscall.tbl     | 479 +++++++++++++++++++++
 tools/perf/arch/arm/include/syscall_table.h        |   2 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 490 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index a19c59c8cd3b..fd511c78dd9b 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 7c5fba39d8e6..faf0cf9b6e59 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/arm/entry/syscalls/Kbuild b/tools/perf/arch/arm/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..9d777540f089
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/Kbuild
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += oabi
+syscalltbl = $(srctree)/tools/perf/arch/arm/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..11707c481a24
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/arm/entry/syscalls/syscall.tbl b/tools/perf/arch/arm/entry/syscalls/syscall.tbl
new file mode 100644
index 000000000000..23c98203c40f
--- /dev/null
+++ b/tools/perf/arch/arm/entry/syscalls/syscall.tbl
@@ -0,0 +1,479 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# Linux system call numbers and entry vectors
+#
+# The format is:
+# <num>	<abi>	<name>			[<entry point>			[<oabi compat entry point>]]
+#
+# Where abi is:
+#  common - for system calls shared between oabi and eabi (may have compat)
+#  oabi   - for oabi-only system calls (may have compat)
+#  eabi   - for eabi-only system calls
+#
+# For each syscall number, "common" is mutually exclusive with oabi and eabi
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open
+6	common	close			sys_close
+# 7 was sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve
+12	common	chdir			sys_chdir
+13	oabi	time			sys_time32
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19	common	lseek			sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+22	oabi	umount			sys_oldumount
+23	common	setuid			sys_setuid16
+24	common	getuid			sys_getuid16
+25	oabi	stime			sys_stime32
+26	common	ptrace			sys_ptrace
+27	oabi	alarm			sys_alarm
+# 28 was sys_fstat
+29	common	pause			sys_pause
+30	oabi	utime			sys_utime32
+# 31 was sys_stty
+# 32 was sys_gtty
+33	common	access			sys_access
+34	common	nice			sys_nice
+# 35 was sys_ftime
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times
+# 44 was sys_prof
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid16
+47	common	getgid			sys_getgid16
+# 48 was sys_signal
+49	common	geteuid			sys_geteuid16
+50	common	getegid			sys_getegid16
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+# 53 was sys_lock
+54	common	ioctl			sys_ioctl
+55	common	fcntl			sys_fcntl
+# 56 was sys_mpx
+57	common	setpgid			sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	sigaction		sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70	common	setreuid		sys_setreuid16
+71	common	setregid		sys_setregid16
+72	common	sigsuspend		sys_sigsuspend
+73	common	sigpending		sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit
+# Back compat 2GB limited rlimit
+76	oabi	getrlimit		sys_old_getrlimit
+77	common	getrusage		sys_getrusage
+78	common	gettimeofday		sys_gettimeofday
+79	common	settimeofday		sys_settimeofday
+80	common	getgroups		sys_getgroups16
+81	common	setgroups		sys_setgroups16
+82	oabi	select			sys_old_select
+83	common	symlink			sys_symlink
+# 84 was sys_lstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_uselib
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+89	oabi	readdir			sys_old_readdir
+90	oabi	mmap			sys_old_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate
+93	common	ftruncate		sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown16
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+# 98 was sys_profil
+99	common	statfs			sys_statfs
+100	common	fstatfs			sys_fstatfs
+# 101 was sys_ioperm
+102	oabi	socketcall		sys_socketcall		sys_oabi_socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer
+105	common	getitimer		sys_getitimer
+106	common	stat			sys_newstat
+107	common	lstat			sys_newlstat
+108	common	fstat			sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111	common	vhangup			sys_vhangup
+# 112 was sys_idle
+# syscall to call a syscall!
+113	oabi	syscall			sys_syscall
+114	common	wait4			sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo
+117	oabi	ipc			sys_ipc			sys_oabi_ipc
+118	common	fsync			sys_fsync
+119	common	sigreturn		sys_sigreturn_wrapper
+120	common	clone			sys_clone
+121	common	setdomainname		sys_setdomainname
+122	common	uname			sys_newuname
+# 123 was sys_modify_ldt
+124	common	adjtimex		sys_adjtimex_time32
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask
+# 127 was sys_create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was sys_get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	common	personality		sys_personality
+# 137 was sys_afs_syscall
+138	common	setfsuid		sys_setfsuid16
+139	common	setfsgid		sys_setfsgid16
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents
+142	common	_newselect		sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	common	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+162	common	nanosleep		sys_nanosleep_time32
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid16
+165	common	getresuid		sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168	common	poll			sys_poll
+169	common	nfsservctl
+170	common	setresgid		sys_setresgid16
+171	common	getresgid		sys_getresgid16
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper
+174	common	rt_sigaction		sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending
+177	common	rt_sigtimedwait		sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend
+180	common	pread64			sys_pread64		sys_oabi_pread64
+181	common	pwrite64		sys_pwrite64		sys_oabi_pwrite64
+182	common	chown			sys_chown16
+183	common	getcwd			sys_getcwd
+184	common	capget			sys_capget
+185	common	capset			sys_capset
+186	common	sigaltstack		sys_sigaltstack
+187	common	sendfile		sys_sendfile
+# 188 reserved
+# 189 reserved
+190	common	vfork			sys_vfork
+# SuS compliant getrlimit
+191	common	ugetrlimit		sys_getrlimit
+192	common	mmap2			sys_mmap2
+193	common	truncate64		sys_truncate64		sys_oabi_truncate64
+194	common	ftruncate64		sys_ftruncate64		sys_oabi_ftruncate64
+195	common	stat64			sys_stat64		sys_oabi_stat64
+196	common	lstat64			sys_lstat64		sys_oabi_lstat64
+197	common	fstat64			sys_fstat64		sys_oabi_fstat64
+198	common	lchown32		sys_lchown
+199	common	getuid32		sys_getuid
+200	common	getgid32		sys_getgid
+201	common	geteuid32		sys_geteuid
+202	common	getegid32		sys_getegid
+203	common	setreuid32		sys_setreuid
+204	common	setregid32		sys_setregid
+205	common	getgroups32		sys_getgroups
+206	common	setgroups32		sys_setgroups
+207	common	fchown32		sys_fchown
+208	common	setresuid32		sys_setresuid
+209	common	getresuid32		sys_getresuid
+210	common	setresgid32		sys_setresgid
+211	common	getresgid32		sys_getresgid
+212	common	chown32			sys_chown
+213	common	setuid32		sys_setuid
+214	common	setgid32		sys_setgid
+215	common	setfsuid32		sys_setfsuid
+216	common	setfsgid32		sys_setfsgid
+217	common	getdents64		sys_getdents64
+218	common	pivot_root		sys_pivot_root
+219	common	mincore			sys_mincore
+220	common	madvise			sys_madvise
+221	common	fcntl64			sys_fcntl64		sys_oabi_fcntl64
+# 222 for tux
+# 223 is unused
+224	common	gettid			sys_gettid
+225	common	readahead		sys_readahead		sys_oabi_readahead
+226	common	setxattr		sys_setxattr
+227	common	lsetxattr		sys_lsetxattr
+228	common	fsetxattr		sys_fsetxattr
+229	common	getxattr		sys_getxattr
+230	common	lgetxattr		sys_lgetxattr
+231	common	fgetxattr		sys_fgetxattr
+232	common	listxattr		sys_listxattr
+233	common	llistxattr		sys_llistxattr
+234	common	flistxattr		sys_flistxattr
+235	common	removexattr		sys_removexattr
+236	common	lremovexattr		sys_lremovexattr
+237	common	fremovexattr		sys_fremovexattr
+238	common	tkill			sys_tkill
+239	common	sendfile64		sys_sendfile64
+240	common	futex			sys_futex_time32
+241	common	sched_setaffinity	sys_sched_setaffinity
+242	common	sched_getaffinity	sys_sched_getaffinity
+243	common	io_setup		sys_io_setup
+244	common	io_destroy		sys_io_destroy
+245	common	io_getevents		sys_io_getevents_time32
+246	common	io_submit		sys_io_submit
+247	common	io_cancel		sys_io_cancel
+248	common	exit_group		sys_exit_group
+249	common	lookup_dcookie		sys_ni_syscall
+250	common	epoll_create		sys_epoll_create
+251	common	epoll_ctl		sys_epoll_ctl		sys_oabi_epoll_ctl
+252	common	epoll_wait		sys_epoll_wait
+253	common	remap_file_pages	sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256	common	set_tid_address		sys_set_tid_address
+257	common	timer_create		sys_timer_create
+258	common	timer_settime		sys_timer_settime32
+259	common	timer_gettime		sys_timer_gettime32
+260	common	timer_getoverrun	sys_timer_getoverrun
+261	common	timer_delete		sys_timer_delete
+262	common	clock_settime		sys_clock_settime32
+263	common	clock_gettime		sys_clock_gettime32
+264	common	clock_getres		sys_clock_getres_time32
+265	common	clock_nanosleep		sys_clock_nanosleep_time32
+266	common	statfs64		sys_statfs64_wrapper
+267	common	fstatfs64		sys_fstatfs64_wrapper
+268	common	tgkill			sys_tgkill
+269	common	utimes			sys_utimes_time32
+270	common	arm_fadvise64_64	sys_arm_fadvise64_64
+271	common	pciconfig_iobase	sys_pciconfig_iobase
+272	common	pciconfig_read		sys_pciconfig_read
+273	common	pciconfig_write		sys_pciconfig_write
+274	common	mq_open			sys_mq_open
+275	common	mq_unlink		sys_mq_unlink
+276	common	mq_timedsend		sys_mq_timedsend_time32
+277	common	mq_timedreceive		sys_mq_timedreceive_time32
+278	common	mq_notify		sys_mq_notify
+279	common	mq_getsetattr		sys_mq_getsetattr
+280	common	waitid			sys_waitid
+281	common	socket			sys_socket
+282	common	bind			sys_bind		sys_oabi_bind
+283	common	connect			sys_connect		sys_oabi_connect
+284	common	listen			sys_listen
+285	common	accept			sys_accept
+286	common	getsockname		sys_getsockname
+287	common	getpeername		sys_getpeername
+288	common	socketpair		sys_socketpair
+289	common	send			sys_send
+290	common	sendto			sys_sendto		sys_oabi_sendto
+291	common	recv			sys_recv
+292	common	recvfrom		sys_recvfrom
+293	common	shutdown		sys_shutdown
+294	common	setsockopt		sys_setsockopt
+295	common	getsockopt		sys_getsockopt
+296	common	sendmsg			sys_sendmsg		sys_oabi_sendmsg
+297	common	recvmsg			sys_recvmsg
+298	common	semop			sys_semop		sys_oabi_semop
+299	common	semget			sys_semget
+300	common	semctl			sys_old_semctl
+301	common	msgsnd			sys_msgsnd
+302	common	msgrcv			sys_msgrcv
+303	common	msgget			sys_msgget
+304	common	msgctl			sys_old_msgctl
+305	common	shmat			sys_shmat
+306	common	shmdt			sys_shmdt
+307	common	shmget			sys_shmget
+308	common	shmctl			sys_old_shmctl
+309	common	add_key			sys_add_key
+310	common	request_key		sys_request_key
+311	common	keyctl			sys_keyctl
+312	common	semtimedop		sys_semtimedop_time32	sys_oabi_semtimedop
+313	common	vserver
+314	common	ioprio_set		sys_ioprio_set
+315	common	ioprio_get		sys_ioprio_get
+316	common	inotify_init		sys_inotify_init
+317	common	inotify_add_watch	sys_inotify_add_watch
+318	common	inotify_rm_watch	sys_inotify_rm_watch
+319	common	mbind			sys_mbind
+320	common	get_mempolicy		sys_get_mempolicy
+321	common	set_mempolicy		sys_set_mempolicy
+322	common	openat			sys_openat
+323	common	mkdirat			sys_mkdirat
+324	common	mknodat			sys_mknodat
+325	common	fchownat		sys_fchownat
+326	common	futimesat		sys_futimesat_time32
+327	common	fstatat64		sys_fstatat64		sys_oabi_fstatat64
+328	common	unlinkat		sys_unlinkat
+329	common	renameat		sys_renameat
+330	common	linkat			sys_linkat
+331	common	symlinkat		sys_symlinkat
+332	common	readlinkat		sys_readlinkat
+333	common	fchmodat		sys_fchmodat
+334	common	faccessat		sys_faccessat
+335	common	pselect6		sys_pselect6_time32
+336	common	ppoll			sys_ppoll_time32
+337	common	unshare			sys_unshare
+338	common	set_robust_list		sys_set_robust_list
+339	common	get_robust_list		sys_get_robust_list
+340	common	splice			sys_splice
+341	common	arm_sync_file_range	sys_sync_file_range2
+342	common	tee			sys_tee
+343	common	vmsplice		sys_vmsplice
+344	common	move_pages		sys_move_pages
+345	common	getcpu			sys_getcpu
+346	common	epoll_pwait		sys_epoll_pwait
+347	common	kexec_load		sys_kexec_load
+348	common	utimensat		sys_utimensat_time32
+349	common	signalfd		sys_signalfd
+350	common	timerfd_create		sys_timerfd_create
+351	common	eventfd			sys_eventfd
+352	common	fallocate		sys_fallocate
+353	common	timerfd_settime		sys_timerfd_settime32
+354	common	timerfd_gettime		sys_timerfd_gettime32
+355	common	signalfd4		sys_signalfd4
+356	common	eventfd2		sys_eventfd2
+357	common	epoll_create1		sys_epoll_create1
+358	common	dup3			sys_dup3
+359	common	pipe2			sys_pipe2
+360	common	inotify_init1		sys_inotify_init1
+361	common	preadv			sys_preadv
+362	common	pwritev			sys_pwritev
+363	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo
+364	common	perf_event_open		sys_perf_event_open
+365	common	recvmmsg		sys_recvmmsg_time32
+366	common	accept4			sys_accept4
+367	common	fanotify_init		sys_fanotify_init
+368	common	fanotify_mark		sys_fanotify_mark
+369	common	prlimit64		sys_prlimit64
+370	common	name_to_handle_at	sys_name_to_handle_at
+371	common	open_by_handle_at	sys_open_by_handle_at
+372	common	clock_adjtime		sys_clock_adjtime32
+373	common	syncfs			sys_syncfs
+374	common	sendmmsg		sys_sendmmsg
+375	common	setns			sys_setns
+376	common	process_vm_readv	sys_process_vm_readv
+377	common	process_vm_writev	sys_process_vm_writev
+378	common	kcmp			sys_kcmp
+379	common	finit_module		sys_finit_module
+380	common	sched_setattr		sys_sched_setattr
+381	common	sched_getattr		sys_sched_getattr
+382	common	renameat2		sys_renameat2
+383	common	seccomp			sys_seccomp
+384	common	getrandom		sys_getrandom
+385	common	memfd_create		sys_memfd_create
+386	common	bpf			sys_bpf
+387	common	execveat		sys_execveat
+388	common	userfaultfd		sys_userfaultfd
+389	common	membarrier		sys_membarrier
+390	common	mlock2			sys_mlock2
+391	common	copy_file_range		sys_copy_file_range
+392	common	preadv2			sys_preadv2
+393	common	pwritev2		sys_pwritev2
+394	common	pkey_mprotect		sys_pkey_mprotect
+395	common	pkey_alloc		sys_pkey_alloc
+396	common	pkey_free		sys_pkey_free
+397	common	statx			sys_statx
+398	common	rseq			sys_rseq
+399	common	io_pgetevents		sys_io_pgetevents_time32
+400	common	migrate_pages		sys_migrate_pages
+401	common	kexec_file_load		sys_kexec_file_load
+# 402 is unused
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/arm/include/syscall_table.h b/tools/perf/arch/arm/include/syscall_table.h
new file mode 100644
index 000000000000..4c942821662d
--- /dev/null
+++ b/tools/perf/arch/arm/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 692f48db810c..542f3bee1501 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -202,6 +202,7 @@ check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscall
 check_2 tools/perf/arch/powerpc/entry/syscalls/syscall.tbl arch/powerpc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
+check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:07 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:07 -0800
Subject: [PATCH RFT 05/16] perf tools: sh: Support syscall headers
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-5-9adae5c761ef@rivosinc.com>

sh uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/sh/entry/syscalls/Kbuild           |   2 +
 .../perf/arch/sh/entry/syscalls/Makefile.syscalls  |   4 +
 tools/perf/arch/sh/entry/syscalls/syscall.tbl      | 468 +++++++++++++++++++++
 tools/perf/arch/sh/include/syscall_table.h         |   2 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 479 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index fd511c78dd9b..a5132ae658f7 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index faf0cf9b6e59..e24e631863fb 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/sh/entry/syscalls/Kbuild b/tools/perf/arch/sh/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..11707c481a24
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..25080390e4ed
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 +=
+syscalltbl = $(srctree)/tools/perf/arch/sh/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sh/entry/syscalls/syscall.tbl b/tools/perf/arch/sh/entry/syscalls/syscall.tbl
new file mode 100644
index 000000000000..c55fd7696d40
--- /dev/null
+++ b/tools/perf/arch/sh/entry/syscalls/syscall.tbl
@@ -0,0 +1,468 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for sh
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	restart_syscall			sys_restart_syscall
+1	common	exit				sys_exit
+2	common	fork				sys_fork
+3	common	read				sys_read
+4	common	write				sys_write
+5	common	open				sys_open
+6	common	close				sys_close
+7	common	waitpid				sys_waitpid
+8	common	creat				sys_creat
+9	common	link				sys_link
+10	common	unlink				sys_unlink
+11	common	execve				sys_execve
+12	common	chdir				sys_chdir
+13	common	time				sys_time32
+14	common	mknod				sys_mknod
+15	common	chmod				sys_chmod
+16	common	lchown				sys_lchown16
+# 17 was break
+18	common	oldstat				sys_stat
+19	common	lseek				sys_lseek
+20	common	getpid				sys_getpid
+21	common	mount				sys_mount
+22	common	umount				sys_oldumount
+23	common	setuid				sys_setuid16
+24	common	getuid				sys_getuid16
+25	common	stime				sys_stime32
+26	common	ptrace				sys_ptrace
+27	common	alarm				sys_alarm
+28	common	oldfstat			sys_fstat
+29	common	pause				sys_pause
+30	common	utime				sys_utime32
+# 31 was stty
+# 32 was gtty
+33	common	access				sys_access
+34	common	nice				sys_nice
+# 35 was ftime
+36	common	sync				sys_sync
+37	common	kill				sys_kill
+38	common	rename				sys_rename
+39	common	mkdir				sys_mkdir
+40	common	rmdir				sys_rmdir
+41	common	dup				sys_dup
+42	common	pipe				sys_sh_pipe
+43	common	times				sys_times
+# 44 was prof
+45	common	brk				sys_brk
+46	common	setgid				sys_setgid16
+47	common	getgid				sys_getgid16
+48	common	signal				sys_signal
+49	common	geteuid				sys_geteuid16
+50	common	getegid				sys_getegid16
+51	common	acct				sys_acct
+52	common	umount2				sys_umount
+# 53 was lock
+54	common	ioctl				sys_ioctl
+55	common	fcntl				sys_fcntl
+# 56 was mpx
+57	common	setpgid				sys_setpgid
+# 58 was ulimit
+# 59 was olduname
+60	common	umask				sys_umask
+61	common	chroot				sys_chroot
+62	common	ustat				sys_ustat
+63	common	dup2				sys_dup2
+64	common	getppid				sys_getppid
+65	common	getpgrp				sys_getpgrp
+66	common	setsid				sys_setsid
+67	common	sigaction			sys_sigaction
+68	common	sgetmask			sys_sgetmask
+69	common	ssetmask			sys_ssetmask
+70	common	setreuid			sys_setreuid16
+71	common	setregid			sys_setregid16
+72	common	sigsuspend			sys_sigsuspend
+73	common	sigpending			sys_sigpending
+74	common	sethostname			sys_sethostname
+75	common	setrlimit			sys_setrlimit
+76	common	getrlimit			sys_old_getrlimit
+77	common	getrusage			sys_getrusage
+78	common	gettimeofday			sys_gettimeofday
+79	common	settimeofday			sys_settimeofday
+80	common	getgroups			sys_getgroups16
+81	common	setgroups			sys_setgroups16
+# 82 was select
+83	common	symlink				sys_symlink
+84	common	oldlstat			sys_lstat
+85	common	readlink			sys_readlink
+86	common	uselib				sys_uselib
+87	common	swapon				sys_swapon
+88	common	reboot				sys_reboot
+89	common	readdir				sys_old_readdir
+90	common	mmap				old_mmap
+91	common	munmap				sys_munmap
+92	common	truncate			sys_truncate
+93	common	ftruncate			sys_ftruncate
+94	common	fchmod				sys_fchmod
+95	common	fchown				sys_fchown16
+96	common	getpriority			sys_getpriority
+97	common	setpriority			sys_setpriority
+# 98 was profil
+99	common	statfs				sys_statfs
+100	common	fstatfs				sys_fstatfs
+# 101 was ioperm
+102	common	socketcall			sys_socketcall
+103	common	syslog				sys_syslog
+104	common	setitimer			sys_setitimer
+105	common	getitimer			sys_getitimer
+106	common	stat				sys_newstat
+107	common	lstat				sys_newlstat
+108	common	fstat				sys_newfstat
+109	common	olduname			sys_uname
+# 110 was iopl
+111	common	vhangup				sys_vhangup
+# 112 was idle
+# 113 was vm86old
+114	common	wait4				sys_wait4
+115	common	swapoff				sys_swapoff
+116	common	sysinfo				sys_sysinfo
+117	common	ipc				sys_ipc
+118	common	fsync				sys_fsync
+119	common	sigreturn			sys_sigreturn
+120	common	clone				sys_clone
+121	common	setdomainname			sys_setdomainname
+122	common	uname				sys_newuname
+123	common	cacheflush			sys_cacheflush
+124	common	adjtimex			sys_adjtimex_time32
+125	common	mprotect			sys_mprotect
+126	common	sigprocmask			sys_sigprocmask
+# 127 was create_module
+128	common	init_module			sys_init_module
+129	common	delete_module			sys_delete_module
+# 130 was get_kernel_syms
+131	common	quotactl			sys_quotactl
+132	common	getpgid				sys_getpgid
+133	common	fchdir				sys_fchdir
+134	common	bdflush				sys_ni_syscall
+135	common	sysfs				sys_sysfs
+136	common	personality			sys_personality
+# 137 was afs_syscall
+138	common	setfsuid			sys_setfsuid16
+139	common	setfsgid			sys_setfsgid16
+140	common	_llseek				sys_llseek
+141	common	getdents			sys_getdents
+142	common	_newselect			sys_select
+143	common	flock				sys_flock
+144	common	msync				sys_msync
+145	common	readv				sys_readv
+146	common	writev				sys_writev
+147	common	getsid				sys_getsid
+148	common	fdatasync			sys_fdatasync
+149	common	_sysctl				sys_ni_syscall
+150	common	mlock				sys_mlock
+151	common	munlock				sys_munlock
+152	common	mlockall			sys_mlockall
+153	common	munlockall			sys_munlockall
+154	common	sched_setparam			sys_sched_setparam
+155	common	sched_getparam			sys_sched_getparam
+156	common	sched_setscheduler		sys_sched_setscheduler
+157	common	sched_getscheduler		sys_sched_getscheduler
+158	common	sched_yield			sys_sched_yield
+159	common	sched_get_priority_max		sys_sched_get_priority_max
+160	common	sched_get_priority_min		sys_sched_get_priority_min
+161	common	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+162	common	nanosleep			sys_nanosleep_time32
+163	common	mremap				sys_mremap
+164	common	setresuid			sys_setresuid16
+165	common	getresuid			sys_getresuid16
+# 166 was vm86
+# 167 was query_module
+168	common	poll				sys_poll
+169	common	nfsservctl			sys_ni_syscall
+170	common	setresgid			sys_setresgid16
+171	common	getresgid			sys_getresgid16
+172	common	prctl				sys_prctl
+173	common	rt_sigreturn			sys_rt_sigreturn
+174	common	rt_sigaction			sys_rt_sigaction
+175	common	rt_sigprocmask			sys_rt_sigprocmask
+176	common	rt_sigpending			sys_rt_sigpending
+177	common	rt_sigtimedwait			sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+179	common	rt_sigsuspend			sys_rt_sigsuspend
+180	common	pread64				sys_pread_wrapper
+181	common	pwrite64			sys_pwrite_wrapper
+182	common	chown				sys_chown16
+183	common	getcwd				sys_getcwd
+184	common	capget				sys_capget
+185	common	capset				sys_capset
+186	common	sigaltstack			sys_sigaltstack
+187	common	sendfile			sys_sendfile
+# 188 is reserved for getpmsg
+# 189 is reserved for putpmsg
+190	common	vfork				sys_vfork
+191	common	ugetrlimit			sys_getrlimit
+192	common	mmap2				sys_mmap2
+193	common	truncate64			sys_truncate64
+194	common	ftruncate64			sys_ftruncate64
+195	common	stat64				sys_stat64
+196	common	lstat64				sys_lstat64
+197	common	fstat64				sys_fstat64
+198	common	lchown32			sys_lchown
+199	common	getuid32			sys_getuid
+200	common	getgid32			sys_getgid
+201	common	geteuid32			sys_geteuid
+202	common	getegid32			sys_getegid
+203	common	setreuid32			sys_setreuid
+204	common	setregid32			sys_setregid
+205	common	getgroups32			sys_getgroups
+206	common	setgroups32			sys_setgroups
+207	common	fchown32			sys_fchown
+208	common	setresuid32			sys_setresuid
+209	common	getresuid32			sys_getresuid
+210	common	setresgid32			sys_setresgid
+211	common	getresgid32			sys_getresgid
+212	common	chown32				sys_chown
+213	common	setuid32			sys_setuid
+214	common	setgid32			sys_setgid
+215	common	setfsuid32			sys_setfsuid
+216	common	setfsgid32			sys_setfsgid
+217	common	pivot_root			sys_pivot_root
+218	common	mincore				sys_mincore
+219	common	madvise				sys_madvise
+220	common	getdents64			sys_getdents64
+221	common	fcntl64				sys_fcntl64
+# 222 is reserved for tux
+# 223 is unused
+224	common	gettid				sys_gettid
+225	common	readahead			sys_readahead
+226	common	setxattr			sys_setxattr
+227	common	lsetxattr			sys_lsetxattr
+228	common	fsetxattr			sys_fsetxattr
+229	common	getxattr			sys_getxattr
+230	common	lgetxattr			sys_lgetxattr
+231	common	fgetxattr			sys_fgetxattr
+232	common	listxattr			sys_listxattr
+233	common	llistxattr			sys_llistxattr
+234	common	flistxattr			sys_flistxattr
+235	common	removexattr			sys_removexattr
+236	common	lremovexattr			sys_lremovexattr
+237	common	fremovexattr			sys_fremovexattr
+238	common	tkill				sys_tkill
+239	common	sendfile64			sys_sendfile64
+240	common	futex				sys_futex_time32
+241	common	sched_setaffinity		sys_sched_setaffinity
+242	common	sched_getaffinity		sys_sched_getaffinity
+# 243 is reserved for set_thread_area
+# 244 is reserved for get_thread_area
+245	common	io_setup			sys_io_setup
+246	common	io_destroy			sys_io_destroy
+247	common	io_getevents			sys_io_getevents_time32
+248	common	io_submit			sys_io_submit
+249	common	io_cancel			sys_io_cancel
+250	common	fadvise64			sys_fadvise64
+# 251 is unused
+252	common	exit_group			sys_exit_group
+253	common	lookup_dcookie			sys_ni_syscall
+254	common	epoll_create			sys_epoll_create
+255	common	epoll_ctl			sys_epoll_ctl
+256	common	epoll_wait			sys_epoll_wait
+257	common	remap_file_pages		sys_remap_file_pages
+258	common	set_tid_address			sys_set_tid_address
+259	common	timer_create			sys_timer_create
+260	common	timer_settime			sys_timer_settime32
+261	common	timer_gettime			sys_timer_gettime32
+262	common	timer_getoverrun		sys_timer_getoverrun
+263	common	timer_delete			sys_timer_delete
+264	common	clock_settime			sys_clock_settime32
+265	common	clock_gettime			sys_clock_gettime32
+266	common	clock_getres			sys_clock_getres_time32
+267	common	clock_nanosleep			sys_clock_nanosleep_time32
+268	common	statfs64			sys_statfs64
+269	common	fstatfs64			sys_fstatfs64
+270	common	tgkill				sys_tgkill
+271	common	utimes				sys_utimes_time32
+272	common	fadvise64_64			sys_fadvise64_64_wrapper
+# 273 is reserved for vserver
+274	common	mbind				sys_mbind
+275	common	get_mempolicy			sys_get_mempolicy
+276	common	set_mempolicy			sys_set_mempolicy
+277	common	mq_open				sys_mq_open
+278	common	mq_unlink			sys_mq_unlink
+279	common	mq_timedsend			sys_mq_timedsend_time32
+280	common	mq_timedreceive			sys_mq_timedreceive_time32
+281	common	mq_notify			sys_mq_notify
+282	common	mq_getsetattr			sys_mq_getsetattr
+283	common	kexec_load			sys_kexec_load
+284	common	waitid				sys_waitid
+285	common	add_key				sys_add_key
+286	common	request_key			sys_request_key
+287	common	keyctl				sys_keyctl
+288	common	ioprio_set			sys_ioprio_set
+289	common	ioprio_get			sys_ioprio_get
+290	common	inotify_init			sys_inotify_init
+291	common	inotify_add_watch		sys_inotify_add_watch
+292	common	inotify_rm_watch		sys_inotify_rm_watch
+# 293 is unused
+294	common	migrate_pages			sys_migrate_pages
+295	common	openat				sys_openat
+296	common	mkdirat				sys_mkdirat
+297	common	mknodat				sys_mknodat
+298	common	fchownat			sys_fchownat
+299	common	futimesat			sys_futimesat_time32
+300	common	fstatat64			sys_fstatat64
+301	common	unlinkat			sys_unlinkat
+302	common	renameat			sys_renameat
+303	common	linkat				sys_linkat
+304	common	symlinkat			sys_symlinkat
+305	common	readlinkat			sys_readlinkat
+306	common	fchmodat			sys_fchmodat
+307	common	faccessat			sys_faccessat
+308	common	pselect6			sys_pselect6_time32
+309	common	ppoll				sys_ppoll_time32
+310	common	unshare				sys_unshare
+311	common	set_robust_list			sys_set_robust_list
+312	common	get_robust_list			sys_get_robust_list
+313	common	splice				sys_splice
+314	common	sync_file_range			sys_sh_sync_file_range6
+315	common	tee				sys_tee
+316	common	vmsplice			sys_vmsplice
+317	common	move_pages			sys_move_pages
+318	common	getcpu				sys_getcpu
+319	common	epoll_pwait			sys_epoll_pwait
+320	common	utimensat			sys_utimensat_time32
+321	common	signalfd			sys_signalfd
+322	common	timerfd_create			sys_timerfd_create
+323	common	eventfd				sys_eventfd
+324	common	fallocate			sys_fallocate
+325	common	timerfd_settime			sys_timerfd_settime32
+326	common	timerfd_gettime			sys_timerfd_gettime32
+327	common	signalfd4			sys_signalfd4
+328	common	eventfd2			sys_eventfd2
+329	common	epoll_create1			sys_epoll_create1
+330	common	dup3				sys_dup3
+331	common	pipe2				sys_pipe2
+332	common	inotify_init1			sys_inotify_init1
+333	common	preadv				sys_preadv
+334	common	pwritev				sys_pwritev
+335	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+336	common	perf_event_open			sys_perf_event_open
+337	common	fanotify_init			sys_fanotify_init
+338	common	fanotify_mark			sys_fanotify_mark
+339	common	prlimit64			sys_prlimit64
+340	common	socket				sys_socket
+341	common	bind				sys_bind
+342	common	connect				sys_connect
+343	common	listen				sys_listen
+344	common	accept				sys_accept
+345	common	getsockname			sys_getsockname
+346	common	getpeername			sys_getpeername
+347	common	socketpair			sys_socketpair
+348	common	send				sys_send
+349	common	sendto				sys_sendto
+350	common	recv				sys_recv
+351	common	recvfrom			sys_recvfrom
+352	common	shutdown			sys_shutdown
+353	common	setsockopt			sys_setsockopt
+354	common	getsockopt			sys_getsockopt
+355	common	sendmsg				sys_sendmsg
+356	common	recvmsg				sys_recvmsg
+357	common	recvmmsg			sys_recvmmsg_time32
+358	common	accept4				sys_accept4
+359	common	name_to_handle_at		sys_name_to_handle_at
+360	common	open_by_handle_at		sys_open_by_handle_at
+361	common	clock_adjtime			sys_clock_adjtime32
+362	common	syncfs				sys_syncfs
+363	common	sendmmsg			sys_sendmmsg
+364	common	setns				sys_setns
+365	common	process_vm_readv		sys_process_vm_readv
+366	common	process_vm_writev		sys_process_vm_writev
+367	common	kcmp				sys_kcmp
+368	common	finit_module			sys_finit_module
+369	common	sched_getattr			sys_sched_getattr
+370	common	sched_setattr			sys_sched_setattr
+371	common	renameat2			sys_renameat2
+372	common	seccomp				sys_seccomp
+373	common	getrandom			sys_getrandom
+374	common	memfd_create			sys_memfd_create
+375	common	bpf				sys_bpf
+376	common	execveat			sys_execveat
+377	common	userfaultfd			sys_userfaultfd
+378	common	membarrier			sys_membarrier
+379	common	mlock2				sys_mlock2
+380	common	copy_file_range			sys_copy_file_range
+381	common	preadv2				sys_preadv2
+382	common	pwritev2			sys_pwritev2
+383	common	statx				sys_statx
+384	common	pkey_mprotect			sys_pkey_mprotect
+385	common	pkey_alloc			sys_pkey_alloc
+386	common	pkey_free			sys_pkey_free
+387	common	rseq				sys_rseq
+388	common	sync_file_range2		sys_sync_file_range2
+# room for arch specific syscalls
+393	common	semget				sys_semget
+394	common	semctl				sys_semctl
+395	common	shmget				sys_shmget
+396	common	shmctl				sys_shmctl
+397	common	shmat				sys_shmat
+398	common	shmdt				sys_shmdt
+399	common	msgget				sys_msgget
+400	common	msgsnd				sys_msgsnd
+401	common	msgrcv				sys_msgrcv
+402	common	msgctl				sys_msgctl
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+# 435 reserved for clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/sh/include/syscall_table.h b/tools/perf/arch/sh/include/syscall_table.h
new file mode 100644
index 000000000000..4c942821662d
--- /dev/null
+++ b/tools/perf/arch/sh/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 542f3bee1501..2f1b42bf337b 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -203,6 +203,7 @@ check_2 tools/perf/arch/powerpc/entry/syscalls/syscall.tbl arch/powerpc/kernel/s
 check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
+check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:08 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:08 -0800
Subject: [PATCH RFT 06/16] perf tools: sparc: Support syscall headers
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-6-9adae5c761ef@rivosinc.com>

sparc uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/sparc/entry/syscalls/Kbuild        |   3 +
 .../arch/sparc/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/sparc/entry/syscalls/syscall.tbl   | 510 +++++++++++++++++++++
 tools/perf/arch/sparc/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 529 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index a5132ae658f7..ad2194fbceb8 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index e24e631863fb..087570b6b1b8 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/sparc/entry/syscalls/Kbuild b/tools/perf/arch/sparc/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..84c6599b4ea6
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..212c1800b644
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscall_abis_64  +=
+syscalltbl = $(srctree)/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/sparc/entry/syscalls/syscall.tbl b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
new file mode 100644
index 000000000000..cfdfb3707c16
--- /dev/null
+++ b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl
@@ -0,0 +1,510 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for sparc
+#
+# The format is:
+# <number> <abi> <name> <entry point> <compat entry point>
+#
+# The <abi> can be common, 64, or 32 for this file.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	32	exit			sys_exit			sparc_exit
+1	64	exit			sparc_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open			compat_sys_open
+6	common	close			sys_close
+7	common	wait4			sys_wait4			compat_sys_wait4
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	32	execv			sunos_execv
+11	64	execv			sys_nis_syscall
+12	common	chdir			sys_chdir
+13	32    	chown			sys_chown16
+13	64	chown			sys_chown
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	32	lchown			sys_lchown16
+16	64	lchown			sys_lchown
+17	common	brk			sys_brk
+18	common	perfctr			sys_nis_syscall
+19	common	lseek			sys_lseek			compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	capget			sys_capget
+22	common	capset			sys_capset
+23	32    	setuid			sys_setuid16
+23	64    	setuid			sys_setuid
+24	32	getuid			sys_getuid16
+24	64   	getuid			sys_getuid
+25	common	vmsplice		sys_vmsplice
+26	common	ptrace			sys_ptrace			compat_sys_ptrace
+27	common	alarm			sys_alarm
+28	common	sigaltstack		sys_sigaltstack			compat_sys_sigaltstack
+29	32    	pause			sys_pause
+29	64    	pause			sys_nis_syscall
+30	32	utime			sys_utime32
+30	64	utime			sys_utime
+31	32    	lchown32		sys_lchown
+32	32    	fchown32		sys_fchown
+33	common	access			sys_access
+34	common	nice			sys_nice
+35	32    	chown32			sys_chown
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	stat			sys_newstat			compat_sys_newstat
+39	32	sendfile		sys_sendfile			compat_sys_sendfile
+39	64	sendfile		sys_sendfile64
+40	common	lstat			sys_newlstat			compat_sys_newlstat
+41	common	dup			sys_dup
+42	common	pipe			sys_sparc_pipe
+43	common	times			sys_times			compat_sys_times
+44	32    	getuid32		sys_getuid
+45	common	umount2			sys_umount
+46	32	setgid			sys_setgid16
+46	64	setgid			sys_setgid
+47	32	getgid			sys_getgid16
+47	64	getgid			sys_getgid
+48	common	signal			sys_signal
+49	32	geteuid			sys_geteuid16
+49	64	geteuid			sys_geteuid
+50	32	getegid			sys_getegid16
+50	64	getegid			sys_getegid
+51	common	acct			sys_acct
+52	64	memory_ordering		sys_memory_ordering
+53	32	getgid32		sys_getgid
+54	common	ioctl			sys_ioctl			compat_sys_ioctl
+55	common	reboot			sys_reboot
+56	32    	mmap2			sys_mmap2			sys32_mmap2
+57	common	symlink			sys_symlink
+58	common	readlink		sys_readlink
+59	32	execve			sys_execve			sys32_execve
+59	64	execve			sys64_execve
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	fstat			sys_newfstat			compat_sys_newfstat
+63	common	fstat64			sys_fstat64			compat_sys_fstat64
+64	common	getpagesize		sys_getpagesize
+65	common	msync			sys_msync
+66	common	vfork			sys_vfork
+67	common	pread64			sys_pread64			compat_sys_pread64
+68	common	pwrite64		sys_pwrite64			compat_sys_pwrite64
+69	32    	geteuid32		sys_geteuid
+70	32	getegid32		sys_getegid
+71	common	mmap			sys_mmap
+72	32	setreuid32		sys_setreuid
+73	32	munmap			sys_munmap
+73	64	munmap			sys_64_munmap
+74	common	mprotect		sys_mprotect
+75	common	madvise			sys_madvise
+76	common	vhangup			sys_vhangup
+77	32	truncate64		sys_truncate64			compat_sys_truncate64
+78	common	mincore			sys_mincore
+79	32	getgroups		sys_getgroups16
+79	64	getgroups		sys_getgroups
+80	32	setgroups		sys_setgroups16
+80	64	setgroups		sys_setgroups
+81	common	getpgrp			sys_getpgrp
+82	32	setgroups32		sys_setgroups
+83	common	setitimer		sys_setitimer			compat_sys_setitimer
+84	32	ftruncate64		sys_ftruncate64			compat_sys_ftruncate64
+85	common	swapon			sys_swapon
+86	common	getitimer		sys_getitimer			compat_sys_getitimer
+87	32	setuid32		sys_setuid
+88	common	sethostname		sys_sethostname
+89	32	setgid32		sys_setgid
+90	common	dup2			sys_dup2
+91	32	setfsuid32		sys_setfsuid
+92	common	fcntl			sys_fcntl			compat_sys_fcntl
+93	common	select			sys_select			compat_sys_select
+94	32	setfsgid32		sys_setfsgid
+95	common	fsync			sys_fsync
+96	common	setpriority		sys_setpriority
+97	common	socket			sys_socket
+98	common	connect			sys_connect
+99	common	accept			sys_accept
+100	common	getpriority		sys_getpriority
+101	common	rt_sigreturn		sys_rt_sigreturn		sys32_rt_sigreturn
+102	common	rt_sigaction		sys_rt_sigaction		compat_sys_rt_sigaction
+103	common	rt_sigprocmask		sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+104	common	rt_sigpending		sys_rt_sigpending		compat_sys_rt_sigpending
+105	32	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+105	64	rt_sigtimedwait		sys_rt_sigtimedwait
+106	common	rt_sigqueueinfo		sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+107	common	rt_sigsuspend		sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+108	32	setresuid32		sys_setresuid
+108	64	setresuid		sys_setresuid
+109	32	getresuid32		sys_getresuid
+109	64	getresuid		sys_getresuid
+110	32	setresgid32		sys_setresgid
+110	64	setresgid		sys_setresgid
+111	32	getresgid32		sys_getresgid
+111	64	getresgid		sys_getresgid
+112	32	setregid32		sys_setregid
+113	common	recvmsg			sys_recvmsg			compat_sys_recvmsg
+114	common	sendmsg			sys_sendmsg			compat_sys_sendmsg
+115	32	getgroups32		sys_getgroups
+116	common	gettimeofday		sys_gettimeofday		compat_sys_gettimeofday
+117	common	getrusage		sys_getrusage			compat_sys_getrusage
+118	common	getsockopt		sys_getsockopt			sys_getsockopt
+119	common	getcwd			sys_getcwd
+120	common	readv			sys_readv
+121	common	writev			sys_writev
+122	common	settimeofday		sys_settimeofday		compat_sys_settimeofday
+123	32	fchown			sys_fchown16
+123	64	fchown			sys_fchown
+124	common	fchmod			sys_fchmod
+125	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
+126	32	setreuid		sys_setreuid16
+126	64	setreuid		sys_setreuid
+127	32	setregid		sys_setregid16
+127	64	setregid		sys_setregid
+128	common	rename			sys_rename
+129	common	truncate		sys_truncate			compat_sys_truncate
+130	common	ftruncate		sys_ftruncate			compat_sys_ftruncate
+131	common	flock			sys_flock
+132	common	lstat64			sys_lstat64			compat_sys_lstat64
+133	common	sendto			sys_sendto
+134	common	shutdown		sys_shutdown
+135	common	socketpair		sys_socketpair
+136	common	mkdir			sys_mkdir
+137	common	rmdir			sys_rmdir
+138	32	utimes			sys_utimes_time32
+138	64	utimes			sys_utimes
+139	common	stat64			sys_stat64			compat_sys_stat64
+140	common	sendfile64		sys_sendfile64
+141	common	getpeername		sys_getpeername
+142	32	futex			sys_futex_time32
+142	64	futex			sys_futex
+143	common	gettid			sys_gettid
+144	common	getrlimit		sys_getrlimit			compat_sys_getrlimit
+145	common	setrlimit		sys_setrlimit			compat_sys_setrlimit
+146	common	pivot_root		sys_pivot_root
+147	common	prctl			sys_prctl
+148	common	pciconfig_read		sys_pciconfig_read
+149	common	pciconfig_write		sys_pciconfig_write
+150	common	getsockname		sys_getsockname
+151	common	inotify_init		sys_inotify_init
+152	common	inotify_add_watch	sys_inotify_add_watch
+153	common	poll			sys_poll
+154	common	getdents64		sys_getdents64
+155	32	fcntl64			sys_fcntl64			compat_sys_fcntl64
+156	common	inotify_rm_watch	sys_inotify_rm_watch
+157	common	statfs			sys_statfs			compat_sys_statfs
+158	common	fstatfs			sys_fstatfs			compat_sys_fstatfs
+159	common	umount			sys_oldumount
+160	common	sched_set_affinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+161	common	sched_get_affinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+162	common	getdomainname		sys_getdomainname
+163	common	setdomainname		sys_setdomainname
+164	64	utrap_install		sys_utrap_install
+165	common	quotactl		sys_quotactl
+166	common	set_tid_address		sys_set_tid_address
+167	common	mount			sys_mount
+168	common	ustat			sys_ustat			compat_sys_ustat
+169	common	setxattr		sys_setxattr
+170	common	lsetxattr		sys_lsetxattr
+171	common	fsetxattr		sys_fsetxattr
+172	common	getxattr		sys_getxattr
+173	common	lgetxattr		sys_lgetxattr
+174	common	getdents		sys_getdents			compat_sys_getdents
+175	common	setsid			sys_setsid
+176	common	fchdir			sys_fchdir
+177	common	fgetxattr		sys_fgetxattr
+178	common	listxattr		sys_listxattr
+179	common	llistxattr		sys_llistxattr
+180	common	flistxattr		sys_flistxattr
+181	common	removexattr		sys_removexattr
+182	common	lremovexattr		sys_lremovexattr
+183	32	sigpending		sys_sigpending			compat_sys_sigpending
+183	64	sigpending		sys_nis_syscall
+184	common	query_module		sys_ni_syscall
+185	common	setpgid			sys_setpgid
+186	common	fremovexattr		sys_fremovexattr
+187	common	tkill			sys_tkill
+188	32	exit_group		sys_exit_group			sparc_exit_group
+188	64	exit_group		sparc_exit_group
+189	common	uname			sys_newuname
+190	common	init_module		sys_init_module
+191	32	personality		sys_personality			sys_sparc64_personality
+191	64	personality		sys_sparc64_personality
+192	32	remap_file_pages	sys_sparc_remap_file_pages	sys_remap_file_pages
+192	64	remap_file_pages	sys_remap_file_pages
+193	common	epoll_create		sys_epoll_create
+194	common	epoll_ctl		sys_epoll_ctl
+195	common	epoll_wait		sys_epoll_wait
+196	common	ioprio_set		sys_ioprio_set
+197	common	getppid			sys_getppid
+198	32	sigaction		sys_sparc_sigaction		compat_sys_sparc_sigaction
+198	64	sigaction		sys_nis_syscall
+199	common	sgetmask		sys_sgetmask
+200	common	ssetmask		sys_ssetmask
+201	32	sigsuspend		sys_sigsuspend
+201	64	sigsuspend		sys_nis_syscall
+202	common	oldlstat		sys_newlstat			compat_sys_newlstat
+203	common	uselib			sys_uselib
+204	32	readdir			sys_old_readdir			compat_sys_old_readdir
+204	64	readdir			sys_nis_syscall
+205	common	readahead		sys_readahead			compat_sys_readahead
+206	common	socketcall		sys_socketcall			compat_sys_socketcall
+207	common	syslog			sys_syslog
+208	common	lookup_dcookie		sys_ni_syscall
+209	common	fadvise64		sys_fadvise64			compat_sys_fadvise64
+210	common	fadvise64_64		sys_fadvise64_64		compat_sys_fadvise64_64
+211	common	tgkill			sys_tgkill
+212	common	waitpid			sys_waitpid
+213	common	swapoff			sys_swapoff
+214	common	sysinfo			sys_sysinfo			compat_sys_sysinfo
+215	32	ipc			sys_ipc				compat_sys_ipc
+215	64	ipc			sys_sparc_ipc
+216	32	sigreturn		sys_sigreturn			sys32_sigreturn
+216	64	sigreturn		sys_nis_syscall
+217	common	clone			sys_clone
+218	common	ioprio_get		sys_ioprio_get
+219	32	adjtimex		sys_adjtimex_time32
+219	64	adjtimex		sys_sparc_adjtimex
+220	32	sigprocmask		sys_sigprocmask			compat_sys_sigprocmask
+220	64	sigprocmask		sys_nis_syscall
+221	common	create_module		sys_ni_syscall
+222	common	delete_module		sys_delete_module
+223	common	get_kernel_syms		sys_ni_syscall
+224	common	getpgid			sys_getpgid
+225	common	bdflush			sys_ni_syscall
+226	common	sysfs			sys_sysfs
+227	common	afs_syscall		sys_nis_syscall
+228	common	setfsuid		sys_setfsuid16
+229	common	setfsgid		sys_setfsgid16
+230	common	_newselect		sys_select			compat_sys_select
+231	32	time			sys_time32
+232	common	splice			sys_splice
+233	32	stime			sys_stime32
+233	64	stime			sys_stime
+234	common	statfs64		sys_statfs64			compat_sys_statfs64
+235	common	fstatfs64		sys_fstatfs64			compat_sys_fstatfs64
+236	common	_llseek			sys_llseek
+237	common	mlock			sys_mlock
+238	common	munlock			sys_munlock
+239	common	mlockall		sys_mlockall
+240	common	munlockall		sys_munlockall
+241	common	sched_setparam		sys_sched_setparam
+242	common	sched_getparam		sys_sched_getparam
+243	common	sched_setscheduler	sys_sched_setscheduler
+244	common	sched_getscheduler	sys_sched_getscheduler
+245	common	sched_yield		sys_sched_yield
+246	common	sched_get_priority_max	sys_sched_get_priority_max
+247	common	sched_get_priority_min	sys_sched_get_priority_min
+248	32	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+248	64	sched_rr_get_interval	sys_sched_rr_get_interval
+249	32	nanosleep		sys_nanosleep_time32
+249	64	nanosleep		sys_nanosleep
+250	32	mremap			sys_mremap
+250	64	mremap			sys_64_mremap
+251	common	_sysctl			sys_ni_syscall
+252	common	getsid			sys_getsid
+253	common	fdatasync		sys_fdatasync
+254	32	nfsservctl		sys_ni_syscall			sys_nis_syscall
+254	64	nfsservctl		sys_nis_syscall
+255	common	sync_file_range		sys_sync_file_range		compat_sys_sync_file_range
+256	32	clock_settime		sys_clock_settime32
+256	64	clock_settime		sys_clock_settime
+257	32	clock_gettime		sys_clock_gettime32
+257	64	clock_gettime		sys_clock_gettime
+258	32	clock_getres		sys_clock_getres_time32
+258	64	clock_getres		sys_clock_getres
+259	32	clock_nanosleep		sys_clock_nanosleep_time32
+259	64	clock_nanosleep		sys_clock_nanosleep
+260	common	sched_getaffinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+261	common	sched_setaffinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+262	32	timer_settime		sys_timer_settime32
+262	64	timer_settime		sys_timer_settime
+263	32	timer_gettime		sys_timer_gettime32
+263	64	timer_gettime		sys_timer_gettime
+264	common	timer_getoverrun	sys_timer_getoverrun
+265	common	timer_delete		sys_timer_delete
+266	common	timer_create		sys_timer_create		compat_sys_timer_create
+# 267 was vserver
+267	common	vserver			sys_nis_syscall
+268	common	io_setup		sys_io_setup			compat_sys_io_setup
+269	common	io_destroy		sys_io_destroy
+270	common	io_submit		sys_io_submit			compat_sys_io_submit
+271	common	io_cancel		sys_io_cancel
+272	32	io_getevents		sys_io_getevents_time32
+272	64	io_getevents		sys_io_getevents
+273	common	mq_open			sys_mq_open			compat_sys_mq_open
+274	common	mq_unlink		sys_mq_unlink
+275	32	mq_timedsend		sys_mq_timedsend_time32
+275	64	mq_timedsend		sys_mq_timedsend
+276	32	mq_timedreceive		sys_mq_timedreceive_time32
+276	64	mq_timedreceive		sys_mq_timedreceive
+277	common	mq_notify		sys_mq_notify			compat_sys_mq_notify
+278	common	mq_getsetattr		sys_mq_getsetattr		compat_sys_mq_getsetattr
+279	common	waitid			sys_waitid			compat_sys_waitid
+280	common	tee			sys_tee
+281	common	add_key			sys_add_key
+282	common	request_key		sys_request_key
+283	common	keyctl			sys_keyctl			compat_sys_keyctl
+284	common	openat			sys_openat			compat_sys_openat
+285	common	mkdirat			sys_mkdirat
+286	common	mknodat			sys_mknodat
+287	common	fchownat		sys_fchownat
+288	32	futimesat		sys_futimesat_time32
+288	64	futimesat		sys_futimesat
+289	common	fstatat64		sys_fstatat64			compat_sys_fstatat64
+290	common	unlinkat		sys_unlinkat
+291	common	renameat		sys_renameat
+292	common	linkat			sys_linkat
+293	common	symlinkat		sys_symlinkat
+294	common	readlinkat		sys_readlinkat
+295	common	fchmodat		sys_fchmodat
+296	common	faccessat		sys_faccessat
+297	32	pselect6		sys_pselect6_time32		compat_sys_pselect6_time32
+297	64	pselect6		sys_pselect6
+298	32	ppoll			sys_ppoll_time32		compat_sys_ppoll_time32
+298	64	ppoll			sys_ppoll
+299	common	unshare			sys_unshare
+300	common	set_robust_list		sys_set_robust_list		compat_sys_set_robust_list
+301	common	get_robust_list		sys_get_robust_list		compat_sys_get_robust_list
+302	common	migrate_pages		sys_migrate_pages
+303	common	mbind			sys_mbind
+304	common	get_mempolicy		sys_get_mempolicy
+305	common	set_mempolicy		sys_set_mempolicy
+306	common	kexec_load		sys_kexec_load			compat_sys_kexec_load
+307	common	move_pages		sys_move_pages
+308	common	getcpu			sys_getcpu
+309	common	epoll_pwait		sys_epoll_pwait			compat_sys_epoll_pwait
+310	32	utimensat		sys_utimensat_time32
+310	64	utimensat		sys_utimensat
+311	common	signalfd		sys_signalfd			compat_sys_signalfd
+312	common	timerfd_create		sys_timerfd_create
+313	common	eventfd			sys_eventfd
+314	common	fallocate		sys_fallocate			compat_sys_fallocate
+315	32	timerfd_settime		sys_timerfd_settime32
+315	64	timerfd_settime		sys_timerfd_settime
+316	32	timerfd_gettime		sys_timerfd_gettime32
+316	64	timerfd_gettime		sys_timerfd_gettime
+317	common	signalfd4		sys_signalfd4			compat_sys_signalfd4
+318	common	eventfd2		sys_eventfd2
+319	common	epoll_create1		sys_epoll_create1
+320	common	dup3			sys_dup3
+321	common	pipe2			sys_pipe2
+322	common	inotify_init1		sys_inotify_init1
+323	common	accept4			sys_accept4
+324	common	preadv			sys_preadv			compat_sys_preadv
+325	common	pwritev			sys_pwritev			compat_sys_pwritev
+326	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+327	common	perf_event_open		sys_perf_event_open
+328	32	recvmmsg		sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+328	64	recvmmsg		sys_recvmmsg
+329	common	fanotify_init		sys_fanotify_init
+330	common	fanotify_mark		sys_fanotify_mark		compat_sys_fanotify_mark
+331	common	prlimit64		sys_prlimit64
+332	common	name_to_handle_at	sys_name_to_handle_at
+333	common	open_by_handle_at	sys_open_by_handle_at		compat_sys_open_by_handle_at
+334	32	clock_adjtime		sys_clock_adjtime32
+334	64	clock_adjtime		sys_sparc_clock_adjtime
+335	common	syncfs			sys_syncfs
+336	common	sendmmsg		sys_sendmmsg			compat_sys_sendmmsg
+337	common	setns			sys_setns
+338	common	process_vm_readv	sys_process_vm_readv
+339	common	process_vm_writev	sys_process_vm_writev
+340	32	kern_features		sys_ni_syscall			sys_kern_features
+340	64	kern_features		sys_kern_features
+341	common	kcmp			sys_kcmp
+342	common	finit_module		sys_finit_module
+343	common	sched_setattr		sys_sched_setattr
+344	common	sched_getattr		sys_sched_getattr
+345	common	renameat2		sys_renameat2
+346	common	seccomp			sys_seccomp
+347	common	getrandom		sys_getrandom
+348	common	memfd_create		sys_memfd_create
+349	common	bpf			sys_bpf
+350	32	execveat		sys_execveat			sys32_execveat
+350	64	execveat		sys64_execveat
+351	common	membarrier		sys_membarrier
+352	common	userfaultfd		sys_userfaultfd
+353	common	bind			sys_bind
+354	common	listen			sys_listen
+355	common	setsockopt		sys_setsockopt			sys_setsockopt
+356	common	mlock2			sys_mlock2
+357	common	copy_file_range		sys_copy_file_range
+358	common	preadv2			sys_preadv2			compat_sys_preadv2
+359	common	pwritev2		sys_pwritev2			compat_sys_pwritev2
+360	common	statx			sys_statx
+361	32	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+361	64	io_pgetevents		sys_io_pgetevents
+362	common	pkey_mprotect		sys_pkey_mprotect
+363	common	pkey_alloc		sys_pkey_alloc
+364	common	pkey_free		sys_pkey_free
+365	common	rseq			sys_rseq
+# room for arch specific syscalls
+392	64	semtimedop			sys_semtimedop
+393	common	semget			sys_semget
+394	common	semctl			sys_semctl			compat_sys_semctl
+395	common	shmget			sys_shmget
+396	common	shmctl			sys_shmctl			compat_sys_shmctl
+397	common	shmat			sys_shmat			compat_sys_shmat
+398	common	shmdt			sys_shmdt
+399	common	msgget			sys_msgget
+400	common	msgsnd			sys_msgsnd			compat_sys_msgsnd
+401	common	msgrcv			sys_msgrcv			compat_sys_msgrcv
+402	common	msgctl			sys_msgctl			compat_sys_msgctl
+403	32	clock_gettime64			sys_clock_gettime		sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime		sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime		sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime		sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime		sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat			sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop			sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+# 435 reserved for clone3
+436	common	close_range			sys_close_range
+437	common	openat2			sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal 				sys_mseal
diff --git a/tools/perf/arch/sparc/include/syscall_table.h b/tools/perf/arch/sparc/include/syscall_table.h
new file mode 100644
index 000000000000..7ff51b783000
--- /dev/null
+++ b/tools/perf/arch/sparc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 2f1b42bf337b..99a278a3f1b5 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -204,6 +204,7 @@ check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscall
 check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:09 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:09 -0800
Subject: [PATCH RFT 07/16] perf tools: xtensa: Support syscall header
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-7-9adae5c761ef@rivosinc.com>

xtensa uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/xtensa/entry/syscalls/Kbuild       |   2 +
 .../arch/xtensa/entry/syscalls/Makefile.syscalls   |   4 +
 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl  | 435 +++++++++++++++++++++
 tools/perf/arch/xtensa/include/syscall_table.h     |   2 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 446 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index ad2194fbceb8..1894db7845d4 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 087570b6b1b8..bcbb83e0f9fd 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Kbuild b/tools/perf/arch/xtensa/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..11707c481a24
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
diff --git a/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls b/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..d4aa2358460c
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscalltbl = $(srctree)/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
new file mode 100644
index 000000000000..67083fc1b2f5
--- /dev/null
+++ b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl
@@ -0,0 +1,435 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for xtensa
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	spill				sys_ni_syscall
+1	common	xtensa				sys_ni_syscall
+2	common	available4			sys_ni_syscall
+3	common	available5			sys_ni_syscall
+4	common	available6			sys_ni_syscall
+5	common	available7			sys_ni_syscall
+6	common	available8			sys_ni_syscall
+7	common	available9			sys_ni_syscall
+# File Operations
+8	common	open				sys_open
+9	common	close				sys_close
+10	common	dup				sys_dup
+11	common	dup2				sys_dup2
+12	common	read				sys_read
+13	common	write				sys_write
+14	common	select				sys_select
+15	common	lseek				sys_lseek
+16	common	poll				sys_poll
+17	common	_llseek				sys_llseek
+18	common	epoll_wait			sys_epoll_wait
+19	common	epoll_ctl			sys_epoll_ctl
+20	common	epoll_create			sys_epoll_create
+21	common	creat				sys_creat
+22	common	truncate			sys_truncate
+23	common	ftruncate			sys_ftruncate
+24	common	readv				sys_readv
+25	common	writev				sys_writev
+26	common	fsync				sys_fsync
+27	common	fdatasync			sys_fdatasync
+28	common	truncate64			sys_truncate64
+29	common	ftruncate64			sys_ftruncate64
+30	common	pread64				sys_pread64
+31	common	pwrite64			sys_pwrite64
+32	common	link				sys_link
+33	common	rename				sys_rename
+34	common	symlink				sys_symlink
+35	common	readlink			sys_readlink
+36	common	mknod				sys_mknod
+37	common	pipe				sys_pipe
+38	common	unlink				sys_unlink
+39	common	rmdir				sys_rmdir
+40	common	mkdir				sys_mkdir
+41	common	chdir				sys_chdir
+42	common	fchdir				sys_fchdir
+43	common	getcwd				sys_getcwd
+44	common	chmod				sys_chmod
+45	common	chown				sys_chown
+46	common	stat				sys_newstat
+47	common	stat64				sys_stat64
+48	common	lchown				sys_lchown
+49	common	lstat				sys_newlstat
+50	common	lstat64				sys_lstat64
+51	common	available51			sys_ni_syscall
+52	common	fchmod				sys_fchmod
+53	common	fchown				sys_fchown
+54	common	fstat				sys_newfstat
+55	common	fstat64				sys_fstat64
+56	common	flock				sys_flock
+57	common	access				sys_access
+58	common	umask				sys_umask
+59	common	getdents			sys_getdents
+60	common	getdents64			sys_getdents64
+61	common	fcntl64				sys_fcntl64
+62	common	fallocate			sys_fallocate
+63	common	fadvise64_64			xtensa_fadvise64_64
+64	common	utime				sys_utime32
+65	common	utimes				sys_utimes_time32
+66	common	ioctl				sys_ioctl
+67	common	fcntl				sys_fcntl
+68	common	setxattr			sys_setxattr
+69	common	getxattr			sys_getxattr
+70	common	listxattr			sys_listxattr
+71	common	removexattr			sys_removexattr
+72	common	lsetxattr			sys_lsetxattr
+73	common	lgetxattr			sys_lgetxattr
+74	common	llistxattr			sys_llistxattr
+75	common	lremovexattr			sys_lremovexattr
+76	common	fsetxattr			sys_fsetxattr
+77	common	fgetxattr			sys_fgetxattr
+78	common	flistxattr			sys_flistxattr
+79	common	fremovexattr			sys_fremovexattr
+# File Map / Shared Memory Operations
+80	common	mmap2				sys_mmap_pgoff
+81	common	munmap				sys_munmap
+82	common	mprotect			sys_mprotect
+83	common	brk				sys_brk
+84	common	mlock				sys_mlock
+85	common	munlock				sys_munlock
+86	common	mlockall			sys_mlockall
+87	common	munlockall			sys_munlockall
+88	common	mremap				sys_mremap
+89	common	msync				sys_msync
+90	common	mincore				sys_mincore
+91	common	madvise				sys_madvise
+92	common	shmget				sys_shmget
+93	common	shmat				xtensa_shmat
+94	common	shmctl				sys_old_shmctl
+95	common	shmdt				sys_shmdt
+# Socket Operations
+96	common	socket				sys_socket
+97	common	setsockopt			sys_setsockopt
+98	common	getsockopt			sys_getsockopt
+99	common	shutdown			sys_shutdown
+100	common	bind				sys_bind
+101	common	connect				sys_connect
+102	common	listen				sys_listen
+103	common	accept				sys_accept
+104	common	getsockname			sys_getsockname
+105	common	getpeername			sys_getpeername
+106	common	sendmsg				sys_sendmsg
+107	common	recvmsg				sys_recvmsg
+108	common	send				sys_send
+109	common	recv				sys_recv
+110	common	sendto				sys_sendto
+111	common	recvfrom			sys_recvfrom
+112	common	socketpair			sys_socketpair
+113	common	sendfile			sys_sendfile
+114	common	sendfile64			sys_sendfile64
+115	common	sendmmsg			sys_sendmmsg
+# Process Operations
+116	common	clone				sys_clone
+117	common	execve				sys_execve
+118	common	exit				sys_exit
+119	common	exit_group			sys_exit_group
+120	common	getpid				sys_getpid
+121	common	wait4				sys_wait4
+122	common	waitid				sys_waitid
+123	common	kill				sys_kill
+124	common	tkill				sys_tkill
+125	common	tgkill				sys_tgkill
+126	common	set_tid_address			sys_set_tid_address
+127	common	gettid				sys_gettid
+128	common	setsid				sys_setsid
+129	common	getsid				sys_getsid
+130	common	prctl				sys_prctl
+131	common	personality			sys_personality
+132	common	getpriority			sys_getpriority
+133	common	setpriority			sys_setpriority
+134	common	setitimer			sys_setitimer
+135	common	getitimer			sys_getitimer
+136	common	setuid				sys_setuid
+137	common	getuid				sys_getuid
+138	common	setgid				sys_setgid
+139	common	getgid				sys_getgid
+140	common	geteuid				sys_geteuid
+141	common	getegid				sys_getegid
+142	common	setreuid			sys_setreuid
+143	common	setregid			sys_setregid
+144	common	setresuid			sys_setresuid
+145	common	getresuid			sys_getresuid
+146	common	setresgid			sys_setresgid
+147	common	getresgid			sys_getresgid
+148	common	setpgid				sys_setpgid
+149	common	getpgid				sys_getpgid
+150	common	getppid				sys_getppid
+151	common	getpgrp				sys_getpgrp
+# 152 was set_thread_area
+152	common	reserved152			sys_ni_syscall
+# 153 was get_thread_area
+153	common	reserved153			sys_ni_syscall
+154	common	times				sys_times
+155	common	acct				sys_acct
+156	common	sched_setaffinity		sys_sched_setaffinity
+157	common	sched_getaffinity		sys_sched_getaffinity
+158	common	capget				sys_capget
+159	common	capset				sys_capset
+160	common	ptrace				sys_ptrace
+161	common	semtimedop			sys_semtimedop_time32
+162	common	semget				sys_semget
+163	common	semop				sys_semop
+164	common	semctl				sys_old_semctl
+165	common	available165			sys_ni_syscall
+166	common	msgget				sys_msgget
+167	common	msgsnd				sys_msgsnd
+168	common	msgrcv				sys_msgrcv
+169	common	msgctl				sys_old_msgctl
+170	common	available170			sys_ni_syscall
+# File System
+171	common	umount2				sys_umount
+172	common	mount				sys_mount
+173	common	swapon				sys_swapon
+174	common	chroot				sys_chroot
+175	common	pivot_root			sys_pivot_root
+176	common	umount				sys_oldumount
+177	common	swapoff				sys_swapoff
+178	common	sync				sys_sync
+179	common	syncfs				sys_syncfs
+180	common	setfsuid			sys_setfsuid
+181	common	setfsgid			sys_setfsgid
+182	common	sysfs				sys_sysfs
+183	common	ustat				sys_ustat
+184	common	statfs				sys_statfs
+185	common	fstatfs				sys_fstatfs
+186	common	statfs64			sys_statfs64
+187	common	fstatfs64			sys_fstatfs64
+# System
+188	common	setrlimit			sys_setrlimit
+189	common	getrlimit			sys_getrlimit
+190	common	getrusage			sys_getrusage
+191	common	futex				sys_futex_time32
+192	common	gettimeofday			sys_gettimeofday
+193	common	settimeofday			sys_settimeofday
+194	common	adjtimex			sys_adjtimex_time32
+195	common	nanosleep			sys_nanosleep_time32
+196	common	getgroups			sys_getgroups
+197	common	setgroups			sys_setgroups
+198	common	sethostname			sys_sethostname
+199	common	setdomainname			sys_setdomainname
+200	common	syslog				sys_syslog
+201	common	vhangup				sys_vhangup
+202	common	uselib				sys_uselib
+203	common	reboot				sys_reboot
+204	common	quotactl			sys_quotactl
+# 205 was old nfsservctl
+205	common	nfsservctl			sys_ni_syscall
+206	common	_sysctl				sys_ni_syscall
+207	common	bdflush				sys_ni_syscall
+208	common	uname				sys_newuname
+209	common	sysinfo				sys_sysinfo
+210	common	init_module			sys_init_module
+211	common	delete_module			sys_delete_module
+212	common	sched_setparam			sys_sched_setparam
+213	common	sched_getparam			sys_sched_getparam
+214	common	sched_setscheduler		sys_sched_setscheduler
+215	common	sched_getscheduler		sys_sched_getscheduler
+216	common	sched_get_priority_max		sys_sched_get_priority_max
+217	common	sched_get_priority_min		sys_sched_get_priority_min
+218	common	sched_rr_get_interval		sys_sched_rr_get_interval_time32
+219	common	sched_yield			sys_sched_yield
+222	common	available222			sys_ni_syscall
+# Signal Handling
+223	common	restart_syscall			sys_restart_syscall
+224	common	sigaltstack			sys_sigaltstack
+225	common	rt_sigreturn			xtensa_rt_sigreturn
+226	common	rt_sigaction			sys_rt_sigaction
+227	common	rt_sigprocmask			sys_rt_sigprocmask
+228	common	rt_sigpending			sys_rt_sigpending
+229	common	rt_sigtimedwait			sys_rt_sigtimedwait_time32
+230	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+231	common	rt_sigsuspend			sys_rt_sigsuspend
+# Message
+232	common	mq_open				sys_mq_open
+233	common	mq_unlink			sys_mq_unlink
+234	common	mq_timedsend			sys_mq_timedsend_time32
+235	common	mq_timedreceive			sys_mq_timedreceive_time32
+236	common	mq_notify			sys_mq_notify
+237	common	mq_getsetattr			sys_mq_getsetattr
+238	common	available238			sys_ni_syscall
+239	common	io_setup			sys_io_setup
+# IO
+240	common	io_destroy			sys_io_destroy
+241	common	io_submit			sys_io_submit
+242	common	io_getevents			sys_io_getevents_time32
+243	common	io_cancel			sys_io_cancel
+244	common	clock_settime			sys_clock_settime32
+245	common	clock_gettime			sys_clock_gettime32
+246	common	clock_getres			sys_clock_getres_time32
+247	common	clock_nanosleep			sys_clock_nanosleep_time32
+# Timer
+248	common	timer_create			sys_timer_create
+249	common	timer_delete			sys_timer_delete
+250	common	timer_settime			sys_timer_settime32
+251	common	timer_gettime			sys_timer_gettime32
+252	common	timer_getoverrun		sys_timer_getoverrun
+# System
+253	common	reserved253			sys_ni_syscall
+254	common	lookup_dcookie			sys_ni_syscall
+255	common	available255			sys_ni_syscall
+256	common	add_key				sys_add_key
+257	common	request_key			sys_request_key
+258	common	keyctl				sys_keyctl
+259	common	available259			sys_ni_syscall
+260	common	readahead			sys_readahead
+261	common	remap_file_pages		sys_remap_file_pages
+262	common	migrate_pages			sys_migrate_pages
+263	common	mbind				sys_mbind
+264	common	get_mempolicy			sys_get_mempolicy
+265	common	set_mempolicy			sys_set_mempolicy
+266	common	unshare				sys_unshare
+267	common	move_pages			sys_move_pages
+268	common	splice				sys_splice
+269	common	tee				sys_tee
+270	common	vmsplice			sys_vmsplice
+271	common	available271			sys_ni_syscall
+272	common	pselect6			sys_pselect6_time32
+273	common	ppoll				sys_ppoll_time32
+274	common	epoll_pwait			sys_epoll_pwait
+275	common	epoll_create1			sys_epoll_create1
+276	common	inotify_init			sys_inotify_init
+277	common	inotify_add_watch		sys_inotify_add_watch
+278	common	inotify_rm_watch		sys_inotify_rm_watch
+279	common	inotify_init1			sys_inotify_init1
+280	common	getcpu				sys_getcpu
+281	common	kexec_load			sys_ni_syscall
+282	common	ioprio_set			sys_ioprio_set
+283	common	ioprio_get			sys_ioprio_get
+284	common	set_robust_list			sys_set_robust_list
+285	common	get_robust_list			sys_get_robust_list
+286	common	available286			sys_ni_syscall
+287	common	available287			sys_ni_syscall
+# Relative File Operations
+288	common	openat				sys_openat
+289	common	mkdirat				sys_mkdirat
+290	common	mknodat				sys_mknodat
+291	common	unlinkat			sys_unlinkat
+292	common	renameat			sys_renameat
+293	common	linkat				sys_linkat
+294	common	symlinkat			sys_symlinkat
+295	common	readlinkat			sys_readlinkat
+296	common	utimensat			sys_utimensat_time32
+297	common	fchownat			sys_fchownat
+298	common	futimesat			sys_futimesat_time32
+299	common	fstatat64			sys_fstatat64
+300	common	fchmodat			sys_fchmodat
+301	common	faccessat			sys_faccessat
+302	common	available302			sys_ni_syscall
+303	common	available303			sys_ni_syscall
+304	common	signalfd			sys_signalfd
+# 305 was timerfd
+306	common	eventfd				sys_eventfd
+307	common	recvmmsg			sys_recvmmsg_time32
+308	common	setns				sys_setns
+309	common	signalfd4			sys_signalfd4
+310	common	dup3				sys_dup3
+311	common	pipe2				sys_pipe2
+312	common	timerfd_create			sys_timerfd_create
+313	common	timerfd_settime			sys_timerfd_settime32
+314	common	timerfd_gettime			sys_timerfd_gettime32
+315	common	available315			sys_ni_syscall
+316	common	eventfd2			sys_eventfd2
+317	common	preadv				sys_preadv
+318	common	pwritev				sys_pwritev
+319	common	available319			sys_ni_syscall
+320	common	fanotify_init			sys_fanotify_init
+321	common	fanotify_mark			sys_fanotify_mark
+322	common	process_vm_readv		sys_process_vm_readv
+323	common	process_vm_writev		sys_process_vm_writev
+324	common	name_to_handle_at		sys_name_to_handle_at
+325	common	open_by_handle_at		sys_open_by_handle_at
+326	common	sync_file_range2		sys_sync_file_range2
+327	common	perf_event_open			sys_perf_event_open
+328	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+329	common	clock_adjtime			sys_clock_adjtime32
+330	common	prlimit64			sys_prlimit64
+331	common	kcmp				sys_kcmp
+332	common	finit_module			sys_finit_module
+333	common	accept4				sys_accept4
+334	common	sched_setattr			sys_sched_setattr
+335	common	sched_getattr			sys_sched_getattr
+336	common	renameat2			sys_renameat2
+337	common	seccomp				sys_seccomp
+338	common	getrandom			sys_getrandom
+339	common	memfd_create			sys_memfd_create
+340	common	bpf				sys_bpf
+341	common	execveat			sys_execveat
+342	common	userfaultfd			sys_userfaultfd
+343	common	membarrier			sys_membarrier
+344	common	mlock2				sys_mlock2
+345	common	copy_file_range			sys_copy_file_range
+346	common	preadv2				sys_preadv2
+347	common	pwritev2			sys_pwritev2
+348	common	pkey_mprotect			sys_pkey_mprotect
+349	common	pkey_alloc			sys_pkey_alloc
+350	common	pkey_free			sys_pkey_free
+351	common	statx				sys_statx
+352	common	rseq				sys_rseq
+# 353 through 402 are unassigned to sync up with generic numbers
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6
+414	common	ppoll_time64			sys_ppoll
+416	common	io_pgetevents_time64		sys_io_pgetevents
+417	common	recvmmsg_time64			sys_recvmmsg
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common  futex_waitv                     sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal 				sys_mseal
diff --git a/tools/perf/arch/xtensa/include/syscall_table.h b/tools/perf/arch/xtensa/include/syscall_table.h
new file mode 100644
index 000000000000..4c942821662d
--- /dev/null
+++ b/tools/perf/arch/xtensa/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_32.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 99a278a3f1b5..e9e352579e6d 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -205,6 +205,7 @@ check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/sys
 check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tbl
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:10 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:10 -0800
Subject: [PATCH RFT 08/16] perf tools: x86: Use generic syscall scripts
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-8-9adae5c761ef@rivosinc.com>

Use the generic scripts to generate headers from the syscall table for
both 32- and 64-bit x86.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  4 +--
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/x86/Build                          |  1 -
 tools/perf/arch/x86/Makefile                       | 25 -------------
 tools/perf/arch/x86/entry/syscalls/Kbuild          |  3 ++
 .../perf/arch/x86/entry/syscalls/Makefile.syscalls |  6 ++++
 tools/perf/arch/x86/entry/syscalls/syscalltbl.sh   | 42 ----------------------
 tools/perf/arch/x86/include/syscall_table.h        |  8 +++++
 tools/perf/util/syscalltbl.c                       | 10 +-----
 9 files changed, 21 insertions(+), 80 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 1894db7845d4..682354d2d4ec 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 powerpc arm64 s390 mips loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips loongarch))
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index bcbb83e0f9fd..b45e3ec8947b 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/x86/Build b/tools/perf/arch/x86/Build
index 87d057491343..02a1ca780a20 100644
--- a/tools/perf/arch/x86/Build
+++ b/tools/perf/arch/x86/Build
@@ -2,7 +2,6 @@ perf-util-y += util/
 perf-test-y += tests/
 
 ifdef SHELLCHECK
-  SHELL_TESTS := entry/syscalls/syscalltbl.sh
   TEST_LOGS := $(SHELL_TESTS:%=%.shellcheck_log)
 else
   SHELL_TESTS :=
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index 67b4969a6738..5277d5aeb079 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -5,28 +5,3 @@ endif
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 PERF_HAVE_JITDUMP := 1
-
-###
-# Syscall table generation
-#
-
-generated := $(OUTPUT)arch/x86/include/generated
-out       := $(generated)/asm
-header    := $(out)/syscalls_64.c
-header_32 := $(out)/syscalls_32.c
-sys       := $(srctree)/tools/perf/arch/x86/entry/syscalls
-systbl    := $(sys)/syscalltbl.sh
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sys)/syscall_64.tbl $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
-
-$(header_32): $(sys)/syscall_32.tbl $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sys)/syscall_32.tbl 'x86' > $@
-
-clean::
-	$(call QUIET_CLEAN, x86) $(RM) -r $(header) $(generated)
-
-archheaders: $(header) $(header_32)
diff --git a/tools/perf/arch/x86/entry/syscalls/Kbuild b/tools/perf/arch/x86/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..84c6599b4ea6
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls b/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..db3d5d6d4e56
--- /dev/null
+++ b/tools/perf/arch/x86/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += i386
+syscall_abis_64 +=
+
+syscalltbl = $(srctree)/tools/perf/arch/x86/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh b/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
deleted file mode 100755
index 2b71f99933a5..000000000000
--- a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-in="$1"
-arch="$2"
-
-syscall_macro() {
-    nr="$1"
-    name="$2"
-
-    echo "	[$nr] = \"$name\","
-}
-
-emit() {
-    nr="$1"
-    entry="$2"
-
-    syscall_macro "$nr" "$entry"
-}
-
-echo "static const char *const syscalltbl_${arch}[] = {"
-
-sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
-grep '^[0-9]' "$in" | sort -n > $sorted_table
-
-max_nr=0
-# the params are: nr abi name entry compat
-# use _ for intentionally unused variables according to SC2034
-while read nr _ name _ _; do
-    if [ $nr -ge 512 ] ; then # discard compat sycalls
-        break
-    fi
-
-    emit "$nr" "$name"
-    max_nr=$nr
-done < $sorted_table
-
-rm -f $sorted_table
-
-echo "};"
-
-echo "#define SYSCALLTBL_${arch}_MAX_ID ${max_nr}"
diff --git a/tools/perf/arch/x86/include/syscall_table.h b/tools/perf/arch/x86/include/syscall_table.h
new file mode 100644
index 000000000000..7ff51b783000
--- /dev/null
+++ b/tools/perf/arch/x86/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 229183e5c55f..094f6d4fffdd 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -13,15 +13,7 @@
 #include <string.h>
 #include "string2.h"
 
-#if defined(__x86_64__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_x86_64;
-#elif defined(__i386__)
-#include <asm/syscalls_32.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_x86_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_x86;
-#elif defined(__s390x__)
+#if defined(__s390x__)
 #include <asm/syscalls_64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_s390_64;

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:11 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:11 -0800
Subject: [PATCH RFT 09/16] perf tools: alpha: Support syscall header
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-9-9adae5c761ef@rivosinc.com>

alpha uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/alpha/entry/syscalls/Kbuild        |   2 +
 .../arch/alpha/entry/syscalls/Makefile.syscalls    |   5 +
 tools/perf/arch/alpha/entry/syscalls/syscall.tbl   | 504 +++++++++++++++++++++
 tools/perf/arch/alpha/include/syscall_table.h      |   2 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 516 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 682354d2d4ec..71cb7390c66a 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index b45e3ec8947b..6a972ef1685d 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/alpha/entry/syscalls/Kbuild b/tools/perf/arch/alpha/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..9a41e3572c3a
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls b/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..690168aac34d
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64  +=
+
+syscalltbl = $(srctree)/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/alpha/entry/syscalls/syscall.tbl b/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
new file mode 100644
index 000000000000..74720667fe09
--- /dev/null
+++ b/tools/perf/arch/alpha/entry/syscalls/syscall.tbl
@@ -0,0 +1,504 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for alpha
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "common" for this file
+#
+0	common	osf_syscall			alpha_syscall_zero
+1	common	exit				sys_exit
+2	common	fork				alpha_fork
+3	common	read				sys_read
+4	common	write				sys_write
+5	common	osf_old_open			sys_ni_syscall
+6	common	close				sys_close
+7	common	osf_wait4			sys_osf_wait4
+8	common	osf_old_creat			sys_ni_syscall
+9	common	link				sys_link
+10	common	unlink				sys_unlink
+11	common	osf_execve			sys_ni_syscall
+12	common	chdir				sys_chdir
+13	common	fchdir				sys_fchdir
+14	common	mknod				sys_mknod
+15	common	chmod				sys_chmod
+16	common	chown				sys_chown
+17	common	brk				sys_osf_brk
+18	common	osf_getfsstat			sys_ni_syscall
+19	common	lseek				sys_lseek
+20	common	getxpid				sys_getxpid
+21	common	osf_mount			sys_osf_mount
+22	common	umount2				sys_umount
+23	common	setuid				sys_setuid
+24	common	getxuid				sys_getxuid
+25	common	exec_with_loader		sys_ni_syscall
+26	common	ptrace				sys_ptrace
+27	common	osf_nrecvmsg			sys_ni_syscall
+28	common	osf_nsendmsg			sys_ni_syscall
+29	common	osf_nrecvfrom			sys_ni_syscall
+30	common	osf_naccept			sys_ni_syscall
+31	common	osf_ngetpeername		sys_ni_syscall
+32	common	osf_ngetsockname		sys_ni_syscall
+33	common	access				sys_access
+34	common	osf_chflags			sys_ni_syscall
+35	common	osf_fchflags			sys_ni_syscall
+36	common	sync				sys_sync
+37	common	kill				sys_kill
+38	common	osf_old_stat			sys_ni_syscall
+39	common	setpgid				sys_setpgid
+40	common	osf_old_lstat			sys_ni_syscall
+41	common	dup				sys_dup
+42	common	pipe				sys_alpha_pipe
+43	common	osf_set_program_attributes	sys_osf_set_program_attributes
+44	common	osf_profil			sys_ni_syscall
+45	common	open				sys_open
+46	common	osf_old_sigaction		sys_ni_syscall
+47	common	getxgid				sys_getxgid
+48	common	osf_sigprocmask			sys_osf_sigprocmask
+49	common	osf_getlogin			sys_ni_syscall
+50	common	osf_setlogin			sys_ni_syscall
+51	common	acct				sys_acct
+52	common	sigpending			sys_sigpending
+54	common	ioctl				sys_ioctl
+55	common	osf_reboot			sys_ni_syscall
+56	common	osf_revoke			sys_ni_syscall
+57	common	symlink				sys_symlink
+58	common	readlink			sys_readlink
+59	common	execve				sys_execve
+60	common	umask				sys_umask
+61	common	chroot				sys_chroot
+62	common	osf_old_fstat			sys_ni_syscall
+63	common	getpgrp				sys_getpgrp
+64	common	getpagesize			sys_getpagesize
+65	common	osf_mremap			sys_ni_syscall
+66	common	vfork				alpha_vfork
+67	common	stat				sys_newstat
+68	common	lstat				sys_newlstat
+69	common	osf_sbrk			sys_ni_syscall
+70	common	osf_sstk			sys_ni_syscall
+71	common	mmap				sys_osf_mmap
+72	common	osf_old_vadvise			sys_ni_syscall
+73	common	munmap				sys_munmap
+74	common	mprotect			sys_mprotect
+75	common	madvise				sys_madvise
+76	common	vhangup				sys_vhangup
+77	common	osf_kmodcall			sys_ni_syscall
+78	common	osf_mincore			sys_ni_syscall
+79	common	getgroups			sys_getgroups
+80	common	setgroups			sys_setgroups
+81	common	osf_old_getpgrp			sys_ni_syscall
+82	common	setpgrp				sys_setpgid
+83	common	osf_setitimer			compat_sys_setitimer
+84	common	osf_old_wait			sys_ni_syscall
+85	common	osf_table			sys_ni_syscall
+86	common	osf_getitimer			compat_sys_getitimer
+87	common	gethostname			sys_gethostname
+88	common	sethostname			sys_sethostname
+89	common	getdtablesize			sys_getdtablesize
+90	common	dup2				sys_dup2
+91	common	fstat				sys_newfstat
+92	common	fcntl				sys_fcntl
+93	common	osf_select			sys_osf_select
+94	common	poll				sys_poll
+95	common	fsync				sys_fsync
+96	common	setpriority			sys_setpriority
+97	common	socket				sys_socket
+98	common	connect				sys_connect
+99	common	accept				sys_accept
+100	common	getpriority			sys_osf_getpriority
+101	common	send				sys_send
+102	common	recv				sys_recv
+103	common	sigreturn			sys_sigreturn
+104	common	bind				sys_bind
+105	common	setsockopt			sys_setsockopt
+106	common	listen				sys_listen
+107	common	osf_plock			sys_ni_syscall
+108	common	osf_old_sigvec			sys_ni_syscall
+109	common	osf_old_sigblock		sys_ni_syscall
+110	common	osf_old_sigsetmask		sys_ni_syscall
+111	common	sigsuspend			sys_sigsuspend
+112	common	osf_sigstack			sys_osf_sigstack
+113	common	recvmsg				sys_recvmsg
+114	common	sendmsg				sys_sendmsg
+115	common	osf_old_vtrace			sys_ni_syscall
+116	common	osf_gettimeofday		sys_osf_gettimeofday
+117	common	osf_getrusage			sys_osf_getrusage
+118	common	getsockopt			sys_getsockopt
+120	common	readv				sys_readv
+121	common	writev				sys_writev
+122	common	osf_settimeofday		sys_osf_settimeofday
+123	common	fchown				sys_fchown
+124	common	fchmod				sys_fchmod
+125	common	recvfrom			sys_recvfrom
+126	common	setreuid			sys_setreuid
+127	common	setregid			sys_setregid
+128	common	rename				sys_rename
+129	common	truncate			sys_truncate
+130	common	ftruncate			sys_ftruncate
+131	common	flock				sys_flock
+132	common	setgid				sys_setgid
+133	common	sendto				sys_sendto
+134	common	shutdown			sys_shutdown
+135	common	socketpair			sys_socketpair
+136	common	mkdir				sys_mkdir
+137	common	rmdir				sys_rmdir
+138	common	osf_utimes			sys_osf_utimes
+139	common	osf_old_sigreturn		sys_ni_syscall
+140	common	osf_adjtime			sys_ni_syscall
+141	common	getpeername			sys_getpeername
+142	common	osf_gethostid			sys_ni_syscall
+143	common	osf_sethostid			sys_ni_syscall
+144	common	getrlimit			sys_getrlimit
+145	common	setrlimit			sys_setrlimit
+146	common	osf_old_killpg			sys_ni_syscall
+147	common	setsid				sys_setsid
+148	common	quotactl			sys_quotactl
+149	common	osf_oldquota			sys_ni_syscall
+150	common	getsockname			sys_getsockname
+153	common	osf_pid_block			sys_ni_syscall
+154	common	osf_pid_unblock			sys_ni_syscall
+156	common	sigaction			sys_osf_sigaction
+157	common	osf_sigwaitprim			sys_ni_syscall
+158	common	osf_nfssvc			sys_ni_syscall
+159	common	osf_getdirentries		sys_osf_getdirentries
+160	common	osf_statfs			sys_osf_statfs
+161	common	osf_fstatfs			sys_osf_fstatfs
+163	common	osf_asynch_daemon		sys_ni_syscall
+164	common	osf_getfh			sys_ni_syscall
+165	common	osf_getdomainname		sys_osf_getdomainname
+166	common	setdomainname			sys_setdomainname
+169	common	osf_exportfs			sys_ni_syscall
+181	common	osf_alt_plock			sys_ni_syscall
+184	common	osf_getmnt			sys_ni_syscall
+187	common	osf_alt_sigpending		sys_ni_syscall
+188	common	osf_alt_setsid			sys_ni_syscall
+199	common	osf_swapon			sys_swapon
+200	common	msgctl				sys_old_msgctl
+201	common	msgget				sys_msgget
+202	common	msgrcv				sys_msgrcv
+203	common	msgsnd				sys_msgsnd
+204	common	semctl				sys_old_semctl
+205	common	semget				sys_semget
+206	common	semop				sys_semop
+207	common	osf_utsname			sys_osf_utsname
+208	common	lchown				sys_lchown
+209	common	shmat				sys_shmat
+210	common	shmctl				sys_old_shmctl
+211	common	shmdt				sys_shmdt
+212	common	shmget				sys_shmget
+213	common	osf_mvalid			sys_ni_syscall
+214	common	osf_getaddressconf		sys_ni_syscall
+215	common	osf_msleep			sys_ni_syscall
+216	common	osf_mwakeup			sys_ni_syscall
+217	common	msync				sys_msync
+218	common	osf_signal			sys_ni_syscall
+219	common	osf_utc_gettime			sys_ni_syscall
+220	common	osf_utc_adjtime			sys_ni_syscall
+222	common	osf_security			sys_ni_syscall
+223	common	osf_kloadcall			sys_ni_syscall
+224	common	osf_stat			sys_osf_stat
+225	common	osf_lstat			sys_osf_lstat
+226	common	osf_fstat			sys_osf_fstat
+227	common	osf_statfs64			sys_osf_statfs64
+228	common	osf_fstatfs64			sys_osf_fstatfs64
+233	common	getpgid				sys_getpgid
+234	common	getsid				sys_getsid
+235	common	sigaltstack			sys_sigaltstack
+236	common	osf_waitid			sys_ni_syscall
+237	common	osf_priocntlset			sys_ni_syscall
+238	common	osf_sigsendset			sys_ni_syscall
+239	common	osf_set_speculative		sys_ni_syscall
+240	common	osf_msfs_syscall		sys_ni_syscall
+241	common	osf_sysinfo			sys_osf_sysinfo
+242	common	osf_uadmin			sys_ni_syscall
+243	common	osf_fuser			sys_ni_syscall
+244	common	osf_proplist_syscall		sys_osf_proplist_syscall
+245	common	osf_ntp_adjtime			sys_ni_syscall
+246	common	osf_ntp_gettime			sys_ni_syscall
+247	common	osf_pathconf			sys_ni_syscall
+248	common	osf_fpathconf			sys_ni_syscall
+250	common	osf_uswitch			sys_ni_syscall
+251	common	osf_usleep_thread		sys_osf_usleep_thread
+252	common	osf_audcntl			sys_ni_syscall
+253	common	osf_audgen			sys_ni_syscall
+254	common	sysfs				sys_sysfs
+255	common	osf_subsys_info			sys_ni_syscall
+256	common	osf_getsysinfo			sys_osf_getsysinfo
+257	common	osf_setsysinfo			sys_osf_setsysinfo
+258	common	osf_afs_syscall			sys_ni_syscall
+259	common	osf_swapctl			sys_ni_syscall
+260	common	osf_memcntl			sys_ni_syscall
+261	common	osf_fdatasync			sys_ni_syscall
+300	common	bdflush				sys_ni_syscall
+301	common	sethae				sys_sethae
+302	common	mount				sys_mount
+303	common	old_adjtimex			sys_old_adjtimex
+304	common	swapoff				sys_swapoff
+305	common	getdents			sys_getdents
+306	common	create_module			sys_ni_syscall
+307	common	init_module			sys_init_module
+308	common	delete_module			sys_delete_module
+309	common	get_kernel_syms			sys_ni_syscall
+310	common	syslog				sys_syslog
+311	common	reboot				sys_reboot
+312	common	clone				alpha_clone
+313	common	uselib				sys_uselib
+314	common	mlock				sys_mlock
+315	common	munlock				sys_munlock
+316	common	mlockall			sys_mlockall
+317	common	munlockall			sys_munlockall
+318	common	sysinfo				sys_sysinfo
+319	common	_sysctl				sys_ni_syscall
+# 320 was sys_idle
+321	common	oldumount			sys_oldumount
+322	common	swapon				sys_swapon
+323	common	times				sys_times
+324	common	personality			sys_personality
+325	common	setfsuid			sys_setfsuid
+326	common	setfsgid			sys_setfsgid
+327	common	ustat				sys_ustat
+328	common	statfs				sys_statfs
+329	common	fstatfs				sys_fstatfs
+330	common	sched_setparam			sys_sched_setparam
+331	common	sched_getparam			sys_sched_getparam
+332	common	sched_setscheduler		sys_sched_setscheduler
+333	common	sched_getscheduler		sys_sched_getscheduler
+334	common	sched_yield			sys_sched_yield
+335	common	sched_get_priority_max		sys_sched_get_priority_max
+336	common	sched_get_priority_min		sys_sched_get_priority_min
+337	common	sched_rr_get_interval		sys_sched_rr_get_interval
+338	common	afs_syscall			sys_ni_syscall
+339	common	uname				sys_newuname
+340	common	nanosleep			sys_nanosleep
+341	common	mremap				sys_mremap
+342	common	nfsservctl			sys_ni_syscall
+343	common	setresuid			sys_setresuid
+344	common	getresuid			sys_getresuid
+345	common	pciconfig_read			sys_pciconfig_read
+346	common	pciconfig_write			sys_pciconfig_write
+347	common	query_module			sys_ni_syscall
+348	common	prctl				sys_prctl
+349	common	pread64				sys_pread64
+350	common	pwrite64			sys_pwrite64
+351	common	rt_sigreturn			sys_rt_sigreturn
+352	common	rt_sigaction			sys_rt_sigaction
+353	common	rt_sigprocmask			sys_rt_sigprocmask
+354	common	rt_sigpending			sys_rt_sigpending
+355	common	rt_sigtimedwait			sys_rt_sigtimedwait
+356	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
+357	common	rt_sigsuspend			sys_rt_sigsuspend
+358	common	select				sys_select
+359	common	gettimeofday			sys_gettimeofday
+360	common	settimeofday			sys_settimeofday
+361	common	getitimer			sys_getitimer
+362	common	setitimer			sys_setitimer
+363	common	utimes				sys_utimes
+364	common	getrusage			sys_getrusage
+365	common	wait4				sys_wait4
+366	common	adjtimex			sys_adjtimex
+367	common	getcwd				sys_getcwd
+368	common	capget				sys_capget
+369	common	capset				sys_capset
+370	common	sendfile			sys_sendfile64
+371	common	setresgid			sys_setresgid
+372	common	getresgid			sys_getresgid
+373	common	dipc				sys_ni_syscall
+374	common	pivot_root			sys_pivot_root
+375	common	mincore				sys_mincore
+376	common	pciconfig_iobase		sys_pciconfig_iobase
+377	common	getdents64			sys_getdents64
+378	common	gettid				sys_gettid
+379	common	readahead			sys_readahead
+# 380 is unused
+381	common	tkill				sys_tkill
+382	common	setxattr			sys_setxattr
+383	common	lsetxattr			sys_lsetxattr
+384	common	fsetxattr			sys_fsetxattr
+385	common	getxattr			sys_getxattr
+386	common	lgetxattr			sys_lgetxattr
+387	common	fgetxattr			sys_fgetxattr
+388	common	listxattr			sys_listxattr
+389	common	llistxattr			sys_llistxattr
+390	common	flistxattr			sys_flistxattr
+391	common	removexattr			sys_removexattr
+392	common	lremovexattr			sys_lremovexattr
+393	common	fremovexattr			sys_fremovexattr
+394	common	futex				sys_futex
+395	common	sched_setaffinity		sys_sched_setaffinity
+396	common	sched_getaffinity		sys_sched_getaffinity
+397	common	tuxcall				sys_ni_syscall
+398	common	io_setup			sys_io_setup
+399	common	io_destroy			sys_io_destroy
+400	common	io_getevents			sys_io_getevents
+401	common	io_submit			sys_io_submit
+402	common	io_cancel			sys_io_cancel
+405	common	exit_group			sys_exit_group
+406	common	lookup_dcookie			sys_ni_syscall
+407	common	epoll_create			sys_epoll_create
+408	common	epoll_ctl			sys_epoll_ctl
+409	common	epoll_wait			sys_epoll_wait
+410	common	remap_file_pages		sys_remap_file_pages
+411	common	set_tid_address			sys_set_tid_address
+412	common	restart_syscall			sys_restart_syscall
+413	common	fadvise64			sys_fadvise64
+414	common	timer_create			sys_timer_create
+415	common	timer_settime			sys_timer_settime
+416	common	timer_gettime			sys_timer_gettime
+417	common	timer_getoverrun		sys_timer_getoverrun
+418	common	timer_delete			sys_timer_delete
+419	common	clock_settime			sys_clock_settime
+420	common	clock_gettime			sys_clock_gettime
+421	common	clock_getres			sys_clock_getres
+422	common	clock_nanosleep			sys_clock_nanosleep
+423	common	semtimedop			sys_semtimedop
+424	common	tgkill				sys_tgkill
+425	common	stat64				sys_stat64
+426	common	lstat64				sys_lstat64
+427	common	fstat64				sys_fstat64
+428	common	vserver				sys_ni_syscall
+429	common	mbind				sys_ni_syscall
+430	common	get_mempolicy			sys_ni_syscall
+431	common	set_mempolicy			sys_ni_syscall
+432	common	mq_open				sys_mq_open
+433	common	mq_unlink			sys_mq_unlink
+434	common	mq_timedsend			sys_mq_timedsend
+435	common	mq_timedreceive			sys_mq_timedreceive
+436	common	mq_notify			sys_mq_notify
+437	common	mq_getsetattr			sys_mq_getsetattr
+438	common	waitid				sys_waitid
+439	common	add_key				sys_add_key
+440	common	request_key			sys_request_key
+441	common	keyctl				sys_keyctl
+442	common	ioprio_set			sys_ioprio_set
+443	common	ioprio_get			sys_ioprio_get
+444	common	inotify_init			sys_inotify_init
+445	common	inotify_add_watch		sys_inotify_add_watch
+446	common	inotify_rm_watch		sys_inotify_rm_watch
+447	common	fdatasync			sys_fdatasync
+448	common	kexec_load			sys_kexec_load
+449	common	migrate_pages			sys_migrate_pages
+450	common	openat				sys_openat
+451	common	mkdirat				sys_mkdirat
+452	common	mknodat				sys_mknodat
+453	common	fchownat			sys_fchownat
+454	common	futimesat			sys_futimesat
+455	common	fstatat64			sys_fstatat64
+456	common	unlinkat			sys_unlinkat
+457	common	renameat			sys_renameat
+458	common	linkat				sys_linkat
+459	common	symlinkat			sys_symlinkat
+460	common	readlinkat			sys_readlinkat
+461	common	fchmodat			sys_fchmodat
+462	common	faccessat			sys_faccessat
+463	common	pselect6			sys_pselect6
+464	common	ppoll				sys_ppoll
+465	common	unshare				sys_unshare
+466	common	set_robust_list			sys_set_robust_list
+467	common	get_robust_list			sys_get_robust_list
+468	common	splice				sys_splice
+469	common	sync_file_range			sys_sync_file_range
+470	common	tee				sys_tee
+471	common	vmsplice			sys_vmsplice
+472	common	move_pages			sys_move_pages
+473	common	getcpu				sys_getcpu
+474	common	epoll_pwait			sys_epoll_pwait
+475	common	utimensat			sys_utimensat
+476	common	signalfd			sys_signalfd
+477	common	timerfd				sys_ni_syscall
+478	common	eventfd				sys_eventfd
+479	common	recvmmsg			sys_recvmmsg
+480	common	fallocate			sys_fallocate
+481	common	timerfd_create			sys_timerfd_create
+482	common	timerfd_settime			sys_timerfd_settime
+483	common	timerfd_gettime			sys_timerfd_gettime
+484	common	signalfd4			sys_signalfd4
+485	common	eventfd2			sys_eventfd2
+486	common	epoll_create1			sys_epoll_create1
+487	common	dup3				sys_dup3
+488	common	pipe2				sys_pipe2
+489	common	inotify_init1			sys_inotify_init1
+490	common	preadv				sys_preadv
+491	common	pwritev				sys_pwritev
+492	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
+493	common	perf_event_open			sys_perf_event_open
+494	common	fanotify_init			sys_fanotify_init
+495	common	fanotify_mark			sys_fanotify_mark
+496	common	prlimit64			sys_prlimit64
+497	common	name_to_handle_at		sys_name_to_handle_at
+498	common	open_by_handle_at		sys_open_by_handle_at
+499	common	clock_adjtime			sys_clock_adjtime
+500	common	syncfs				sys_syncfs
+501	common	setns				sys_setns
+502	common	accept4				sys_accept4
+503	common	sendmmsg			sys_sendmmsg
+504	common	process_vm_readv		sys_process_vm_readv
+505	common	process_vm_writev		sys_process_vm_writev
+506	common	kcmp				sys_kcmp
+507	common	finit_module			sys_finit_module
+508	common	sched_setattr			sys_sched_setattr
+509	common	sched_getattr			sys_sched_getattr
+510	common	renameat2			sys_renameat2
+511	common	getrandom			sys_getrandom
+512	common	memfd_create			sys_memfd_create
+513	common	execveat			sys_execveat
+514	common	seccomp				sys_seccomp
+515	common	bpf				sys_bpf
+516	common	userfaultfd			sys_userfaultfd
+517	common	membarrier			sys_membarrier
+518	common	mlock2				sys_mlock2
+519	common	copy_file_range			sys_copy_file_range
+520	common	preadv2				sys_preadv2
+521	common	pwritev2			sys_pwritev2
+522	common	statx				sys_statx
+523	common	io_pgetevents			sys_io_pgetevents
+524	common	pkey_mprotect			sys_pkey_mprotect
+525	common	pkey_alloc			sys_pkey_alloc
+526	common	pkey_free			sys_pkey_free
+527	common	rseq				sys_rseq
+528	common	statfs64			sys_statfs64
+529	common	fstatfs64			sys_fstatfs64
+530	common	getegid				sys_getegid
+531	common	geteuid				sys_geteuid
+532	common	getppid				sys_getppid
+# all other architectures have common numbers for new syscall, alpha
+# is the exception.
+534	common	pidfd_send_signal		sys_pidfd_send_signal
+535	common	io_uring_setup			sys_io_uring_setup
+536	common	io_uring_enter			sys_io_uring_enter
+537	common	io_uring_register		sys_io_uring_register
+538	common	open_tree			sys_open_tree
+539	common	move_mount			sys_move_mount
+540	common	fsopen				sys_fsopen
+541	common	fsconfig			sys_fsconfig
+542	common	fsmount				sys_fsmount
+543	common	fspick				sys_fspick
+544	common	pidfd_open			sys_pidfd_open
+545	common	clone3				alpha_clone3
+546	common	close_range			sys_close_range
+547	common	openat2				sys_openat2
+548	common	pidfd_getfd			sys_pidfd_getfd
+549	common	faccessat2			sys_faccessat2
+550	common	process_madvise			sys_process_madvise
+551	common	epoll_pwait2			sys_epoll_pwait2
+552	common	mount_setattr			sys_mount_setattr
+553	common	quotactl_fd			sys_quotactl_fd
+554	common	landlock_create_ruleset		sys_landlock_create_ruleset
+555	common	landlock_add_rule		sys_landlock_add_rule
+556	common	landlock_restrict_self		sys_landlock_restrict_self
+# 557 reserved for memfd_secret
+558	common	process_mrelease		sys_process_mrelease
+559	common  futex_waitv                     sys_futex_waitv
+560	common	set_mempolicy_home_node		sys_ni_syscall
+561	common	cachestat			sys_cachestat
+562	common	fchmodat2			sys_fchmodat2
+563	common	map_shadow_stack		sys_map_shadow_stack
+564	common	futex_wake			sys_futex_wake
+565	common	futex_wait			sys_futex_wait
+566	common	futex_requeue			sys_futex_requeue
+567	common	statmount			sys_statmount
+568	common	listmount			sys_listmount
+569	common	lsm_get_self_attr		sys_lsm_get_self_attr
+570	common	lsm_set_self_attr		sys_lsm_set_self_attr
+571	common	lsm_list_modules		sys_lsm_list_modules
+572	common  mseal				sys_mseal
diff --git a/tools/perf/arch/alpha/include/syscall_table.h b/tools/perf/arch/alpha/include/syscall_table.h
new file mode 100644
index 000000000000..b53e31c15805
--- /dev/null
+++ b/tools/perf/arch/alpha/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index e9e352579e6d..a821df1fd4c0 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -206,6 +206,7 @@ check_2 tools/perf/arch/arm/entry/syscalls/syscall.tbl arch/arm/tools/syscall.tb
 check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:12 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:12 -0800
Subject: [PATCH RFT 10/16] perf tools: parisc: Support syscall header
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-10-9adae5c761ef@rivosinc.com>

parisc uses a syscall table, use that in perf instead of requiring
libaudit.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   2 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/parisc/entry/syscalls/Kbuild       |   3 +
 .../arch/parisc/entry/syscalls/Makefile.syscalls   |   6 +
 tools/perf/arch/parisc/entry/syscalls/syscall.tbl  | 463 +++++++++++++++++++++
 tools/perf/arch/parisc/include/syscall_table.h     |   8 +
 tools/perf/check-headers.sh                        |   1 +
 7 files changed, 483 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 71cb7390c66a..925d3a10893a 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -36,7 +36,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 6a972ef1685d..b92500bf22fb 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/parisc/entry/syscalls/Kbuild b/tools/perf/arch/parisc/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..84c6599b4ea6
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..ae326fecb83b
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32  +=
+syscall_abis_64  +=
+
+syscalltbl = $(srctree)/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/parisc/entry/syscalls/syscall.tbl b/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
new file mode 100644
index 000000000000..66dc406b12e4
--- /dev/null
+++ b/tools/perf/arch/parisc/entry/syscalls/syscall.tbl
@@ -0,0 +1,463 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for parisc
+#
+# The format is:
+# <number> <abi> <name> <entry point> <compat entry point>
+#
+# The <abi> can be common, 64, or 32 for this file.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork_wrapper
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open			compat_sys_open
+6	common	close			sys_close
+7	common	waitpid			sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve			compat_sys_execve
+12	common	chdir			sys_chdir
+13	32	time			sys_time32
+13	64	time			sys_time
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown
+17	common	socket			sys_socket
+18	common	stat			sys_newstat			compat_sys_newstat
+19	common	lseek			sys_lseek			compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+22	common	bind			sys_bind
+23	common	setuid			sys_setuid
+24	common	getuid			sys_getuid
+25	32	stime			sys_stime32
+25	64	stime			sys_stime
+26	common	ptrace			sys_ptrace			compat_sys_ptrace
+27	common	alarm			sys_alarm
+28	common	fstat			sys_newfstat			compat_sys_newfstat
+29	common	pause			sys_pause
+30	32	utime			sys_utime32
+30	64	utime			sys_utime
+31	common	connect			sys_connect
+32	common	listen			sys_listen
+33	common	access			sys_access
+34	common	nice			sys_nice
+35	common	accept			sys_accept
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times			compat_sys_times
+44	common	getsockname		sys_getsockname
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid
+47	common	getgid			sys_getgid
+48	common	signal			sys_signal
+49	common	geteuid			sys_geteuid
+50	common	getegid			sys_getegid
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+53	common	getpeername		sys_getpeername
+54	common	ioctl			sys_ioctl			compat_sys_ioctl
+55	common	fcntl			sys_fcntl			compat_sys_fcntl
+56	common	socketpair		sys_socketpair
+57	common	setpgid			sys_setpgid
+58	common	send			sys_send
+59	common	uname			sys_newuname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat			compat_sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	pivot_root		sys_pivot_root
+68	common	sgetmask		sys_sgetmask			sys32_unimplemented
+69	common	ssetmask		sys_ssetmask			sys32_unimplemented
+70	common	setreuid		sys_setreuid
+71	common	setregid		sys_setregid
+72	common	mincore			sys_mincore
+73	common	sigpending		sys_sigpending			compat_sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit			compat_sys_setrlimit
+76	common	getrlimit		sys_getrlimit			compat_sys_getrlimit
+77	common	getrusage		sys_getrusage			compat_sys_getrusage
+78	common	gettimeofday		sys_gettimeofday		compat_sys_gettimeofday
+79	common	settimeofday		sys_settimeofday		compat_sys_settimeofday
+80	common	getgroups		sys_getgroups
+81	common	setgroups		sys_setgroups
+82	common	sendto			sys_sendto
+83	common	symlink			sys_symlink
+84	common	lstat			sys_newlstat			compat_sys_newlstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_ni_syscall
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+89	common	mmap2			sys_mmap2
+90	common	mmap			sys_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate			compat_sys_truncate
+93	common	ftruncate		sys_ftruncate			compat_sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+98	common	recv			sys_recv			compat_sys_recv
+99	common	statfs			sys_statfs			compat_sys_statfs
+100	common	fstatfs			sys_fstatfs			compat_sys_fstatfs
+101	common	stat64			sys_stat64
+# 102 was socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer			compat_sys_setitimer
+105	common	getitimer		sys_getitimer			compat_sys_getitimer
+106	common	capget			sys_capget
+107	common	capset			sys_capset
+108	32	pread64			parisc_pread64
+108	64	pread64			sys_pread64
+109	32	pwrite64		parisc_pwrite64
+109	64	pwrite64		sys_pwrite64
+110	common	getcwd			sys_getcwd
+111	common	vhangup			sys_vhangup
+112	common	fstat64			sys_fstat64
+113	common	vfork			sys_vfork_wrapper
+114	common	wait4			sys_wait4			compat_sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo			compat_sys_sysinfo
+117	common	shutdown		sys_shutdown
+118	common	fsync			sys_fsync
+119	common	madvise			parisc_madvise
+120	common	clone			sys_clone_wrapper
+121	common	setdomainname		sys_setdomainname
+122	common	sendfile		sys_sendfile			compat_sys_sendfile
+123	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
+124	32	adjtimex		sys_adjtimex_time32
+124	64	adjtimex		sys_adjtimex
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask			compat_sys_sigprocmask
+# 127 was create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	32	personality		parisc_personality
+136	64	personality		sys_personality
+# 137 was afs_syscall
+138	common	setfsuid		sys_setfsuid
+139	common	setfsgid		sys_setfsgid
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents			compat_sys_getdents
+142	common	_newselect		sys_select			compat_sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	32	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+161	64	sched_rr_get_interval	sys_sched_rr_get_interval
+162	32	nanosleep		sys_nanosleep_time32
+162	64	nanosleep		sys_nanosleep
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid
+165	common	getresuid		sys_getresuid
+166	common	sigaltstack		sys_sigaltstack			compat_sys_sigaltstack
+# 167 was query_module
+168	common	poll			sys_poll
+# 169 was nfsservctl
+170	common	setresgid		sys_setresgid
+171	common	getresgid		sys_getresgid
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper
+174	common	rt_sigaction		sys_rt_sigaction		compat_sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask		compat_sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending		compat_sys_rt_sigpending
+177	32	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+177	64	rt_sigtimedwait		sys_rt_sigtimedwait
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo		compat_sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend		compat_sys_rt_sigsuspend
+180	common	chown			sys_chown
+181	common	setsockopt		sys_setsockopt			sys_setsockopt
+182	common	getsockopt		sys_getsockopt			sys_getsockopt
+183	common	sendmsg			sys_sendmsg			compat_sys_sendmsg
+184	common	recvmsg			sys_recvmsg			compat_sys_recvmsg
+185	common	semop			sys_semop
+186	common	semget			sys_semget
+187	common	semctl			sys_semctl			compat_sys_semctl
+188	common	msgsnd			sys_msgsnd			compat_sys_msgsnd
+189	common	msgrcv			sys_msgrcv			compat_sys_msgrcv
+190	common	msgget			sys_msgget
+191	common	msgctl			sys_msgctl			compat_sys_msgctl
+192	common	shmat			sys_shmat			compat_sys_shmat
+193	common	shmdt			sys_shmdt
+194	common	shmget			sys_shmget
+195	common	shmctl			sys_shmctl			compat_sys_shmctl
+# 196 was getpmsg
+# 197 was putpmsg
+198	common	lstat64			sys_lstat64
+199	32	truncate64		parisc_truncate64
+199	64	truncate64		sys_truncate64
+200	32	ftruncate64		parisc_ftruncate64
+200	64	ftruncate64		sys_ftruncate64
+201	common	getdents64		sys_getdents64
+202	common	fcntl64			sys_fcntl64			compat_sys_fcntl64
+# 203 was attrctl
+# 204 was acl_get
+# 205 was acl_set
+206	common	gettid			sys_gettid
+207	32	readahead		parisc_readahead
+207	64	readahead		sys_readahead
+208	common	tkill			sys_tkill
+209	common	sendfile64		sys_sendfile64			compat_sys_sendfile64
+210	32	futex			sys_futex_time32
+210	64	futex			sys_futex
+211	common	sched_setaffinity	sys_sched_setaffinity		compat_sys_sched_setaffinity
+212	common	sched_getaffinity	sys_sched_getaffinity		compat_sys_sched_getaffinity
+# 213 was set_thread_area
+# 214 was get_thread_area
+215	common	io_setup		sys_io_setup			compat_sys_io_setup
+216	common	io_destroy		sys_io_destroy
+217	32	io_getevents		sys_io_getevents_time32
+217	64	io_getevents		sys_io_getevents
+218	common	io_submit		sys_io_submit			compat_sys_io_submit
+219	common	io_cancel		sys_io_cancel
+# 220 was alloc_hugepages
+# 221 was free_hugepages
+222	common	exit_group		sys_exit_group
+223	common	lookup_dcookie		sys_ni_syscall
+224	common	epoll_create		sys_epoll_create
+225	common	epoll_ctl		sys_epoll_ctl
+226	common	epoll_wait		sys_epoll_wait
+227	common	remap_file_pages	sys_remap_file_pages
+228	32	semtimedop		sys_semtimedop_time32
+228	64	semtimedop		sys_semtimedop
+229	common	mq_open			sys_mq_open			compat_sys_mq_open
+230	common	mq_unlink		sys_mq_unlink
+231	32	mq_timedsend		sys_mq_timedsend_time32
+231	64	mq_timedsend		sys_mq_timedsend
+232	32	mq_timedreceive		sys_mq_timedreceive_time32
+232	64	mq_timedreceive		sys_mq_timedreceive
+233	common	mq_notify		sys_mq_notify			compat_sys_mq_notify
+234	common	mq_getsetattr		sys_mq_getsetattr		compat_sys_mq_getsetattr
+235	common	waitid			sys_waitid			compat_sys_waitid
+236	32	fadvise64_64		parisc_fadvise64_64
+236	64	fadvise64_64		sys_fadvise64_64
+237	common	set_tid_address		sys_set_tid_address
+238	common	setxattr		sys_setxattr
+239	common	lsetxattr		sys_lsetxattr
+240	common	fsetxattr		sys_fsetxattr
+241	common	getxattr		sys_getxattr
+242	common	lgetxattr		sys_lgetxattr
+243	common	fgetxattr		sys_fgetxattr
+244	common	listxattr		sys_listxattr
+245	common	llistxattr		sys_llistxattr
+246	common	flistxattr		sys_flistxattr
+247	common	removexattr		sys_removexattr
+248	common	lremovexattr		sys_lremovexattr
+249	common	fremovexattr		sys_fremovexattr
+250	common	timer_create		sys_timer_create		compat_sys_timer_create
+251	32	timer_settime		sys_timer_settime32
+251	64	timer_settime		sys_timer_settime
+252	32	timer_gettime		sys_timer_gettime32
+252	64	timer_gettime		sys_timer_gettime
+253	common	timer_getoverrun	sys_timer_getoverrun
+254	common	timer_delete		sys_timer_delete
+255	32	clock_settime		sys_clock_settime32
+255	64	clock_settime		sys_clock_settime
+256	32	clock_gettime		sys_clock_gettime32
+256	64	clock_gettime		sys_clock_gettime
+257	32	clock_getres		sys_clock_getres_time32
+257	64	clock_getres		sys_clock_getres
+258	32	clock_nanosleep		sys_clock_nanosleep_time32
+258	64	clock_nanosleep		sys_clock_nanosleep
+259	common	tgkill			sys_tgkill
+260	common	mbind			sys_mbind
+261	common	get_mempolicy		sys_get_mempolicy
+262	common	set_mempolicy		sys_set_mempolicy
+# 263 was vserver
+264	common	add_key			sys_add_key
+265	common	request_key		sys_request_key
+266	common	keyctl			sys_keyctl			compat_sys_keyctl
+267	common	ioprio_set		sys_ioprio_set
+268	common	ioprio_get		sys_ioprio_get
+269	common	inotify_init		sys_inotify_init
+270	common	inotify_add_watch	sys_inotify_add_watch
+271	common	inotify_rm_watch	sys_inotify_rm_watch
+272	common	migrate_pages		sys_migrate_pages
+273	32	pselect6		sys_pselect6_time32		compat_sys_pselect6_time32
+273	64	pselect6		sys_pselect6
+274	32	ppoll			sys_ppoll_time32		compat_sys_ppoll_time32
+274	64	ppoll			sys_ppoll
+275	common	openat			sys_openat			compat_sys_openat
+276	common	mkdirat			sys_mkdirat
+277	common	mknodat			sys_mknodat
+278	common	fchownat		sys_fchownat
+279	32	futimesat		sys_futimesat_time32
+279	64	futimesat		sys_futimesat
+280	common	fstatat64		sys_fstatat64
+281	common	unlinkat		sys_unlinkat
+282	common	renameat		sys_renameat
+283	common	linkat			sys_linkat
+284	common	symlinkat		sys_symlinkat
+285	common	readlinkat		sys_readlinkat
+286	common	fchmodat		sys_fchmodat
+287	common	faccessat		sys_faccessat
+288	common	unshare			sys_unshare
+289	common	set_robust_list		sys_set_robust_list		compat_sys_set_robust_list
+290	common	get_robust_list		sys_get_robust_list		compat_sys_get_robust_list
+291	common	splice			sys_splice
+292	32	sync_file_range		parisc_sync_file_range
+292	64	sync_file_range		sys_sync_file_range
+293	common	tee			sys_tee
+294	common	vmsplice		sys_vmsplice
+295	common	move_pages		sys_move_pages
+296	common	getcpu			sys_getcpu
+297	common	epoll_pwait		sys_epoll_pwait			compat_sys_epoll_pwait
+298	common	statfs64		sys_statfs64			compat_sys_statfs64
+299	common	fstatfs64		sys_fstatfs64			compat_sys_fstatfs64
+300	common	kexec_load		sys_kexec_load			compat_sys_kexec_load
+301	32	utimensat		sys_utimensat_time32
+301	64	utimensat		sys_utimensat
+302	common	signalfd		sys_signalfd			compat_sys_signalfd
+# 303 was timerfd
+304	common	eventfd			sys_eventfd
+305	32	fallocate		parisc_fallocate
+305	64	fallocate		sys_fallocate
+306	common	timerfd_create		parisc_timerfd_create
+307	32	timerfd_settime		sys_timerfd_settime32
+307	64	timerfd_settime		sys_timerfd_settime
+308	32	timerfd_gettime		sys_timerfd_gettime32
+308	64	timerfd_gettime		sys_timerfd_gettime
+309	common	signalfd4		parisc_signalfd4		parisc_compat_signalfd4
+310	common	eventfd2		parisc_eventfd2
+311	common	epoll_create1		sys_epoll_create1
+312	common	dup3			sys_dup3
+313	common	pipe2			parisc_pipe2
+314	common	inotify_init1		parisc_inotify_init1
+315	common	preadv	sys_preadv	compat_sys_preadv
+316	common	pwritev	sys_pwritev	compat_sys_pwritev
+317	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo		compat_sys_rt_tgsigqueueinfo
+318	common	perf_event_open		sys_perf_event_open
+319	32	recvmmsg		sys_recvmmsg_time32		compat_sys_recvmmsg_time32
+319	64	recvmmsg		sys_recvmmsg
+320	common	accept4			sys_accept4
+321	common	prlimit64		sys_prlimit64
+322	common	fanotify_init		sys_fanotify_init
+323	common	fanotify_mark		sys_fanotify_mark		compat_sys_fanotify_mark
+324	32	clock_adjtime		sys_clock_adjtime32
+324	64	clock_adjtime		sys_clock_adjtime
+325	common	name_to_handle_at	sys_name_to_handle_at
+326	common	open_by_handle_at	sys_open_by_handle_at		compat_sys_open_by_handle_at
+327	common	syncfs			sys_syncfs
+328	common	setns			sys_setns
+329	common	sendmmsg		sys_sendmmsg			compat_sys_sendmmsg
+330	common	process_vm_readv	sys_process_vm_readv
+331	common	process_vm_writev	sys_process_vm_writev
+332	common	kcmp			sys_kcmp
+333	common	finit_module		sys_finit_module
+334	common	sched_setattr		sys_sched_setattr
+335	common	sched_getattr		sys_sched_getattr
+336	32	utimes			sys_utimes_time32
+336	64	utimes			sys_utimes
+337	common	renameat2		sys_renameat2
+338	common	seccomp			sys_seccomp
+339	common	getrandom		sys_getrandom
+340	common	memfd_create		sys_memfd_create
+341	common	bpf			sys_bpf
+342	common	execveat		sys_execveat			compat_sys_execveat
+343	common	membarrier		sys_membarrier
+344	common	userfaultfd		parisc_userfaultfd
+345	common	mlock2			sys_mlock2
+346	common	copy_file_range		sys_copy_file_range
+347	common	preadv2			sys_preadv2			compat_sys_preadv2
+348	common	pwritev2		sys_pwritev2			compat_sys_pwritev2
+349	common	statx			sys_statx
+350	32	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+350	64	io_pgetevents		sys_io_pgetevents
+351	common	pkey_mprotect		sys_pkey_mprotect
+352	common	pkey_alloc		sys_pkey_alloc
+353	common	pkey_free		sys_pkey_free
+354	common	rseq			sys_rseq
+355	common	kexec_file_load		sys_kexec_file_load		sys_kexec_file_load
+356	common	cacheflush		sys_cacheflush
+# up to 402 is unassigned and reserved for arch specific syscalls
+403	32	clock_gettime64			sys_clock_gettime		sys_clock_gettime
+404	32	clock_settime64			sys_clock_settime		sys_clock_settime
+405	32	clock_adjtime64			sys_clock_adjtime		sys_clock_adjtime
+406	32	clock_getres_time64		sys_clock_getres		sys_clock_getres
+407	32	clock_nanosleep_time64		sys_clock_nanosleep		sys_clock_nanosleep
+408	32	timer_gettime64			sys_timer_gettime		sys_timer_gettime
+409	32	timer_settime64			sys_timer_settime		sys_timer_settime
+410	32	timerfd_gettime64		sys_timerfd_gettime		sys_timerfd_gettime
+411	32	timerfd_settime64		sys_timerfd_settime		sys_timerfd_settime
+412	32	utimensat_time64		sys_utimensat			sys_utimensat
+413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
+419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
+420	32	semtimedop_time64		sys_semtimedop			sys_semtimedop
+421	32	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	32	futex_time64			sys_futex			sys_futex
+423	32	sched_rr_get_interval_time64	sys_sched_rr_get_interval	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3_wrapper
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/parisc/include/syscall_table.h b/tools/perf/arch/parisc/include/syscall_table.h
new file mode 100644
index 000000000000..7ff51b783000
--- /dev/null
+++ b/tools/perf/arch/parisc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index a821df1fd4c0..ae9f00ae79f3 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -207,6 +207,7 @@ check_2 tools/perf/arch/sh/entry/syscalls/syscall.tbl arch/sh/kernel/syscalls/sy
 check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
+check_2 tools/perf/arch/parisc/entry/syscalls/syscall.tbl arch/parisc/entry/syscalls/syscall.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:13 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:13 -0800
Subject: [PATCH RFT 11/16] perf tools: arm64: Use syscall table
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-11-9adae5c761ef@rivosinc.com>

arm64 uses a syscall table, use that in perf instead of using unistd.h.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |   4 +-
 tools/perf/Makefile.perf                           |   2 +-
 tools/perf/arch/arm64/Makefile                     |  22 -
 tools/perf/arch/arm64/entry/syscalls/Kbuild        |   3 +
 .../arch/arm64/entry/syscalls/Makefile.syscalls    |   6 +
 tools/perf/arch/arm64/entry/syscalls/mksyscalltbl  |  46 --
 .../perf/arch/arm64/entry/syscalls/syscall_32.tbl  | 476 +++++++++++++++++++++
 .../perf/arch/arm64/entry/syscalls/syscall_64.tbl  |   1 +
 tools/perf/arch/arm64/include/syscall_table.h      |   8 +
 tools/perf/check-headers.sh                        |   2 +
 tools/perf/util/syscalltbl.c                       |   4 -
 11 files changed, 499 insertions(+), 75 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 925d3a10893a..1da374873514 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips loongarch))
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index b92500bf22fb..ced8dc312b20 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
index 5735ed4479bb..8da04bd7e687 100644
--- a/tools/perf/arch/arm64/Makefile
+++ b/tools/perf/arch/arm64/Makefile
@@ -5,25 +5,3 @@ endif
 PERF_HAVE_JITDUMP := 1
 PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/arm64/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/arm64/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, arm64) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/arm64/entry/syscalls/Kbuild b/tools/perf/arch/arm64/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..84c6599b4ea6
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls b/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..e7e78c2d1c02
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 +=
+syscall_abis_64 += renameat rlimit memfd_secret
+
+syscalltbl = $(srctree)/tools/perf/arch/arm64/entry/syscalls/syscall_%.tbl
diff --git a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 27d747c92d44..000000000000
--- a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-# Changed by: Kim Phillips <kim.phillips at arm.com>
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_ARM64_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_arm64[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl b/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl
new file mode 100644
index 000000000000..9a37930d4e26
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl
@@ -0,0 +1,476 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# AArch32 (compat) system call definitions.
+#
+# Copyright (C) 2001-2005 Russell King
+# Copyright (C) 2012 ARM Ltd.
+#
+# This file corresponds to arch/arm/tools/syscall.tbl
+# for the native EABI syscalls and should be kept in sync
+# Instead of the OABI syscalls, it contains pointers to
+# the compat entry points where they differ from the native
+# syscalls.
+#
+0	common	restart_syscall		sys_restart_syscall
+1	common	exit			sys_exit
+2	common	fork			sys_fork
+3	common	read			sys_read
+4	common	write			sys_write
+5	common	open			sys_open		compat_sys_open
+6	common	close			sys_close
+# 7 was sys_waitpid
+8	common	creat			sys_creat
+9	common	link			sys_link
+10	common	unlink			sys_unlink
+11	common	execve			sys_execve		compat_sys_execve
+12	common	chdir			sys_chdir
+# 13 was sys_time
+14	common	mknod			sys_mknod
+15	common	chmod			sys_chmod
+16	common	lchown			sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19	common	lseek			sys_lseek		compat_sys_lseek
+20	common	getpid			sys_getpid
+21	common	mount			sys_mount
+# 22 was sys_umount
+23	common	setuid			sys_setuid16
+24	common	getuid			sys_getuid16
+# 25 was sys_stime
+26	common	ptrace			sys_ptrace		compat_sys_ptrace
+# 27 was sys_alarm
+# 28 was sys_fstat
+29	common	pause			sys_pause
+# 30 was sys_utime
+# 31 was sys_stty
+# 32 was sys_gtty
+33	common	access			sys_access
+34	common	nice			sys_nice
+# 35 was sys_ftime
+36	common	sync			sys_sync
+37	common	kill			sys_kill
+38	common	rename			sys_rename
+39	common	mkdir			sys_mkdir
+40	common	rmdir			sys_rmdir
+41	common	dup			sys_dup
+42	common	pipe			sys_pipe
+43	common	times			sys_times		compat_sys_times
+# 44 was sys_prof
+45	common	brk			sys_brk
+46	common	setgid			sys_setgid16
+47	common	getgid			sys_getgid16
+# 48 was sys_signal
+49	common	geteuid			sys_geteuid16
+50	common	getegid			sys_getegid16
+51	common	acct			sys_acct
+52	common	umount2			sys_umount
+# 53 was sys_lock
+54	common	ioctl			sys_ioctl		compat_sys_ioctl
+55	common	fcntl			sys_fcntl		compat_sys_fcntl
+# 56 was sys_mpx
+57	common	setpgid			sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60	common	umask			sys_umask
+61	common	chroot			sys_chroot
+62	common	ustat			sys_ustat		compat_sys_ustat
+63	common	dup2			sys_dup2
+64	common	getppid			sys_getppid
+65	common	getpgrp			sys_getpgrp
+66	common	setsid			sys_setsid
+67	common	sigaction		sys_sigaction		compat_sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70	common	setreuid		sys_setreuid16
+71	common	setregid		sys_setregid16
+72	common	sigsuspend		sys_sigsuspend
+73	common	sigpending		sys_sigpending		compat_sys_sigpending
+74	common	sethostname		sys_sethostname
+75	common	setrlimit		sys_setrlimit		compat_sys_setrlimit
+# 76 was compat_sys_getrlimit
+77	common	getrusage		sys_getrusage		compat_sys_getrusage
+78	common	gettimeofday		sys_gettimeofday	compat_sys_gettimeofday
+79	common	settimeofday		sys_settimeofday	compat_sys_settimeofday
+80	common	getgroups		sys_getgroups16
+81	common	setgroups		sys_setgroups16
+# 82 was compat_sys_select
+83	common	symlink			sys_symlink
+# 84 was sys_lstat
+85	common	readlink		sys_readlink
+86	common	uselib			sys_uselib
+87	common	swapon			sys_swapon
+88	common	reboot			sys_reboot
+# 89 was sys_readdir
+# 90 was sys_mmap
+91	common	munmap			sys_munmap
+92	common	truncate		sys_truncate		compat_sys_truncate
+93	common	ftruncate		sys_ftruncate		compat_sys_ftruncate
+94	common	fchmod			sys_fchmod
+95	common	fchown			sys_fchown16
+96	common	getpriority		sys_getpriority
+97	common	setpriority		sys_setpriority
+# 98 was sys_profil
+99	common	statfs			sys_statfs		compat_sys_statfs
+100	common	fstatfs			sys_fstatfs		compat_sys_fstatfs
+# 101 was sys_ioperm
+# 102 was sys_socketcall
+103	common	syslog			sys_syslog
+104	common	setitimer		sys_setitimer		compat_sys_setitimer
+105	common	getitimer		sys_getitimer		compat_sys_getitimer
+106	common	stat			sys_newstat		compat_sys_newstat
+107	common	lstat			sys_newlstat		compat_sys_newlstat
+108	common	fstat			sys_newfstat		compat_sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111	common	vhangup			sys_vhangup
+# 112 was sys_idle
+# 113 was sys_syscall
+114	common	wait4			sys_wait4		compat_sys_wait4
+115	common	swapoff			sys_swapoff
+116	common	sysinfo			sys_sysinfo		compat_sys_sysinfo
+# 117 was sys_ipc
+118	common	fsync			sys_fsync
+119	common	sigreturn		sys_sigreturn_wrapper	compat_sys_sigreturn
+120	common	clone			sys_clone
+121	common	setdomainname		sys_setdomainname
+122	common	uname			sys_newuname
+# 123 was sys_modify_ldt
+124	common	adjtimex		sys_adjtimex_time32
+125	common	mprotect		sys_mprotect
+126	common	sigprocmask		sys_sigprocmask		compat_sys_sigprocmask
+# 127 was sys_create_module
+128	common	init_module		sys_init_module
+129	common	delete_module		sys_delete_module
+# 130 was sys_get_kernel_syms
+131	common	quotactl		sys_quotactl
+132	common	getpgid			sys_getpgid
+133	common	fchdir			sys_fchdir
+134	common	bdflush			sys_ni_syscall
+135	common	sysfs			sys_sysfs
+136	common	personality		sys_personality
+# 137 was sys_afs_syscall
+138	common	setfsuid		sys_setfsuid16
+139	common	setfsgid		sys_setfsgid16
+140	common	_llseek			sys_llseek
+141	common	getdents		sys_getdents		compat_sys_getdents
+142	common	_newselect		sys_select		compat_sys_select
+143	common	flock			sys_flock
+144	common	msync			sys_msync
+145	common	readv			sys_readv
+146	common	writev			sys_writev
+147	common	getsid			sys_getsid
+148	common	fdatasync		sys_fdatasync
+149	common	_sysctl			sys_ni_syscall
+150	common	mlock			sys_mlock
+151	common	munlock			sys_munlock
+152	common	mlockall		sys_mlockall
+153	common	munlockall		sys_munlockall
+154	common	sched_setparam		sys_sched_setparam
+155	common	sched_getparam		sys_sched_getparam
+156	common	sched_setscheduler	sys_sched_setscheduler
+157	common	sched_getscheduler	sys_sched_getscheduler
+158	common	sched_yield		sys_sched_yield
+159	common	sched_get_priority_max	sys_sched_get_priority_max
+160	common	sched_get_priority_min	sys_sched_get_priority_min
+161	common	sched_rr_get_interval	sys_sched_rr_get_interval_time32
+162	common	nanosleep		sys_nanosleep_time32
+163	common	mremap			sys_mremap
+164	common	setresuid		sys_setresuid16
+165	common	getresuid		sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168	common	poll			sys_poll
+169	common	nfsservctl		sys_ni_syscall
+170	common	setresgid		sys_setresgid16
+171	common	getresgid		sys_getresgid16
+172	common	prctl			sys_prctl
+173	common	rt_sigreturn		sys_rt_sigreturn_wrapper	compat_sys_rt_sigreturn
+174	common	rt_sigaction		sys_rt_sigaction	compat_sys_rt_sigaction
+175	common	rt_sigprocmask		sys_rt_sigprocmask	compat_sys_rt_sigprocmask
+176	common	rt_sigpending		sys_rt_sigpending	compat_sys_rt_sigpending
+177	common	rt_sigtimedwait		sys_rt_sigtimedwait_time32	compat_sys_rt_sigtimedwait_time32
+178	common	rt_sigqueueinfo		sys_rt_sigqueueinfo	compat_sys_rt_sigqueueinfo
+179	common	rt_sigsuspend		sys_rt_sigsuspend	compat_sys_rt_sigsuspend
+180	common	pread64			sys_pread64		compat_sys_aarch32_pread64
+181	common	pwrite64		sys_pwrite64		compat_sys_aarch32_pwrite64
+182	common	chown			sys_chown16
+183	common	getcwd			sys_getcwd
+184	common	capget			sys_capget
+185	common	capset			sys_capset
+186	common	sigaltstack		sys_sigaltstack		compat_sys_sigaltstack
+187	common	sendfile		sys_sendfile		compat_sys_sendfile
+# 188 reserved
+# 189 reserved
+190	common	vfork			sys_vfork
+# SuS compliant getrlimit
+191	common	ugetrlimit		sys_getrlimit		compat_sys_getrlimit
+192	common	mmap2			sys_mmap2		compat_sys_aarch32_mmap2
+193	common	truncate64		sys_truncate64		compat_sys_aarch32_truncate64
+194	common	ftruncate64		sys_ftruncate64		compat_sys_aarch32_ftruncate64
+195	common	stat64			sys_stat64
+196	common	lstat64			sys_lstat64
+197	common	fstat64			sys_fstat64
+198	common	lchown32		sys_lchown
+199	common	getuid32		sys_getuid
+200	common	getgid32		sys_getgid
+201	common	geteuid32		sys_geteuid
+202	common	getegid32		sys_getegid
+203	common	setreuid32		sys_setreuid
+204	common	setregid32		sys_setregid
+205	common	getgroups32		sys_getgroups
+206	common	setgroups32		sys_setgroups
+207	common	fchown32		sys_fchown
+208	common	setresuid32		sys_setresuid
+209	common	getresuid32		sys_getresuid
+210	common	setresgid32		sys_setresgid
+211	common	getresgid32		sys_getresgid
+212	common	chown32			sys_chown
+213	common	setuid32		sys_setuid
+214	common	setgid32		sys_setgid
+215	common	setfsuid32		sys_setfsuid
+216	common	setfsgid32		sys_setfsgid
+217	common	getdents64		sys_getdents64
+218	common	pivot_root		sys_pivot_root
+219	common	mincore			sys_mincore
+220	common	madvise			sys_madvise
+221	common	fcntl64			sys_fcntl64		compat_sys_fcntl64
+# 222 for tux
+# 223 is unused
+224	common	gettid			sys_gettid
+225	common	readahead		sys_readahead		compat_sys_aarch32_readahead
+226	common	setxattr		sys_setxattr
+227	common	lsetxattr		sys_lsetxattr
+228	common	fsetxattr		sys_fsetxattr
+229	common	getxattr		sys_getxattr
+230	common	lgetxattr		sys_lgetxattr
+231	common	fgetxattr		sys_fgetxattr
+232	common	listxattr		sys_listxattr
+233	common	llistxattr		sys_llistxattr
+234	common	flistxattr		sys_flistxattr
+235	common	removexattr		sys_removexattr
+236	common	lremovexattr		sys_lremovexattr
+237	common	fremovexattr		sys_fremovexattr
+238	common	tkill			sys_tkill
+239	common	sendfile64		sys_sendfile64
+240	common	futex			sys_futex_time32
+241	common	sched_setaffinity	sys_sched_setaffinity	compat_sys_sched_setaffinity
+242	common	sched_getaffinity	sys_sched_getaffinity	compat_sys_sched_getaffinity
+243	common	io_setup		sys_io_setup		compat_sys_io_setup
+244	common	io_destroy		sys_io_destroy
+245	common	io_getevents		sys_io_getevents_time32
+246	common	io_submit		sys_io_submit		compat_sys_io_submit
+247	common	io_cancel		sys_io_cancel
+248	common	exit_group		sys_exit_group
+249	common	lookup_dcookie		sys_ni_syscall
+250	common	epoll_create		sys_epoll_create
+251	common	epoll_ctl		sys_epoll_ctl
+252	common	epoll_wait		sys_epoll_wait
+253	common	remap_file_pages	sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256	common	set_tid_address		sys_set_tid_address
+257	common	timer_create		sys_timer_create	compat_sys_timer_create
+258	common	timer_settime		sys_timer_settime32
+259	common	timer_gettime		sys_timer_gettime32
+260	common	timer_getoverrun	sys_timer_getoverrun
+261	common	timer_delete		sys_timer_delete
+262	common	clock_settime		sys_clock_settime32
+263	common	clock_gettime		sys_clock_gettime32
+264	common	clock_getres		sys_clock_getres_time32
+265	common	clock_nanosleep		sys_clock_nanosleep_time32
+266	common	statfs64		sys_statfs64_wrapper	compat_sys_aarch32_statfs64
+267	common	fstatfs64		sys_fstatfs64_wrapper	compat_sys_aarch32_fstatfs64
+268	common	tgkill			sys_tgkill
+269	common	utimes			sys_utimes_time32
+270	common	arm_fadvise64_64	sys_arm_fadvise64_64	compat_sys_aarch32_fadvise64_64
+271	common	pciconfig_iobase	sys_pciconfig_iobase
+272	common	pciconfig_read		sys_pciconfig_read
+273	common	pciconfig_write		sys_pciconfig_write
+274	common	mq_open			sys_mq_open		compat_sys_mq_open
+275	common	mq_unlink		sys_mq_unlink
+276	common	mq_timedsend		sys_mq_timedsend_time32
+277	common	mq_timedreceive		sys_mq_timedreceive_time32
+278	common	mq_notify		sys_mq_notify		compat_sys_mq_notify
+279	common	mq_getsetattr		sys_mq_getsetattr	compat_sys_mq_getsetattr
+280	common	waitid			sys_waitid		compat_sys_waitid
+281	common	socket			sys_socket
+282	common	bind			sys_bind
+283	common	connect			sys_connect
+284	common	listen			sys_listen
+285	common	accept			sys_accept
+286	common	getsockname		sys_getsockname
+287	common	getpeername		sys_getpeername
+288	common	socketpair		sys_socketpair
+289	common	send			sys_send
+290	common	sendto			sys_sendto
+291	common	recv			sys_recv		compat_sys_recv
+292	common	recvfrom		sys_recvfrom		compat_sys_recvfrom
+293	common	shutdown		sys_shutdown
+294	common	setsockopt		sys_setsockopt
+295	common	getsockopt		sys_getsockopt
+296	common	sendmsg			sys_sendmsg		compat_sys_sendmsg
+297	common	recvmsg			sys_recvmsg		compat_sys_recvmsg
+298	common	semop			sys_semop
+299	common	semget			sys_semget
+300	common	semctl			sys_old_semctl		compat_sys_old_semctl
+301	common	msgsnd			sys_msgsnd		compat_sys_msgsnd
+302	common	msgrcv			sys_msgrcv		compat_sys_msgrcv
+303	common	msgget			sys_msgget
+304	common	msgctl			sys_old_msgctl		compat_sys_old_msgctl
+305	common	shmat			sys_shmat		compat_sys_shmat
+306	common	shmdt			sys_shmdt
+307	common	shmget			sys_shmget
+308	common	shmctl			sys_old_shmctl		compat_sys_old_shmctl
+309	common	add_key			sys_add_key
+310	common	request_key		sys_request_key
+311	common	keyctl			sys_keyctl		compat_sys_keyctl
+312	common	semtimedop		sys_semtimedop_time32
+313	common	vserver			sys_ni_syscall
+314	common	ioprio_set		sys_ioprio_set
+315	common	ioprio_get		sys_ioprio_get
+316	common	inotify_init		sys_inotify_init
+317	common	inotify_add_watch	sys_inotify_add_watch
+318	common	inotify_rm_watch	sys_inotify_rm_watch
+319	common	mbind			sys_mbind
+320	common	get_mempolicy		sys_get_mempolicy
+321	common	set_mempolicy		sys_set_mempolicy
+322	common	openat			sys_openat		compat_sys_openat
+323	common	mkdirat			sys_mkdirat
+324	common	mknodat			sys_mknodat
+325	common	fchownat		sys_fchownat
+326	common	futimesat		sys_futimesat_time32
+327	common	fstatat64		sys_fstatat64
+328	common	unlinkat		sys_unlinkat
+329	common	renameat		sys_renameat
+330	common	linkat			sys_linkat
+331	common	symlinkat		sys_symlinkat
+332	common	readlinkat		sys_readlinkat
+333	common	fchmodat		sys_fchmodat
+334	common	faccessat		sys_faccessat
+335	common	pselect6		sys_pselect6_time32	compat_sys_pselect6_time32
+336	common	ppoll			sys_ppoll_time32	compat_sys_ppoll_time32
+337	common	unshare			sys_unshare
+338	common	set_robust_list		sys_set_robust_list	compat_sys_set_robust_list
+339	common	get_robust_list		sys_get_robust_list	compat_sys_get_robust_list
+340	common	splice			sys_splice
+341	common	arm_sync_file_range	sys_sync_file_range2	compat_sys_aarch32_sync_file_range2
+342	common	tee			sys_tee
+343	common	vmsplice		sys_vmsplice
+344	common	move_pages		sys_move_pages
+345	common	getcpu			sys_getcpu
+346	common	epoll_pwait		sys_epoll_pwait		compat_sys_epoll_pwait
+347	common	kexec_load		sys_kexec_load		compat_sys_kexec_load
+348	common	utimensat		sys_utimensat_time32
+349	common	signalfd		sys_signalfd		compat_sys_signalfd
+350	common	timerfd_create		sys_timerfd_create
+351	common	eventfd			sys_eventfd
+352	common	fallocate		sys_fallocate		compat_sys_aarch32_fallocate
+353	common	timerfd_settime		sys_timerfd_settime32
+354	common	timerfd_gettime		sys_timerfd_gettime32
+355	common	signalfd4		sys_signalfd4		compat_sys_signalfd4
+356	common	eventfd2		sys_eventfd2
+357	common	epoll_create1		sys_epoll_create1
+358	common	dup3			sys_dup3
+359	common	pipe2			sys_pipe2
+360	common	inotify_init1		sys_inotify_init1
+361	common	preadv			sys_preadv		compat_sys_preadv
+362	common	pwritev			sys_pwritev		compat_sys_pwritev
+363	common	rt_tgsigqueueinfo	sys_rt_tgsigqueueinfo	compat_sys_rt_tgsigqueueinfo
+364	common	perf_event_open		sys_perf_event_open
+365	common	recvmmsg		sys_recvmmsg_time32	compat_sys_recvmmsg_time32
+366	common	accept4			sys_accept4
+367	common	fanotify_init		sys_fanotify_init
+368	common	fanotify_mark		sys_fanotify_mark	compat_sys_fanotify_mark
+369	common	prlimit64		sys_prlimit64
+370	common	name_to_handle_at	sys_name_to_handle_at
+371	common	open_by_handle_at	sys_open_by_handle_at	compat_sys_open_by_handle_at
+372	common	clock_adjtime		sys_clock_adjtime32
+373	common	syncfs			sys_syncfs
+374	common	sendmmsg		sys_sendmmsg		compat_sys_sendmmsg
+375	common	setns			sys_setns
+376	common	process_vm_readv	sys_process_vm_readv
+377	common	process_vm_writev	sys_process_vm_writev
+378	common	kcmp			sys_kcmp
+379	common	finit_module		sys_finit_module
+380	common	sched_setattr		sys_sched_setattr
+381	common	sched_getattr		sys_sched_getattr
+382	common	renameat2		sys_renameat2
+383	common	seccomp			sys_seccomp
+384	common	getrandom		sys_getrandom
+385	common	memfd_create		sys_memfd_create
+386	common	bpf			sys_bpf
+387	common	execveat		sys_execveat		compat_sys_execveat
+388	common	userfaultfd		sys_userfaultfd
+389	common	membarrier		sys_membarrier
+390	common	mlock2			sys_mlock2
+391	common	copy_file_range		sys_copy_file_range
+392	common	preadv2			sys_preadv2		compat_sys_preadv2
+393	common	pwritev2		sys_pwritev2		compat_sys_pwritev2
+394	common	pkey_mprotect		sys_pkey_mprotect
+395	common	pkey_alloc		sys_pkey_alloc
+396	common	pkey_free		sys_pkey_free
+397	common	statx			sys_statx
+398	common	rseq			sys_rseq
+399	common	io_pgetevents		sys_io_pgetevents_time32	compat_sys_io_pgetevents
+400	common	migrate_pages		sys_migrate_pages
+401	common	kexec_file_load		sys_kexec_file_load
+# 402 is unused
+403	common	clock_gettime64			sys_clock_gettime
+404	common	clock_settime64			sys_clock_settime
+405	common	clock_adjtime64			sys_clock_adjtime
+406	common	clock_getres_time64		sys_clock_getres
+407	common	clock_nanosleep_time64		sys_clock_nanosleep
+408	common	timer_gettime64			sys_timer_gettime
+409	common	timer_settime64			sys_timer_settime
+410	common	timerfd_gettime64		sys_timerfd_gettime
+411	common	timerfd_settime64		sys_timerfd_settime
+412	common	utimensat_time64		sys_utimensat
+413	common	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
+414	common	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
+416	common	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
+417	common	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
+418	common	mq_timedsend_time64		sys_mq_timedsend
+419	common	mq_timedreceive_time64		sys_mq_timedreceive
+420	common	semtimedop_time64		sys_semtimedop
+421	common	rt_sigtimedwait_time64		sys_rt_sigtimedwait		compat_sys_rt_sigtimedwait_time64
+422	common	futex_time64			sys_futex
+423	common	sched_rr_get_interval_time64	sys_sched_rr_get_interval
+424	common	pidfd_send_signal		sys_pidfd_send_signal
+425	common	io_uring_setup			sys_io_uring_setup
+426	common	io_uring_enter			sys_io_uring_enter
+427	common	io_uring_register		sys_io_uring_register
+428	common	open_tree			sys_open_tree
+429	common	move_mount			sys_move_mount
+430	common	fsopen				sys_fsopen
+431	common	fsconfig			sys_fsconfig
+432	common	fsmount				sys_fsmount
+433	common	fspick				sys_fspick
+434	common	pidfd_open			sys_pidfd_open
+435	common	clone3				sys_clone3
+436	common	close_range			sys_close_range
+437	common	openat2				sys_openat2
+438	common	pidfd_getfd			sys_pidfd_getfd
+439	common	faccessat2			sys_faccessat2
+440	common	process_madvise			sys_process_madvise
+441	common	epoll_pwait2			sys_epoll_pwait2		compat_sys_epoll_pwait2
+442	common	mount_setattr			sys_mount_setattr
+443	common	quotactl_fd			sys_quotactl_fd
+444	common	landlock_create_ruleset		sys_landlock_create_ruleset
+445	common	landlock_add_rule		sys_landlock_add_rule
+446	common	landlock_restrict_self		sys_landlock_restrict_self
+# 447 reserved for memfd_secret
+448	common	process_mrelease		sys_process_mrelease
+449	common	futex_waitv			sys_futex_waitv
+450	common	set_mempolicy_home_node		sys_set_mempolicy_home_node
+451	common	cachestat			sys_cachestat
+452	common	fchmodat2			sys_fchmodat2
+453	common	map_shadow_stack		sys_map_shadow_stack
+454	common	futex_wake			sys_futex_wake
+455	common	futex_wait			sys_futex_wait
+456	common	futex_requeue			sys_futex_requeue
+457	common	statmount			sys_statmount
+458	common	listmount			sys_listmount
+459	common	lsm_get_self_attr		sys_lsm_get_self_attr
+460	common	lsm_set_self_attr		sys_lsm_set_self_attr
+461	common	lsm_list_modules		sys_lsm_list_modules
+462	common	mseal				sys_mseal
diff --git a/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl b/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl
new file mode 120000
index 000000000000..4fdd58f10c15
--- /dev/null
+++ b/tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl
@@ -0,0 +1 @@
+../../../../../scripts/syscall.tbl
\ No newline at end of file
diff --git a/tools/perf/arch/arm64/include/syscall_table.h b/tools/perf/arch/arm64/include/syscall_table.h
new file mode 100644
index 000000000000..7ff51b783000
--- /dev/null
+++ b/tools/perf/arch/arm64/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index ae9f00ae79f3..d3c6e10dce73 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -208,6 +208,8 @@ check_2 tools/perf/arch/sparc/entry/syscalls/syscall.tbl arch/sparc/kernel/sysca
 check_2 tools/perf/arch/xtensa/entry/syscalls/syscall.tbl arch/xtensa/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/alpha/entry/syscalls/syscall.tbl arch/alpha/entry/syscalls/syscall.tbl
 check_2 tools/perf/arch/parisc/entry/syscalls/syscall.tbl arch/parisc/entry/syscalls/syscall.tbl
+check_2 tools/perf/arch/arm64/entry/syscalls/syscall_32.tbl arch/arm64/entry/syscalls/syscall_32.tbl
+check_2 tools/perf/arch/arm64/entry/syscalls/syscall_64.tbl arch/arm64/entry/syscalls/syscall_64.tbl
 
 for i in "${BEAUTY_FILES[@]}"
 do
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 094f6d4fffdd..0bd49247e486 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -25,10 +25,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
 #include <asm/syscalls_32.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
-#elif defined(__aarch64__)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_arm64;
 #elif defined(__mips__)
 #include <asm/syscalls_n64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:14 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:14 -0800
Subject: [PATCH RFT 12/16] perf tools: loongarch: Use syscall table
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-12-9adae5c761ef@rivosinc.com>

loongarch uses a syscall table, use that in perf instead of using unistd.h.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  4 +-
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/loongarch/Makefile                 | 22 -----------
 tools/perf/arch/loongarch/entry/syscalls/Kbuild    |  2 +
 .../loongarch/entry/syscalls/Makefile.syscalls     |  3 ++
 .../arch/loongarch/entry/syscalls/mksyscalltbl     | 45 ----------------------
 tools/perf/arch/loongarch/include/syscall_table.h  |  2 +
 tools/perf/util/syscalltbl.c                       |  4 --
 8 files changed, 10 insertions(+), 74 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 1da374873514..2cf45e3f2659 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips))
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index ced8dc312b20..ce2c4e1c0623 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/loongarch/Makefile b/tools/perf/arch/loongarch/Makefile
index c89d6bb6b184..a2fa918e548c 100644
--- a/tools/perf/arch/loongarch/Makefile
+++ b/tools/perf/arch/loongarch/Makefile
@@ -5,25 +5,3 @@ endif
 PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/loongarch/include/generated/asm
-header := $(out)/syscalls.c
-incpath := $(srctree)/tools
-sysdef := $(srctree)/tools/arch/loongarch/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/loongarch/entry/syscalls/
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, loongarch) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Kbuild b/tools/perf/arch/loongarch/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..9a41e3572c3a
--- /dev/null
+++ b/tools/perf/arch/loongarch/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls b/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..47d32da2aed8
--- /dev/null
+++ b/tools/perf/arch/loongarch/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 +=
diff --git a/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl b/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
deleted file mode 100755
index c10ad3580aef..000000000000
--- a/tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# powerpc script.
-#
-# Author(s):  Ming Wang <wangming01 at loongson.cn>
-# Author(s):  Huacai Chen <chenhuacai at loongson.cn>
-# Copyright (C) 2020-2023 Loongson Technology Corporation Limited
-
-gcc=$1
-hostcc=$2
-incpath=$3
-input=$4
-
-if ! test -r $input; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_sc_table()
-{
-	local sc nr max_nr
-
-	while read sc nr; do
-		printf "%s\n" "	[$nr] = \"$sc\","
-		max_nr=$nr
-	done
-
-	echo "#define SYSCALLTBL_LOONGARCH_MAX_ID $max_nr"
-}
-
-create_table()
-{
-	echo "#include \"$input\""
-	echo "static const char *const syscalltbl_loongarch[] = {"
-	create_sc_table
-	echo "};"
-}
-
-$gcc -E -dM -x c -I $incpath/include/uapi $input \
-	|awk '$2 ~ "__NR" && $3 !~ "__NR3264_" {
-		sub("^#define __NR(3264)?_", "");
-		print | "sort -k2 -n"}' \
-	|create_table
diff --git a/tools/perf/arch/loongarch/include/syscall_table.h b/tools/perf/arch/loongarch/include/syscall_table.h
new file mode 100644
index 000000000000..9d0646d3455c
--- /dev/null
+++ b/tools/perf/arch/loongarch/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscall_table_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 0bd49247e486..7c8550ef0d7b 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -29,10 +29,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
 #include <asm/syscalls_n64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_mips_n64;
-#elif defined(__loongarch__)
-#include <asm/syscalls.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_loongarch;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:15 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:15 -0800
Subject: [PATCH RFT 13/16] perf tools: mips: Use generic syscall scripts
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-13-9adae5c761ef@rivosinc.com>

Use the generic scripts to generate headers from the syscall table for
mips.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  4 +--
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/mips/Makefile                      | 18 ------------
 tools/perf/arch/mips/entry/syscalls/Kbuild         |  2 ++
 .../arch/mips/entry/syscalls/Makefile.syscalls     |  5 ++++
 tools/perf/arch/mips/entry/syscalls/mksyscalltbl   | 32 ----------------------
 tools/perf/arch/mips/include/syscall_table.h       |  2 ++
 tools/perf/util/syscalltbl.c                       |  4 ---
 8 files changed, 12 insertions(+), 57 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 2cf45e3f2659..ce7e9ae276e8 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390 mips))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390))
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index ce2c4e1c0623..c9b78518c9a5 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/mips/Makefile b/tools/perf/arch/mips/Makefile
index cd0b011b3be5..6e1106fab26e 100644
--- a/tools/perf/arch/mips/Makefile
+++ b/tools/perf/arch/mips/Makefile
@@ -2,21 +2,3 @@
 ifndef NO_DWARF
 PERF_HAVE_DWARF_REGS := 1
 endif
-
-# Syscall table generation for perf
-out    := $(OUTPUT)arch/mips/include/generated/asm
-header := $(out)/syscalls_n64.c
-sysprf := $(srctree)/tools/perf/arch/mips/entry/syscalls
-sysdef := $(sysprf)/syscall_n64.tbl
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, mips) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/mips/entry/syscalls/Kbuild b/tools/perf/arch/mips/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..9a41e3572c3a
--- /dev/null
+++ b/tools/perf/arch/mips/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls b/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..9ee914bdfb05
--- /dev/null
+++ b/tools/perf/arch/mips/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 += n64
+
+syscalltbl = $(srctree)/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
diff --git a/tools/perf/arch/mips/entry/syscalls/mksyscalltbl b/tools/perf/arch/mips/entry/syscalls/mksyscalltbl
deleted file mode 100644
index c0d93f959c4e..000000000000
--- a/tools/perf/arch/mips/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# s390 script.
-#
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Tiezhu Yang <yangtiezhu at loongson.cn>
-
-SYSCALL_TBL=$1
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local max_nr nr abi sc discard
-
-	echo 'static const char *const syscalltbl_mips_n64[] = {'
-	while read nr abi sc discard; do
-		printf '\t[%d] = "%s",\n' $nr $sc
-		max_nr=$nr
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_MIPS_N64_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(n64)" $SYSCALL_TBL	\
-	|sort -k1 -n					\
-	|create_table
diff --git a/tools/perf/arch/mips/include/syscall_table.h b/tools/perf/arch/mips/include/syscall_table.h
new file mode 100644
index 000000000000..b53e31c15805
--- /dev/null
+++ b/tools/perf/arch/mips/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 7c8550ef0d7b..724e1391893f 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -25,10 +25,6 @@ static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
 #include <asm/syscalls_32.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
-#elif defined(__mips__)
-#include <asm/syscalls_n64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_mips_n64;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:16 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:16 -0800
Subject: [PATCH RFT 14/16] perf tools: powerpc: Use generic syscall table
 scripts
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-14-9adae5c761ef@rivosinc.com>

Use the generic scripts to generate headers from the syscall table
instead of the custom ones for powerpc.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  4 +--
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/powerpc/Makefile                   | 25 --------------
 tools/perf/arch/powerpc/entry/syscalls/Kbuild      |  3 ++
 .../arch/powerpc/entry/syscalls/Makefile.syscalls  |  6 ++++
 .../perf/arch/powerpc/entry/syscalls/mksyscalltbl  | 39 ----------------------
 tools/perf/arch/powerpc/include/syscall_table.h    |  8 +++++
 tools/perf/util/syscalltbl.c                       |  8 -----
 8 files changed, 20 insertions(+), 75 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index ce7e9ae276e8..76dbd368aa9f 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,12 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc s390))
+  ifeq ($(SRCARCH),s390)
     NO_SYSCALL_TABLE := 0
   endif
 
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c9b78518c9a5..c42cc4901005 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index bf6d323574f6..42dab7c8f508 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -6,28 +6,3 @@ endif
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 PERF_HAVE_JITDUMP := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/powerpc/include/generated/asm
-header32 := $(out)/syscalls_32.c
-header64 := $(out)/syscalls_64.c
-sysprf := $(srctree)/tools/perf/arch/powerpc/entry/syscalls
-sysdef := $(sysprf)/syscall.tbl
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header64): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '64' $(sysdef) > $@
-
-$(header32): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' '32' $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, powerpc) $(RM) $(header32) $(header64)
-
-archheaders: $(header32) $(header64)
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Kbuild b/tools/perf/arch/powerpc/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..84c6599b4ea6
--- /dev/null
+++ b/tools/perf/arch/powerpc/entry/syscalls/Kbuild
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_32.h
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls b/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..f7e87a61401c
--- /dev/null
+++ b/tools/perf/arch/powerpc/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_32 += spu nospu
+syscall_abis_64 += spu nospu
+
+syscalltbl = $(srctree)/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl b/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 0eb316fe6dd1..000000000000
--- a/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf. Derived from
-# s390 script.
-#
-# Copyright IBM Corp. 2017
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-# Changed by: Ravi Bangoria <ravi.bangoria at linux.vnet.ibm.com>
-
-wordsize=$1
-SYSCALL_TBL=$2
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local wordsize=$1
-	local max_nr nr abi sc discard
-	max_nr=-1
-	nr=0
-
-	echo "static const char *const syscalltbl_powerpc_${wordsize}[] = {"
-	while read nr abi sc discard; do
-		if [ "$max_nr" -lt "$nr" ]; then
-			printf '\t[%d] = "%s",\n' $nr $sc
-			max_nr=$nr
-		fi
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_POWERPC_${wordsize}_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(common|spu|nospu|${wordsize})" $SYSCALL_TBL \
-	|sort -k1 -n                                                           \
-	|create_table ${wordsize}
diff --git a/tools/perf/arch/powerpc/include/syscall_table.h b/tools/perf/arch/powerpc/include/syscall_table.h
new file mode 100644
index 000000000000..7ff51b783000
--- /dev/null
+++ b/tools/perf/arch/powerpc/include/syscall_table.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 64
+#include <asm/syscalls_64.h>
+#else
+#include <asm/syscalls_32.h>
+#endif
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 724e1391893f..4320876242ae 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -17,14 +17,6 @@
 #include <asm/syscalls_64.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl_s390_64;
-#elif defined(__powerpc64__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_powerpc_64;
-#elif defined(__powerpc__)
-#include <asm/syscalls_32.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_powerpc_32;
 #elif defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:17 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:17 -0800
Subject: [PATCH RFT 15/16] perf tools: s390: Use generic syscall table
 scripts
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-15-9adae5c761ef@rivosinc.com>

Use the generic scripts to generate headers from the syscall table
instead of the custom ones for s390.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/perf/Makefile.config                         |  6 +---
 tools/perf/Makefile.perf                           |  2 +-
 tools/perf/arch/s390/Makefile                      | 21 --------------
 tools/perf/arch/s390/entry/syscalls/Kbuild         |  2 ++
 .../arch/s390/entry/syscalls/Makefile.syscalls     |  5 ++++
 tools/perf/arch/s390/entry/syscalls/mksyscalltbl   | 32 ----------------------
 tools/perf/arch/s390/include/syscall_table.h       |  2 ++
 tools/perf/util/syscalltbl.c                       |  6 +---
 8 files changed, 12 insertions(+), 64 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 76dbd368aa9f..787be3201eec 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -31,12 +31,8 @@ $(call detected_var,SRCARCH)
 ifneq ($(NO_SYSCALL_TABLE),1)
   NO_SYSCALL_TABLE := 1
 
-  ifeq ($(SRCARCH),s390)
-    NO_SYSCALL_TABLE := 0
-  endif
-
   # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc))
+  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390))
     NO_SYSCALL_TABLE := 0
     CFLAGS += -DGENERIC_SYSCALL_TABLE
     CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index c42cc4901005..410d850f7b9a 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -311,7 +311,7 @@ FEATURE_TESTS := all
 endif
 endif
 # architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc))
+ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
 endif
 include Makefile.config
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
index 56994e63b43a..51dd7d7827e5 100644
--- a/tools/perf/arch/s390/Makefile
+++ b/tools/perf/arch/s390/Makefile
@@ -5,24 +5,3 @@ endif
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 PERF_HAVE_JITDUMP := 1
-
-#
-# Syscall table generation for perf
-#
-
-out    := $(OUTPUT)arch/s390/include/generated/asm
-header := $(out)/syscalls_64.c
-sysprf := $(srctree)/tools/perf/arch/s390/entry/syscalls
-sysdef := $(sysprf)/syscall.tbl
-systbl := $(sysprf)/mksyscalltbl
-
-# Create output directory if not already present
-$(shell [ -d '$(out)' ] || mkdir -p '$(out)')
-
-$(header): $(sysdef) $(systbl)
-	$(Q)$(SHELL) '$(systbl)' $(sysdef) > $@
-
-clean::
-	$(call QUIET_CLEAN, s390) $(RM) $(header)
-
-archheaders: $(header)
diff --git a/tools/perf/arch/s390/entry/syscalls/Kbuild b/tools/perf/arch/s390/entry/syscalls/Kbuild
new file mode 100644
index 000000000000..9a41e3572c3a
--- /dev/null
+++ b/tools/perf/arch/s390/entry/syscalls/Kbuild
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+syscall-y += syscalls_64.h
diff --git a/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls b/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
new file mode 100644
index 000000000000..9762d7abf17c
--- /dev/null
+++ b/tools/perf/arch/s390/entry/syscalls/Makefile.syscalls
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+syscall_abis_64 += renameat rlimit memfd_secret
+
+syscalltbl = $(srctree)/tools/perf/arch/s390/entry/syscalls/syscall.tbl
diff --git a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl b/tools/perf/arch/s390/entry/syscalls/mksyscalltbl
deleted file mode 100755
index 52eb88a77c94..000000000000
--- a/tools/perf/arch/s390/entry/syscalls/mksyscalltbl
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Generate system call table for perf
-#
-# Copyright IBM Corp. 2017, 2018
-# Author(s):  Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
-#
-
-SYSCALL_TBL=$1
-
-if ! test -r $SYSCALL_TBL; then
-	echo "Could not read input file" >&2
-	exit 1
-fi
-
-create_table()
-{
-	local max_nr nr abi sc discard
-
-	echo 'static const char *const syscalltbl_s390_64[] = {'
-	while read nr abi sc discard; do
-		printf '\t[%d] = "%s",\n' $nr $sc
-		max_nr=$nr
-	done
-	echo '};'
-	echo "#define SYSCALLTBL_S390_64_MAX_ID $max_nr"
-}
-
-grep -E "^[[:digit:]]+[[:space:]]+(common|64)" $SYSCALL_TBL	\
-	|sort -k1 -n					\
-	|create_table
diff --git a/tools/perf/arch/s390/include/syscall_table.h b/tools/perf/arch/s390/include/syscall_table.h
new file mode 100644
index 000000000000..b53e31c15805
--- /dev/null
+++ b/tools/perf/arch/s390/include/syscall_table.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/syscalls_64.h>
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 4320876242ae..9341f0d442fe 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -13,11 +13,7 @@
 #include <string.h>
 #include "string2.h"
 
-#if defined(__s390x__)
-#include <asm/syscalls_64.c>
-const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl_s390_64;
-#elif defined(GENERIC_SYSCALL_TABLE)
+#if defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl;

-- 
2.34.1



From charlie at rivosinc.com  Mon Nov  4 13:06:18 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 04 Nov 2024 13:06:18 -0800
Subject: [PATCH RFT 16/16] perf tools: Remove dependency on libaudit
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <20241104-perf_syscalltbl-v1-16-9adae5c761ef@rivosinc.com>

All architectures now support HAVE_SYSCALL_TABLE_SUPPORT, so the flag is
no longer needed. With the removal of the flag, the related
GENERIC_SYSCALL_TABLE can also be removed. libaudit was only used as a
fallback for when HAVE_SYSCALL_TABLE_SUPPORT was not defined, so
libaudit is also no longer needed for any architecture.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 Documentation/admin-guide/workload-tracing.rst |  2 +-
 tools/build/feature/Makefile                   |  4 --
 tools/build/feature/test-libaudit.c            | 11 ------
 tools/perf/Documentation/perf-check.txt        |  1 -
 tools/perf/Makefile.config                     | 31 +--------------
 tools/perf/Makefile.perf                       | 14 -------
 tools/perf/builtin-check.c                     |  1 -
 tools/perf/builtin-help.c                      |  2 -
 tools/perf/builtin-trace.c                     | 30 ---------------
 tools/perf/perf.c                              |  6 +--
 tools/perf/tests/make                          |  7 +---
 tools/perf/util/env.c                          |  4 +-
 tools/perf/util/generate-cmdlist.sh            |  4 +-
 tools/perf/util/syscalltbl.c                   | 52 --------------------------
 14 files changed, 10 insertions(+), 159 deletions(-)

diff --git a/Documentation/admin-guide/workload-tracing.rst b/Documentation/admin-guide/workload-tracing.rst
index b2e254ec8ee8..6be38c1b9c5b 100644
--- a/Documentation/admin-guide/workload-tracing.rst
+++ b/Documentation/admin-guide/workload-tracing.rst
@@ -83,7 +83,7 @@ scripts/ver_linux is a good way to check if your system already has
 the necessary tools::
 
   sudo apt-get build-essentials flex bison yacc
-  sudo apt install libelf-dev systemtap-sdt-dev libaudit-dev libslang2-dev libperl-dev libdw-dev
+  sudo apt install libelf-dev systemtap-sdt-dev libslang2-dev libperl-dev libdw-dev
 
 cscope is a good tool to browse kernel sources. Let's install it now::
 
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 1658596188bf..728420d3888f 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -15,7 +15,6 @@ FILES=                                          \
          test-gtk2.bin                          \
          test-gtk2-infobar.bin                  \
          test-hello.bin                         \
-         test-libaudit.bin                      \
          test-libbfd.bin                        \
          test-libbfd-buildid.bin		\
          test-disassembler-four-args.bin        \
@@ -236,9 +235,6 @@ $(OUTPUT)test-libunwind-debug-frame-arm.bin:
 $(OUTPUT)test-libunwind-debug-frame-aarch64.bin:
 	$(BUILD) -lelf -llzma -lunwind-aarch64
 
-$(OUTPUT)test-libaudit.bin:
-	$(BUILD) -laudit
-
 $(OUTPUT)test-libslang.bin:
 	$(BUILD) -lslang
 
diff --git a/tools/build/feature/test-libaudit.c b/tools/build/feature/test-libaudit.c
deleted file mode 100644
index f5b0863fa1ec..000000000000
--- a/tools/build/feature/test-libaudit.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <libaudit.h>
-
-extern int printf(const char *format, ...);
-
-int main(void)
-{
-	printf("error message: %s\n", audit_errno_to_name(0));
-
-	return audit_open();
-}
diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt
index 10f69fb6850b..27e6b97961f3 100644
--- a/tools/perf/Documentation/perf-check.txt
+++ b/tools/perf/Documentation/perf-check.txt
@@ -51,7 +51,6 @@ feature::
                 dwarf_getlocations      /  HAVE_DWARF_GETLOCATIONS_SUPPORT
                 dwarf-unwind            /  HAVE_DWARF_UNWIND_SUPPORT
                 auxtrace                /  HAVE_AUXTRACE_SUPPORT
-                libaudit                /  HAVE_LIBAUDIT_SUPPORT
                 libbfd                  /  HAVE_LIBBFD_SUPPORT
                 libcapstone             /  HAVE_LIBCAPSTONE_SUPPORT
                 libcrypto               /  HAVE_LIBCRYPTO_SUPPORT
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 787be3201eec..352f32f5cb81 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -28,20 +28,7 @@ include $(srctree)/tools/scripts/Makefile.arch
 
 $(call detected_var,SRCARCH)
 
-ifneq ($(NO_SYSCALL_TABLE),1)
-  NO_SYSCALL_TABLE := 1
-
-  # architectures that use the generic syscall table scripts
-  ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390))
-    NO_SYSCALL_TABLE := 0
-    CFLAGS += -DGENERIC_SYSCALL_TABLE
-    CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
-  endif
-
-  ifneq ($(NO_SYSCALL_TABLE),1)
-    CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
-  endif
-endif
+CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated
 
 # Additional ARCH settings for ppc
 ifeq ($(SRCARCH),powerpc)
@@ -784,21 +771,7 @@ ifndef NO_LIBUNWIND
 endif
 
 ifneq ($(NO_LIBTRACEEVENT),1)
-  ifeq ($(NO_SYSCALL_TABLE),0)
-    $(call detected,CONFIG_TRACE)
-  else
-    ifndef NO_LIBAUDIT
-      $(call feature_check,libaudit)
-      ifneq ($(feature-libaudit), 1)
-        $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev)
-        NO_LIBAUDIT := 1
-      else
-        CFLAGS += -DHAVE_LIBAUDIT_SUPPORT
-        EXTLIBS += -laudit
-        $(call detected,CONFIG_TRACE)
-      endif
-    endif
-  endif
+  $(call detected,CONFIG_TRACE)
 endif
 
 ifndef NO_LIBCRYPTO
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 410d850f7b9a..a21d4d0994af 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -59,8 +59,6 @@ include ../scripts/utilities.mak
 #
 # Define NO_LIBNUMA if you do not want numa perf benchmark
 #
-# Define NO_LIBAUDIT if you do not want libaudit support
-#
 # Define NO_LIBBIONIC if you do not want bionic support
 #
 # Define NO_LIBCRYPTO if you do not want libcrypto (openssl) support
@@ -119,10 +117,6 @@ include ../scripts/utilities.mak
 #
 # Define LIBBPF_DYNAMIC to enable libbpf dynamic linking.
 #
-# Define NO_SYSCALL_TABLE=1 to disable the use of syscall id to/from name tables
-# generated from the kernel .tbl or unistd.h files and use, if available, libaudit
-# for doing the conversions to/from strings/id.
-#
 # Define NO_LIBPFM4 to disable libpfm4 events extension.
 #
 # Define NO_LIBDEBUGINFOD if you do not want support debuginfod
@@ -310,10 +304,7 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump)
 FEATURE_TESTS := all
 endif
 endif
-# architectures that use the generic syscall table
-ifeq ($(SRCARCH),$(filter $(SRCARCH),riscv arc csky arm sh sparc xtensa x86 alpha parisc arm64 loongarch mips powerpc s390))
 include $(srctree)/tools/perf/scripts/Makefile.syscalls
-endif
 include Makefile.config
 endif
 
@@ -1098,11 +1089,6 @@ endif
 		$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 	$(call QUIET_INSTALL, perf-iostat) \
 		$(INSTALL) $(OUTPUT)perf-iostat -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
-ifndef NO_LIBAUDIT
-	$(call QUIET_INSTALL, strace/groups) \
-		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'; \
-		$(INSTALL) trace/strace/groups/* -m 644 -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'
-endif
 ifndef NO_LIBPERL
 	$(call QUIET_INSTALL, perl-scripts) \
 		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
index 0b76b6e42b78..5af0987d7d4c 100644
--- a/tools/perf/builtin-check.c
+++ b/tools/perf/builtin-check.c
@@ -31,7 +31,6 @@ struct feature_status supported_features[] = {
 	FEATURE_STATUS("dwarf_getlocations", HAVE_DWARF_GETLOCATIONS_SUPPORT),
 	FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT),
 	FEATURE_STATUS("auxtrace", HAVE_AUXTRACE_SUPPORT),
-	FEATURE_STATUS("libaudit", HAVE_LIBAUDIT_SUPPORT),
 	FEATURE_STATUS("libbfd", HAVE_LIBBFD_SUPPORT),
 	FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT),
 	FEATURE_STATUS("libcrypto", HAVE_LIBCRYPTO_SUPPORT),
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 0854d3cd9f6a..7be6fb6df595 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -447,9 +447,7 @@ int cmd_help(int argc, const char **argv)
 #ifdef HAVE_LIBELF_SUPPORT
 		"probe",
 #endif
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
 		"trace",
-#endif
 	NULL };
 	const char *builtin_help_usage[] = {
 		"perf help [--all] [--man|--web|--info] [command]",
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d3f11b90d025..0374dedaa2ef 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2069,30 +2069,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
 	const char *name = syscalltbl__name(trace->sctbl, id);
 	int err;
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 	if (trace->syscalls.table == NULL) {
 		trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc));
 		if (trace->syscalls.table == NULL)
 			return -ENOMEM;
 	}
-#else
-	if (id > trace->sctbl->syscalls.max_id || (id == 0 && trace->syscalls.table == NULL)) {
-		// When using libaudit we don't know beforehand what is the max syscall id
-		struct syscall *table = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
-
-		if (table == NULL)
-			return -ENOMEM;
-
-		// Need to memset from offset 0 and +1 members if brand new
-		if (trace->syscalls.table == NULL)
-			memset(table, 0, (id + 1) * sizeof(*sc));
-		else
-			memset(table + trace->sctbl->syscalls.max_id + 1, 0, (id - trace->sctbl->syscalls.max_id) * sizeof(*sc));
-
-		trace->syscalls.table	      = table;
-		trace->sctbl->syscalls.max_id = id;
-	}
-#endif
 	sc = trace->syscalls.table + id;
 	if (sc->nonexistent)
 		return -EEXIST;
@@ -2439,18 +2420,7 @@ static struct syscall *trace__syscall_info(struct trace *trace,
 
 	err = -EINVAL;
 
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 	if (id > trace->sctbl->syscalls.max_id) {
-#else
-	if (id >= trace->sctbl->syscalls.max_id) {
-		/*
-		 * With libaudit we don't know beforehand what is the max_id,
-		 * so we let trace__read_syscall_info() figure that out as we
-		 * go on reading syscalls.
-		 */
-		err = trace__read_syscall_info(trace, id);
-		if (err)
-#endif
 		goto out_cant_read;
 	}
 
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 4def800f4089..9f99c6979409 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -84,7 +84,7 @@ static struct cmd_struct commands[] = {
 #endif
 	{ "kvm",	cmd_kvm,	0 },
 	{ "test",	cmd_test,	0 },
-#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))
+#if defined(HAVE_LIBTRACEEVENT)
 	{ "trace",	cmd_trace,	0 },
 #endif
 	{ "inject",	cmd_inject,	0 },
@@ -514,10 +514,6 @@ int main(int argc, const char **argv)
 		fprintf(stderr,
 			"trace command not available: missing libtraceevent devel package at build time.\n");
 		goto out;
-#elif !defined(HAVE_LIBAUDIT_SUPPORT) && !defined(HAVE_SYSCALL_TABLE_SUPPORT)
-		fprintf(stderr,
-			"trace command not available: missing audit-libs devel package at build time.\n");
-		goto out;
 #else
 		setup_path();
 		argv[0] = "trace";
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index a5040772043f..0d2b6c85dc03 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -86,7 +86,6 @@ make_no_libdw_dwarf_unwind := NO_LIBDW_DWARF_UNWIND=1
 make_no_backtrace   := NO_BACKTRACE=1
 make_no_libcapstone := NO_CAPSTONE=1
 make_no_libnuma     := NO_LIBNUMA=1
-make_no_libaudit    := NO_LIBAUDIT=1
 make_no_libbionic   := NO_LIBBIONIC=1
 make_no_auxtrace    := NO_AUXTRACE=1
 make_no_libbpf	    := NO_LIBBPF=1
@@ -97,7 +96,6 @@ make_no_libllvm     := NO_LIBLLVM=1
 make_with_babeltrace:= LIBBABELTRACE=1
 make_with_coresight := CORESIGHT=1
 make_no_sdt	    := NO_SDT=1
-make_no_syscall_tbl := NO_SYSCALL_TABLE=1
 make_no_libpfm4     := NO_LIBPFM4=1
 make_with_gtk2      := GTK2=1
 make_refcnt_check   := EXTRA_CFLAGS="-DREFCNT_CHECKING=1"
@@ -122,10 +120,10 @@ make_static         := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX3
 # all the NO_* variable combined
 make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_GTK2=1
 make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
-make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
+make_minimal        += NO_LIBNUMA=1 NO_LIBBIONIC=1
 make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
 make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
-make_minimal        += NO_LIBCAP=1 NO_SYSCALL_TABLE=1 NO_CAPSTONE=1
+make_minimal        += NO_LIBCAP=1 NO_CAPSTONE=1
 
 # $(run) contains all available tests
 run := make_pure
@@ -158,7 +156,6 @@ run += make_no_libdw_dwarf_unwind
 run += make_no_backtrace
 run += make_no_libcapstone
 run += make_no_libnuma
-run += make_no_libaudit
 run += make_no_libbionic
 run += make_no_auxtrace
 run += make_no_libbpf
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index 1edbccfc3281..4d915adc7239 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -471,13 +471,13 @@ const char *perf_env__arch(struct perf_env *env)
 
 const char *perf_env__arch_strerrno(struct perf_env *env __maybe_unused, int err __maybe_unused)
 {
-#if defined(HAVE_SYSCALL_TABLE_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#if defined(HAVE_LIBTRACEEVENT)
 	if (env->arch_strerrno == NULL)
 		env->arch_strerrno = arch_syscalls__strerrno_function(perf_env__arch(env));
 
 	return env->arch_strerrno ? env->arch_strerrno(err) : "no arch specific strerrno function";
 #else
-	return "!(HAVE_SYSCALL_TABLE_SUPPORT && HAVE_LIBTRACEEVENT)";
+	return "!HAVE_LIBTRACEEVENT";
 #endif
 }
 
diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh
index 1b5140e5ce99..6a73c903d690 100755
--- a/tools/perf/util/generate-cmdlist.sh
+++ b/tools/perf/util/generate-cmdlist.sh
@@ -38,7 +38,7 @@ do
 done
 echo "#endif /* HAVE_LIBELF_SUPPORT */"
 
-echo "#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))"
+echo "#if defined(HAVE_LIBTRACEEVENT)"
 sed -n -e 's/^perf-\([^ 	]*\)[ 	].* audit*/\1/p' command-list.txt |
 sort |
 while read cmd
@@ -51,7 +51,7 @@ do
 	    p
      }' "Documentation/perf-$cmd.txt"
 done
-echo "#endif /* HAVE_LIBTRACEEVENT && (HAVE_LIBAUDIT_SUPPORT || HAVE_SYSCALL_TABLE_SUPPORT) */"
+echo "#endif /* HAVE_LIBTRACEEVENT */"
 
 echo "#ifdef HAVE_LIBTRACEEVENT"
 sed -n -e 's/^perf-\([^ 	]*\)[ 	].* traceevent.*/\1/p' command-list.txt |
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 9341f0d442fe..7e24e4164da9 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -9,20 +9,12 @@
 #include <stdlib.h>
 #include <linux/compiler.h>
 #include <linux/zalloc.h>
-#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 #include <string.h>
 #include "string2.h"
 
-#if defined(GENERIC_SYSCALL_TABLE)
 #include <syscall_table.h>
 const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
 static const char *const *syscalltbl_native = syscalltbl;
-#else
-const int syscalltbl_native_max_id = 0;
-static const char *const syscalltbl_native[] = {
-	[0] = "unknown",
-};
-#endif
 
 struct syscall {
 	int id;
@@ -130,47 +122,3 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
 	*idx = -1;
 	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 }
-
-#else /* HAVE_SYSCALL_TABLE_SUPPORT */
-
-#include <libaudit.h>
-
-struct syscalltbl *syscalltbl__new(void)
-{
-	struct syscalltbl *tbl = zalloc(sizeof(*tbl));
-	if (tbl)
-		tbl->audit_machine = audit_detect_machine();
-	return tbl;
-}
-
-void syscalltbl__delete(struct syscalltbl *tbl)
-{
-	free(tbl);
-}
-
-const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
-{
-	return audit_syscall_to_name(id, tbl->audit_machine);
-}
-
-int syscalltbl__id(struct syscalltbl *tbl, const char *name)
-{
-	return audit_name_to_syscall(name, tbl->audit_machine);
-}
-
-int syscalltbl__id_at_idx(struct syscalltbl *tbl __maybe_unused, int idx)
-{
-	return idx;
-}
-
-int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
-				  const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
-{
-	return -1;
-}
-
-int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
-{
-	return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
-}
-#endif /* HAVE_SYSCALL_TABLE_SUPPORT */

-- 
2.34.1



From arnd at arndb.de  Mon Nov  4 13:13:18 2024
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 04 Nov 2024 22:13:18 +0100
Subject: [PATCH RFT 00/16] perf tools: Use generic syscall scripts for all archs
In-Reply-To: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
Message-ID: <3b56fc50-4c6c-4520-adba-461797a3b5ec@app.fastmail.com>

On Mon, Nov 4, 2024, at 22:06, Charlie Jenkins wrote:
> Standardize the generation of syscall headers around syscall tables.
> Previously each architecture independently selected how syscall headers
> would be generated, or would not define a way and fallback onto
> libaudit. Convert all architectures to use a standard syscall header
> generation script and allow each architecture to override the syscall
> table to use if they do not use the generic table.
>
> As a result of these changes, no architecture will require libaudit, and
> so the fallback case of using libaudit is removed by this series.
>
> Testing:
>
> I have tested that the syscall mappings of id to name generation works
> as expected for every architecture, but I have only validated that perf
> trace compiles and runs as expected on riscv, arm64, and x86_64.
>
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>

Thanks for doing this, I had plans to do this myself, but hadn't
completed that bit so far. I'm travelling at the moment, so I'm
not sure I have time to look at it in enough detail this week.

One problem I ran into doing this previously was the incompatible
format of the tables for x86 and s390, which have conflicting
interpretations of what the '-' character means. It's possible
that this is only really relevant for the in-kernel table,
not the version in tools.

     Arnd


From david at redhat.com  Mon Nov  4 13:30:53 2024
From: david at redhat.com (David Hildenbrand)
Date: Mon, 4 Nov 2024 22:30:53 +0100
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <90c9d8c0-814e-4c86-86ef-439cb5552cb6@amazon.co.uk>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <4aa0ccf4-ebbe-4244-bc85-8bc8dcd14e74@redhat.com>
 <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
 <d1a69eb7-85d5-4ffa-88e2-f4841713c1d7@redhat.com>
 <90c9d8c0-814e-4c86-86ef-439cb5552cb6@amazon.co.uk>
Message-ID: <10e4d078-3cdb-4d1c-a1a3-80e91b247217@redhat.com>

>> We talked about shared (faultable) vs. private (unfaultable), and how it
>> would interact with the directmap patches here.
>>
>> As discussed, having private (unfaultable) memory with the direct-map
>> removed and shared (faultable) memory with the direct-mapping can make
>> sense for non-TDX/AMD-SEV/... non-CoCo use cases. Not sure about CoCo,
>> the discussion here seems to indicate that it might currently not be
>> required.
>>
>> So one thing we could do is that shared (faultable) will have a direct
>> mapping and be gup-able and private (unfaultable) memory will not have a
>> direct mapping and is, by design, not gup-able.>
>> Maybe it could make sense to not have a direct map for all guest_memfd
>> memory, making it behave like secretmem (and it would be easy to
>> implement)? But I'm not sure if that is really desirable in VM context.
> 
> This would work for us (in this scenario, the swiotlb areas would be
> "traditional" memory, e.g. set to shared via mem attributes instead of
> "shared" inside KVM), it's kinda what I had prototyped in my v1 of this
> series (well, we'd need to figure out how to get the mappings of gmem
> back into KVM, since in this setup, short-circuiting it into
> userspace_addr wouldn't work, unless we banish swiotlb into a different
> memslot altogether somehow).

Right.

> But I don't think it'd work for pKVM, iirc
> they need GUP on gmem, and also want direct map removal (... but maybe,
> the gmem VMA for non-CoCo usecase and the gmem VMA for pKVM could be
> behave differently?  non-CoCo gets essentially memfd_secret, pKVM gets
> GUP+no faults of private mem).

Good question. So far my perception was that the directmap removal on 
"private/unfaultable" would be sufficient.

> 
>> Having a mixture of "has directmap" and "has no directmap" for shared
>> (faultable) memory should not be done. Similarly, private memory really
>> should stay "unfaultable".
> 
> You've convinced me that having both GUP-able and non GUP-able
> memory in the same VMA will be tricky. However, I'm less convinced on
> why private memory should stay unfaultable; only that it shouldn't be
> faultable into a VMA that also allows GUP. Can we have two VMAs? One
> that disallows GUP, but allows userspace access to shared and private,
> and one that allows GUP, but disallows accessing private memory? Maybe
> via some `PROT_NOGUP` flag to `mmap`? I guess this is a slightly
> different spin of the above idea.

What we are trying to achieve is making guest_memfd not behave 
completely different on that level for different "types" of VMs. So one 
of the goals should be to try to unify it as much as possible.

shared -> faultable: GUP-able
private -> unfaultable: unGUP-able


And it makes sense, because a lot of future work will rely on some 
important properties: for example, if private memory cannot be faulted 
in + GUPed, core-MM will never have obtained valid references to such a 
page. There is no need to split large folios into smaller ones for 
tracking purposes; there is no need to maintain per-page refcounts and 
pincounts ...

It doesn't mean that we cannot consider it if really required, but there 
really has to be a strong case for it, because it will all get really messy.

For example, one issue is that a folio only has a single mapping 
(folio->mapping), and that is used in the GUP-fast path (no VMA) to 
determine whether GUP-fast is allowed or not.

So you'd have to force everything through GUP-slow, where you could 
consider VMA properties :( It sounds quite suboptimal.

I don't think multiple VMAs are what we really want. See below.

> 
>> I think one of the points raised during the bi-weekly call was that
>> using a viommu/swiotlb might be the right call, such that all memory can
>> be considered private (unfaultable) that is not explicitly
>> shared/expected to be modified by the hypervisor (-> faultable, ->
>> GUP-able).
>>
>> Further, I think Sean had some good points why we should explore that
>> direction, but I recall that there were some issue to be sorted out
>> (interpreted instructions requiring direct map when accessing "private"
>> memory?), not sure if that is already working/can be made working in KVM.
> 
> Yeah, the big one is MMIO instruction emulation on x86, which does guest
> page table walks and instruction fetch (and particularly the latter
> cannot be known ahead-of-time by the guest, aka cannot be explicitly
> "shared"). That's what the majority of my v2 series was about. For
> traditional memslots, KVM handles these via get_user and friends, but if
> we don't have a VMA that allows faulting all of gmem, then that's
> impossible, and we're in "temporarily restore direct map" land. Which
> comes with significantly performance penalties due to TLB flushes.

Agreed.

 > >> What's your opinion after the call and the next step for use cases 
like
>> you have in mind (IIRC firecracker, which wants to not have the
>> direct-map for guest memory where it can be avoided)?
> 
> Yea, the usecase is for Firecracker to not have direct map entries for
> guest memory, unless needed for I/O (-> swiotlb).
> 
> As for next steps, let's determine once and for all if we can do the
> KVM-internal guest memory accesses for MMIO emulation through userspace
> mappings (although if we can't I'll have some serious soul-searching to
> do, because all other solutions we talked about so far also have fairly
> big drawbacks; on-demand direct map reinsertion has terrible
> performance
So IIUC, KVM would have to access "unfaultable" guest_memfd memory using 
fd+offset, and that's problematic because "no-directmap".

So you'd have to map+unmap the directmap repeatedly, and still expose it 
temporarily in the direct map to others. I see how that is undesirable, 
even when trying to cache hotspots (partly destroying the purpose of the 
directmap removal).


Would a per-MM kernel mapping of these pages work, so KVM can access them?

It sounds a bit like what is required for clean per-MM allocations [1]: 
establish a per-MM kernel mapping of (selected?) pages. Not necessarily 
all of them.

Yes, we'd be avoiding VMAs, GUP, mapcounts, pincounts and everything 
involved with ordinary user mappings for these private/unfaultable 
thingies. Just like as discussed in, and similar to [1].

Just throwing it out there, maybe we really want to avoid the directmap 
(keep it unmapped) and maintain a per-mm mapping for a bunch of folios 
that can be easily removed when required by guest_memfd (ftruncate, 
conversion private->shared) on request.

[1] https://lore.kernel.org/all/20240911143421.85612-1-faresx at amazon.de/T/#u

-- 
Cheers,

David / dhildenb



From charlie at rivosinc.com  Mon Nov  4 13:32:53 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 4 Nov 2024 13:32:53 -0800
Subject: [PATCH RFT 00/16] perf tools: Use generic syscall scripts for
 all archs
In-Reply-To: <3b56fc50-4c6c-4520-adba-461797a3b5ec@app.fastmail.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
 <3b56fc50-4c6c-4520-adba-461797a3b5ec@app.fastmail.com>
Message-ID: <Zyk9hX8CB_2rbWsi@ghost>

On Mon, Nov 04, 2024 at 10:13:18PM +0100, Arnd Bergmann wrote:
> On Mon, Nov 4, 2024, at 22:06, Charlie Jenkins wrote:
> > Standardize the generation of syscall headers around syscall tables.
> > Previously each architecture independently selected how syscall headers
> > would be generated, or would not define a way and fallback onto
> > libaudit. Convert all architectures to use a standard syscall header
> > generation script and allow each architecture to override the syscall
> > table to use if they do not use the generic table.
> >
> > As a result of these changes, no architecture will require libaudit, and
> > so the fallback case of using libaudit is removed by this series.
> >
> > Testing:
> >
> > I have tested that the syscall mappings of id to name generation works
> > as expected for every architecture, but I have only validated that perf
> > trace compiles and runs as expected on riscv, arm64, and x86_64.
> >
> > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> 
> Thanks for doing this, I had plans to do this myself, but hadn't
> completed that bit so far. I'm travelling at the moment, so I'm
> not sure I have time to look at it in enough detail this week.
> 
> One problem I ran into doing this previously was the incompatible
> format of the tables for x86 and s390, which have conflicting
> interpretations of what the '-' character means. It's possible
> that this is only really relevant for the in-kernel table,
> not the version in tools.
> 

I don't think that is an issue for this usecase because the only
information that is taken from the syscall table is the number and the
name of the syscall. '-' doesn't appear in either of these columns! 

- Charlie

>      Arnd


From irogers at google.com  Mon Nov  4 14:03:28 2024
From: irogers at google.com (Ian Rogers)
Date: Mon, 4 Nov 2024 14:03:28 -0800
Subject: [PATCH RFT 00/16] perf tools: Use generic syscall scripts for all archs
In-Reply-To: <Zyk9hX8CB_2rbWsi@ghost>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
 <3b56fc50-4c6c-4520-adba-461797a3b5ec@app.fastmail.com> <Zyk9hX8CB_2rbWsi@ghost>
Message-ID: <CAP-5=fUdZRbCp+2ghEUdp+qJ1BuMDuTtw9R+dFAaom+3oqQV_g@mail.gmail.com>

On Mon, Nov 4, 2024 at 1:32?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
>
> On Mon, Nov 04, 2024 at 10:13:18PM +0100, Arnd Bergmann wrote:
> > On Mon, Nov 4, 2024, at 22:06, Charlie Jenkins wrote:
> > > Standardize the generation of syscall headers around syscall tables.
> > > Previously each architecture independently selected how syscall headers
> > > would be generated, or would not define a way and fallback onto
> > > libaudit. Convert all architectures to use a standard syscall header
> > > generation script and allow each architecture to override the syscall
> > > table to use if they do not use the generic table.
> > >
> > > As a result of these changes, no architecture will require libaudit, and
> > > so the fallback case of using libaudit is removed by this series.
> > >
> > > Testing:
> > >
> > > I have tested that the syscall mappings of id to name generation works
> > > as expected for every architecture, but I have only validated that perf
> > > trace compiles and runs as expected on riscv, arm64, and x86_64.
> > >
> > > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> >
> > Thanks for doing this, I had plans to do this myself, but hadn't
> > completed that bit so far. I'm travelling at the moment, so I'm
> > not sure I have time to look at it in enough detail this week.
> >
> > One problem I ran into doing this previously was the incompatible
> > format of the tables for x86 and s390, which have conflicting
> > interpretations of what the '-' character means. It's possible
> > that this is only really relevant for the in-kernel table,
> > not the version in tools.
> >
>
> I don't think that is an issue for this usecase because the only
> information that is taken from the syscall table is the number and the
> name of the syscall. '-' doesn't appear in either of these columns!

This is cool stuff. An area that may not be immediately apparent for
improvement is that the x86-64 build only has access to the 64-bit
syscall table. Perhaps all the syscall tables should always be built
and then at runtime the architecture of the perf.data file, etc. used
to choose the appropriate one. The cleanup to add an ELF host #define
could help with this:
https://lore.kernel.org/linux-perf-users/20241017002520.59124-1-irogers at google.com/

Ultimately I'd like to see less arch code as it inherently makes cross
platform worker harder. That doesn't impact this work which I'm happy
to review.

Thanks,
Ian


From nathan at kernel.org  Mon Nov  4 15:27:41 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Mon, 4 Nov 2024 16:27:41 -0700
Subject: [PATCH v7 6/8] x86/module: prepare module loading for ROX
 allocations of text
In-Reply-To: <20241023162711.2579610-7-rppt@kernel.org>
References: <20241023162711.2579610-1-rppt@kernel.org>
 <20241023162711.2579610-7-rppt@kernel.org>
Message-ID: <20241104232741.GA3843610@thelio-3990X>

Hi Mike,

On Wed, Oct 23, 2024 at 07:27:09PM +0300, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt at kernel.org>
> 
> When module text memory will be allocated with ROX permissions, the
> memory at the actual address where the module will live will contain
> invalid instructions and there will be a writable copy that contains the
> actual module code.
> 
> Update relocations and alternatives patching to deal with it.
> 
> Signed-off-by: Mike Rapoport (Microsoft) <rppt at kernel.org>
> Tested-by: kdevops <kdevops at lists.linux.dev>

Hopefully the last time you have to hear from me, as I am only
experiencing issues with only one of my test machines at this point and
it is my only machine that supports IBT, so it seems to point to
something specific with the IBT part of the FineIBT support. I notice
either a boot hang or an almost immediate reboot (triple fault?). I
guess this is how I missed reporting this earlier, as my machine was
falling back to the default distribution kernel after the restart and I
did not notice I was not actually testing a -next kernel.

Checking out the version of this change that is in next-20241104, commit
7ca6ed09db62 ("x86/module: prepare module loading for ROX allocations of
text"), it boots with either 'cfi=off' or 'cfi=kcfi' but it exhibits the
issues noted above with 'cfi=fineibt'. At the immediate parent, commit
b575d981092f ("arch: introduce set_direct_map_valid_noflush()"), all
three combinations boot fine.

  $ uname -r; tr ' ' '\n' </proc/cmdline | grep cfi=

  6.12.0-rc5-debug-00214-g7ca6ed09db62
  cfi=kcfi

  6.12.0-rc5-debug-00214-g7ca6ed09db62
  cfi=off

  6.12.0-rc5-debug-00213-gb575d981092f
  cfi=fineibt

  6.12.0-rc5-debug-00213-gb575d981092f
  cfi=kcfi

  6.12.0-rc5-debug-00213-gb575d981092f
  cfi=off

I do not think this machine has an accessible serial port and I do not
think IBT virtualization is supported via either KVM or TCG in QEMU, so
I am not sure how to get more information about what is going on here. I
wanted to try reverting these changes on top of next-20241104 but there
was a non-trivial conflict in mm/execmem.c due to some changes on top,
so I just tested in the mm history.

If there is any other information I can provide or patches I can test, I
am more than happy to do so.

Cheers,
Nathan


From charlie at rivosinc.com  Mon Nov  4 15:35:33 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Mon, 4 Nov 2024 15:35:33 -0800
Subject: [PATCH RFT 00/16] perf tools: Use generic syscall scripts for
 all archs
In-Reply-To: <CAP-5=fUdZRbCp+2ghEUdp+qJ1BuMDuTtw9R+dFAaom+3oqQV_g@mail.gmail.com>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
 <3b56fc50-4c6c-4520-adba-461797a3b5ec@app.fastmail.com>
 <Zyk9hX8CB_2rbWsi@ghost>
 <CAP-5=fUdZRbCp+2ghEUdp+qJ1BuMDuTtw9R+dFAaom+3oqQV_g@mail.gmail.com>
Message-ID: <ZylaRaMqEsEjYjs6@ghost>

On Mon, Nov 04, 2024 at 02:03:28PM -0800, Ian Rogers wrote:
> On Mon, Nov 4, 2024 at 1:32?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
> >
> > On Mon, Nov 04, 2024 at 10:13:18PM +0100, Arnd Bergmann wrote:
> > > On Mon, Nov 4, 2024, at 22:06, Charlie Jenkins wrote:
> > > > Standardize the generation of syscall headers around syscall tables.
> > > > Previously each architecture independently selected how syscall headers
> > > > would be generated, or would not define a way and fallback onto
> > > > libaudit. Convert all architectures to use a standard syscall header
> > > > generation script and allow each architecture to override the syscall
> > > > table to use if they do not use the generic table.
> > > >
> > > > As a result of these changes, no architecture will require libaudit, and
> > > > so the fallback case of using libaudit is removed by this series.
> > > >
> > > > Testing:
> > > >
> > > > I have tested that the syscall mappings of id to name generation works
> > > > as expected for every architecture, but I have only validated that perf
> > > > trace compiles and runs as expected on riscv, arm64, and x86_64.
> > > >
> > > > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > >
> > > Thanks for doing this, I had plans to do this myself, but hadn't
> > > completed that bit so far. I'm travelling at the moment, so I'm
> > > not sure I have time to look at it in enough detail this week.
> > >
> > > One problem I ran into doing this previously was the incompatible
> > > format of the tables for x86 and s390, which have conflicting
> > > interpretations of what the '-' character means. It's possible
> > > that this is only really relevant for the in-kernel table,
> > > not the version in tools.
> > >
> >
> > I don't think that is an issue for this usecase because the only
> > information that is taken from the syscall table is the number and the
> > name of the syscall. '-' doesn't appear in either of these columns!
> 
> This is cool stuff. An area that may not be immediately apparent for
> improvement is that the x86-64 build only has access to the 64-bit
> syscall table. Perhaps all the syscall tables should always be built
> and then at runtime the architecture of the perf.data file, etc. used
> to choose the appropriate one. The cleanup to add an ELF host #define
> could help with this:
> https://lore.kernel.org/linux-perf-users/20241017002520.59124-1-irogers at google.com/

Oh that's a great idea! I think these changes will make it more seamless
to make that a reality.

> 
> Ultimately I'd like to see less arch code as it inherently makes cross
> platform worker harder. That doesn't impact this work which I'm happy
> to review.

Yeah I agree. Reducing arch code was the motivation for this change.
There was the issue a couple weeks ago that caused all architectures
that used libaudit to break from commit 7a2fb5619cc1fb53 ("perf trace:
Fix iteration of syscall ids in syscalltbl->entries"), so this change
will eliminate that source of difference between architectures.

- Charlie

> 
> Thanks,
> Ian


From troymitchell988 at gmail.com  Mon Nov  4 17:14:51 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Tue, 5 Nov 2024 09:14:51 +0800
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <502b0b14-0e1f-4a59-85ad-7edeb9d3033d@kernel.org>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <6zx3tqdc5bma2vutexwigzlir6nr6adp7arg4qwl5ieyd3avbu@5yyhv57ttwcl>
 <dbeea869-54cd-43fe-9021-783d641f1278@gmail.com>
 <ariqiukhztgziwwgaauqy6q3pghflnoeuwtag4izwkfmtvi2kh@gnlq4d7jsaw4>
 <6cce463e-25cc-4a07-971f-6260347cb581@gmail.com>
 <502b0b14-0e1f-4a59-85ad-7edeb9d3033d@kernel.org>
Message-ID: <a08384bf-6747-4975-b025-f8fd3685fc30@gmail.com>


On 2024/11/4 22:48, Krzysztof Kozlowski wrote:
> On 04/11/2024 14:01, Troy Mitchell wrote:
>>
>> On 2024/10/31 16:00, Krzysztof Kozlowski wrote:
>>> On Tue, Oct 29, 2024 at 04:36:00PM +0800, Troy Mitchell wrote:
>>>> On 2024/10/28 15:38, Krzysztof Kozlowski wrote:
>>>>> On Mon, Oct 28, 2024 at 01:32:19PM +0800, Troy Mitchell wrote:
>>>>>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
>>>>>> and supports FIFO transmission.
>>>>>>
>>>>>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>>>>>> ---
>> Change in v2:
>>  - Change the maxItems of reg from 1 to 2 in properties
> 
> Why?
I need the address and size. In v1, I wrote it as 1, and I got the make
dt_binding_check error.
> 
>>  - Change 'i2c' to 'I2C' in the commit message.
>>  - Drop fifo-disable property
>>  - Drop alias in dts example
>>  - Move `unevaluatedProperties` after `required:` block
> 
> Rest look ok.
> 
> Best regards,
> Krzysztof
> 

-- 
Troy Mitchell


From martin.petersen at oracle.com  Mon Nov  4 17:33:47 2024
From: martin.petersen at oracle.com (Martin K. Petersen)
Date: Mon, 04 Nov 2024 20:33:47 -0500
Subject: [PATCH v3 18/18] scsi: target: iscsi: switch to using the
 crc32c library
In-Reply-To: <20241103223154.136127-19-ebiggers@kernel.org> (Eric Biggers's
	message of "Sun, 3 Nov 2024 14:31:54 -0800")
References: <20241103223154.136127-1-ebiggers@kernel.org>
	<20241103223154.136127-19-ebiggers@kernel.org>
Message-ID: <yq1bjyu5usb.fsf@ca-mkp.ca.oracle.com>


Eric,

> Now that the crc32c() library function directly takes advantage of
> architecture-specific optimizations, it is unnecessary to go through
> the crypto API. Just use crc32c(). This is much simpler, and it
> improves performance due to eliminating the crypto API overhead.

Reviewed-by: Martin K. Petersen <martin.petersen at oracle.com>

-- 
Martin K. Petersen	Oracle Linux Engineering


From chao at kernel.org  Mon Nov  4 17:34:23 2024
From: chao at kernel.org (Chao Yu)
Date: Tue, 5 Nov 2024 09:34:23 +0800
Subject: [f2fs-dev] [PATCH v3 17/18] f2fs: switch to using the crc32
 library
In-Reply-To: <20241103223154.136127-18-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
 <20241103223154.136127-18-ebiggers@kernel.org>
Message-ID: <43d8b52e-5e5b-4a37-9a18-6ac392048d92@kernel.org>

On 2024/11/4 6:31, Eric Biggers via Linux-f2fs-devel wrote:
> From: Eric Biggers <ebiggers at google.com>
> 
> Now that the crc32() library function takes advantage of
> architecture-specific optimizations, it is unnecessary to go through the
> crypto API.  Just use crc32().  This is much simpler, and it improves
> performance due to eliminating the crypto API overhead.
> 
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Eric Biggers <ebiggers at google.com>

Acked-by: Chao Yu <chao at kernel.org>

Thanks,


From samuel.holland at sifive.com  Mon Nov  4 18:50:52 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Mon, 4 Nov 2024 20:50:52 -0600
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <a08384bf-6747-4975-b025-f8fd3685fc30@gmail.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <6zx3tqdc5bma2vutexwigzlir6nr6adp7arg4qwl5ieyd3avbu@5yyhv57ttwcl>
 <dbeea869-54cd-43fe-9021-783d641f1278@gmail.com>
 <ariqiukhztgziwwgaauqy6q3pghflnoeuwtag4izwkfmtvi2kh@gnlq4d7jsaw4>
 <6cce463e-25cc-4a07-971f-6260347cb581@gmail.com>
 <502b0b14-0e1f-4a59-85ad-7edeb9d3033d@kernel.org>
 <a08384bf-6747-4975-b025-f8fd3685fc30@gmail.com>
Message-ID: <8a04f84b-453b-44e5-9053-204a08d38e19@sifive.com>

Hi Troy,

On 2024-11-04 7:14 PM, Troy Mitchell wrote:
> 
> On 2024/11/4 22:48, Krzysztof Kozlowski wrote:
>> On 04/11/2024 14:01, Troy Mitchell wrote:
>>>
>>> On 2024/10/31 16:00, Krzysztof Kozlowski wrote:
>>>> On Tue, Oct 29, 2024 at 04:36:00PM +0800, Troy Mitchell wrote:
>>>>> On 2024/10/28 15:38, Krzysztof Kozlowski wrote:
>>>>>> On Mon, Oct 28, 2024 at 01:32:19PM +0800, Troy Mitchell wrote:
>>>>>>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
>>>>>>> and supports FIFO transmission.
>>>>>>>
>>>>>>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>>>>>>> ---
>>> Change in v2:
>>>  - Change the maxItems of reg from 1 to 2 in properties
>>
>> Why?
> I need the address and size. In v1, I wrote it as 1, and I got the make
> dt_binding_check error.

One "<address size>" element is just one item. maxItems > 1 would be for
hardware with multiple discontiguous register ranges: <address1 size1>,
<address2 size2>.

Regards,
Samuel



From ruanjinjie at huawei.com  Mon Nov  4 18:54:54 2024
From: ruanjinjie at huawei.com (Jinjie Ruan)
Date: Tue, 5 Nov 2024 10:54:54 +0800
Subject: [PATCH] docs/zh_CN: add the translation of kbuild/llvm.rst
In-Reply-To: <20241023153235.1291567-1-dzm91@hust.edu.cn>
References: <20241023153235.1291567-1-dzm91@hust.edu.cn>
Message-ID: <d987b09d-985b-8d85-36e6-97ab4e8e222f@huawei.com>



On 2024/10/23 23:32, Dongliang Mu wrote:
> Finish the translation of kbuild/llvm.rst and move llvm from TODO
> to the main body.
> 
> Update to commit 145082ebfcf0 ("Documentation/llvm: turn make command
> for ccache into code block")
> 
> Signed-off-by: Dongliang Mu <dzm91 at hust.edu.cn>
> ---
>  .../translations/zh_CN/kbuild/index.rst       |   3 +-
>  .../translations/zh_CN/kbuild/llvm.rst        | 203 ++++++++++++++++++
>  2 files changed, 205 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/translations/zh_CN/kbuild/llvm.rst
> 
> diff --git a/Documentation/translations/zh_CN/kbuild/index.rst b/Documentation/translations/zh_CN/kbuild/index.rst
> index 0ba96aecb13a..3f9ab52fa5bb 100644
> --- a/Documentation/translations/zh_CN/kbuild/index.rst
> +++ b/Documentation/translations/zh_CN/kbuild/index.rst
> @@ -17,6 +17,7 @@
>      gcc-plugins
>      kbuild
>      reproducible-builds
> +    llvm
>  
>  TODO:
>  
> @@ -25,7 +26,7 @@ TODO:
>  - makefiles
>  - modules
>  - issues
> -- llvm
> +
>  
>  .. only::  subproject and html
>  
> diff --git a/Documentation/translations/zh_CN/kbuild/llvm.rst b/Documentation/translations/zh_CN/kbuild/llvm.rst
> new file mode 100644
> index 000000000000..f71092144a26
> --- /dev/null
> +++ b/Documentation/translations/zh_CN/kbuild/llvm.rst
> @@ -0,0 +1,203 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +.. include:: ../disclaimer-zh_CN.rst
> +
> +:Original: Documentation/kbuild/llvm.rst
> +:Translator: ??? Dongliang Mu <dzm91 at hust.edu.cn>
> +
> +==========================
> +?? Clang/LLVM ?? Linux
> +==========================
> +
> +????????? Clang ? LLVM ???? Linux ???
> +
> +??
> +----
> +
> +Linux ????????? GNU ????? GCC ? binutils?????????????
> +`Clang <https://clang.llvm.org/>`_ ? `LLVM <https://llvm.org/>`_ ???
> +???????????????? `Android <https://www.android.com/>`_?
> +`ChromeOS <https://www.chromium.org/chromium-os>`_?`OpenMandriva
> +<https://www.openmandriva.org/>`_ ? `Chimera Linux
> +<https://chimera-linux.org/>`_ ?? Clang ????????? Meta ?????
> +?????? Clang ??????
> +
> +`LLVM ?? C++ ???????????? <https://www.aosabook.org/en/llvm.html>`_?
> +Clang ? LLVM ?????? C ???????? GNU C ??????? "klang"???
> +"see-lang"?
> +
> +?? LLVM ??
> +--------------
> +
> +???????? ``make``::
> +
> +	make LLVM=1
> +
> +????????????????::
> +
> +	make LLVM=1 ARCH=arm64
> +
> +LLVM= ??
> +----------
> +
> +LLVM ? GNU binutils ???????????????????????? make ??
> +????::
> +
> +	make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip \
> +	  OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump READELF=llvm-readelf \
> +	  HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld
> +
> +``LLVM=1`` ????????
> +
> +???? LLVM ???? PATH ????????????? LLVM ?????????::
> +
> +	make LLVM=/path/to/llvm/
> +
> +???? ``/path/to/llvm/clang``?``/path/to/llvm/ld.lld`` ???????
> +??????::
> +
> +	PATH=/path/to/llvm:$PATH make LLVM=1
> +
> +???? LLVM ?????????????????????????????????
> +??? ``LLVM=1``?????? ``LLVM`` ???????::
> +
> +	make LLVM=-14
> +
> +???? ``clang-14``?``ld.lld-14`` ??????????????????????
> +????::
> +
> +	PATH=/path/to/llvm/:$PATH make LLVM=-14
> +
> +``LLVM=0`` ??? ``LLVM`` ??????????? ``LLVM=1``?????????
> +?? LLVM ??????????? make ???
> +
> +???????????????????? ``make`` ????? ``LLVM=`` ????
> +?????????? ``make``????? ``LLVM=`` ????????
> +
> +????
> +--------
> +
> +?? Clang ?????????????? LLVM ???????????????????
> +???????????? ``LLVM=1`` ??????? LLVM ???``CROSS_COMPILE``
> +?????????????????::
> +
> +	make LLVM=1 ARCH=arm64
> +
> +???? LLVM ? GNU ????????? ``ARCH=s390`` ????????
> +``ld.lld`` ? ``llvm-objcopy`` ??????????????? ``make``::
> +
> +	make LLVM=1 ARCH=s390 LD=s390x-linux-gnu-ld.bfd \
> +	  OBJCOPY=s390x-linux-gnu-objcopy
> +
> +?????? ``s390x-linux-gnu-ld.bfd`` ??????
> +``s390x-linux-gnu-objcopy``??????????? ``$PATH`` ??
> +
> +? ``LLVM=1`` ?????``CROSS_COMPILE`` ????? Clang ????????
> +????? LLVM ????????? GNU ?????????
> +
> +LLVM_IAS= ??
> +--------------
> +
> +Clang ?????????????? ``LLVM_IAS=0`` ??????? Clang ??
> +????????????::
> +
> +	make LLVM=1 LLVM_IAS=0
> +
> +???????????? ``CROSS_COMPILE`` ? ``LLVM_IAS=0``?????
> +``--prefix=`` ??????????????????????????????
> +??????????????::
> +
> +	make LLVM=1 ARCH=arm LLVM_IAS=0 CROSS_COMPILE=arm-linux-gnueabi-
> +
> +Ccache
> +------
> +
> +``ccache`` ??? ``clang`` ??????????????????????
> +KBUILD_BUILD_TIMESTAMP_ ????????????? 100% ???????
> +?? Reproducible_builds_ ???????::
> +
> +	KBUILD_BUILD_TIMESTAMP='' make LLVM=1 CC="ccache clang"
> +
> +.. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp
> +.. _Reproducible_builds: reproducible-builds.html#timestamps
> +
> +?????
> +----------
> +
> +LLVM ???? Linux ???????????????? LLVM ??????????????
> +????????????????????? ``CC=clang`` ? ``LLVM=1`` ????????
> +??????? MAINTAINERS ???? "S" ??????????????? LLVM ????
> +???????????????? LLVM ??????????????????????
> +``defconfig`` ?????????????????????????????????
> +?????????????
> +
> +.. list-table::
> +   :widths: 10 10 10
> +   :header-rows: 1
> +
> +   * - ??
> +     - ????
> +     - ``make`` ??
> +   * - arm
> +     - ??
> +     - ``LLVM=1``
> +   * - arm64
> +     - ??
> +     - ``LLVM=1``
> +   * - hexagon
> +     - ??
> +     - ``LLVM=1``
> +   * - loongarch
> +     - ??
> +     - ``LLVM=1``
> +   * - mips
> +     - ??
> +     - ``LLVM=1``
> +   * - powerpc
> +     - ??
> +     - ``LLVM=1``
> +   * - riscv
> +     - ??
> +     - ``LLVM=1``
> +   * - s390
> +     - ??
> +     - ``LLVM=1`` ?LLVM >= 18.1.0??``CC=clang`` ?LLVM < 18.1.0?
> +   * - um (????)
> +     - ??
> +     - ``LLVM=1``
> +   * - x86
> +     - ??
> +     - ``LLVM=1``
> +
> +????
> +--------
> +
> +- `?? <https://clangbuiltlinux.github.io/>`_
> +- `???? <https://lore.kernel.org/llvm/>`_: <llvm at lists.linux.dev>
> +- `??????? <https://groups.google.com/g/clang-built-linux>`_
> +- `????? <https://github.com/ClangBuiltLinux/linux/issues>`_
> +- IRC: #clangbuiltlinux ? irc.libera.chat
> +- `Telegram <https://t.me/ClangBuiltLinux>`_: @ClangBuiltLinux
> +- `?? <https://github.com/ClangBuiltLinux/linux/wiki>`_
> +- `????? <https://github.com/ClangBuiltLinux/linux/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22>`_
> +
> +.. _zh_cn_getting_llvm:
> +
> +?? LLVM
> +---------
> +
> +??? `kernel.org <https://kernel.org/pub/tools/llvm/>`_ ????????? LLVM?
> +???????? Linux ???????????????????????????? LLVM?????
> +??????????
^^^^^^^^^^^^^^^^^^^^^^

It doesn't match the meaning of the original text.

may be "??/????????" or "????????".

> +
> +?????????????? LLVM ????????????? LLVM ????
> +
> +- https://releases.llvm.org/download.html
> +- https://github.com/llvm/llvm-project
> +- https://llvm.org/docs/GettingStarted.html
> +- https://llvm.org/docs/CMake.html
> +- https://apt.llvm.org/
> +- https://www.archlinux.org/packages/extra/x86_64/llvm/
> +- https://github.com/ClangBuiltLinux/tc-build
> +- https://github.com/ClangBuiltLinux/linux/wiki/Building-Clang-from-source
> +- https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/


From dzm91 at hust.edu.cn  Mon Nov  4 19:01:45 2024
From: dzm91 at hust.edu.cn (Dongliang Mu)
Date: Tue, 5 Nov 2024 11:01:45 +0800
Subject: [PATCH] docs/zh_CN: add the translation of kbuild/llvm.rst
In-Reply-To: <d987b09d-985b-8d85-36e6-97ab4e8e222f@huawei.com>
References: <20241023153235.1291567-1-dzm91@hust.edu.cn>
 <d987b09d-985b-8d85-36e6-97ab4e8e222f@huawei.com>
Message-ID: <fbd3db23-f89b-4868-b657-c36fcfe9f8b2@hust.edu.cn>


On 2024/11/5 10:54, 'Jinjie Ruan' via HUST OS Kernel Contribution wrote:
>
> On 2024/10/23 23:32, Dongliang Mu wrote:
>> Finish the translation of kbuild/llvm.rst and move llvm from TODO
>> to the main body.
>>
>> Update to commit 145082ebfcf0 ("Documentation/llvm: turn make command
>> for ccache into code block")
>>
>> Signed-off-by: Dongliang Mu <dzm91 at hust.edu.cn>
>> ---
>>   .../translations/zh_CN/kbuild/index.rst       |   3 +-
>>   .../translations/zh_CN/kbuild/llvm.rst        | 203 ++++++++++++++++++
>>   2 files changed, 205 insertions(+), 1 deletion(-)
>>   create mode 100644 Documentation/translations/zh_CN/kbuild/llvm.rst
>>
>> diff --git a/Documentation/translations/zh_CN/kbuild/index.rst b/Documentation/translations/zh_CN/kbuild/index.rst
>> index 0ba96aecb13a..3f9ab52fa5bb 100644
>> --- a/Documentation/translations/zh_CN/kbuild/index.rst
>> +++ b/Documentation/translations/zh_CN/kbuild/index.rst
>> @@ -17,6 +17,7 @@
>>       gcc-plugins
>>       kbuild
>>       reproducible-builds
>> +    llvm
>>   
>>   TODO:
>>   
>> @@ -25,7 +26,7 @@ TODO:
>>   - makefiles
>>   - modules
>>   - issues
>> -- llvm
>> +
>>   
>>   .. only::  subproject and html
>>   
>> diff --git a/Documentation/translations/zh_CN/kbuild/llvm.rst b/Documentation/translations/zh_CN/kbuild/llvm.rst
>> new file mode 100644
>> index 000000000000..f71092144a26
>> --- /dev/null
>> +++ b/Documentation/translations/zh_CN/kbuild/llvm.rst
>> @@ -0,0 +1,203 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +
>> +.. include:: ../disclaimer-zh_CN.rst
>> +
>> +:Original: Documentation/kbuild/llvm.rst
>> +:Translator: ??? Dongliang Mu <dzm91 at hust.edu.cn>
>> +
>> +==========================
>> +?? Clang/LLVM ?? Linux
>> +==========================
>> +
>> +????????? Clang ? LLVM ???? Linux ???
>> +
>> +??
>> +----
>> +
>> +Linux ????????? GNU ????? GCC ? binutils?????????????
>> +`Clang <https://clang.llvm.org/>`_ ? `LLVM <https://llvm.org/>`_ ???
>> +???????????????? `Android <https://www.android.com/>`_?
>> +`ChromeOS <https://www.chromium.org/chromium-os>`_?`OpenMandriva
>> +<https://www.openmandriva.org/>`_ ? `Chimera Linux
>> +<https://chimera-linux.org/>`_ ?? Clang ????????? Meta ?????
>> +?????? Clang ??????
>> +
>> +`LLVM ?? C++ ???????????? <https://www.aosabook.org/en/llvm.html>`_?
>> +Clang ? LLVM ?????? C ???????? GNU C ??????? "klang"???
>> +"see-lang"?
>> +
>> +?? LLVM ??
>> +--------------
>> +
>> +???????? ``make``::
>> +
>> +	make LLVM=1
>> +
>> +????????????????::
>> +
>> +	make LLVM=1 ARCH=arm64
>> +
>> +LLVM= ??
>> +----------
>> +
>> +LLVM ? GNU binutils ???????????????????????? make ??
>> +????::
>> +
>> +	make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip \
>> +	  OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump READELF=llvm-readelf \
>> +	  HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld
>> +
>> +``LLVM=1`` ????????
>> +
>> +???? LLVM ???? PATH ????????????? LLVM ?????????::
>> +
>> +	make LLVM=/path/to/llvm/
>> +
>> +???? ``/path/to/llvm/clang``?``/path/to/llvm/ld.lld`` ???????
>> +??????::
>> +
>> +	PATH=/path/to/llvm:$PATH make LLVM=1
>> +
>> +???? LLVM ?????????????????????????????????
>> +??? ``LLVM=1``?????? ``LLVM`` ???????::
>> +
>> +	make LLVM=-14
>> +
>> +???? ``clang-14``?``ld.lld-14`` ??????????????????????
>> +????::
>> +
>> +	PATH=/path/to/llvm/:$PATH make LLVM=-14
>> +
>> +``LLVM=0`` ??? ``LLVM`` ??????????? ``LLVM=1``?????????
>> +?? LLVM ??????????? make ???
>> +
>> +???????????????????? ``make`` ????? ``LLVM=`` ????
>> +?????????? ``make``????? ``LLVM=`` ????????
>> +
>> +????
>> +--------
>> +
>> +?? Clang ?????????????? LLVM ???????????????????
>> +???????????? ``LLVM=1`` ??????? LLVM ???``CROSS_COMPILE``
>> +?????????????????::
>> +
>> +	make LLVM=1 ARCH=arm64
>> +
>> +???? LLVM ? GNU ????????? ``ARCH=s390`` ????????
>> +``ld.lld`` ? ``llvm-objcopy`` ??????????????? ``make``::
>> +
>> +	make LLVM=1 ARCH=s390 LD=s390x-linux-gnu-ld.bfd \
>> +	  OBJCOPY=s390x-linux-gnu-objcopy
>> +
>> +?????? ``s390x-linux-gnu-ld.bfd`` ??????
>> +``s390x-linux-gnu-objcopy``??????????? ``$PATH`` ??
>> +
>> +? ``LLVM=1`` ?????``CROSS_COMPILE`` ????? Clang ????????
>> +????? LLVM ????????? GNU ?????????
>> +
>> +LLVM_IAS= ??
>> +--------------
>> +
>> +Clang ?????????????? ``LLVM_IAS=0`` ??????? Clang ??
>> +????????????::
>> +
>> +	make LLVM=1 LLVM_IAS=0
>> +
>> +???????????? ``CROSS_COMPILE`` ? ``LLVM_IAS=0``?????
>> +``--prefix=`` ??????????????????????????????
>> +??????????????::
>> +
>> +	make LLVM=1 ARCH=arm LLVM_IAS=0 CROSS_COMPILE=arm-linux-gnueabi-
>> +
>> +Ccache
>> +------
>> +
>> +``ccache`` ??? ``clang`` ??????????????????????
>> +KBUILD_BUILD_TIMESTAMP_ ????????????? 100% ???????
>> +?? Reproducible_builds_ ???????::
>> +
>> +	KBUILD_BUILD_TIMESTAMP='' make LLVM=1 CC="ccache clang"
>> +
>> +.. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp
>> +.. _Reproducible_builds: reproducible-builds.html#timestamps
>> +
>> +?????
>> +----------
>> +
>> +LLVM ???? Linux ???????????????? LLVM ??????????????
>> +????????????????????? ``CC=clang`` ? ``LLVM=1`` ????????
>> +??????? MAINTAINERS ???? "S" ??????????????? LLVM ????
>> +???????????????? LLVM ??????????????????????
>> +``defconfig`` ?????????????????????????????????
>> +?????????????
>> +
>> +.. list-table::
>> +   :widths: 10 10 10
>> +   :header-rows: 1
>> +
>> +   * - ??
>> +     - ????
>> +     - ``make`` ??
>> +   * - arm
>> +     - ??
>> +     - ``LLVM=1``
>> +   * - arm64
>> +     - ??
>> +     - ``LLVM=1``
>> +   * - hexagon
>> +     - ??
>> +     - ``LLVM=1``
>> +   * - loongarch
>> +     - ??
>> +     - ``LLVM=1``
>> +   * - mips
>> +     - ??
>> +     - ``LLVM=1``
>> +   * - powerpc
>> +     - ??
>> +     - ``LLVM=1``
>> +   * - riscv
>> +     - ??
>> +     - ``LLVM=1``
>> +   * - s390
>> +     - ??
>> +     - ``LLVM=1`` ?LLVM >= 18.1.0??``CC=clang`` ?LLVM < 18.1.0?
>> +   * - um (????)
>> +     - ??
>> +     - ``LLVM=1``
>> +   * - x86
>> +     - ??
>> +     - ``LLVM=1``
>> +
>> +????
>> +--------
>> +
>> +- `?? <https://clangbuiltlinux.github.io/>`_
>> +- `???? <https://lore.kernel.org/llvm/>`_: <llvm at lists.linux.dev>
>> +- `??????? <https://groups.google.com/g/clang-built-linux>`_
>> +- `????? <https://github.com/ClangBuiltLinux/linux/issues>`_
>> +- IRC: #clangbuiltlinux ? irc.libera.chat
>> +- `Telegram <https://t.me/ClangBuiltLinux>`_: @ClangBuiltLinux
>> +- `?? <https://github.com/ClangBuiltLinux/linux/wiki>`_
>> +- `????? <https://github.com/ClangBuiltLinux/linux/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22>`_
>> +
>> +.. _zh_cn_getting_llvm:
>> +
>> +?? LLVM
>> +---------
>> +
>> +??? `kernel.org <https://kernel.org/pub/tools/llvm/>`_ ????????? LLVM?
>> +???????? Linux ???????????????????????????? LLVM?????
>> +??????????
> ^^^^^^^^^^^^^^^^^^^^^^
>
> It doesn't match the meaning of the original text.
>
> may be "??/????????" or "????????".

??????????????? ???????????

??????? patch ????

>
>> +
>> +?????????????? LLVM ????????????? LLVM ????
>> +
>> +- https://releases.llvm.org/download.html
>> +- https://github.com/llvm/llvm-project
>> +- https://llvm.org/docs/GettingStarted.html
>> +- https://llvm.org/docs/CMake.html
>> +- https://apt.llvm.org/
>> +- https://www.archlinux.org/packages/extra/x86_64/llvm/
>> +- https://github.com/ClangBuiltLinux/tc-build
>> +- https://github.com/ClangBuiltLinux/linux/wiki/Building-Clang-from-source
>> +- https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/



From anup at brainfault.org  Mon Nov  4 21:11:41 2024
From: anup at brainfault.org (Anup Patel)
Date: Tue, 5 Nov 2024 10:41:41 +0530
Subject: [PATCH v2 1/1] RISC-V: KVM: Fix APLIC in_clrip and clripnum write emulation
In-Reply-To: <20241029085542.30541-1-yongxuan.wang@sifive.com>
References: <20241029085542.30541-1-yongxuan.wang@sifive.com>
Message-ID: <CAAhSdy022PTmMZ90OxRxSOiR9nKept+tKVj8XrqbekkM209eYQ@mail.gmail.com>

On Tue, Oct 29, 2024 at 2:25?PM Yong-Xuan Wang <yongxuan.wang at sifive.com> wrote:
>
> In the section "4.7 Precise effects on interrupt-pending bits"
> of the RISC-V AIA specification defines that:
>
> "If the source mode is Level1 or Level0 and the interrupt domain
> is configured in MSI delivery mode (domaincfg.DM = 1):
> The pending bit is cleared whenever the rectified input value is
> low, when the interrupt is forwarded by MSI, or by a relevant
> write to an in_clrip register or to clripnum."
>
> Update the aplic_write_pending() to match the spec.
>
> Fixes: d8dd9f113e16 ("RISC-V: KVM: Fix APLIC setipnum_le/be write emulation")
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang at sifive.com>
> Reviewed-by: Vincent Chen <vincent.chen at sifive.com>

Looks good to me.

Reviewed-by: Anup Patel <anup at brainfault.org>

Queued this patch for Linux-6.13.

Thanks,
Anup

> ---
> v2;
> - add fixes tag (Anup)
> - follow the suggestion from Anup
> ---
>  arch/riscv/kvm/aia_aplic.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/kvm/aia_aplic.c b/arch/riscv/kvm/aia_aplic.c
> index da6ff1bade0d..f59d1c0c8c43 100644
> --- a/arch/riscv/kvm/aia_aplic.c
> +++ b/arch/riscv/kvm/aia_aplic.c
> @@ -143,7 +143,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)
>         if (sm == APLIC_SOURCECFG_SM_LEVEL_HIGH ||
>             sm == APLIC_SOURCECFG_SM_LEVEL_LOW) {
>                 if (!pending)
> -                       goto skip_write_pending;
> +                       goto noskip_write_pending;
>                 if ((irqd->state & APLIC_IRQ_STATE_INPUT) &&
>                     sm == APLIC_SOURCECFG_SM_LEVEL_LOW)
>                         goto skip_write_pending;
> @@ -152,6 +152,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)
>                         goto skip_write_pending;
>         }
>
> +noskip_write_pending:
>         if (pending)
>                 irqd->state |= APLIC_IRQ_STATE_PENDING;
>         else
> --
> 2.17.1
>


From troymitchell988 at gmail.com  Mon Nov  4 21:20:12 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Tue, 5 Nov 2024 13:20:12 +0800
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <8a04f84b-453b-44e5-9053-204a08d38e19@sifive.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <6zx3tqdc5bma2vutexwigzlir6nr6adp7arg4qwl5ieyd3avbu@5yyhv57ttwcl>
 <dbeea869-54cd-43fe-9021-783d641f1278@gmail.com>
 <ariqiukhztgziwwgaauqy6q3pghflnoeuwtag4izwkfmtvi2kh@gnlq4d7jsaw4>
 <6cce463e-25cc-4a07-971f-6260347cb581@gmail.com>
 <502b0b14-0e1f-4a59-85ad-7edeb9d3033d@kernel.org>
 <a08384bf-6747-4975-b025-f8fd3685fc30@gmail.com>
 <8a04f84b-453b-44e5-9053-204a08d38e19@sifive.com>
Message-ID: <190e9d7b-daaa-4c7d-9954-ca143925a08d@gmail.com>


On 2024/11/5 10:50, Samuel Holland wrote:
> One "<address size>" element is just one item. maxItems > 1 would be for
> hardware with multiple discontiguous register ranges: <address1 size1>,
> <address2 size2>.
got it.I will fix it in next version.
> 
> Regards,
> Samuel

-- 
Troy Mitchell


From seanjc at google.com  Mon Nov  4 21:53:48 2024
From: seanjc at google.com (Sean Christopherson)
Date: Mon, 4 Nov 2024 21:53:48 -0800
Subject: [PATCH v3 00/14] KVM: selftests: Morph max_guest_mem to mmu_stress
In-Reply-To: <173039503553.1508387.3074658713815866060.b4-ty@google.com>
References: <20241009154953.1073471-1-seanjc@google.com> <173039503553.1508387.3074658713815866060.b4-ty@google.com>
Message-ID: <Zymy7M5dHs6dWUmu@google.com>

On Thu, Oct 31, 2024, Sean Christopherson wrote:
> On Wed, 09 Oct 2024 08:49:39 -0700, Sean Christopherson wrote:
> > The main purpose of this series is to convert the max_guest_memory_test
> > into a more generic mmu_stress_test.  The basic gist of the "conversion"
> > is to have the test do mprotect() on guest memory while vCPUs are
> > accessing said memory, e.g. to verify KVM and mmu_notifiers are working
> > as intended.
> > 
> > Patches 1-4 are a somewhat unexpected side quest.  The original plan was
> > that patch 3 would be a single patch, but things snowballed.
> > 
> > [...]
> 
> Applied to kvm-x86 selftests, with the typo fixup pointed out by James.  Thanks!
> 
> [01/14] KVM: Move KVM_REG_SIZE() definition to common uAPI header
>         https://github.com/kvm-x86/linux/commit/5e07fd0bf516
> [02/14] KVM: selftests: Disable strict aliasing
>         https://github.com/kvm-x86/linux/commit/d1ce2bcd8d2e
> [03/14] KVM: selftests: Return a value from vcpu_get_reg() instead of using an out-param
>         https://github.com/kvm-x86/linux/commit/5c6c7b71a45c
> [04/14] KVM: selftests: Assert that vcpu_{g,s}et_reg() won't truncate
>         https://github.com/kvm-x86/linux/commit/6aa2df3eb90b
> [05/14] KVM: selftests: Check for a potential unhandled exception iff KVM_RUN succeeded
>         https://github.com/kvm-x86/linux/commit/be9f2746d20b
> [06/14] KVM: selftests: Rename max_guest_memory_test to mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/06694f27cfcc
> [07/14] KVM: selftests: Only muck with SREGS on x86 in mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/8556ce365a07
> [08/14] KVM: selftests: Compute number of extra pages needed in mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/c7b7876ac5d4
> [09/14] KVM: sefltests: Explicitly include ucall_common.h in mmu_stress_test.c
>         https://github.com/kvm-x86/linux/commit/a657856469e1
> [10/14] KVM: selftests: Enable mmu_stress_test on arm64
>         https://github.com/kvm-x86/linux/commit/1e53cde06102
> [11/14] KVM: selftests: Use vcpu_arch_put_guest() in mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/8630563012b9
> [12/14] KVM: selftests: Precisely limit the number of guest loops in mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/3d4585c220dc
> [13/14] KVM: selftests: Add a read-only mprotect() phase to mmu_stress_test
>         https://github.com/kvm-x86/linux/commit/eaafeebca75a
> [14/14] KVM: selftests: Verify KVM correctly handles mprotect(PROT_READ)
>         https://github.com/kvm-x86/linux/commit/a3cd5c187742

As mentioned later in the thread[*], I dropped this series from the 6.13 queue
and will instead target 6.14.

I did however grab the no-strict-aliasing fix for 6.12, and tagged it for stable.
There's no reason to wait to land that commit, and I definitely have no desire to
ever debug that mess again.

[02/14] KVM: selftests: Disable strict aliasing
      https://github.com/kvm-x86/linux/commit/5b188cc4866a

[*] https://lore.kernel.org/all/ZyT61FF0-g8gKZfc at google.com


From anup at brainfault.org  Mon Nov  4 22:28:51 2024
From: anup at brainfault.org (Anup Patel)
Date: Tue, 5 Nov 2024 11:58:51 +0530
Subject: [PATCH] riscv: kvm: Fix out-of-bounds array access
In-Reply-To: <20241104191503.74725-1-bjorn@kernel.org>
References: <20241104191503.74725-1-bjorn@kernel.org>
Message-ID: <CAAhSdy1Z93TyYrFCYw+qOHh05q0FaEPRJ=ZHf4UztUEKXuphYg@mail.gmail.com>

On Tue, Nov 5, 2024 at 12:45?AM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> From: Bj?rn T?pel <bjorn at rivosinc.com>
>
> In kvm_riscv_vcpu_sbi_init() the entry->ext_idx can contain an
> out-of-bound index. This is used as a special marker for the base
> extensions, that cannot be disabled. However, when traversing the
> extensions, that special marker is not checked prior indexing the
> array.
>
> Add an out-of-bounds check to the function.
>
> Fixes: 56d8a385b605 ("RISC-V: KVM: Allow some SBI extensions to be disabled by default")
> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
> ---
> Don't know if it matters, but I hit this when trying kvmtool.

Looks like this went unnoticed. Thanks for catching.

Reviewed-by: Anup Patel <anup at brainfault.org>

Queued this patch for Linux-6.13.

Thanks,
Anup

>
>
> Bj?rn
> ---
> arch/riscv/kvm/vcpu_sbi.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
> index 7de128be8db9..6e704ed86a83 100644
> --- a/arch/riscv/kvm/vcpu_sbi.c
> +++ b/arch/riscv/kvm/vcpu_sbi.c
> @@ -486,19 +486,22 @@ void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu)
>         struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
>         const struct kvm_riscv_sbi_extension_entry *entry;
>         const struct kvm_vcpu_sbi_extension *ext;
> -       int i;
> +       int idx, i;
>
>         for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) {
>                 entry = &sbi_ext[i];
>                 ext = entry->ext_ptr;
> +               idx = entry->ext_idx;
> +
> +               if (idx < 0 || idx >= ARRAY_SIZE(scontext->ext_status))
> +                       continue;
>
>                 if (ext->probe && !ext->probe(vcpu)) {
> -                       scontext->ext_status[entry->ext_idx] =
> -                               KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE;
> +                       scontext->ext_status[idx] = KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE;
>                         continue;
>                 }
>
> -               scontext->ext_status[entry->ext_idx] = ext->default_disabled ?
> +               scontext->ext_status[idx] = ext->default_disabled ?
>                                         KVM_RISCV_SBI_EXT_STATUS_DISABLED :
>                                         KVM_RISCV_SBI_EXT_STATUS_ENABLED;
>         }
>
> base-commit: 59b723cd2adbac2a34fc8e12c74ae26ae45bf230
> --
> 2.43.0
>


From troymitchell988 at gmail.com  Mon Nov  4 22:50:36 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Tue, 5 Nov 2024 14:50:36 +0800
Subject: [PATCH v2 2/2] i2c: spacemit: add support for SpacemiT K1 SoC
In-Reply-To: <20241028053220.346283-3-TroyMitchell988@gmail.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-3-TroyMitchell988@gmail.com>
Message-ID: <84d07d21-54bc-45eb-b231-8f800a2afed3@gmail.com>

On 2024/10/28 13:32, Troy Mitchell wrote:
> This patch introduces basic I2C support for the SpacemiT K1 SoC,
> utilizing interrupts for transfers.
> 
> The driver has been tested using i2c-tools on a Bananapi-F3 board,
> and basic I2C read/write operations have been confirmed to work.
> 
> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
> ---
>  drivers/i2c/busses/Kconfig  |  18 +
>  drivers/i2c/busses/Makefile |   1 +
>  drivers/i2c/busses/i2c-k1.c | 658 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 677 insertions(+)
>  create mode 100644 drivers/i2c/busses/i2c-k1.c
> 
> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> index 6b3ba7e5723a..38ebfd38dc41 100644
> --- a/drivers/i2c/busses/Kconfig
> +++ b/drivers/i2c/busses/Kconfig
> @@ -779,6 +779,24 @@ config I2C_JZ4780
>  
>  	 If you don't know what to do here, say N.
>  
> +config I2C_K1
> +	tristate "Spacemit K1 I2C adapter"
> +	depends on HAS_IOMEM
I think I should retain the depends on from v1, like this:
depends on ARCH_SPACEMIT || COMPILE_TEST

Krzysztof mentioned that there is no such thing as ARCH_SPACEMIT, that's because
this patch depends on the basic DT from dlan:
https://lore.kernel.org/all/20240730-k1-01-basic-dt-v5-0-98263aae83be at gentoo.org/
> +	help
> +	  This option enables support for the I2C interface on the Spacemit K1
> +	  platform.
> +
> +	  If you enable this configuration, the kernel will include support for
> +	  the I2C adapter specific to the Spacemit K1 platform. This driver ca
> +	  be used to manage I2C bus transactions, which are necessary for
> +	  interfacing with I2C peripherals such as sensors, EEPROMs, and other
> +	  devices.
> +
> +	  This driver can also be compiled as a module. If you choose to build
> +	  it as a module, the resulting kernel module will be named `i2c-k1`.
> +	  Loading this module will enable the I2C functionality for the K1
> +	  platform dynamically, without requiring a rebuild of the kernel.
> +
>  config I2C_KEBA
>  	tristate "KEBA I2C controller support"
>  	depends on HAS_IOMEM

-- 
Troy Mitchell


From rppt at kernel.org  Mon Nov  4 23:02:26 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Tue, 5 Nov 2024 09:02:26 +0200
Subject: [PATCH v7 6/8] x86/module: prepare module loading for ROX
 allocations of text
In-Reply-To: <20241104232741.GA3843610@thelio-3990X>
References: <20241023162711.2579610-1-rppt@kernel.org>
 <20241023162711.2579610-7-rppt@kernel.org>
 <20241104232741.GA3843610@thelio-3990X>
Message-ID: <ZynDAhW0lKCfOqZl@kernel.org>

Hi Nathan,

On Mon, Nov 04, 2024 at 04:27:41PM -0700, Nathan Chancellor wrote:
> Hi Mike,
> 
> On Wed, Oct 23, 2024 at 07:27:09PM +0300, Mike Rapoport wrote:
> > From: "Mike Rapoport (Microsoft)" <rppt at kernel.org>
> > 
> > When module text memory will be allocated with ROX permissions, the
> > memory at the actual address where the module will live will contain
> > invalid instructions and there will be a writable copy that contains the
> > actual module code.
> > 
> > Update relocations and alternatives patching to deal with it.
> > 
> > Signed-off-by: Mike Rapoport (Microsoft) <rppt at kernel.org>
> > Tested-by: kdevops <kdevops at lists.linux.dev>
> 
> Hopefully the last time you have to hear from me, as I am only
> experiencing issues with only one of my test machines at this point and
> it is my only machine that supports IBT, so it seems to point to
> something specific with the IBT part of the FineIBT support. I notice
> either a boot hang or an almost immediate reboot (triple fault?). I
> guess this is how I missed reporting this earlier, as my machine was
> falling back to the default distribution kernel after the restart and I
> did not notice I was not actually testing a -next kernel.
> 
> Checking out the version of this change that is in next-20241104, commit
> 7ca6ed09db62 ("x86/module: prepare module loading for ROX allocations of
> text"), it boots with either 'cfi=off' or 'cfi=kcfi' but it exhibits the
> issues noted above with 'cfi=fineibt'. At the immediate parent, commit
> b575d981092f ("arch: introduce set_direct_map_valid_noflush()"), all
> three combinations boot fine.
> 
>   $ uname -r; tr ' ' '\n' </proc/cmdline | grep cfi=
> 
>   6.12.0-rc5-debug-00214-g7ca6ed09db62
>   cfi=kcfi
> 
>   6.12.0-rc5-debug-00214-g7ca6ed09db62
>   cfi=off
> 
>   6.12.0-rc5-debug-00213-gb575d981092f
>   cfi=fineibt
> 
>   6.12.0-rc5-debug-00213-gb575d981092f
>   cfi=kcfi
> 
>   6.12.0-rc5-debug-00213-gb575d981092f
>   cfi=off
> 
> I do not think this machine has an accessible serial port and I do not
> think IBT virtualization is supported via either KVM or TCG in QEMU, so
> I am not sure how to get more information about what is going on here. I
> wanted to try reverting these changes on top of next-20241104 but there
> was a non-trivial conflict in mm/execmem.c due to some changes on top,
> so I just tested in the mm history.
> 
> If there is any other information I can provide or patches I can test, I
> am more than happy to do so.

Yes, please :)

There's a silly mistake in cfi_rewrite_endbr() in that commit, the patch
below should fix it. Can you please test?

diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 3407efc26528..243843e44e89 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -1241,7 +1241,7 @@ static void cfi_rewrite_endbr(s32 *start, s32 *end, struct module *mod)
 		void *addr = (void *)s + *s;
 		void *wr_addr = module_writable_address(mod, addr);
 
-		poison_endbr(addr+16, wr_addr, false);
+		poison_endbr(addr + 16, wr_addr + 16, false);
 	}
 }
 
 
> Cheers,
> Nathan

-- 
Sincerely yours,
Mike.


From philip.li at intel.com  Tue Nov  5 00:47:01 2024
From: philip.li at intel.com (Philip Li)
Date: Tue, 5 Nov 2024 16:47:01 +0800
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <CAHVXubj8EXCXNPuJ+hqrHwyujjz3GDcqqMjQ4ZFC5VbmZurV3w@mail.gmail.com>
References: <20241103145153.105097-14-alexghiti@rivosinc.com>
 <202411041609.gxjI2dsw-lkp@intel.com>
 <CAHVXubj8EXCXNPuJ+hqrHwyujjz3GDcqqMjQ4ZFC5VbmZurV3w@mail.gmail.com>
Message-ID: <ZynbhcW864CHhpDL@rli9-mobl>

On Mon, Nov 04, 2024 at 10:09:07AM +0100, Alexandre Ghiti wrote:
> On Mon, Nov 4, 2024 at 10:05?AM kernel test robot <lkp at intel.com> wrote:
> >
> > Hi Alexandre,
> >
> > kernel test robot noticed the following build warnings:
> >
> > [auto build test WARNING on arnd-asm-generic/master]
> > [also build test WARNING on robh/for-next tip/locking/core linus/master v6.12-rc6]
> > [cannot apply to next-20241101]
> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > And when submitting patch, we suggest to use '--base' as documented in
> > https://git-scm.com/docs/git-format-patch#_base_tree_information]
> >
> > url:    https://github.com/intel-lab-lkp/linux/commits/Alexandre-Ghiti/riscv-Move-cpufeature-h-macros-into-their-own-header/20241103-230614
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
> > patch link:    https://lore.kernel.org/r/20241103145153.105097-14-alexghiti%40rivosinc.com
> > patch subject: [PATCH v6 13/13] riscv: Add qspinlock support
> > compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
> >
> > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > the same patch/commit), kindly add following tags
> > | Reported-by: kernel test robot <lkp at intel.com>
> > | Closes: https://lore.kernel.org/oe-kbuild-all/202411041609.gxjI2dsw-lkp at intel.com/
> >
> > includecheck warnings: (new ones prefixed by >>)
> > >> arch/riscv/include/asm/spinlock.h: asm/ticket_spinlock.h is included more than once.
> > >> arch/riscv/include/asm/spinlock.h: asm/qspinlock.h is included more than once.
> 
> Yes but that's in a #ifdef/#elif#else clause so nothing to do here!

Thanks for the info, we will fix the bot. Sorry for the false positive report.

> 
> >
> > vim +10 arch/riscv/include/asm/spinlock.h
> >
> >      8
> >      9  #define __no_arch_spinlock_redefine
> >   > 10  #include <asm/ticket_spinlock.h>
> >     11  #include <asm/qspinlock.h>
> >     12  #include <asm/jump_label.h>
> >     13
> >     14  /*
> >     15   * TODO: Use an alternative instead of a static key when we are able to parse
> >     16   * the extensions string earlier in the boot process.
> >     17   */
> >     18  DECLARE_STATIC_KEY_TRUE(qspinlock_key);
> >     19
> >     20  #define SPINLOCK_BASE_DECLARE(op, type, type_lock)                      \
> >     21  static __always_inline type arch_spin_##op(type_lock lock)              \
> >     22  {                                                                       \
> >     23          if (static_branch_unlikely(&qspinlock_key))                     \
> >     24                  return queued_spin_##op(lock);                          \
> >     25          return ticket_spin_##op(lock);                                  \
> >     26  }
> >     27
> >     28  SPINLOCK_BASE_DECLARE(lock, void, arch_spinlock_t *)
> >     29  SPINLOCK_BASE_DECLARE(unlock, void, arch_spinlock_t *)
> >     30  SPINLOCK_BASE_DECLARE(is_locked, int, arch_spinlock_t *)
> >     31  SPINLOCK_BASE_DECLARE(is_contended, int, arch_spinlock_t *)
> >     32  SPINLOCK_BASE_DECLARE(trylock, bool, arch_spinlock_t *)
> >     33  SPINLOCK_BASE_DECLARE(value_unlocked, int, arch_spinlock_t)
> >     34
> >     35  #elif defined(CONFIG_RISCV_QUEUED_SPINLOCKS)
> >     36
> >     37  #include <asm/qspinlock.h>
> >     38
> >     39  #else
> >     40
> >   > 41  #include <asm/ticket_spinlock.h>
> >     42
> >
> > --
> > 0-DAY CI Kernel Test Service
> > https://github.com/intel/lkp-tests/wiki
> 


From ajones at ventanamicro.com  Tue Nov  5 01:14:48 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Tue, 5 Nov 2024 10:14:48 +0100
Subject: [PATCH kvmtool] riscv: Pass correct size to snprintf()
In-Reply-To: <20241104192120.75841-1-bjorn@kernel.org>
References: <20241104192120.75841-1-bjorn@kernel.org>
Message-ID: <20241105-546ce4236046e9742cf081e7@orel>

On Mon, Nov 04, 2024 at 08:21:19PM +0100, Bj?rn T?pel wrote:
> From: Bj?rn T?pel <bjorn at rivosinc.com>
> 
> The snprintf() function does not get the correct size argument passed,
> when the FDT ISA string is built. Instead of adjusting the size for
> each extension, the full size is passed for every iteration. Doing so
> will make __snprinf_chk() bail out on glibc.
> 
> Adjust size for each iteration.
> 
> Fixes: 8aff29e1dafe ("riscv: Append ISA extensions to the device tree")
> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
> ---
>  riscv/fdt.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/riscv/fdt.c b/riscv/fdt.c
> index 8189601f46de..85c8f95604f6 100644
> --- a/riscv/fdt.c
> +++ b/riscv/fdt.c
> @@ -157,7 +157,7 @@ static void generate_cpu_nodes(void *fdt, struct kvm *kvm)
>  					   isa_info_arr[i].name);
>  				break;
>  			}
> -			pos += snprintf(cpu_isa + pos, CPU_ISA_MAX_LEN, "_%s",
> +			pos += snprintf(cpu_isa + pos, CPU_ISA_MAX_LEN - pos, "_%s",

Just above this we confirm strlen(isa_info_arr[i].name) + pos + 1 is less
than CPU_ISA_MAX_LEN, which means we should be able to use anything for
size which is greater than or equal to strlen(isa_info_arr[i].name) + 1,
as snprintf won't write more anyway. But, it's understandable that
__snprinf_chk doesn't know that.

>  					isa_info_arr[i].name);
>  		}
>  		cpu_isa[pos] = '\0';

Not part of this patch, but part of the context, so I'll comment on it
anyway, this '\0' assignment could be removed. It looks like it's a left
over from commit 7c9aac003925 ("riscv: Generate FDT at runtime for
Guest/VM") which could have been removed with commit 8aff29e1dafe ("riscv:
Append ISA extensions to the device tree")

Anyway,

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>

Thanks,
drew


From mpe at ellerman.id.au  Tue Nov  5 01:22:53 2024
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Tue, 05 Nov 2024 20:22:53 +1100
Subject: [PATCH v3 08/18] powerpc/crc32: expose CRC32 functions through lib
In-Reply-To: <20241103223154.136127-9-ebiggers@kernel.org>
References: <20241103223154.136127-1-ebiggers@kernel.org>
 <20241103223154.136127-9-ebiggers@kernel.org>
Message-ID: <87zfme826q.fsf@mpe.ellerman.id.au>

Eric Biggers <ebiggers at kernel.org> writes:
> From: Eric Biggers <ebiggers at google.com>
>
> Move the powerpc CRC32C assembly code into the lib directory and wire it
> up to the library interface.  This allows it to be used without going
> through the crypto API.  It remains usable via the crypto API too via
> the shash algorithms that use the library interface.  Thus all the
> arch-specific "shash" code becomes unnecessary and is removed.
>
> Note: to see the diff from arch/powerpc/crypto/crc32c-vpmsum_glue.c to
> arch/powerpc/lib/crc32-glue.c, view this commit with 'git show -M10'.
>
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Eric Biggers <ebiggers at google.com>
> ---
>  arch/powerpc/Kconfig                          |   1 +
>  arch/powerpc/configs/powernv_defconfig        |   1 -
>  arch/powerpc/configs/ppc64_defconfig          |   1 -
>  arch/powerpc/crypto/Kconfig                   |  15 +-
>  arch/powerpc/crypto/Makefile                  |   2 -
>  arch/powerpc/crypto/crc32c-vpmsum_glue.c      | 173 ------------------
>  arch/powerpc/crypto/crct10dif-vpmsum_asm.S    |   2 +-
>  arch/powerpc/lib/Makefile                     |   3 +
>  arch/powerpc/lib/crc32-glue.c                 |  92 ++++++++++
>  .../{crypto => lib}/crc32-vpmsum_core.S       |   0
>  .../{crypto => lib}/crc32c-vpmsum_asm.S       |   0
>  11 files changed, 98 insertions(+), 192 deletions(-)
>  delete mode 100644 arch/powerpc/crypto/crc32c-vpmsum_glue.c
>  create mode 100644 arch/powerpc/lib/crc32-glue.c
>  rename arch/powerpc/{crypto => lib}/crc32-vpmsum_core.S (100%)
>  rename arch/powerpc/{crypto => lib}/crc32c-vpmsum_asm.S (100%)

Acked-by: Michael Ellerman <mpe at ellerman.id.au> (powerpc)

...
> deleted file mode 100644
> index 63760b7dbb76..000000000000
> --- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c
> +++ /dev/null
> @@ -1,173 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -
...
> -static int __init crc32c_vpmsum_mod_init(void)
> -{
> -	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
> -		return -ENODEV;
> -
> -	return crypto_register_shash(&alg);
> -}
> -
> -static void __exit crc32c_vpmsum_mod_fini(void)
> -{
> -	crypto_unregister_shash(&alg);
> -}
> -
> -module_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, crc32c_vpmsum_mod_init);
> -module_exit(crc32c_vpmsum_mod_fini);
> -
> -MODULE_AUTHOR("Anton Blanchard <anton at samba.org>");
> -MODULE_DESCRIPTION("CRC32C using vector polynomial multiply-sum instructions");
> -MODULE_LICENSE("GPL");
> -MODULE_ALIAS_CRYPTO("crc32c");
> -MODULE_ALIAS_CRYPTO("crc32c-vpmsum");
...
> new file mode 100644
> index 000000000000..e9730f028afb
> --- /dev/null
> +++ b/arch/powerpc/lib/crc32-glue.c
> @@ -0,0 +1,92 @@
> +// SPDX-License-Identifier: GPL-2.0-only
...
> +
> +static int __init crc32_powerpc_init(void)
> +{
> +	if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
> +	    (cur_cpu_spec->cpu_user_features2 & PPC_FEATURE2_VEC_CRYPTO))
> +		static_branch_enable(&have_vec_crypto);

For any other reviewers, this looks like a new cpu feature check, but
it's not. In the old code there was a module feature check:

  module_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, crc32c_vpmsum_mod_init);

And PPC_MODULE_FEATURE_VEC_CRYPTO maps to PPC_FEATURE2_VEC_CRYPTO, so
the logic is equivalent.

cheers


From christophe.leroy at csgroup.eu  Tue Nov  5 01:56:42 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Tue, 5 Nov 2024 10:56:42 +0100
Subject: [PATCH 2/2] asm-generic: add an optional pfn_valid check to
 page_to_phys
In-Reply-To: <20241023053644.311692-3-hch@lst.de>
References: <20241023053644.311692-1-hch@lst.de>
 <20241023053644.311692-3-hch@lst.de>
Message-ID: <9ee9c21b-179f-49aa-8c65-304c8ef2c9a7@csgroup.eu>



Le 23/10/2024 ? 07:36, Christoph Hellwig a ?crit?:
> page_to_pfn is usually implemented by pointer arithmetics on the memory
> map, which means that bogus input can lead to even more bogus output.
> 
> Powerpc had a pfn_valid check on the intermediate pfn in the page_to_phys
> implementation when CONFIG_DEBUG_VIRTUAL is defined, which seems
> generally useful, so add that to the generic version.
> 
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---
>   include/asm-generic/memory_model.h | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
> index a73a140cbecd..6d1fb6162ac1 100644
> --- a/include/asm-generic/memory_model.h
> +++ b/include/asm-generic/memory_model.h
> @@ -64,7 +64,17 @@ static inline int pfn_valid(unsigned long pfn)
>   #define page_to_pfn __page_to_pfn
>   #define pfn_to_page __pfn_to_page
>   
> +#ifdef CONFIG_DEBUG_VIRTUAL
> +#define page_to_phys(page)						\
> +({									\
> +	unsigned long __pfn = page_to_pfn(page);			\
> +									\
> +	WARN_ON_ONCE(!pfn_valid(__pfn));				\

On powerpc I think it was a WARN_ON().

Will a WARN_ON_ONCE() be enough ?

> +	PFN_PHYS(__pfn);						\
> +})
> +#else
>   #define page_to_phys(page)	PFN_PHYS(page_to_pfn(page))
> +#endif /* CONFIG_DEBUG_VIRTUAL */
>   #define phys_to_page(phys)	pfn_to_page(PHYS_PFN(phys))
>   
>   #endif /* __ASSEMBLY__ */


From alex at ghiti.fr  Tue Nov  5 01:58:43 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 10:58:43 +0100
Subject: [PATCH 03/11] riscv: mm: Deduplicate pgtable address conversion
 functions
In-Reply-To: <20241102000843.1301099-4-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
 <20241102000843.1301099-4-samuel.holland@sifive.com>
Message-ID: <6a62e26b-3c55-425c-813f-2f84b56c6951@ghiti.fr>

Hi Samuel,

On 02/11/2024 01:07, Samuel Holland wrote:
> Some functions were defined equivalently in both pgtable.h and
> pgtable-64.h. Keep only one definition, and move it to pgtable-64.h
> unless it is also used for Sv32. Note that while Sv32 uses only two
> levels of page tables, the kernel is not consistent with how they are
> folded. THP requires pfn_pmd()/pmd_pfn() and mm/init.c requires
> pfn_pgd()/pgd_pfn(), so for now both are provided.
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
>   arch/riscv/include/asm/pgtable-32.h |  4 ++++
>   arch/riscv/include/asm/pgtable-64.h | 28 ++++++++++++++--------------
>   arch/riscv/include/asm/pgtable.h    | 23 ++++-------------------
>   arch/riscv/mm/init.c                |  8 ++++----
>   arch/riscv/mm/kasan_init.c          |  8 ++++----
>   5 files changed, 30 insertions(+), 41 deletions(-)
>
> diff --git a/arch/riscv/include/asm/pgtable-32.h b/arch/riscv/include/asm/pgtable-32.h
> index 00f3369570a8..23137347dc15 100644
> --- a/arch/riscv/include/asm/pgtable-32.h
> +++ b/arch/riscv/include/asm/pgtable-32.h
> @@ -33,6 +33,10 @@
>   					  _PAGE_WRITE | _PAGE_EXEC |	\
>   					  _PAGE_USER | _PAGE_GLOBAL))
>   
> +#define pud_pfn(pud)				(pmd_pfn((pmd_t){ pud }))
> +#define p4d_pfn(p4d)				(pud_pfn((pud_t){ p4d }))


pud_pfn() and p4d_pfn() should not be used in 32-bit right? I think you 
can remove their definitions and simplify pgd_pfn().


> +#define pgd_pfn(pgd)				(p4d_pfn((p4d_t){ pgd }))
> +
>   static const __maybe_unused int pgtable_l4_enabled;
>   static const __maybe_unused int pgtable_l5_enabled;
>   
> diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
> index 0897dd99ab8d..33e7ff049c4a 100644
> --- a/arch/riscv/include/asm/pgtable-64.h
> +++ b/arch/riscv/include/asm/pgtable-64.h
> @@ -213,19 +213,20 @@ static inline pud_t pfn_pud(unsigned long pfn, pgprot_t prot)
>   	return __pud((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
>   }
>   
> -static inline unsigned long _pud_pfn(pud_t pud)
> +#define pud_pfn pud_pfn
> +static inline unsigned long pud_pfn(pud_t pud)
>   {
>   	return __page_val_to_pfn(pud_val(pud));
>   }
>   
>   static inline pmd_t *pud_pgtable(pud_t pud)
>   {
> -	return (pmd_t *)pfn_to_virt(__page_val_to_pfn(pud_val(pud)));
> +	return (pmd_t *)pfn_to_virt(pud_pfn(pud));
>   }
>   
>   static inline struct page *pud_page(pud_t pud)
>   {
> -	return pfn_to_page(__page_val_to_pfn(pud_val(pud)));
> +	return pfn_to_page(pud_pfn(pud));
>   }
>   
>   #define mm_p4d_folded  mm_p4d_folded
> @@ -257,11 +258,6 @@ static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t prot)
>   	return __pmd((pfn << _PAGE_PFN_SHIFT) | prot_val);
>   }
>   
> -static inline unsigned long _pmd_pfn(pmd_t pmd)
> -{
> -	return __page_val_to_pfn(pmd_val(pmd));
> -}
> -
>   #define mk_pmd(page, prot)    pfn_pmd(page_to_pfn(page), prot)
>   
>   #define pmd_ERROR(e) \
> @@ -316,7 +312,7 @@ static inline p4d_t pfn_p4d(unsigned long pfn, pgprot_t prot)
>   	return __p4d((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
>   }
>   
> -static inline unsigned long _p4d_pfn(p4d_t p4d)
> +static inline unsigned long p4d_pfn(p4d_t p4d)
>   {
>   	return __page_val_to_pfn(p4d_val(p4d));
>   }
> @@ -324,7 +320,7 @@ static inline unsigned long _p4d_pfn(p4d_t p4d)
>   static inline pud_t *p4d_pgtable(p4d_t p4d)
>   {
>   	if (pgtable_l4_enabled)
> -		return (pud_t *)pfn_to_virt(__page_val_to_pfn(p4d_val(p4d)));
> +		return (pud_t *)pfn_to_virt(p4d_pfn(p4d));
>   
>   	return (pud_t *)pud_pgtable((pud_t) { p4d_val(p4d) });
>   }
> @@ -332,7 +328,7 @@ static inline pud_t *p4d_pgtable(p4d_t p4d)
>   
>   static inline struct page *p4d_page(p4d_t p4d)
>   {
> -	return pfn_to_page(__page_val_to_pfn(p4d_val(p4d)));
> +	return pfn_to_page(p4d_pfn(p4d));
>   }
>   
>   #define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
> @@ -378,10 +374,15 @@ static inline void pgd_clear(pgd_t *pgd)
>   		set_pgd(pgd, __pgd(0));
>   }
>   
> +static inline unsigned long pgd_pfn(pgd_t pgd)
> +{
> +	return __page_val_to_pfn(pgd_val(pgd));
> +}
> +
>   static inline p4d_t *pgd_pgtable(pgd_t pgd)
>   {
>   	if (pgtable_l5_enabled)
> -		return (p4d_t *)pfn_to_virt(__page_val_to_pfn(pgd_val(pgd)));
> +		return (p4d_t *)pfn_to_virt(pgd_pfn(pgd));
>   
>   	return (p4d_t *)p4d_pgtable((p4d_t) { pgd_val(pgd) });
>   }
> @@ -389,9 +390,8 @@ static inline p4d_t *pgd_pgtable(pgd_t pgd)
>   
>   static inline struct page *pgd_page(pgd_t pgd)
>   {
> -	return pfn_to_page(__page_val_to_pfn(pgd_val(pgd)));
> +	return pfn_to_page(pgd_pfn(pgd));
>   }
> -#define pgd_page(pgd)	pgd_page(pgd)
>   
>   #define p4d_index(addr) (((addr) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
>   
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index e79f15293492..3e0e1177107d 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -258,19 +258,19 @@ static inline pgd_t pfn_pgd(unsigned long pfn, pgprot_t prot)
>   	return __pgd((pfn << _PAGE_PFN_SHIFT) | prot_val);
>   }
>   
> -static inline unsigned long _pgd_pfn(pgd_t pgd)
> +static inline unsigned long pmd_pfn(pmd_t pmd)
>   {
> -	return __page_val_to_pfn(pgd_val(pgd));
> +	return __page_val_to_pfn(pmd_val(pmd));
>   }
>   
>   static inline struct page *pmd_page(pmd_t pmd)
>   {
> -	return pfn_to_page(__page_val_to_pfn(pmd_val(pmd)));
> +	return pfn_to_page(pmd_pfn(pmd));
>   }
>   
>   static inline unsigned long pmd_page_vaddr(pmd_t pmd)
>   {
> -	return (unsigned long)pfn_to_virt(__page_val_to_pfn(pmd_val(pmd)));
> +	return (unsigned long)pfn_to_virt(pmd_pfn(pmd));
>   }
>   
>   static inline pte_t pmd_pte(pmd_t pmd)
> @@ -673,21 +673,6 @@ static inline pmd_t pmd_mkinvalid(pmd_t pmd)
>   	return __pmd(pmd_val(pmd) & ~(_PAGE_PRESENT|_PAGE_PROT_NONE));
>   }
>   
> -#define __pmd_to_phys(pmd)  (__page_val_to_pfn(pmd_val(pmd)) << PAGE_SHIFT)
> -
> -static inline unsigned long pmd_pfn(pmd_t pmd)
> -{
> -	return ((__pmd_to_phys(pmd) & PMD_MASK) >> PAGE_SHIFT);
> -}
> -
> -#define __pud_to_phys(pud)  (__page_val_to_pfn(pud_val(pud)) << PAGE_SHIFT)
> -
> -#define pud_pfn pud_pfn
> -static inline unsigned long pud_pfn(pud_t pud)
> -{
> -	return ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT);
> -}
> -
>   static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
>   {
>   	return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 0e8c20adcd98..7282b62b7e8d 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -497,7 +497,7 @@ static void __meminit create_pmd_mapping(pmd_t *pmdp,
>   		ptep = pt_ops.get_pte_virt(pte_phys);
>   		memset(ptep, 0, PAGE_SIZE);
>   	} else {
> -		pte_phys = PFN_PHYS(_pmd_pfn(pmdp[pmd_idx]));
> +		pte_phys = PFN_PHYS(pmd_pfn(pmdp[pmd_idx]));
>   		ptep = pt_ops.get_pte_virt(pte_phys);
>   	}
>   
> @@ -599,7 +599,7 @@ static void __meminit create_pud_mapping(pud_t *pudp, uintptr_t va, phys_addr_t
>   		nextp = pt_ops.get_pmd_virt(next_phys);
>   		memset(nextp, 0, PAGE_SIZE);
>   	} else {
> -		next_phys = PFN_PHYS(_pud_pfn(pudp[pud_index]));
> +		next_phys = PFN_PHYS(pud_pfn(pudp[pud_index]));
>   		nextp = pt_ops.get_pmd_virt(next_phys);
>   	}
>   
> @@ -625,7 +625,7 @@ static void __meminit create_p4d_mapping(p4d_t *p4dp, uintptr_t va, phys_addr_t
>   		nextp = pt_ops.get_pud_virt(next_phys);
>   		memset(nextp, 0, PAGE_SIZE);
>   	} else {
> -		next_phys = PFN_PHYS(_p4d_pfn(p4dp[p4d_index]));
> +		next_phys = PFN_PHYS(p4d_pfn(p4dp[p4d_index]));
>   		nextp = pt_ops.get_pud_virt(next_phys);
>   	}
>   
> @@ -682,7 +682,7 @@ void __meminit create_pgd_mapping(pgd_t *pgdp, uintptr_t va, phys_addr_t pa, phy
>   		nextp = get_pgd_next_virt(next_phys);
>   		memset(nextp, 0, PAGE_SIZE);
>   	} else {
> -		next_phys = PFN_PHYS(_pgd_pfn(pgdp[pgd_idx]));
> +		next_phys = PFN_PHYS(pgd_pfn(pgdp[pgd_idx]));
>   		nextp = get_pgd_next_virt(next_phys);
>   	}
>   
> diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c
> index c301c8d291d2..bac65e3268a4 100644
> --- a/arch/riscv/mm/kasan_init.c
> +++ b/arch/riscv/mm/kasan_init.c
> @@ -171,7 +171,7 @@ static void __init kasan_early_clear_pud(p4d_t *p4dp,
>   	if (!pgtable_l4_enabled) {
>   		pudp = (pud_t *)p4dp;
>   	} else {
> -		base_pud = pt_ops.get_pud_virt(pfn_to_phys(_p4d_pfn(p4dp_get(p4dp))));
> +		base_pud = pt_ops.get_pud_virt(pfn_to_phys(p4d_pfn(p4dp_get(p4dp))));
>   		pudp = base_pud + pud_index(vaddr);
>   	}
>   
> @@ -196,7 +196,7 @@ static void __init kasan_early_clear_p4d(pgd_t *pgdp,
>   	if (!pgtable_l5_enabled) {
>   		p4dp = (p4d_t *)pgdp;
>   	} else {
> -		base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(pgdp_get(pgdp))));
> +		base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(pgd_pfn(pgdp_get(pgdp))));
>   		p4dp = base_p4d + p4d_index(vaddr);
>   	}
>   
> @@ -242,7 +242,7 @@ static void __init kasan_early_populate_pud(p4d_t *p4dp,
>   	if (!pgtable_l4_enabled) {
>   		pudp = (pud_t *)p4dp;
>   	} else {
> -		base_pud = pt_ops.get_pud_virt(pfn_to_phys(_p4d_pfn(p4dp_get(p4dp))));
> +		base_pud = pt_ops.get_pud_virt(pfn_to_phys(p4d_pfn(p4dp_get(p4dp))));
>   		pudp = base_pud + pud_index(vaddr);
>   	}
>   
> @@ -280,7 +280,7 @@ static void __init kasan_early_populate_p4d(pgd_t *pgdp,
>   	if (!pgtable_l5_enabled) {
>   		p4dp = (p4d_t *)pgdp;
>   	} else {
> -		base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(pgdp_get(pgdp))));
> +		base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(pgd_pfn(pgdp_get(pgdp))));
>   		p4dp = base_p4d + p4d_index(vaddr);
>   	}
>   


Otherwise, this is a nice cleanup, you can add:

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From alex at ghiti.fr  Tue Nov  5 02:00:08 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 11:00:08 +0100
Subject: [PATCH 04/11] riscv: mm: Deduplicate _PAGE_CHG_MASK definition
In-Reply-To: <20241102000843.1301099-5-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
 <20241102000843.1301099-5-samuel.holland@sifive.com>
Message-ID: <e9aebe78-2e5b-43f3-bd96-45bd9f9e7269@ghiti.fr>

On 02/11/2024 01:07, Samuel Holland wrote:
> The two existing definitions are equivalent because _PAGE_MTMASK is
> defined as 0 on riscv32.
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
>   arch/riscv/include/asm/pgtable-32.h | 5 -----
>   arch/riscv/include/asm/pgtable-64.h | 7 -------
>   arch/riscv/include/asm/pgtable.h    | 6 ++++++
>   3 files changed, 6 insertions(+), 12 deletions(-)
>
> diff --git a/arch/riscv/include/asm/pgtable-32.h b/arch/riscv/include/asm/pgtable-32.h
> index 23137347dc15..7dc0751d67dc 100644
> --- a/arch/riscv/include/asm/pgtable-32.h
> +++ b/arch/riscv/include/asm/pgtable-32.h
> @@ -28,11 +28,6 @@
>   #define _PAGE_IO		0
>   #define _PAGE_MTMASK		0
>   
> -/* Set of bits to preserve across pte_modify() */
> -#define _PAGE_CHG_MASK  (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ |	\
> -					  _PAGE_WRITE | _PAGE_EXEC |	\
> -					  _PAGE_USER | _PAGE_GLOBAL))
> -
>   #define pud_pfn(pud)				(pmd_pfn((pmd_t){ pud }))
>   #define p4d_pfn(p4d)				(pud_pfn((pud_t){ p4d }))
>   #define pgd_pfn(pgd)				(p4d_pfn((p4d_t){ pgd }))
> diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
> index 33e7ff049c4a..4ba88592b8d1 100644
> --- a/arch/riscv/include/asm/pgtable-64.h
> +++ b/arch/riscv/include/asm/pgtable-64.h
> @@ -66,7 +66,6 @@ typedef struct {
>   
>   #define pmd_val(x)      ((x).pmd)
>   #define __pmd(x)        ((pmd_t) { (x) })
> -
>   #define PTRS_PER_PMD    (PAGE_SIZE / sizeof(pmd_t))
>   
>   /*
> @@ -166,12 +165,6 @@ static inline u64 riscv_page_io(void)
>   #define _PAGE_IO		riscv_page_io()
>   #define _PAGE_MTMASK		riscv_page_mtmask()
>   
> -/* Set of bits to preserve across pte_modify() */
> -#define _PAGE_CHG_MASK  (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ |	\
> -					  _PAGE_WRITE | _PAGE_EXEC |	\
> -					  _PAGE_USER | _PAGE_GLOBAL |	\
> -					  _PAGE_MTMASK))
> -
>   static inline int pud_present(pud_t pud)
>   {
>   	return (pud_val(pud) & _PAGE_PRESENT);
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index 3e0e1177107d..afa0b455eaa4 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -201,6 +201,12 @@ extern struct pt_alloc_ops pt_ops __meminitdata;
>   #define _PAGE_IOREMAP	((_PAGE_KERNEL & ~_PAGE_MTMASK) | _PAGE_IO)
>   #define PAGE_KERNEL_IO		__pgprot(_PAGE_IOREMAP)
>   
> +/* Set of bits to preserve across pte_modify() */
> +#define _PAGE_CHG_MASK  (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ |	\
> +					  _PAGE_WRITE | _PAGE_EXEC |	\
> +					  _PAGE_USER | _PAGE_GLOBAL |	\
> +					  _PAGE_MTMASK))
> +
>   extern pgd_t swapper_pg_dir[];
>   extern pgd_t trampoline_pg_dir[];
>   extern pgd_t early_pg_dir[];

Nice clean up too, you can add:

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From alex at ghiti.fr  Tue Nov  5 02:06:36 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 11:06:36 +0100
Subject: [PATCH 05/11] riscv: ptdump: Only show N and MT bits when enabled
 in the kernel
In-Reply-To: <20241102000843.1301099-6-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
 <20241102000843.1301099-6-samuel.holland@sifive.com>
Message-ID: <20db5f94-5606-473c-9c5c-ebb0e4488090@ghiti.fr>

On 02/11/2024 01:07, Samuel Holland wrote:
> When the Svnapot or Svpbmt extension is not implemented, the
> corresponding page table bits are reserved, and must be zero. There is
> no need to show them in the ptdump output.
>
> When the Kconfig option for an extension is disabled, we assume it is
> not implemented. In that case, the kernel may provide a fallback
> definition for the fields, like how _PAGE_MTMASK is defined on riscv32.
> Using those fallback definitions in ptdump would produce incorrect
> results. To avoid this, hide the fields from the ptdump output.
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
>   arch/riscv/mm/ptdump.c | 6 ++++--
>   1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
> index 9d5f657a251b..58a7322e9a82 100644
> --- a/arch/riscv/mm/ptdump.c
> +++ b/arch/riscv/mm/ptdump.c
> @@ -135,11 +135,13 @@ struct prot_bits {
>   
>   static const struct prot_bits pte_bits[] = {
>   	{
> -#ifdef CONFIG_64BIT
> +#ifdef CONFIG_RISCV_ISA_SVNAPOT
>   		.mask = _PAGE_NAPOT,
>   		.set = "N",
>   		.clear = ".",
>   	}, {
> +#endif
> +#ifdef CONFIG_RISCV_ISA_SVPBMT
>   		.mask = _PAGE_MTMASK_SVPBMT,
>   		.set = "MT(%s)",
>   		.clear = "  ..  ",
> @@ -215,7 +217,7 @@ static void dump_prot(struct pg_state *st)
>   		if (val) {
>   			if (pte_bits[i].mask == _PAGE_SOFT)
>   				sprintf(s, pte_bits[i].set, val >> 8);
> -#ifdef CONFIG_64BIT
> +#ifdef CONFIG_RISCV_ISA_SVPBMT
>   			else if (pte_bits[i].mask == _PAGE_MTMASK_SVPBMT) {
>   				if (val == _PAGE_NOCACHE_SVPBMT)
>   					sprintf(s, pte_bits[i].set, "NC");


It makes sense so:

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From alex at ghiti.fr  Tue Nov  5 02:25:01 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 11:25:01 +0100
Subject: [PATCH 02/11] riscv: mm: Increment PFN in place when splitting
 mappings
In-Reply-To: <20241102000843.1301099-3-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
 <20241102000843.1301099-3-samuel.holland@sifive.com>
Message-ID: <38936e70-e293-446a-8efc-208d52e42573@ghiti.fr>

Hi Samuel,

On 02/11/2024 01:07, Samuel Holland wrote:
> The current code separates page table entry values into a PFN and a
> pgprot_t before incrementing the PFN and combining the two parts using
> pfn_pXX(). On some hardware with custom page table formats or memory
> aliases, the pfn_pXX() functions need to transform the PTE value, so
> these functions would need to apply the opposite transformation when
> breaking apart the PTE value.
>
> However, both transformations can be avoided by incrementing the PFN in
> place, as done by pte_advance_pfn() and set_ptes().
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
>   arch/riscv/mm/pageattr.c | 17 ++++++++---------
>   1 file changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
> index 271d01a5ba4d..335060adc1a6 100644
> --- a/arch/riscv/mm/pageattr.c
> +++ b/arch/riscv/mm/pageattr.c
> @@ -109,9 +109,8 @@ static int __split_linear_mapping_pmd(pud_t *pudp,
>   			continue;
>   
>   		if (pmd_leaf(pmdp_get(pmdp))) {
> +			pte_t pte = pmd_pte(pmdp_get(pmdp));
>   			struct page *pte_page;
> -			unsigned long pfn = _pmd_pfn(pmdp_get(pmdp));
> -			pgprot_t prot = __pgprot(pmd_val(pmdp_get(pmdp)) & ~_PAGE_PFN_MASK);
>   			pte_t *ptep_new;
>   			int i;
>   
> @@ -121,7 +120,7 @@ static int __split_linear_mapping_pmd(pud_t *pudp,
>   
>   			ptep_new = (pte_t *)page_address(pte_page);
>   			for (i = 0; i < PTRS_PER_PTE; ++i, ++ptep_new)
> -				set_pte(ptep_new, pfn_pte(pfn + i, prot));
> +				set_pte(ptep_new, pte_advance_pfn(pte, i));
>   
>   			smp_wmb();
>   
> @@ -149,9 +148,8 @@ static int __split_linear_mapping_pud(p4d_t *p4dp,
>   			continue;
>   
>   		if (pud_leaf(pudp_get(pudp))) {
> +			pmd_t pmd = __pmd(pud_val(pudp_get(pudp)));


Nit: You could use pud_pte() here.


>   			struct page *pmd_page;
> -			unsigned long pfn = _pud_pfn(pudp_get(pudp));
> -			pgprot_t prot = __pgprot(pud_val(pudp_get(pudp)) & ~_PAGE_PFN_MASK);
>   			pmd_t *pmdp_new;
>   			int i;
>   
> @@ -162,7 +160,8 @@ static int __split_linear_mapping_pud(p4d_t *p4dp,
>   			pmdp_new = (pmd_t *)page_address(pmd_page);
>   			for (i = 0; i < PTRS_PER_PMD; ++i, ++pmdp_new)
>   				set_pmd(pmdp_new,
> -					pfn_pmd(pfn + ((i * PMD_SIZE) >> PAGE_SHIFT), prot));
> +					__pmd(pmd_val(pmd) +
> +					      (i << (PMD_SHIFT - PAGE_SHIFT + PFN_PTE_SHIFT))));


Nit: Here you could use pte_advance_pfn(pmd, i << (PMD_SHIFT - PAGE_SHIFT))


>   
>   			smp_wmb();
>   
> @@ -198,9 +197,8 @@ static int __split_linear_mapping_p4d(pgd_t *pgdp,
>   			continue;
>   
>   		if (p4d_leaf(p4dp_get(p4dp))) {
> +			pud_t pud = __pud(p4d_val(p4dp_get(p4dp)));
>   			struct page *pud_page;
> -			unsigned long pfn = _p4d_pfn(p4dp_get(p4dp));
> -			pgprot_t prot = __pgprot(p4d_val(p4dp_get(p4dp)) & ~_PAGE_PFN_MASK);
>   			pud_t *pudp_new;
>   			int i;
>   
> @@ -215,7 +213,8 @@ static int __split_linear_mapping_p4d(pgd_t *pgdp,
>   			pudp_new = (pud_t *)page_address(pud_page);
>   			for (i = 0; i < PTRS_PER_PUD; ++i, ++pudp_new)
>   				set_pud(pudp_new,
> -					pfn_pud(pfn + ((i * PUD_SIZE) >> PAGE_SHIFT), prot));
> +					__pud(pud_val(pud) +
> +					      (i << (PUD_SHIFT - PAGE_SHIFT + PFN_PTE_SHIFT))));


Nit: Ditto


>   
>   			/*
>   			 * Make sure the pud filling is not reordered with the


Other than the nits (which are up to you), you can add:

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From alex at ghiti.fr  Tue Nov  5 03:03:01 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 12:03:01 +0100
Subject: [PATCH 06/11] riscv: mm: Fix up memory types when writing page
 tables
In-Reply-To: <20241102000843.1301099-7-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
 <20241102000843.1301099-7-samuel.holland@sifive.com>
Message-ID: <4123bd5d-33b8-4248-a03a-de784c433040@ghiti.fr>

On 02/11/2024 01:08, Samuel Holland wrote:
> Currently, Linux on RISC-V has three ways to specify the cacheability
> and ordering PMAs of a page:
>   1) Do nothing; assume the system is entirely cache-coherent and rely on
>      the hardware for any ordering requirements
>   2) Use the page table bits specified by Svpbmt
>   3) Use the page table bits specified by XTheadMae
>
> To support all three methods, the kernel dynamically determines the
> definitions of the _PAGE_NOCACHE and _PAGE_IO fields. However, this
> alone is not sufficient, as XTheadMae uses a nonzero memory type value
> for normal memory pages. So the kernel has an additional alternative
> sequence (ALT_THEAD_PMA) to insert the correct memory type when writing
> page table entries.


I have just taken a look, and it's not exactly when the page table is 
written but rather when the page table entry is being created.

And I have to admit that I find it weird, moving that to the set_pXd() 
functions seems way more robust. Indeed those functions must be used to 
write a page table entry but a page table entry can be created by other 
means than with the pfn_pXd() functions.

This is what I did for NAPOT to hide the size of the mapping contained 
in the pfn from the generic kernel here 
https://lore.kernel.org/linux-riscv/20240802151430.99114-1-alexghiti at rivosinc.com/


>
> Some RISC-V platforms use a fourth method to specify the cacheability of
> a page of RAM: RAM is mapped to multiple physical address ranges, with
> each alias having a different set of statically-determined PMAs.
> Software selects the PMAs for a page by choosing a PFN from the
> corresponding physical address range. This strategy also requires
> applying a transformation when writing page table entries. Since these
> physical memory aliases should be invisible to the rest of the kernel,
> the opposite transformation must be applied when reading page table
> entries.
>
> However, with this last method of specifying PMAs, there is no inherent
> way to indicate the cacheability of a page in the pgprot_t value, since
> the PFN itself determines cacheability. One possible way is to reuse the
> PTE bits from Svpbmt, as Svpbmt is the standard extension. This requires
> the Svpbmt version of _PAGE_NOCACHE and _PAGE_IO to be available even
> when the CPU does not support the extension.
>
> It turns out that with some clever bit manipulation, it is just as
> efficient to transform all three Svpbmt memory type values to the
> corresponding XTheadMae values, as it is to check for and insert the
> one XTheadMae memory type value for normal memory. This allows the
> _PAGE_NOCACHE and _PAGE_IO definitions to be compile-time constants,
> and it centralizes all memory type handling to one set of ALTERNATIVE
> macros.
>
> For a kernel with both Svpbmt and XTheadMae enabled, this change reduces
> both kernel text size and the number of alternatives applied at boot.
> However, there are a couple of small costs. For platforms using the
> first method ("do nothing"), we must mask off the memory type bits when
> writing page table entries, whereas previously no action was needed.
> Second, when reading page table entries, the XTheadMae values must be
> transformed back to the Svpbmt values. This "unfix" operation is also
> needed for alias-based PMA selection, so both methods can use the same
> ALTERNATIVE.
>
> As a side effect, this change fixes the reporting of the NAPOT and
> memory type bits from ptdump on platforms with XTheadMae.
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
>   arch/riscv/Kconfig.errata            |   1 +
>   arch/riscv/include/asm/errata_list.h |  45 -----------
>   arch/riscv/include/asm/pgtable-32.h  |   3 +
>   arch/riscv/include/asm/pgtable-64.h  | 108 ++++++++++++++++++---------
>   arch/riscv/include/asm/pgtable.h     |  18 +++--
>   arch/riscv/mm/ptdump.c               |  13 ++--
>   6 files changed, 93 insertions(+), 95 deletions(-)
>
> diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
> index 2acc7d876e1f..2806ed7916c7 100644
> --- a/arch/riscv/Kconfig.errata
> +++ b/arch/riscv/Kconfig.errata
> @@ -86,6 +86,7 @@ config ERRATA_THEAD_MAE
>   	bool "Apply T-Head's memory attribute extension (XTheadMae) errata"
>   	depends on ERRATA_THEAD && 64BIT && MMU
>   	select RISCV_ALTERNATIVE_EARLY
> +	select RISCV_ISA_SVPBMT
>   	default y
>   	help
>   	  This will apply the memory attribute extension errata to handle the
> diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
> index 7c8a71a526a3..b127f4891083 100644
> --- a/arch/riscv/include/asm/errata_list.h
> +++ b/arch/riscv/include/asm/errata_list.h
> @@ -58,51 +58,6 @@ asm(ALTERNATIVE("sfence.vma %0, %1", "sfence.vma", SIFIVE_VENDOR_ID,	\
>   		ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200)	\
>   		: : "r" (addr), "r" (asid) : "memory")
>   
> -/*
> - * _val is marked as "will be overwritten", so need to set it to 0
> - * in the default case.
> - */
> -#define ALT_SVPBMT_SHIFT 61
> -#define ALT_THEAD_MAE_SHIFT 59
> -#define ALT_SVPBMT(_val, prot)						\
> -asm(ALTERNATIVE_2("li %0, 0\t\nnop",					\
> -		  "li %0, %1\t\nslli %0,%0,%3", 0,			\
> -			RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,	\
> -		  "li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID,	\
> -			ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)	\
> -		: "=r"(_val)						\
> -		: "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT),		\
> -		  "I"(prot##_THEAD >> ALT_THEAD_MAE_SHIFT),		\
> -		  "I"(ALT_SVPBMT_SHIFT),				\
> -		  "I"(ALT_THEAD_MAE_SHIFT))
> -
> -#ifdef CONFIG_ERRATA_THEAD_MAE
> -/*
> - * IO/NOCACHE memory types are handled together with svpbmt,
> - * so on T-Head chips, check if no other memory type is set,
> - * and set the non-0 PMA type if applicable.
> - */
> -#define ALT_THEAD_PMA(_val)						\
> -asm volatile(ALTERNATIVE(						\
> -	__nops(7),							\
> -	"li      t3, %1\n\t"						\
> -	"slli    t3, t3, %3\n\t"					\
> -	"and     t3, %0, t3\n\t"					\
> -	"bne     t3, zero, 2f\n\t"					\
> -	"li      t3, %2\n\t"						\
> -	"slli    t3, t3, %3\n\t"					\
> -	"or      %0, %0, t3\n\t"					\
> -	"2:",  THEAD_VENDOR_ID,						\
> -		ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)		\
> -	: "+r"(_val)							\
> -	: "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_MAE_SHIFT),		\
> -	  "I"(_PAGE_PMA_THEAD >> ALT_THEAD_MAE_SHIFT),			\
> -	  "I"(ALT_THEAD_MAE_SHIFT)					\
> -	: "t3")
> -#else
> -#define ALT_THEAD_PMA(_val)
> -#endif
> -
>   #define ALT_CMO_OP(_op, _start, _size, _cachesize)			\
>   asm volatile(ALTERNATIVE(						\
>   	__nops(5),							\
> diff --git a/arch/riscv/include/asm/pgtable-32.h b/arch/riscv/include/asm/pgtable-32.h
> index 7dc0751d67dc..b422a15fb464 100644
> --- a/arch/riscv/include/asm/pgtable-32.h
> +++ b/arch/riscv/include/asm/pgtable-32.h
> @@ -28,6 +28,9 @@
>   #define _PAGE_IO		0
>   #define _PAGE_MTMASK		0
>   
> +#define ALT_FIXUP_MT(_val)
> +#define ALT_UNFIX_MT(_val)
> +
>   #define pud_pfn(pud)				(pmd_pfn((pmd_t){ pud }))
>   #define p4d_pfn(p4d)				(pud_pfn((pud_t){ p4d }))
>   #define pgd_pfn(pgd)				(p4d_pfn((p4d_t){ pgd }))
> diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
> index 4ba88592b8d1..4e8a32f035d7 100644
> --- a/arch/riscv/include/asm/pgtable-64.h
> +++ b/arch/riscv/include/asm/pgtable-64.h
> @@ -8,7 +8,7 @@
>   
>   #include <linux/bits.h>
>   #include <linux/const.h>
> -#include <asm/errata_list.h>
> +#include <asm/alternative-macros.h>
>   
>   extern bool pgtable_l4_enabled;
>   extern bool pgtable_l5_enabled;
> @@ -109,6 +109,8 @@ enum napot_cont_order {
>   #define HUGE_MAX_HSTATE		2
>   #endif
>   
> +#ifdef CONFIG_RISCV_ISA_SVPBMT
> +
>   /*
>    * [62:61] Svpbmt Memory Type definitions:
>    *
> @@ -117,9 +119,9 @@ enum napot_cont_order {
>    *  10 - IO     Non-cacheable, non-idempotent, strongly-ordered I/O memory
>    *  11 - Rsvd   Reserved for future standard use
>    */
> -#define _PAGE_NOCACHE_SVPBMT	(1UL << 61)
> -#define _PAGE_IO_SVPBMT		(1UL << 62)
> -#define _PAGE_MTMASK_SVPBMT	(_PAGE_NOCACHE_SVPBMT | _PAGE_IO_SVPBMT)
> +#define _PAGE_NOCACHE		(1UL << 61)
> +#define _PAGE_IO		(2UL << 61)
> +#define _PAGE_MTMASK		(3UL << 61)
>   
>   /*
>    * [63:59] T-Head Memory Type definitions:
> @@ -128,42 +130,66 @@ enum napot_cont_order {
>    * bit[61] B - Bufferable
>    * bit[60] SH - Shareable
>    * bit[59] Sec - Trustable
> - * 00110 - NC   Weakly-ordered, Non-cacheable, Bufferable, Shareable, Non-trustable
>    * 01110 - PMA  Weakly-ordered, Cacheable, Bufferable, Shareable, Non-trustable
> + * 00110 - NC   Weakly-ordered, Non-cacheable, Bufferable, Shareable, Non-trustable
>    * 10010 - IO   Strongly-ordered, Non-cacheable, Non-bufferable, Shareable, Non-trustable
> + *
> + * ALT_FIXUP_MT translates Svpbmt memory types to XTheadMae memory types.
> + * Pseudocode operating on bits [63:60]:
> + *   t0 = mt << 1
> + *   if (t0 == 0)
> + *     t0 |= 2
> + *   t0 ^= 0x5
> + *   mt ^= t0
> + *
> + * ALT_UNFIX_MT translates XTheadMae memory types to Svpbmt memory types.
> + * Pseudocode operating on bits [63:60]:
> + *   t0 = mt & 0xd
> + *   t0 ^= t0 >> 1
> + *   mt ^= t0
>    */
> -#define _PAGE_PMA_THEAD		((1UL << 62) | (1UL << 61) | (1UL << 60))
> -#define _PAGE_NOCACHE_THEAD	((1UL << 61) | (1UL << 60))
> -#define _PAGE_IO_THEAD		((1UL << 63) | (1UL << 60))
> -#define _PAGE_MTMASK_THEAD	(_PAGE_PMA_THEAD | _PAGE_IO_THEAD | (1UL << 59))
> -
> -static inline u64 riscv_page_mtmask(void)
> -{
> -	u64 val;
> -
> -	ALT_SVPBMT(val, _PAGE_MTMASK);
> -	return val;
> -}
>   
> -static inline u64 riscv_page_nocache(void)
> -{
> -	u64 val;
> +#define ALT_FIXUP_MT(_val)								\
> +	asm(ALTERNATIVE_2("addi	t0, zero, 0x3\n\t"					\
> +			  "slli	t0, t0, 61\n\t"						\
> +			  "not	t0, t0\n\t"						\
> +			  "and	%0, %0, t0\n\t"						\
> +			  "nop\n\t"							\
> +			  "nop\n\t"							\
> +			  "nop",							\
> +			  __nops(7),							\
> +			  0, RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,		\
> +			  "srli	t0, %0, 59\n\t"						\
> +			  "seqz t1, t0\n\t"						\
> +			  "slli	t1, t1, 1\n\t"						\
> +			  "or	t0, t0, t1\n\t"						\
> +			  "xori	t0, t0, 0x5\n\t"					\
> +			  "slli	t0, t0, 60\n\t"						\
> +			  "xor	%0, %0, t0",						\
> +			  THEAD_VENDOR_ID, ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)	\
> +			  : "+r" (_val) :: "t0", "t1")
> +
> +#define ALT_UNFIX_MT(_val)								\
> +	asm(ALTERNATIVE(__nops(6),							\
> +			  "srli	t0, %0, 60\n\t"						\
> +			  "andi	t0, t0, 0xd\n\t"					\
> +			  "srli	t1, t0, 1\n\t"						\
> +			  "xor	t0, t0, t1\n\t"						\
> +			  "slli	t0, t0, 60\n\t"						\
> +			  "xor	%0, %0, t0",						\
> +			  THEAD_VENDOR_ID, ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)	\
> +			  : "+r" (_val) :: "t0", "t1")
>   
> -	ALT_SVPBMT(val, _PAGE_NOCACHE);
> -	return val;
> -}
> +#else
>   
> -static inline u64 riscv_page_io(void)
> -{
> -	u64 val;
> +#define _PAGE_NOCACHE		0
> +#define _PAGE_IO		0
> +#define _PAGE_MTMASK		0
>   
> -	ALT_SVPBMT(val, _PAGE_IO);
> -	return val;
> -}
> +#define ALT_FIXUP_MT(_val)
> +#define ALT_UNFIX_MT(_val)
>   
> -#define _PAGE_NOCACHE		riscv_page_nocache()
> -#define _PAGE_IO		riscv_page_io()
> -#define _PAGE_MTMASK		riscv_page_mtmask()
> +#endif /* CONFIG_RISCV_ISA_SVPBMT */
>   
>   static inline int pud_present(pud_t pud)
>   {
> @@ -203,7 +229,11 @@ static inline void pud_clear(pud_t *pudp)
>   
>   static inline pud_t pfn_pud(unsigned long pfn, pgprot_t prot)
>   {
> -	return __pud((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
> +	pud_t pud = __pud((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
> +
> +	ALT_FIXUP_MT(pud);
> +
> +	return pud;
>   }
>   
>   #define pud_pfn pud_pfn
> @@ -244,11 +274,11 @@ static inline bool mm_pud_folded(struct mm_struct *mm)
>   
>   static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t prot)
>   {
> -	unsigned long prot_val = pgprot_val(prot);
> +	pmd_t pmd = __pmd((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
>   
> -	ALT_THEAD_PMA(prot_val);
> +	ALT_FIXUP_MT(pmd);
>   
> -	return __pmd((pfn << _PAGE_PFN_SHIFT) | prot_val);
> +	return pmd;
>   }
>   
>   #define mk_pmd(page, prot)    pfn_pmd(page_to_pfn(page), prot)
> @@ -302,7 +332,11 @@ static inline void p4d_clear(p4d_t *p4d)
>   
>   static inline p4d_t pfn_p4d(unsigned long pfn, pgprot_t prot)
>   {
> -	return __p4d((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
> +	p4d_t p4d = __p4d((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
> +
> +	ALT_FIXUP_MT(p4d);
> +
> +	return p4d;
>   }
>   
>   static inline unsigned long p4d_pfn(p4d_t p4d)
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index afa0b455eaa4..3ffcff76ac0d 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -257,11 +257,11 @@ static inline void pmd_clear(pmd_t *pmdp)
>   
>   static inline pgd_t pfn_pgd(unsigned long pfn, pgprot_t prot)
>   {
> -	unsigned long prot_val = pgprot_val(prot);
> +	pgd_t pgd = __pgd((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
>   
> -	ALT_THEAD_PMA(prot_val);
> +	ALT_FIXUP_MT(pgd);
>   
> -	return __pgd((pfn << _PAGE_PFN_SHIFT) | prot_val);
> +	return pgd;
>   }
>   
>   static inline unsigned long pmd_pfn(pmd_t pmd)
> @@ -338,11 +338,11 @@ static inline unsigned long pte_pfn(pte_t pte)
>   /* Constructs a page table entry */
>   static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
>   {
> -	unsigned long prot_val = pgprot_val(prot);
> +	pte_t pte = __pte((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
>   
> -	ALT_THEAD_PMA(prot_val);
> +	ALT_FIXUP_MT(pte);
>   
> -	return __pte((pfn << _PAGE_PFN_SHIFT) | prot_val);
> +	return pte;
>   }
>   
>   #define mk_pte(page, prot)       pfn_pte(page_to_pfn(page), prot)
> @@ -489,9 +489,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
>   {
>   	unsigned long newprot_val = pgprot_val(newprot);
>   
> -	ALT_THEAD_PMA(newprot_val);
> +	ALT_UNFIX_MT(pte);
> +	pte = __pte((pte_val(pte) & _PAGE_CHG_MASK) | newprot_val);
> +	ALT_FIXUP_MT(pte);
>   
> -	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | newprot_val);
> +	return pte;
>   }
>   
>   #define pgd_ERROR(e) \
> diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
> index 58a7322e9a82..6528c2561437 100644
> --- a/arch/riscv/mm/ptdump.c
> +++ b/arch/riscv/mm/ptdump.c
> @@ -142,7 +142,7 @@ static const struct prot_bits pte_bits[] = {
>   	}, {
>   #endif
>   #ifdef CONFIG_RISCV_ISA_SVPBMT
> -		.mask = _PAGE_MTMASK_SVPBMT,
> +		.mask = _PAGE_MTMASK,
>   		.set = "MT(%s)",
>   		.clear = "  ..  ",
>   	}, {
> @@ -218,10 +218,10 @@ static void dump_prot(struct pg_state *st)
>   			if (pte_bits[i].mask == _PAGE_SOFT)
>   				sprintf(s, pte_bits[i].set, val >> 8);
>   #ifdef CONFIG_RISCV_ISA_SVPBMT
> -			else if (pte_bits[i].mask == _PAGE_MTMASK_SVPBMT) {
> -				if (val == _PAGE_NOCACHE_SVPBMT)
> +			else if (pte_bits[i].mask == _PAGE_MTMASK) {
> +				if (val == _PAGE_NOCACHE)
>   					sprintf(s, pte_bits[i].set, "NC");
> -				else if (val == _PAGE_IO_SVPBMT)
> +				else if (val == _PAGE_IO)
>   					sprintf(s, pte_bits[i].set, "IO");
>   				else
>   					sprintf(s, pte_bits[i].set, "??");
> @@ -282,9 +282,12 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr,
>   		      int level, u64 val)
>   {
>   	struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
> -	u64 pa = PFN_PHYS(pte_pfn(__pte(val)));
>   	u64 prot = 0;
> +	u64 pa;
>   
> +	ALT_UNFIX_MT(val);
> +
> +	pa = PFN_PHYS(pte_pfn(__pte(val)));
>   	if (level >= 0)
>   		prot = val & pg_level[level].mask;
>   


From kexybiscuit at aosc.io  Tue Nov  5 03:46:21 2024
From: kexybiscuit at aosc.io (Kexy Biscuit)
Date: Tue, 5 Nov 2024 19:46:21 +0800
Subject: [PATCH bpf-next 1/2] libbpf: Add missing per-arch include path
In-Reply-To: <20240927131355.350918-1-bjorn@kernel.org>
References: <20240927131355.350918-1-bjorn@kernel.org>
Message-ID: <48a22231-89ec-460b-913b-54af18166da7@aosc.io>

On 9/27/2024 9:13 PM, Bj?rn T?pel wrote:
> From: Bj?rn T?pel <bjorn at rivosinc.com>
> 
> libbpf does not include the per-arch tools include path, e.g.
> tools/arch/riscv/include. Some architectures depend those files to
> build properly.
> 
> Include tools/arch/$(SUBARCH)/include in the libbpf build.
> 
> Fixes: 6d74d178fe6e ("tools: Add riscv barrier implementation")
> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
> ---
>   tools/lib/bpf/Makefile | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
> index 1b22f0f37288..857a5f7b413d 100644
> --- a/tools/lib/bpf/Makefile
> +++ b/tools/lib/bpf/Makefile
> @@ -61,7 +61,8 @@ ifndef VERBOSE
>   endif
>   
>   INCLUDES = -I$(or $(OUTPUT),.) \
> -	   -I$(srctree)/tools/include -I$(srctree)/tools/include/uapi
> +	   -I$(srctree)/tools/include -I$(srctree)/tools/include/uapi \
> +	   -I$(srctree)/tools/arch/$(SRCARCH)/include
>   
>   export prefix libdir src obj
>   
> 
> base-commit: db5ca265e3334b48c4e3fa07eef79e8bc578c430

This fixes building of bpf tools, thanks! You can add the following tags...

Reported-by: Andreas Schwab <schwab at suse.de>
Closes: https://lore.kernel.org/all/mvmo74441tr.fsf at suse.de/
Tested-by: Kexy Biscuit <kexybiscuit at aosc.io>
-- 
Best Regards,
Kexy Biscuit


From alex at ghiti.fr  Tue Nov  5 04:45:44 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 13:45:44 +0100
Subject: [RESEND PATCH V4 1/3] riscv: mm: Prepare for reusing PTE RSW
 bit(9)
In-Reply-To: <20240830011101.3189522-2-zhangchunyan@iscas.ac.cn>
References: <20240830011101.3189522-1-zhangchunyan@iscas.ac.cn>
 <20240830011101.3189522-2-zhangchunyan@iscas.ac.cn>
Message-ID: <bedac8d9-4ba4-427c-9323-edcdbd7876ee@ghiti.fr>

Hi Chunyan,

On 30/08/2024 03:10, Chunyan Zhang wrote:
> The PTE bit(9) on RISC-V is reserved for software, it is used by DEVMAP
> now which has to be disabled if we want to use bit(9) for other features,
> since there's no more free PTE bit on RISC-V now.
>
> So to make ARCH_HAS_PTE_DEVMAP selectable, this patch uses it as
> the build condition of devmap definitions.
>
> Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
> ---
>   arch/riscv/include/asm/pgtable-64.h   | 2 +-
>   arch/riscv/include/asm/pgtable-bits.h | 6 ++++++
>   2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
> index 0897dd99ab8d..babb8d2b0f0b 100644
> --- a/arch/riscv/include/asm/pgtable-64.h
> +++ b/arch/riscv/include/asm/pgtable-64.h
> @@ -398,7 +398,7 @@ static inline struct page *pgd_page(pgd_t pgd)
>   #define p4d_offset p4d_offset
>   p4d_t *p4d_offset(pgd_t *pgd, unsigned long address);
>   
> -#ifdef CONFIG_TRANSPARENT_HUGEPAGE
> +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && defined(CONFIG_ARCH_HAS_PTE_DEVMAP)
>   static inline int pte_devmap(pte_t pte);
>   static inline pte_t pmd_pte(pmd_t pmd);
>   
> diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
> index a8f5205cea54..5bcc73430829 100644
> --- a/arch/riscv/include/asm/pgtable-bits.h
> +++ b/arch/riscv/include/asm/pgtable-bits.h
> @@ -19,7 +19,13 @@
>   #define _PAGE_SOFT      (3 << 8)    /* Reserved for software */
>   
>   #define _PAGE_SPECIAL   (1 << 8)    /* RSW: 0x1 */
> +
> +#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
>   #define _PAGE_DEVMAP    (1 << 9)    /* RSW, devmap */
> +#else
> +#define _PAGE_DEVMAP	0
> +#endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
> +
>   #define _PAGE_TABLE     _PAGE_PRESENT
>   
>   /*


There is a small inconsistency in our code: pte_devmap() is protected by 
a #ifdef but pte_mkdevmap() is not, I guess that's why you had to define 
_PAGE_DEVMAP if !CONFIG_ARCH_HAS_PTE_DEVMAP.

I'd be in favor of removing the #ifdef around pte_devmap() too.

Thanks,

Alex



From cleger at rivosinc.com  Tue Nov  5 04:48:35 2024
From: cleger at rivosinc.com (=?UTF-8?B?Q2zDqW1lbnQgTMOpZ2Vy?=)
Date: Tue, 5 Nov 2024 13:48:35 +0100
Subject: [PATCH] riscv: cacheinfo: Use of_property_present() for
 non-boolean properties
In-Reply-To: <20241104190314.270095-1-robh@kernel.org>
References: <20241104190314.270095-1-robh@kernel.org>
Message-ID: <78cdcdc4-8087-449d-b771-e41e6295137f@rivosinc.com>



On 04/11/2024 20:03, Rob Herring (Arm) wrote:
> The use of of_property_read_bool() for non-boolean properties is
> deprecated in favor of of_property_present() when testing for property
> presence.
> 
> Signed-off-by: Rob Herring (Arm) <robh at kernel.org>
> ---
>  arch/riscv/kernel/cacheinfo.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
> index b320b1d9aa01..0115051fa1e1 100644
> --- a/arch/riscv/kernel/cacheinfo.c
> +++ b/arch/riscv/kernel/cacheinfo.c
> @@ -105,11 +105,11 @@ int populate_cache_leaves(unsigned int cpu)
>  		return 0;
>  	}
>  
> -	if (of_property_read_bool(np, "cache-size"))
> +	if (of_property_present(np, "cache-size"))
>  		ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
> -	if (of_property_read_bool(np, "i-cache-size"))
> +	if (of_property_present(np, "i-cache-size"))
>  		ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
> -	if (of_property_read_bool(np, "d-cache-size"))
> +	if (of_property_present(np, "d-cache-size"))
>  		ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
>  
>  	prev = np;
> @@ -122,11 +122,11 @@ int populate_cache_leaves(unsigned int cpu)
>  			break;
>  		if (level <= levels)
>  			break;
> -		if (of_property_read_bool(np, "cache-size"))
> +		if (of_property_present(np, "cache-size"))
>  			ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
> -		if (of_property_read_bool(np, "i-cache-size"))
> +		if (of_property_present(np, "i-cache-size"))
>  			ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
> -		if (of_property_read_bool(np, "d-cache-size"))
> +		if (of_property_present(np, "d-cache-size"))
>  			ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
>  		levels = level;
>  	}


Looks good to me,

Reviewed-by: Cl?ment L?ger <cleger at rivosinc.com>

Thanks,

Cl?ment


From alex at ghiti.fr  Tue Nov  5 05:13:17 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 14:13:17 +0100
Subject: [RESEND PATCH V4 2/3] riscv: mm: Add soft-dirty page tracking
 support
In-Reply-To: <20240830011101.3189522-3-zhangchunyan@iscas.ac.cn>
References: <20240830011101.3189522-1-zhangchunyan@iscas.ac.cn>
 <20240830011101.3189522-3-zhangchunyan@iscas.ac.cn>
Message-ID: <97898777-8129-4ce9-8ae4-9d4bbc2a5a26@ghiti.fr>

On 30/08/2024 03:11, Chunyan Zhang wrote:
> The PTE bit(9) is reserved for software, now used by DEVMAP,
> this patch reuse bit(9) for soft-dirty which is enabled only


s/reuse/reuses


> if !CONFIG_ARCH_HAS_PTE_DEVMAP, in other words, soft-dirty
> and devmap will be mutually exclusive on RISC-V.
>
> To add swap PTE soft-dirty tracking, we borrow bit (4) which is
> available for swap PTEs on RISC-V systems.
>
> Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
> ---
>   arch/riscv/Kconfig                    | 27 ++++++++++-
>   arch/riscv/include/asm/pgtable-bits.h | 12 +++++
>   arch/riscv/include/asm/pgtable.h      | 69 ++++++++++++++++++++++++++-
>   3 files changed, 106 insertions(+), 2 deletions(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 0f3cd7c3a436..f1460fc01cd4 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -39,7 +39,6 @@ config RISCV
>   	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
>   	select ARCH_HAS_PMEM_API
>   	select ARCH_HAS_PREPARE_SYNC_CORE_CMD
> -	select ARCH_HAS_PTE_DEVMAP if 64BIT && MMU
>   	select ARCH_HAS_PTE_SPECIAL
>   	select ARCH_HAS_SET_DIRECT_MAP if MMU
>   	select ARCH_HAS_SET_MEMORY if MMU
> @@ -948,6 +947,32 @@ config RANDOMIZE_BASE
>   
>             If unsure, say N.
>   
> +choice
> +	prompt "PET RSW Bit(9) used for"


I would say: "PTE RSW bit(9) usage"


> +	default RISCV_HAS_PTE_DEVMEP


s/DEVMEP/DEVMAP


> +	depends on MMU && 64BIT
> +	help
> +	  RISC-V PTE bit(9) is reserved for software, and used by more than
> +	  one kernel features which cannot be supported at the same time.


s/features/feature


> +	  So we have to select one for it.
> +
> +config RISCV_HAS_PTE_DEVMEP
> +	bool "DEVMAP mark"


I would say simply "devmap"


> +	select ARCH_HAS_PTE_DEVMAP
> +	help
> +	  The PTE bit(9) is used for DEVMAP mark. ZONE_DEVICE pages need DEVMAP


"is used for devmap...pages need devmap"


> +	  PTEs support to function.
> +
> +	  So if you want to use ZONE_DEVICE, select this.
> +
> +config RISCV_HAS_SOFT_DIRTY
> +	bool "soft dirty"


s/soft dirty/soft-dirty


> +	select HAVE_ARCH_SOFT_DIRTY
> +	help
> +	  The PTE bit(9) is used for soft-dirty tracking.
> +
> +endchoice
> +
>   endmenu # "Kernel features"
>   
>   menu "Boot options"
> diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
> index 5bcc73430829..c6d51fe9fc6f 100644
> --- a/arch/riscv/include/asm/pgtable-bits.h
> +++ b/arch/riscv/include/asm/pgtable-bits.h
> @@ -26,6 +26,18 @@
>   #define _PAGE_DEVMAP	0
>   #endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
>   
> +#ifdef CONFIG_MEM_SOFT_DIRTY


For consistency with CONFIG_ARCH_HAS_PTE_DEVMAP, I would use 
CONFIG_HAVE_ARCH_SOFT_DIRTY


> +#define _PAGE_SOFT_DIRTY	(1 << 9)    /* RSW: 0x2 for software dirty tracking */
> +/*
> + * BIT 4 is not involved into swap entry computation, so we
> + * can borrow it for swap page soft-dirty tracking.
> + */
> +#define _PAGE_SWP_SOFT_DIRTY	_PAGE_USER
> +#else
> +#define _PAGE_SOFT_DIRTY	0
> +#define _PAGE_SWP_SOFT_DIRTY	0
> +#endif /* CONFIG_MEM_SOFT_DIRTY */


Same here.


> +
>   #define _PAGE_TABLE     _PAGE_PRESENT
>   
>   /*
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index 089f3c9f56a3..d41507919ef2 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -428,7 +428,7 @@ static inline pte_t pte_mkwrite_novma(pte_t pte)
>   
>   static inline pte_t pte_mkdirty(pte_t pte)
>   {
> -	return __pte(pte_val(pte) | _PAGE_DIRTY);
> +	return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
>   }
>   
>   static inline pte_t pte_mkclean(pte_t pte)
> @@ -461,6 +461,38 @@ static inline pte_t pte_mkhuge(pte_t pte)
>   	return pte;
>   }
>   
> +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
> +static inline int pte_soft_dirty(pte_t pte)
> +{
> +	return pte_val(pte) & _PAGE_SOFT_DIRTY;
> +}
> +
> +static inline pte_t pte_mksoft_dirty(pte_t pte)
> +{
> +	return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY);
> +}
> +
> +static inline pte_t pte_clear_soft_dirty(pte_t pte)
> +{
> +	return __pte(pte_val(pte) & ~(_PAGE_SOFT_DIRTY));
> +}
> +
> +static inline int pte_swp_soft_dirty(pte_t pte)
> +{
> +	return pte_val(pte) & _PAGE_SWP_SOFT_DIRTY;
> +}
> +
> +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
> +{
> +	return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY);
> +}
> +
> +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
> +{
> +	return __pte(pte_val(pte) & ~(_PAGE_SWP_SOFT_DIRTY));
> +}
> +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
> +
>   #ifdef CONFIG_RISCV_ISA_SVNAPOT
>   #define pte_leaf_size(pte)	(pte_napot(pte) ?				\
>   					napot_cont_size(napot_cont_order(pte)) :\
> @@ -751,6 +783,40 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
>   	return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
>   }
>   
> +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
> +static inline int pmd_soft_dirty(pmd_t pmd)
> +{
> +	return pte_soft_dirty(pmd_pte(pmd));
> +}
> +
> +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
> +{
> +	return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
> +}
> +
> +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
> +{
> +	return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
> +}
> +
> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> +static inline int pmd_swp_soft_dirty(pmd_t pmd)
> +{
> +	return pte_swp_soft_dirty(pmd_pte(pmd));
> +}
> +
> +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
> +{
> +	return pte_pmd(pte_swp_mksoft_dirty(pmd_pte(pmd)));
> +}
> +
> +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
> +{
> +	return pte_pmd(pte_swp_clear_soft_dirty(pmd_pte(pmd)));
> +}
> +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
> +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
> +
>   static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
>   				pmd_t *pmdp, pmd_t pmd)
>   {
> @@ -841,6 +907,7 @@ extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
>    * Format of swap PTE:
>    *	bit            0:	_PAGE_PRESENT (zero)
>    *	bit       1 to 3:       _PAGE_LEAF (zero)
> + *	bit	       4:	_PAGE_SWP_SOFT_DIRTY
>    *	bit            5:	_PAGE_PROT_NONE (zero)
>    *	bit            6:	exclusive marker
>    *	bits      7 to 11:	swap type


Apart from the minor things above, the rest looks good so you can add:

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From alex at ghiti.fr  Tue Nov  5 05:14:52 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 14:14:52 +0100
Subject: [RESEND PATCH V4 2/3] riscv: mm: Add soft-dirty page tracking
 support
In-Reply-To: <CAAfSe-vDtJKeSeUgpeJM0ZQe4XKdKz_Rgz2TQkPb4giPBLsOdw@mail.gmail.com>
References: <20240830011101.3189522-1-zhangchunyan@iscas.ac.cn>
 <20240830011101.3189522-3-zhangchunyan@iscas.ac.cn>
 <c4fbc62f-e398-1229-c1b1-7bab30e4460e@huawei.com>
 <CAAfSe-vDtJKeSeUgpeJM0ZQe4XKdKz_Rgz2TQkPb4giPBLsOdw@mail.gmail.com>
Message-ID: <d1a84096-9722-47f1-ad8e-671144a3d109@ghiti.fr>

On 30/08/2024 04:31, Chunyan Zhang wrote:
> Hi Jinjie,
>
> On Fri, 30 Aug 2024 at 09:31, Jinjie Ruan <ruanjinjie at huawei.com> wrote:
>>
>>
>> On 2024/8/30 9:11, Chunyan Zhang wrote:
>>> The PTE bit(9) is reserved for software, now used by DEVMAP,
>>> this patch reuse bit(9) for soft-dirty which is enabled only
>>> if !CONFIG_ARCH_HAS_PTE_DEVMAP, in other words, soft-dirty
>>> and devmap will be mutually exclusive on RISC-V.
>>>
>>> To add swap PTE soft-dirty tracking, we borrow bit (4) which is
>>> available for swap PTEs on RISC-V systems.
>>>
>>> Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
>>> ---
>>>   arch/riscv/Kconfig                    | 27 ++++++++++-
>>>   arch/riscv/include/asm/pgtable-bits.h | 12 +++++
>>>   arch/riscv/include/asm/pgtable.h      | 69 ++++++++++++++++++++++++++-
>>>   3 files changed, 106 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
>>> index 0f3cd7c3a436..f1460fc01cd4 100644
>>> --- a/arch/riscv/Kconfig
>>> +++ b/arch/riscv/Kconfig
>>> @@ -39,7 +39,6 @@ config RISCV
>>>        select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
>>>        select ARCH_HAS_PMEM_API
>>>        select ARCH_HAS_PREPARE_SYNC_CORE_CMD
>>> -     select ARCH_HAS_PTE_DEVMAP if 64BIT && MMU
>>>        select ARCH_HAS_PTE_SPECIAL
>>>        select ARCH_HAS_SET_DIRECT_MAP if MMU
>>>        select ARCH_HAS_SET_MEMORY if MMU
>>> @@ -948,6 +947,32 @@ config RANDOMIZE_BASE
>>>
>>>             If unsure, say N.
>>>
>>> +choice
>>> +     prompt "PET RSW Bit(9) used for"
>>> +     default RISCV_HAS_PTE_DEVMEP
>>> +     depends on MMU && 64BIT
>>> +     help
>>> +       RISC-V PTE bit(9) is reserved for software, and used by more than
>>> +       one kernel features which cannot be supported at the same time.
>>> +       So we have to select one for it.
>>> +
>>> +config RISCV_HAS_PTE_DEVMEP
>>> +     bool "DEVMAP mark"
>>> +     select ARCH_HAS_PTE_DEVMAP
>>> +     help
>>> +       The PTE bit(9) is used for DEVMAP mark. ZONE_DEVICE pages need DEVMAP
>>> +       PTEs support to function.
>>> +
>>> +       So if you want to use ZONE_DEVICE, select this.
>>> +
>>> +config RISCV_HAS_SOFT_DIRTY
>>> +     bool "soft dirty"
>>> +     select HAVE_ARCH_SOFT_DIRTY
>>> +     help
>>> +       The PTE bit(9) is used for soft-dirty tracking.
>>> +
>>> +endchoice
>>> +
>> Hi, ARCH_HAS_PTE_DEVMAP will be removed in following patch, I guess
>> riscv will too:
>>
>> https://lore.kernel.org/all/47c26640cd85f3db2e0a2796047199bb984d1b3f.1719386613.git-series.apopple at nvidia.com/
> Thanks for sharing, I didn't notice this.
> It looks like we should remove PTE_DEVMAP first and then add soft
> dirty and uffd_wp.


I have not seen any progress in the removal of PTE_DEVMAP so I'd say we 
should keep going with your patchset and we can still remove devmap later.

Thanks,

Alex


>
> Thanks,
> Chunyan
>
>>>   endmenu # "Kernel features"
>>>
>>>   menu "Boot options"
>>> diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
>>> index 5bcc73430829..c6d51fe9fc6f 100644
>>> --- a/arch/riscv/include/asm/pgtable-bits.h
>>> +++ b/arch/riscv/include/asm/pgtable-bits.h
>>> @@ -26,6 +26,18 @@
>>>   #define _PAGE_DEVMAP 0
>>>   #endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
>>>
>>> +#ifdef CONFIG_MEM_SOFT_DIRTY
>>> +#define _PAGE_SOFT_DIRTY     (1 << 9)    /* RSW: 0x2 for software dirty tracking */
>>> +/*
>>> + * BIT 4 is not involved into swap entry computation, so we
>>> + * can borrow it for swap page soft-dirty tracking.
>>> + */
>>> +#define _PAGE_SWP_SOFT_DIRTY _PAGE_USER
>>> +#else
>>> +#define _PAGE_SOFT_DIRTY     0
>>> +#define _PAGE_SWP_SOFT_DIRTY 0
>>> +#endif /* CONFIG_MEM_SOFT_DIRTY */
>>> +
>>>   #define _PAGE_TABLE     _PAGE_PRESENT
>>>
>>>   /*
>>> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
>>> index 089f3c9f56a3..d41507919ef2 100644
>>> --- a/arch/riscv/include/asm/pgtable.h
>>> +++ b/arch/riscv/include/asm/pgtable.h
>>> @@ -428,7 +428,7 @@ static inline pte_t pte_mkwrite_novma(pte_t pte)
>>>
>>>   static inline pte_t pte_mkdirty(pte_t pte)
>>>   {
>>> -     return __pte(pte_val(pte) | _PAGE_DIRTY);
>>> +     return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
>>>   }
>>>
>>>   static inline pte_t pte_mkclean(pte_t pte)
>>> @@ -461,6 +461,38 @@ static inline pte_t pte_mkhuge(pte_t pte)
>>>        return pte;
>>>   }
>>>
>>> +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
>>> +static inline int pte_soft_dirty(pte_t pte)
>>> +{
>>> +     return pte_val(pte) & _PAGE_SOFT_DIRTY;
>>> +}
>>> +
>>> +static inline pte_t pte_mksoft_dirty(pte_t pte)
>>> +{
>>> +     return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY);
>>> +}
>>> +
>>> +static inline pte_t pte_clear_soft_dirty(pte_t pte)
>>> +{
>>> +     return __pte(pte_val(pte) & ~(_PAGE_SOFT_DIRTY));
>>> +}
>>> +
>>> +static inline int pte_swp_soft_dirty(pte_t pte)
>>> +{
>>> +     return pte_val(pte) & _PAGE_SWP_SOFT_DIRTY;
>>> +}
>>> +
>>> +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
>>> +{
>>> +     return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY);
>>> +}
>>> +
>>> +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
>>> +{
>>> +     return __pte(pte_val(pte) & ~(_PAGE_SWP_SOFT_DIRTY));
>>> +}
>>> +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
>>> +
>>>   #ifdef CONFIG_RISCV_ISA_SVNAPOT
>>>   #define pte_leaf_size(pte)   (pte_napot(pte) ?                               \
>>>                                        napot_cont_size(napot_cont_order(pte)) :\
>>> @@ -751,6 +783,40 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
>>>        return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
>>>   }
>>>
>>> +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
>>> +static inline int pmd_soft_dirty(pmd_t pmd)
>>> +{
>>> +     return pte_soft_dirty(pmd_pte(pmd));
>>> +}
>>> +
>>> +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
>>> +{
>>> +     return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
>>> +}
>>> +
>>> +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
>>> +{
>>> +     return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
>>> +}
>>> +
>>> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
>>> +static inline int pmd_swp_soft_dirty(pmd_t pmd)
>>> +{
>>> +     return pte_swp_soft_dirty(pmd_pte(pmd));
>>> +}
>>> +
>>> +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
>>> +{
>>> +     return pte_pmd(pte_swp_mksoft_dirty(pmd_pte(pmd)));
>>> +}
>>> +
>>> +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
>>> +{
>>> +     return pte_pmd(pte_swp_clear_soft_dirty(pmd_pte(pmd)));
>>> +}
>>> +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
>>> +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
>>> +
>>>   static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
>>>                                pmd_t *pmdp, pmd_t pmd)
>>>   {
>>> @@ -841,6 +907,7 @@ extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
>>>    * Format of swap PTE:
>>>    *   bit            0:       _PAGE_PRESENT (zero)
>>>    *   bit       1 to 3:       _PAGE_LEAF (zero)
>>> + *   bit            4:       _PAGE_SWP_SOFT_DIRTY
>>>    *   bit            5:       _PAGE_PROT_NONE (zero)
>>>    *   bit            6:       exclusive marker
>>>    *   bits      7 to 11:      swap type
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From emil.renner.berthing at canonical.com  Tue Nov  5 05:21:07 2024
From: emil.renner.berthing at canonical.com (Emil Renner Berthing)
Date: Tue, 5 Nov 2024 08:21:07 -0500
Subject: [PATCH 10/11] riscv: mm: Use physical memory aliases to apply PMAs
In-Reply-To: <20241102000843.1301099-11-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com> <20241102000843.1301099-11-samuel.holland@sifive.com>
Message-ID: <CAJM55Z-aVZfKf+HeoHU8DbVJVAgm=8sbW7SvLsi+yQcfzkz1NA@mail.gmail.com>

Samuel Holland wrote:
> On some RISC-V platforms, RAM is mapped to multiple physical address
> ranges, with each alias having a different set of statically-determined
> Physical Memory Attributes (PMAs). Software selects the PMAs for a page
> by choosing a PFN from the corresponding physical address range.
>
> Implement this by transforming the PFN when writing page tables.  If the
> memory type field is nonzero, replace the PFN with the corresponding PFN
> from the noncached alias. Similarly, when reading from the page tables,
> if the PFN is found in a noncached alias, replace it with the
> corresponding PFN from the cached alias, and insert _PAGE_NOCACHE.
>
> The rest of the kernel sees only the cached PFNs and _PAGE_MTMASK values
> as if Svpbmt was implemented.
>
> Memory alias pairs are determined from the devicetree. A new cpufeature
> bit is required because that is the only way to trigger alternative
> patching.
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
>  arch/riscv/Kconfig                  |   3 +
>  arch/riscv/include/asm/hwcap.h      |   1 +
>  arch/riscv/include/asm/pgtable-64.h |  27 ++++++--
>  arch/riscv/include/asm/pgtable.h    |   8 +++
>  arch/riscv/kernel/cpufeature.c      |   6 ++
>  arch/riscv/kernel/setup.c           |   1 +
>  arch/riscv/mm/Makefile              |   1 +
>  arch/riscv/mm/memory-alias.S        | 101 ++++++++++++++++++++++++++++
>  arch/riscv/mm/pgtable.c             |  91 +++++++++++++++++++++++++
>  9 files changed, 235 insertions(+), 4 deletions(-)
>  create mode 100644 arch/riscv/mm/memory-alias.S
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 62545946ecf4..d28d1dab5f26 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -566,6 +566,9 @@ config RISCV_ISA_SVPBMT
>
>  	   The Svpbmt extension is only available on 64-bit cpus.
>
> +	   This option also controls selection of memory type based on
> +	   physical memory aliases.
> +

I wonder how much work it would be to make this its own Kconfig option only
enabled by JH7100 and EIC7700 support. Hopefully future chips will just
implement the standard Svpmt and this code will be unneded overhead.

/Emil

>  	   If you don't know what to do here, say Y.
>
>  config TOOLCHAIN_HAS_V
> diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
> index 46d9de54179e..8a37e22f4223 100644
> --- a/arch/riscv/include/asm/hwcap.h
> +++ b/arch/riscv/include/asm/hwcap.h
> @@ -94,6 +94,7 @@
>  #define RISCV_ISA_EXT_ZAWRS		85
>  #define RISCV_ISA_EXT_SVVPTC		86
>
> +#define RISCV_ISA_EXT_XLINUXMEMALIAS	126
>  #define RISCV_ISA_EXT_XLINUXENVCFG	127
>
>  #define RISCV_ISA_EXT_MAX		128
> diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
> index 174b6a5837c2..6b4af408a37a 100644
> --- a/arch/riscv/include/asm/pgtable-64.h
> +++ b/arch/riscv/include/asm/pgtable-64.h
> @@ -124,27 +124,46 @@ enum napot_cont_order {
>   */
>
>  #define ALT_FIXUP_MT(_val)								\
> -	asm(ALTERNATIVE_2("addi	t0, zero, 0x3\n\t"					\
> +	asm(ALTERNATIVE_3("addi	t0, zero, 0x3\n\t"					\
>  			  "slli	t0, t0, 61\n\t"						\
>  			  "not	t0, t0\n\t"						\
>  			  "and	%0, %0, t0\n\t"						\
>  			  "nop\n\t"							\
>  			  "nop\n\t"							\
> +			  "nop\n\t"							\
>  			  "nop",							\
> -			  __nops(7),							\
> +			  __nops(8),							\
>  			  0, RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,		\
> +			  "addi t0, zero, 0x3\n\t"					\
> +			  "slli	t0, t0, 61\n\t"						\
> +			  "and	t0, %0, t0\n\t"						\
> +			  "beqz t0, 2f\n\t"						\
> +			  "xor	t1, %0, t0\n\t"						\
> +			  "1: auipc t0, %%pcrel_hi(riscv_fixup_memory_alias)\n\t"	\
> +			  "jalr	t0, t0, %%pcrel_lo(1b)\n\t"				\
> +			  "mv	%0, t1\n"						\
> +			  "2:",								\
> +			  0, RISCV_ISA_EXT_XLINUXMEMALIAS, CONFIG_RISCV_ISA_SVPBMT,	\
>  			  "srli	t0, %0, 59\n\t"						\
>  			  "seqz t1, t0\n\t"						\
>  			  "slli	t1, t1, 1\n\t"						\
>  			  "or	t0, t0, t1\n\t"						\
>  			  "xori	t0, t0, 0x5\n\t"					\
>  			  "slli	t0, t0, 60\n\t"						\
> -			  "xor	%0, %0, t0",						\
> +			  "xor	%0, %0, t0\n\t"						\
> +			  "nop",							\
>  			  THEAD_VENDOR_ID, ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)	\
>  			  : "+r" (_val) :: "t0", "t1")
>
>  #define ALT_UNFIX_MT(_val)								\
> -	asm(ALTERNATIVE(__nops(6),							\
> +	asm(ALTERNATIVE_2(__nops(6),							\
> +			  "mv	t1, %0\n\t"						\
> +			  "1: auipc t0, %%pcrel_hi(riscv_unfix_memory_alias)\n\t"	\
> +			  "jalr	t0, t0, %%pcrel_lo(1b)\n\t"				\
> +			  "mv	%0, t1\n\t"						\
> +			  "nop\n\t"							\
> +			  "nop",							\
> +			  0, RISCV_ISA_EXT_XLINUXMEMALIAS, CONFIG_RISCV_ISA_SVPBMT,	\
>  			  "srli	t0, %0, 60\n\t"						\
>  			  "andi	t0, t0, 0xd\n\t"					\
>  			  "srli	t1, t0, 1\n\t"						\
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index 3ffcff76ac0d..0e52dfaaff63 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -949,6 +949,14 @@ extern u64 satp_mode;
>  void paging_init(void);
>  void misc_mem_init(void);
>
> +#ifdef CONFIG_RISCV_ISA_SVPBMT
> +bool __init riscv_have_memory_alias(void);
> +void __init riscv_init_memory_alias(void);
> +#else
> +static inline bool riscv_have_memory_alias(void) { return false; }
> +static inline void riscv_init_memory_alias(void) {}
> +#endif /* CONFIG_RISCV_ISA_SVPBMT */
> +
>  /*
>   * ZERO_PAGE is a global shared page that is always zero,
>   * used for zero-mapped memory areas, etc.
> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 3a8eeaa9310c..ca36f8240a86 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -892,6 +892,12 @@ void __init riscv_fill_hwcap(void)
>  			elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
>  	}
>
> +	/* Vendor-independent alternatives require a bit in the ISA bitmap. */
> +	if (riscv_have_memory_alias()) {
> +		set_bit(RISCV_ISA_EXT_XLINUXMEMALIAS, riscv_isa);
> +		pr_info("Using physical memory alias for noncached mappings\n");
> +	}
> +
>  	memset(print_str, 0, sizeof(print_str));
>  	for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)
>  		if (riscv_isa[0] & BIT_MASK(i))
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index a2cde65b69e9..ab718fc4538f 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -287,6 +287,7 @@ void __init setup_arch(char **cmdline_p)
>  	}
>
>  	riscv_init_cbo_blocksizes();
> +	riscv_init_memory_alias();
>  	riscv_fill_hwcap();
>  	init_rt_signal_env();
>  	apply_boot_alternatives();
> diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
> index cbe4d775ef56..50d843b298cd 100644
> --- a/arch/riscv/mm/Makefile
> +++ b/arch/riscv/mm/Makefile
> @@ -33,3 +33,4 @@ endif
>  obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
>  obj-$(CONFIG_RISCV_DMA_NONCOHERENT) += dma-noncoherent.o
>  obj-$(CONFIG_RISCV_NONSTANDARD_CACHE_OPS) += cache-ops.o
> +obj-$(CONFIG_RISCV_ISA_SVPBMT) += memory-alias.o
> diff --git a/arch/riscv/mm/memory-alias.S b/arch/riscv/mm/memory-alias.S
> new file mode 100644
> index 000000000000..df2e8cc3f69c
> --- /dev/null
> +++ b/arch/riscv/mm/memory-alias.S
> @@ -0,0 +1,101 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2024 SiFive
> + */
> +
> +#include <linux/bits.h>
> +#include <linux/linkage.h>
> +#include <asm/asm.h>
> +#include <asm/pgtable.h>
> +
> +#define CACHED_BASE_OFFSET	(0 * RISCV_SZPTR)
> +#define NONCACHED_BASE_OFFSET	(1 * RISCV_SZPTR)
> +#define SIZE_OFFSET		(2 * RISCV_SZPTR)
> +
> +#define SIZEOF_PAIR		(4 * RISCV_SZPTR)
> +
> +SYM_CODE_START(riscv_fixup_memory_alias)
> +	addi	sp, sp, -4 * SZREG
> +	REG_S	t2, (0 * SZREG)(sp)
> +	REG_S	t3, (1 * SZREG)(sp)
> +	REG_S	t4, (2 * SZREG)(sp)
> +#ifdef CONFIG_RISCV_ISA_SVNAPOT
> +	REG_S	t5, (3 * SZREG)(sp)
> +
> +	/* Save and mask off _PAGE_NAPOT if present. */
> +	li	t5, _PAGE_NAPOT
> +	and	t5, t1, t5
> +	xor	t1, t1, t5
> +#endif
> +
> +	lla	t2, memory_alias_pairs
> +.Lfixup_loop:
> +	REG_L	t3, SIZE_OFFSET(t2)
> +	beqz	t3, .Lfixup_end
> +	REG_L	t4, CACHED_BASE_OFFSET(t2)
> +	sub	t4, t1, t4
> +	bltu	t4, t3, .Lfixup_found
> +	addi	t2, t2, SIZEOF_PAIR
> +	j	.Lfixup_loop
> +
> +.Lfixup_found:
> +	REG_L	t3, NONCACHED_BASE_OFFSET(t2)
> +	add	t1, t3, t4
> +
> +.Lfixup_end:
> +#ifdef CONFIG_RISCV_ISA_SVNAPOT
> +	xor	t1, t1, t5
> +
> +	REG_L	t5, (3 * SZREG)(sp)
> +#endif
> +	REG_L	t4, (2 * SZREG)(sp)
> +	REG_L	t3, (1 * SZREG)(sp)
> +	REG_L	t2, (0 * SZREG)(sp)
> +	addi	sp, sp, 4 * SZREG
> +	jr	t0
> +SYM_CODE_END(riscv_fixup_memory_alias)
> +
> +SYM_CODE_START(riscv_unfix_memory_alias)
> +	addi	sp, sp, -4 * SZREG
> +	REG_S	t2, (0 * SZREG)(sp)
> +	REG_S	t3, (1 * SZREG)(sp)
> +	REG_S	t4, (2 * SZREG)(sp)
> +#ifdef CONFIG_RISCV_ISA_SVNAPOT
> +	REG_S	t5, (3 * SZREG)(sp)
> +
> +	/* Save and mask off _PAGE_NAPOT if present. */
> +	li	t5, _PAGE_NAPOT
> +	and	t5, t1, t5
> +	xor	t1, t1, t5
> +#endif
> +
> +	lla	t2, memory_alias_pairs
> +.Lunfix_loop:
> +	REG_L	t3, SIZE_OFFSET(t2)
> +	beqz	t3, .Lunfix_end
> +	REG_L	t4, NONCACHED_BASE_OFFSET(t2)
> +	sub	t4, t1, t4
> +	bltu	t4, t3, .Lunfix_found
> +	addi	t2, t2, SIZEOF_PAIR
> +	j	.Lunfix_loop
> +
> +.Lunfix_found:
> +	REG_L	t3, CACHED_BASE_OFFSET(t2)
> +	add	t1, t3, t4
> +
> +	/* PFN was in the noncached alias, so mark it as such. */
> +	li	t2, _PAGE_NOCACHE
> +	or	t1, t1, t2
> +
> +.Lunfix_end:
> +#ifdef CONFIG_RISCV_ISA_SVNAPOT
> +	xor	t1, t1, t5
> +
> +	REG_L	t5, (3 * SZREG)(sp)
> +#endif
> +	REG_L	t4, (2 * SZREG)(sp)
> +	REG_L	t3, (1 * SZREG)(sp)
> +	REG_L	t2, (0 * SZREG)(sp)
> +	addi	sp, sp, 4 * SZREG
> +	jr	t0
> +SYM_CODE_END(riscv_unfix_memory_alias)
> diff --git a/arch/riscv/mm/pgtable.c b/arch/riscv/mm/pgtable.c
> index 4ae67324f992..8dd43001cd10 100644
> --- a/arch/riscv/mm/pgtable.c
> +++ b/arch/riscv/mm/pgtable.c
> @@ -1,8 +1,12 @@
>  // SPDX-License-Identifier: GPL-2.0
>
>  #include <asm/pgalloc.h>
> +#include <dt-bindings/riscv/physical-memory.h>
> +#include <linux/bitfield.h>
>  #include <linux/gfp.h>
>  #include <linux/kernel.h>
> +#include <linux/memblock.h>
> +#include <linux/of.h>
>  #include <linux/pgtable.h>
>
>  int ptep_set_access_flags(struct vm_area_struct *vma,
> @@ -155,3 +159,90 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
>  	return pmd;
>  }
>  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
> +
> +#ifdef CONFIG_RISCV_ISA_SVPBMT
> +struct memory_alias_pair {
> +	unsigned long cached_base;
> +	unsigned long noncached_base;
> +	unsigned long size;
> +	int index;
> +} memory_alias_pairs[5];
> +
> +bool __init riscv_have_memory_alias(void)
> +{
> +	return memory_alias_pairs[0].size;
> +}
> +
> +void __init riscv_init_memory_alias(void)
> +{
> +	int na = of_n_addr_cells(of_root);
> +	int ns = of_n_size_cells(of_root);
> +	int nc = na + ns + 2;
> +	const __be32 *prop;
> +	int pairs = 0;
> +	int len;
> +
> +	prop = of_get_property(of_root, "riscv,physical-memory-regions", &len);
> +	if (!prop)
> +		return;
> +
> +	len /= sizeof(__be32);
> +	for (int i = 0; len >= nc; i++, prop += nc, len -= nc) {
> +		unsigned long base = of_read_ulong(prop, na);
> +		unsigned long size = of_read_ulong(prop + na, ns);
> +		unsigned long flags = be32_to_cpup(prop + na + ns);
> +		struct memory_alias_pair *pair;
> +		int alias;
> +
> +		/* We only care about non-coherent memory. */
> +		if ((flags & PMA_ORDER_MASK) != PMA_ORDER_MEMORY || (flags & PMA_COHERENT))
> +			continue;
> +
> +		/* The cacheable alias must be usable memory. */
> +		if ((flags & PMA_CACHEABLE) &&
> +		    !memblock_overlaps_region(&memblock.memory, base, size))
> +			continue;
> +
> +		alias = FIELD_GET(PMR_ALIAS_MASK, flags);
> +		if (alias) {
> +			pair = NULL;
> +			for (int j = 0; j < pairs; j++) {
> +				if (alias == memory_alias_pairs[j].index) {
> +					pair = &memory_alias_pairs[j];
> +					break;
> +				}
> +			}
> +			if (!pair)
> +				continue;
> +		} else {
> +			/* Leave room for the null sentinel. */
> +			if (pairs == ARRAY_SIZE(memory_alias_pairs) - 1)
> +				continue;
> +			pair = &memory_alias_pairs[pairs++];
> +			pair->index = i;
> +		}
> +
> +		/* Align the address and size with the page table PFN field. */
> +		base >>= PAGE_SHIFT - _PAGE_PFN_SHIFT;
> +		size >>= PAGE_SHIFT - _PAGE_PFN_SHIFT;
> +
> +		if (flags & PMA_CACHEABLE)
> +			pair->cached_base = base;
> +		else
> +			pair->noncached_base = base;
> +		pair->size = min_not_zero(pair->size, size);
> +	}
> +
> +	/* Remove any unmatched pairs. */
> +	for (int i = 0; i < pairs; i++) {
> +		struct memory_alias_pair *pair = &memory_alias_pairs[i];
> +
> +		if (pair->cached_base && pair->noncached_base && pair->size)
> +			continue;
> +
> +		for (int j = i + 1; j < pairs; j++)
> +			memory_alias_pairs[j - 1] = memory_alias_pairs[j];
> +		memory_alias_pairs[--pairs].size = 0;
> +	}
> +}
> +#endif /* CONFIG_RISCV_ISA_SVPBMT */
> --
> 2.45.1


From alex at ghiti.fr  Tue Nov  5 05:24:47 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 14:24:47 +0100
Subject: [RESEND PATCH V4 3/3] riscv: mm: Add uffd write-protect support
In-Reply-To: <20240830011101.3189522-4-zhangchunyan@iscas.ac.cn>
References: <20240830011101.3189522-1-zhangchunyan@iscas.ac.cn>
 <20240830011101.3189522-4-zhangchunyan@iscas.ac.cn>
Message-ID: <4aceb7ac-08fa-486f-a4cc-0bca16968deb@ghiti.fr>

On 30/08/2024 03:11, Chunyan Zhang wrote:
> Reuse PTE bit(9) to do uffd-wp tracking and make it mutually exclusive
> with soft-dirty and DEVMAP which all use this PTE bit.
>
> Additionally for tracking the uffd-wp state as a PTE swap bit,
> we use swap entry pte bit(4) which is also used by swap
> soft-dirty tracking.
>
> Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
> ---
>   arch/riscv/Kconfig                    |  7 +++
>   arch/riscv/include/asm/pgtable-bits.h | 13 ++++++
>   arch/riscv/include/asm/pgtable.h      | 66 ++++++++++++++++++++++++++-
>   3 files changed, 85 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index f1460fc01cd4..aa595a5ed4b8 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -971,6 +971,13 @@ config RISCV_HAS_SOFT_DIRTY
>   	help
>   	  The PTE bit(9) is used for soft-dirty tracking.
>   
> +config RISCV_HAS_USERFAULTFD_WP
> +	bool "userfaultfd write protection"
> +	select HAVE_ARCH_USERFAULTFD_WP
> +	depends on USERFAULTFD
> +	help
> +	  The PTE bit(9) is used for userfaultfd write-protected
> +	  tracking.
>   endchoice
>   
>   endmenu # "Kernel features"
> diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
> index c6d51fe9fc6f..7de16141c049 100644
> --- a/arch/riscv/include/asm/pgtable-bits.h
> +++ b/arch/riscv/include/asm/pgtable-bits.h
> @@ -38,6 +38,19 @@
>   #define _PAGE_SWP_SOFT_DIRTY	0
>   #endif /* CONFIG_MEM_SOFT_DIRTY */
>   
> +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
> +/*
> + * CONFIG_HAVE_ARCH_USERFAULTFD_WP is mutually exclusive with
> + * HAVE_ARCH_SOFT_DIRTY so we can use the same bit for uffd-wp
> + * and soft-dirty tracking.
> + */
> +#define _PAGE_UFFD_WP		(1 << 9) /* RSW: 0x2 for uffd-wp tracking */
> +#define _PAGE_SWP_UFFD_WP	_PAGE_USER
> +#else
> +#define _PAGE_UFFD_WP		0
> +#define _PAGE_SWP_UFFD_WP	0
> +#endif
> +
>   #define _PAGE_TABLE     _PAGE_PRESENT
>   
>   /*
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index d41507919ef2..6ce4c9ba862a 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -417,6 +417,38 @@ static inline pte_t pte_wrprotect(pte_t pte)
>   	return __pte(pte_val(pte) & ~(_PAGE_WRITE));
>   }
>   
> +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
> +static inline int pte_uffd_wp(pte_t pte)
> +{
> +	return pte_val(pte) & _PAGE_UFFD_WP;
> +}
> +
> +static inline pte_t pte_mkuffd_wp(pte_t pte)
> +{
> +	return pte_wrprotect(__pte(pte_val(pte) | _PAGE_UFFD_WP));
> +}
> +
> +static inline pte_t pte_clear_uffd_wp(pte_t pte)
> +{
> +	return __pte(pte_val(pte) & ~(_PAGE_UFFD_WP));
> +}
> +
> +static inline int pte_swp_uffd_wp(pte_t pte)
> +{
> +	return pte_val(pte) & _PAGE_SWP_UFFD_WP;
> +}
> +
> +static inline pte_t pte_swp_mkuffd_wp(pte_t pte)
> +{
> +	return pte_wrprotect(__pte(pte_val(pte) | _PAGE_SWP_UFFD_WP));
> +}


Weird to wrprotect a swap entry here, given x86/arm64 don't do that, you 
should remove it.


> +
> +static inline pte_t pte_swp_clear_uffd_wp(pte_t pte)
> +{
> +	return __pte(pte_val(pte) & ~(_PAGE_SWP_UFFD_WP));
> +}
> +#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
> +
>   /* static inline pte_t pte_mkread(pte_t pte) */
>   
>   static inline pte_t pte_mkwrite_novma(pte_t pte)
> @@ -783,6 +815,38 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
>   	return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
>   }
>   
> +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
> +static inline int pmd_uffd_wp(pmd_t pmd)
> +{
> +	return pte_uffd_wp(pmd_pte(pmd));
> +}
> +
> +static inline pmd_t pmd_mkuffd_wp(pmd_t pmd)
> +{
> +	return pte_pmd(pte_mkuffd_wp(pmd_pte(pmd)));
> +}
> +
> +static inline pmd_t pmd_clear_uffd_wp(pmd_t pmd)
> +{
> +	return pte_pmd(pte_clear_uffd_wp(pmd_pte(pmd)));
> +}
> +
> +static inline int pmd_swp_uffd_wp(pmd_t pmd)
> +{
> +	return pte_swp_uffd_wp(pmd_pte(pmd));
> +}
> +
> +static inline pmd_t pmd_swp_mkuffd_wp(pmd_t pmd)
> +{
> +	return pte_pmd(pte_swp_mkuffd_wp(pmd_pte(pmd)));
> +}
> +
> +static inline pmd_t pmd_swp_clear_uffd_wp(pmd_t pmd)
> +{
> +	return pte_pmd(pte_swp_clear_uffd_wp(pmd_pte(pmd)));
> +}
> +#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
> +
>   #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
>   static inline int pmd_soft_dirty(pmd_t pmd)
>   {
> @@ -907,7 +971,7 @@ extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
>    * Format of swap PTE:
>    *	bit            0:	_PAGE_PRESENT (zero)
>    *	bit       1 to 3:       _PAGE_LEAF (zero)
> - *	bit	       4:	_PAGE_SWP_SOFT_DIRTY
> + *	bit	       4:	_PAGE_SWP_SOFT_DIRTY or _PAGE_SWP_UFFD_WP
>    *	bit            5:	_PAGE_PROT_NONE (zero)
>    *	bit            6:	exclusive marker
>    *	bits      7 to 11:	swap type


From tytso at mit.edu  Sat Nov  2 15:26:35 2024
From: tytso at mit.edu (Theodore Ts'o)
Date: Sat, 2 Nov 2024 15:26:35 -0700
Subject: [PATCH v2 15/18] ext4: switch to using the crc32c library
In-Reply-To: <20241025191454.72616-16-ebiggers@kernel.org>
References: <20241025191454.72616-1-ebiggers@kernel.org>
 <20241025191454.72616-16-ebiggers@kernel.org>
Message-ID: <20241102222635.GB455688@mit.edu>

On Fri, Oct 25, 2024 at 12:14:51PM -0700, Eric Biggers wrote:
> From: Eric Biggers <ebiggers at google.com>
> 
> Now that the crc32c() library function directly takes advantage of
> architecture-specific optimizations, it is unnecessary to go through the
> crypto API.  Just use crc32c().  This is much simpler, and it improves
> performance due to eliminating the crypto API overhead.
> 
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Eric Biggers <ebiggers at google.com>

Acked-by: Theodore Ts'o <tytso at mit.edu>


From alex at ghiti.fr  Tue Nov  5 05:44:25 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 14:44:25 +0100
Subject: [PATCH v2 5/9] riscv: mm: Log potential KASAN shadow alias
In-Reply-To: <20241022015913.3524425-6-samuel.holland@sifive.com>
References: <20241022015913.3524425-1-samuel.holland@sifive.com>
 <20241022015913.3524425-6-samuel.holland@sifive.com>
Message-ID: <5dba5a49-91e5-4988-9018-63b146b5e26c@ghiti.fr>

Hi Samuel,

On 22/10/2024 03:57, Samuel Holland wrote:
> When KASAN is enabled, shadow memory is allocated and mapped for all
> legitimate kernel addresses, but not for the entire address space. As a
> result, the kernel can fault when accessing a shadow address computed
> from a bogus pointer. This can be confusing, because the shadow address
> computed for (e.g.) NULL looks nothing like a NULL pointer. To assist
> debugging, if the faulting address might be the result of a KASAN shadow
> memory address computation, report the range of original memory
> addresses that would map to the faulting address.
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
> Changes in v2:
>   - New patch for v2
>
>   arch/riscv/mm/fault.c | 3 +++
>   1 file changed, 3 insertions(+)
>
> diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
> index a9f2b4af8f3f..dae1131221b7 100644
> --- a/arch/riscv/mm/fault.c
> +++ b/arch/riscv/mm/fault.c
> @@ -8,6 +8,7 @@
>   
>   
>   #include <linux/mm.h>
> +#include <linux/kasan.h>
>   #include <linux/kernel.h>
>   #include <linux/interrupt.h>
>   #include <linux/perf_event.h>
> @@ -30,6 +31,8 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
>   	pr_alert("Unable to handle kernel %s at virtual address " REG_FMT "\n", msg,
>   		addr);
>   
> +	kasan_non_canonical_hook(addr);
> +
>   	bust_spinlocks(0);
>   	die(regs, "Oops");
>   	make_task_dead(SIGKILL);


That's nice, I used to do that by hand :)

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From alex at ghiti.fr  Tue Nov  5 05:47:50 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 14:47:50 +0100
Subject: [PATCH v2 6/9] riscv: Do not rely on KASAN to define the memory
 layout
In-Reply-To: <20241022015913.3524425-7-samuel.holland@sifive.com>
References: <20241022015913.3524425-1-samuel.holland@sifive.com>
 <20241022015913.3524425-7-samuel.holland@sifive.com>
Message-ID: <717b3757-4f6f-49f3-9da1-82faaff57485@ghiti.fr>

On 22/10/2024 03:57, Samuel Holland wrote:
> Commit 66673099f734 ("riscv: mm: Pre-allocate vmemmap/direct map/kasan
> PGD entries") used the start of the KASAN shadow memory region to
> represent the end of the linear map, since the two memory regions were
> immediately adjacent. This is no longer the case for Sv39; commit
> 5c8405d763dc ("riscv: Extend sv39 linear mapping max size to 128G")
> introduced a 4 GiB hole between the regions. Introducing KASAN_SW_TAGS
> will cut the size of the shadow memory region in half, creating an even
> larger hole.
>
> Avoid wasting PGD entries on this hole by using the size of the linear
> map (KERN_VIRT_SIZE) to compute PAGE_END.
>
> Since KASAN_SHADOW_START/KASAN_SHADOW_END are used inside an IS_ENABLED
> block, it's not possible to completely hide the constants when KASAN is
> disabled, so provide dummy definitions for that case.
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
> (no changes since v1)
>
>   arch/riscv/include/asm/kasan.h | 11 +++++++++--
>   arch/riscv/mm/init.c           |  2 +-
>   2 files changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/arch/riscv/include/asm/kasan.h b/arch/riscv/include/asm/kasan.h
> index e6a0071bdb56..a4e92ce9fa31 100644
> --- a/arch/riscv/include/asm/kasan.h
> +++ b/arch/riscv/include/asm/kasan.h
> @@ -6,6 +6,8 @@
>   
>   #ifndef __ASSEMBLY__
>   
> +#ifdef CONFIG_KASAN
> +
>   /*
>    * The following comment was copied from arm64:
>    * KASAN_SHADOW_START: beginning of the kernel virtual addresses.
> @@ -33,13 +35,18 @@
>   #define KASAN_SHADOW_START	((KASAN_SHADOW_END - KASAN_SHADOW_SIZE) & PGDIR_MASK)
>   #define KASAN_SHADOW_END	MODULES_LOWEST_VADDR
>   
> -#ifdef CONFIG_KASAN
>   #define KASAN_SHADOW_OFFSET	_AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
>   
>   void kasan_init(void);
>   asmlinkage void kasan_early_init(void);
>   void kasan_swapper_init(void);
>   
> -#endif
> +#else /* CONFIG_KASAN */
> +
> +#define KASAN_SHADOW_START	MODULES_LOWEST_VADDR
> +#define KASAN_SHADOW_END	MODULES_LOWEST_VADDR
> +
> +#endif /* CONFIG_KASAN */
> +
>   #endif
>   #endif /* __ASM_KASAN_H */
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 0e8c20adcd98..1f9bb95c2169 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -1494,7 +1494,7 @@ static void __init preallocate_pgd_pages_range(unsigned long start, unsigned lon
>   	panic("Failed to pre-allocate %s pages for %s area\n", lvl, area);
>   }
>   
> -#define PAGE_END KASAN_SHADOW_START
> +#define PAGE_END (PAGE_OFFSET + KERN_VIRT_SIZE)
>   
>   void __init pgtable_cache_init(void)
>   {


Looks good and cleaner, you can add:

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From alex at ghiti.fr  Tue Nov  5 05:55:01 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Tue, 5 Nov 2024 14:55:01 +0100
Subject: [PATCH v2 7/9] riscv: Align the sv39 linear map to 16 GiB
In-Reply-To: <20241022015913.3524425-8-samuel.holland@sifive.com>
References: <20241022015913.3524425-1-samuel.holland@sifive.com>
 <20241022015913.3524425-8-samuel.holland@sifive.com>
Message-ID: <e8cf563f-d840-4e33-9ca0-2fa734c9f6c2@ghiti.fr>

On 22/10/2024 03:57, Samuel Holland wrote:
> The KASAN implementation on RISC-V requires the shadow memory for the
> vmemmap and linear map regions to be aligned to a PMD boundary (1 GiB).


PUD boundary


> For KASAN_GENERIC (KASAN_SHADOW_SCALE_SHIFT == 3), this enforces 8 GiB
> alignment for the memory regions themselves. KASAN_SW_TAGS uses 16-byte
> granules (KASAN_SHADOW_SCALE_SHIFT == 4), so now the memory regions must
> be aligned to a 16 GiB boundary.
>
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
> (no changes since v1)
>
>   Documentation/arch/riscv/vm-layout.rst | 10 +++++-----
>   arch/riscv/include/asm/page.h          |  2 +-
>   2 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/arch/riscv/vm-layout.rst b/Documentation/arch/riscv/vm-layout.rst
> index eabec99b5852..c0778c421b34 100644
> --- a/Documentation/arch/riscv/vm-layout.rst
> +++ b/Documentation/arch/riscv/vm-layout.rst
> @@ -47,11 +47,11 @@ RISC-V Linux Kernel SV39
>                                                                 | Kernel-space virtual memory, shared between all processes:
>     ____________________________________________________________|___________________________________________________________
>                       |            |                  |         |
> -   ffffffc4fea00000 | -236    GB | ffffffc4feffffff |    6 MB | fixmap
> -   ffffffc4ff000000 | -236    GB | ffffffc4ffffffff |   16 MB | PCI io
> -   ffffffc500000000 | -236    GB | ffffffc5ffffffff |    4 GB | vmemmap
> -   ffffffc600000000 | -232    GB | ffffffd5ffffffff |   64 GB | vmalloc/ioremap space
> -   ffffffd600000000 | -168    GB | fffffff5ffffffff |  128 GB | direct mapping of all physical memory
> +   ffffffc2fea00000 | -244    GB | ffffffc2feffffff |    6 MB | fixmap
> +   ffffffc2ff000000 | -244    GB | ffffffc2ffffffff |   16 MB | PCI io
> +   ffffffc300000000 | -244    GB | ffffffc3ffffffff |    4 GB | vmemmap
> +   ffffffc400000000 | -240    GB | ffffffd3ffffffff |   64 GB | vmalloc/ioremap space
> +   ffffffd400000000 | -176    GB | fffffff3ffffffff |  128 GB | direct mapping of all physical memory
>                       |            |                  |         |
>      fffffff700000000 |  -36    GB | fffffffeffffffff |   32 GB | kasan
>     __________________|____________|__________________|_________|____________________________________________________________
> diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
> index 32d308a3355f..6e2f79cf77c5 100644
> --- a/arch/riscv/include/asm/page.h
> +++ b/arch/riscv/include/asm/page.h
> @@ -37,7 +37,7 @@
>    * define the PAGE_OFFSET value for SV48 and SV39.
>    */
>   #define PAGE_OFFSET_L4		_AC(0xffffaf8000000000, UL)
> -#define PAGE_OFFSET_L3		_AC(0xffffffd600000000, UL)
> +#define PAGE_OFFSET_L3		_AC(0xffffffd400000000, UL)
>   #else
>   #define PAGE_OFFSET		_AC(CONFIG_PAGE_OFFSET, UL)
>   #endif /* CONFIG_64BIT */


Other than the nit above (that I think should be fixed though), you can add:

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From christophe.leroy at csgroup.eu  Tue Nov  5 06:04:31 2024
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Tue, 5 Nov 2024 15:04:31 +0100
Subject: [PATCH 00/28] vdso: Preparations for generic data storage
In-Reply-To: <871pzxzuny.ffs@tglx>
References: <20241010-vdso-generic-base-v1-0-b64f0842d512@linutronix.de>
 <871pzxzuny.ffs@tglx>
Message-ID: <e33569c8-1591-462c-9388-4a514e156bfa@csgroup.eu>



Le 30/10/2024 ? 12:39, Thomas Gleixner a ?crit?:
> Folks!
> 
> On Thu, Oct 10 2024 at 09:01, Thomas Wei?schuh wrote:
>> Historically each architecture defined their own datapage to store the
>> VDSO data. This stands in contrast to the generic nature of the VDSO
>> code itself.
>> We plan to introduce a generic framework for the management of the VDSO
>> data storage that can be used by all architectures and which works
>> together with the existing generic VDSO code.
>>
>> Before that is possible align the different architectures by
>> standardizing on the existing generic infrastructure and moving things
>> out of the VDSO data page which does not belong there.
>>
>> Patches	 1- 2:	csky
>> Patch	    3:	s390
>> Patches	 4- 5:	arm64
>> Patch	    6:	riscv
>> Patch	    7:	arm
>> Patch	    8:	LoongArch
>> Patch	    9:	MIPS
>> Patches 10-20:	x86
>> Patches 21-27:	powerpc
>> Patch      28: 	Renamings to avoid a name clash with the new code.
> 
> As this has been sitting for two weeks now without major comments, I'm
> planning to merge that through the tip tree tomorrow.

To avoid any future conflicts with powerpc tree, I suggest you merge 
https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git 
topic/vdso into your tree before applying this series.

Christophe


From andi.shyti at kernel.org  Tue Nov  5 06:21:31 2024
From: andi.shyti at kernel.org (Andi Shyti)
Date: Tue, 5 Nov 2024 15:21:31 +0100
Subject: [PATCH v2 0/2] riscv: spacemit: add i2c support to K1 SoC
In-Reply-To: <edfaccd7-ac96-47fc-a174-912c8aaf0f5e@gmail.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <stpzkggfwseaqy6kbppiog4xfbpq4r2jwix2nvredbmmjqzbsi@wkllt4jlingv>
 <edfaccd7-ac96-47fc-a174-912c8aaf0f5e@gmail.com>
Message-ID: <o55tg4zybyfroh7on7b6pxwbkw46fgafryzlc2gczmgecxr4ph@lptxs2timypu>

Hy Troy,

On Mon, Nov 04, 2024 at 08:23:23PM +0800, Troy Mitchell wrote:
> On 2024/10/31 19:43, Andi Shyti wrote:
> > Hi Tony,

Sorry, I misread your name :-/

> > On Mon, Oct 28, 2024 at 01:32:18PM +0800, Troy Mitchell wrote:
> >> Hi all,
> >>
> >> This patch implements I2C driver for the SpacemiT K1 SoC,
> >> providing basic support for I2C read/write communication which
> >> compatible with standard I2C bus specifications.
> >>
> >> In this version, the driver defaults to use fast-speed-mode and
> >> interrupts for transmission, and does not support DMA, high-speed mode, or FIFO.
> >>
> >> The docs of I2C can be found here, in chapter 16.1 I2C [1]
> >>
> >> Link: https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#part5 [1]
> >>
> >> Troy Mitchell (2):
> >>   dt-bindings: i2c: spacemit: add support for K1 SoC
> >>   i2c: spacemit: add support for SpacemiT K1 SoC
> > 
> > As Krzysztof has asked, please do provide the changelog, it's
> > important to track the progress of your series.
> I saw a compilation warning sent to me by the robot, and I've
> fixed the warning. Should I resend V2 with the changelog
> what I miss or send V3?

Please send a v3. When there are compilation issues, normally
patches are less keen to be reviewed.

You can add the changelog in the Patch 0/2 to avoid editing all
the .patch files.

Thanks,
Andi


From helgaas at kernel.org  Tue Nov  5 09:18:28 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 5 Nov 2024 11:18:28 -0600
Subject: [PATCH v5 2/2] PCI: microchip: rework reg region handing to
 support using either instance 1 or 2
In-Reply-To: <20241104-stabilize-friday-94705c3dc244@spud>
Message-ID: <20241105171828.GA1474726@bhelgaas>

On Mon, Nov 04, 2024 at 11:18:43AM +0000, Conor Dooley wrote:
> On Fri, Nov 01, 2024 at 02:51:29PM -0500, Bjorn Helgaas wrote:
> > On Wed, Aug 14, 2024 at 09:08:42AM +0100, Conor Dooley wrote:
> > > From: Conor Dooley <conor.dooley at microchip.com>
> > > 
> > > The PCI host controller on PolarFire SoC has multiple "instances", each
> > > with their own bridge and ctrl address spaces. The original binding has
> > > an "apb" register region, and it is expected to be set to the base
> > > address of the host controllers register space. Defines in the driver
> > > were used to compute the addresses of the bridge and ctrl address ranges
> > > corresponding to instance1. Some customers want to use instance0 however
> > > and that requires changing the defines in the driver, which is clearly
> > > not a portable solution.
> > 
> > The subject mentions "instance 1 or 2".
> > 
> > This paragraph implies adding support for "instance0" ("customers want
> > to use instance0").
> > 
> > The DT patch suggests that we're adding support for "instance2"
> > ("customers want to use instance2").
> > 
> > Both patches suggest that the existing support is for "instance 1".
> > 
> > Maybe what's being added is "instance 2", and this commit log should
> > s/instance0/instance 2/ ?  And probably s/instance1/instance 1/ so the
> > style is consistent?
> 
> Hmm no, it would be s/instance1/instance 2/ & s/instance0/instance 1/.
> The indices are 1-based, not 0-based.
> 
> > Is this a "pick one or the other but not both" situation, or does this
> > device support two independent PCIe controllers?
> > 
> > I first thought this driver supported a single PCIe controller, and
> > you were adding support for a second independent controller.
> 
> I don't know if they are fully independent (Daire would have to confirm)
> but as far as the driver in linux is concerned they are. As far as I
> know, you could operate both instances at the same time, but I've not
> heard of any customer that is actually doing that nor tested it myself.
> Operating both instances would require another node in the devicetree,
> which should work fine given the private data structs are allocated at
> runtime. I think the config space is shared.
> 
> > But the fact that you say "the [singular] host controller on
> > PolarFire", and you're not changing mc_host_probe() to call
> > pci_host_common_probe() more than once makes me think there is only a
> > single PCIe controller, and for some reason you can choose to operate
> > it using either register set 1 or register set 2.
> 
> The wording I've used mostly stems from conversations with Daire. We've
> kinda been saying that there's a single controller with two root port
> instances. 

If these are two separate Root Ports, can we call them "Root Ports"
instead of "instances"?  Common terminology makes for common
understanding.

> Each root port instance is connected to different IOs,
> they're more than just different registers for accessing the same thing.

Sounds like some customers use Root Port 1 and others use Root Port 2,
maybe based on things like which pins are more convenient to route.

I would very much like to reword these commit logs using as much
standard PCIe terminology as possible.  Most of these native PCIe
controller drivers have Root Complex and Root Port concepts all mixed
together, and anything we can do to standardize them will be a
benefit.

Bjorn


From valentina.fernandezalanis at microchip.com  Tue Nov  5 10:35:11 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Tue, 5 Nov 2024 18:35:11 +0000
Subject: [PATCH v3 2/4] riscv: export __cpuid_to_hartid_map
In-Reply-To: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
References: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
Message-ID: <20241105183513.1358736-3-valentina.fernandezalanis@microchip.com>

EXPORT_SYMBOL_GPL() is missing for __cpuid_to_hartid_map array.
Export this symbol to allow drivers compiled as modules to use
cpuid_to_hartid_map().

Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
---
 arch/riscv/kernel/smp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index c180a647a30e..d58b5e751286 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -43,6 +43,7 @@ enum ipi_message_type {
 unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = {
 	[0 ... NR_CPUS-1] = INVALID_HARTID
 };
+EXPORT_SYMBOL_GPL(__cpuid_to_hartid_map);
 
 void __init smp_setup_processor_id(void)
 {
-- 
2.34.1



From valentina.fernandezalanis at microchip.com  Tue Nov  5 10:35:12 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Tue, 5 Nov 2024 18:35:12 +0000
Subject: [PATCH v3 3/4] dt-bindings: mailbox: add binding for Microchip IPC mailbox controller
In-Reply-To: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
References: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
Message-ID: <20241105183513.1358736-4-valentina.fernandezalanis@microchip.com>

Add a dt-binding for the Microchip Inter-Processor Communication (IPC)
mailbox controller.

Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
---
 .../bindings/mailbox/microchip,sbi-ipc.yaml   | 117 ++++++++++++++++++
 1 file changed, 117 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml b/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
new file mode 100644
index 000000000000..9e67c09e4bea
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/microchip,sbi-ipc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip Inter-processor communication (IPC) mailbox controller
+
+maintainers:
+  - Valentina Fernandez <valentina.fernandezalanis at microchip.com>
+
+description:
+  The Microchip Inter-processor Communication (IPC) facilitates
+  message passing between processors using an interrupt signaling
+  mechanism.
+
+properties:
+  compatible:
+    oneOf:
+      - description:
+          Intended for use by software running in supervisor privileged
+          mode (s-mode). This SBI interface is compatible with the Mi-V
+          Inter-hart Communication (IHC) IP.
+        items:
+          - const: microchip,sbi-ipc
+
+      - description:
+          SoC-specific compatible, intended for use by the SBI
+          implementation in machine mode (m-mode).
+        items:
+          - const: microchip,miv-ihc-rtl-v2
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 5
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 5
+    items:
+      pattern: "^hart-[0-5]+$"
+
+  "#mbox-cells":
+    description: >
+      For the SBI "device", the cell represents the global "logical" channel IDs.
+      The meaning of channel IDs are platform firmware dependent.
+
+      For the SoC-specific compatible string, the cell represents the physical
+      channel and does not vary based on the platform firmware.
+    const: 1
+
+  microchip,ihc-chan-disabled-mask:
+    description: >
+      Represents the enable/disable state of the bi-directional IHC
+      channels within the MIV-IHC IP configuration.
+
+      The mask is a 16-bit value, but only the first 15 bits are utilized.
+      Each of the bits corresponds to one of the 15 IHC channels.
+
+      A bit set to '1' indicates that the corresponding channel is disabled,
+      and any read or write operations to that channel will return zero.
+
+      A bit set to '0' indicates that the corresponding channel is enabled
+      and will be accessible through its dedicated address range registers.
+
+      The remaining bit of the 16-bit mask is reserved and should be ignored.
+
+      The actual enable/disable state of each channel is determined by the
+      IP block?s configuration.
+    $ref: /schemas/types.yaml#/definitions/uint16
+    default: 0
+
+required:
+  - compatible
+  - interrupts
+  - interrupt-names
+  - "#mbox-cells"
+
+additionalProperties: false
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: microchip,sbi-ipc
+    then:
+      properties:
+        reg: false
+        microchip,ihc-chan-disabled-mask: false
+    else:
+      required:
+        - reg
+        - microchip,ihc-chan-disabled-mask
+
+examples:
+  - |
+    mailbox {
+      compatible = "microchip,sbi-ipc";
+      interrupt-parent = <&plic>;
+      interrupts = <180>, <179>, <178>;
+      interrupt-names = "hart-1", "hart-2", "hart-3";
+      #mbox-cells = <1>;
+    };
+  - |
+    mailbox at 50000000 {
+      compatible = "microchip,miv-ihc-rtl-v2";
+      microchip,ihc-chan-disabled-mask = /bits/ 16 <0>;
+      reg = <0x50000000 0x1C000>;
+      interrupt-parent = <&plic>;
+      interrupts = <180>, <179>, <178>;
+      interrupt-names = "hart-1", "hart-2", "hart-3";
+      #mbox-cells = <1>;
+    };
-- 
2.34.1



From valentina.fernandezalanis at microchip.com  Tue Nov  5 10:35:09 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Tue, 5 Nov 2024 18:35:09 +0000
Subject: [PATCH v3 0/4] Add Microchip IPC mailbox
Message-ID: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>

Hello all,

This series adds support for the Microchip Inter-Processor Communication
(IPC) mailbox driver.

Microchip's family of RISC-V SoCs typically has one or more clusters
that can be configured to run in Asymmetric Multi-Processing (AMP) mode.

The Microchip IPC is used to send messages between processors using
an interrupt signaling mechanism. The driver uses the RISC-V Supervisor
Binary Interface (SBI) to communicate with software running in machine
mode (M-mode) to access the IPC hardware block.

Additional details on the Microchip vendor extension and the IPC
function IDs described in the driver can be found in the following
documentation:

https://github.com/linux4microchip/microchip-sbi-ecall-extension

The PIC64GX MPU has a Mi-V IHC block, this will be added to the PIC64GX
dts after the initial upstreaming [1].

[1] https://patchwork.kernel.org/project/linux-riscv/patch/20240725121609.13101-18-pierre-henry.moussay at microchip.com/

Changes in v3:
- Fix incorrent formatting around '=' in dt binding examples
- Add per compatible descriptions in dt binding
- Add '>' in certain dt binding descriptions to keep paragraphs maintained
- export __cpuid_to_hartid_map to compile mailbox driver as module
- Drop unused enum ipc_irq_type
- rename struct mchp_ipc_probe to mchp_ipc_mbox_info
- rename struct ipc_chan_info to mchp_ipc_sbi_chan
- rename struct microchip_ipc to mchp_ipc_sbi_mbox
- use phys_addr_t for __pa()
- drop mchp_ipc_get_chan_id function
- use num_chans in mbox_controller
- Fix buf_base_tx and buf_base_rx sizes using max and kmalloc

Changes in v2:
- use kmalloc and __pa() instead of DMA API
- fix size of buf_base to avoid potential buffer overflow
- add kernel doc for exported functions (mchp_ipc_get_chan_id)
- use EXPORT_SYMBOL_GPL instead of EXPORT_SYMBOL
- drop unnecessary blank line and fix alignment issues
- drop of_match_ptr
- move MODULE_DEVICE_TABLE next to the definition
- reword subject from riscv: asm: vendorid_list to riscv: sbi: vendorid_list
- remove the word "driver" from dt-binding commit subject
- make interrupt-names a required property for all cases
- add dependency on COMPILE_TEST and ARCH_MICROCHIP

Regards,
Valentina

Valentina Fernandez (4):
  riscv: sbi: vendorid_list: Add Microchip Technology to the vendor list
  riscv: export __cpuid_to_hartid_map
  dt-bindings: mailbox: add binding for Microchip IPC mailbox controller
  mailbox: add Microchip IPC support

 .../bindings/mailbox/microchip,sbi-ipc.yaml   | 117 ++++
 arch/riscv/include/asm/vendorid_list.h        |   1 +
 arch/riscv/kernel/smp.c                       |   1 +
 drivers/mailbox/Kconfig                       |  13 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mailbox-mchp-ipc-sbi.c        | 504 ++++++++++++++++++
 include/linux/mailbox/mchp-ipc.h              |  33 ++
 7 files changed, 671 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
 create mode 100644 drivers/mailbox/mailbox-mchp-ipc-sbi.c
 create mode 100644 include/linux/mailbox/mchp-ipc.h

-- 
2.34.1



From valentina.fernandezalanis at microchip.com  Tue Nov  5 10:35:10 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Tue, 5 Nov 2024 18:35:10 +0000
Subject: [PATCH v3 1/4] riscv: sbi: vendorid_list: Add Microchip Technology to the vendor list
In-Reply-To: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
References: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
Message-ID: <20241105183513.1358736-2-valentina.fernandezalanis@microchip.com>

Add Microchip Technology to the RISC-V vendor list.

Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
---
 arch/riscv/include/asm/vendorid_list.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h
index 2f2bb0c84f9a..a5150cdf34d8 100644
--- a/arch/riscv/include/asm/vendorid_list.h
+++ b/arch/riscv/include/asm/vendorid_list.h
@@ -6,6 +6,7 @@
 #define ASM_VENDOR_LIST_H
 
 #define ANDES_VENDOR_ID		0x31e
+#define MICROCHIP_VENDOR_ID	0x029
 #define SIFIVE_VENDOR_ID	0x489
 #define THEAD_VENDOR_ID		0x5b7
 
-- 
2.34.1



From valentina.fernandezalanis at microchip.com  Tue Nov  5 10:35:13 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Tue, 5 Nov 2024 18:35:13 +0000
Subject: [PATCH v3 4/4] mailbox: add Microchip IPC support
In-Reply-To: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
References: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
Message-ID: <20241105183513.1358736-5-valentina.fernandezalanis@microchip.com>

Add a mailbox controller driver for the Microchip Inter-processor
Communication (IPC), which is used to send and receive data between
processors.

The driver uses the RISC-V Supervisor Binary Interface (SBI) to
communicate with software running in machine mode (M-mode) to access
the IPC hardware block.

Additional details on the Microchip vendor extension and the IPC
function IDs described in the driver can be found in the following
documentation:

https://github.com/linux4microchip/microchip-sbi-ecall-extension

This SBI interface in this driver is compatible with the Mi-V Inter-hart
Communication (IHC) IP.

Transmitting and receiving data through the mailbox framework is done
through struct mchp_ipc_msg.

Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
---
 drivers/mailbox/Kconfig                |  13 +
 drivers/mailbox/Makefile               |   2 +
 drivers/mailbox/mailbox-mchp-ipc-sbi.c | 504 +++++++++++++++++++++++++
 include/linux/mailbox/mchp-ipc.h       |  33 ++
 4 files changed, 552 insertions(+)
 create mode 100644 drivers/mailbox/mailbox-mchp-ipc-sbi.c
 create mode 100644 include/linux/mailbox/mchp-ipc.h

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 6fb995778636..a61b3b0c5da3 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -177,6 +177,19 @@ config POLARFIRE_SOC_MAILBOX
 
 	  If unsure, say N.
 
+config MCHP_SBI_IPC_MBOX
+	tristate "Microchip Inter-processor Communication (IPC) SBI driver"
+	depends on RISCV_SBI || COMPILE_TEST
+	depends on ARCH_MICROCHIP
+	help
+	  Mailbox implementation for Microchip devices with an
+	  Inter-process communication (IPC) controller.
+
+	  To compile this driver as a module, choose M here. the
+	  module will be called mailbox-mchp-ipc-sbi.
+
+	  If unsure, say N.
+
 config QCOM_APCS_IPC
 	tristate "Qualcomm APCS IPC driver"
 	depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 3c3c27d54c13..a78d1948e331 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -45,6 +45,8 @@ obj-$(CONFIG_BCM_FLEXRM_MBOX)	+= bcm-flexrm-mailbox.o
 
 obj-$(CONFIG_POLARFIRE_SOC_MAILBOX)	+= mailbox-mpfs.o
 
+obj-$(CONFIG_MCHP_SBI_IPC_MBOX)		+= mailbox-mchp-ipc-sbi.o
+
 obj-$(CONFIG_QCOM_APCS_IPC)	+= qcom-apcs-ipc-mailbox.o
 
 obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
diff --git a/drivers/mailbox/mailbox-mchp-ipc-sbi.c b/drivers/mailbox/mailbox-mchp-ipc-sbi.c
new file mode 100644
index 000000000000..a6e52009a424
--- /dev/null
+++ b/drivers/mailbox/mailbox-mchp-ipc-sbi.c
@@ -0,0 +1,504 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Microchip Inter-Processor communication (IPC) driver
+ *
+ * Copyright (c) 2021 - 2024 Microchip Technology Inc. All rights reserved.
+ *
+ * Author: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/of_device.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mailbox/mchp-ipc.h>
+#include <asm/sbi.h>
+#include <asm/vendorid_list.h>
+
+#define IRQ_STATUS_BITS			12
+#define NUM_CHANS_PER_CLUSTER		5
+#define IPC_DMA_BIT_MASK		32
+#define SBI_EXT_MICROCHIP_TECHNOLOGY	(SBI_EXT_VENDOR_START | \
+					 MICROCHIP_VENDOR_ID)
+
+enum {
+	SBI_EXT_IPC_PROBE = 0x100,
+	SBI_EXT_IPC_CH_INIT,
+	SBI_EXT_IPC_SEND,
+	SBI_EXT_IPC_RECEIVE,
+	SBI_EXT_IPC_STATUS,
+};
+
+enum ipc_hw {
+	MIV_IHC,
+};
+
+/**
+ * struct mchp_ipc_mbox_info - IPC probe message format
+ *
+ * @hw_type:		IPC implementation available in the hardware
+ * @num_channels:	number of IPC channels available in the hardware
+ *
+ * Used to retrieve information on the IPC implementation
+ * using the SBI_EXT_IPC_PROBE SBI function id.
+ */
+struct mchp_ipc_mbox_info {
+	enum ipc_hw hw_type;
+	u8 num_channels;
+};
+
+/**
+ * struct mchp_ipc_init - IPC channel init message format
+ *
+ * @max_msg_size:	maxmimum message size in bytes of a given channel
+ *
+ * struct used by the SBI_EXT_IPC_CH_INIT SBI function id to get
+ * the max message size in bytes of the initialized channel.
+ */
+struct mchp_ipc_init {
+	u16 max_msg_size;
+};
+
+/**
+ * struct mchp_ipc_status - IPC status message format
+ *
+ * @status:	interrupt status for all channels associated to a cluster
+ * @cluster:	specifies the cluster instance that originated an irq
+ *
+ * struct used by the SBI_EXT_IPC_STATUS SBI function id to get
+ * the message present and message clear interrupt status for all the
+ * channels associated to a cluster.
+ */
+struct mchp_ipc_status {
+	u32 status;
+	u8 cluster;
+};
+
+/**
+ * struct mchp_ipc_sbi_msg - IPC SBI payload message
+ *
+ * @buf_addr:	physical address where the received data should be copied to
+ * @size:	maximum size(in bytes) that can be stored in the buffer pointed to by `buf`
+ * @irq_type:	mask representing the irq types that triggered an irq
+ *
+ * struct used by the SBI_EXT_IPC_SEND/SBI_EXT_IPC_RECEIVE SBI function
+ * ids to send/receive a message from an associated processor using
+ * the IPC.
+ */
+struct mchp_ipc_sbi_msg {
+	u64 buf_addr;
+	u16 size;
+	u8 irq_type;
+};
+
+struct mchp_ipc_cluster_cfg {
+	void *buf_base;
+	phys_addr_t buf_base_addr;
+	int irq;
+};
+
+struct mchp_ipc_sbi_mbox {
+	struct device *dev;
+	struct mbox_chan *chans;
+	struct mchp_ipc_cluster_cfg *cluster_cfg;
+	void *buf_base;
+	unsigned long buf_base_addr;
+	struct mbox_controller controller;
+	enum ipc_hw hw_type;
+};
+
+static int mchp_ipc_sbi_chan_send(u32 command, u32 channel, unsigned long address)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_MICROCHIP_TECHNOLOGY, command, channel,
+			address, 0, 0, 0, 0);
+
+	if (ret.error)
+		return sbi_err_map_linux_errno(ret.error);
+	else
+		return ret.value;
+}
+
+static int mchp_ipc_sbi_send(u32 command, unsigned long address)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_MICROCHIP_TECHNOLOGY, command, address,
+			0, 0, 0, 0, 0);
+
+	if (ret.error)
+		return sbi_err_map_linux_errno(ret.error);
+	else
+		return ret.value;
+}
+
+static struct mchp_ipc_sbi_mbox *to_mchp_ipc_mbox(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mchp_ipc_sbi_mbox, controller);
+}
+
+static inline void mchp_ipc_prepare_receive_req(struct mbox_chan *chan)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+	struct mchp_ipc_sbi_msg request;
+
+	request.buf_addr = chan_info->msg_buf_rx_addr;
+	request.size = chan_info->max_msg_size;
+	memcpy(chan_info->buf_base_rx, &request, sizeof(struct mchp_ipc_sbi_msg));
+}
+
+static inline void mchp_ipc_process_received_data(struct mbox_chan *chan,
+						  struct mchp_ipc_msg *ipc_msg)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+	struct mchp_ipc_sbi_msg sbi_msg;
+
+	memcpy(&sbi_msg, chan_info->buf_base_rx, sizeof(struct mchp_ipc_sbi_msg));
+	ipc_msg->buf = (u32 *)chan_info->msg_buf_rx;
+	ipc_msg->size = sbi_msg.size;
+}
+
+static irqreturn_t mchp_ipc_cluster_aggr_isr(int irq, void *data)
+{
+	struct mbox_chan *chan;
+	struct mchp_ipc_sbi_chan *chan_info;
+	struct mchp_ipc_sbi_mbox *ipc = (struct mchp_ipc_sbi_mbox *)data;
+	struct mchp_ipc_msg ipc_msg;
+	struct mchp_ipc_status status_msg;
+	int ret;
+	unsigned long hartid;
+	u32 i, chan_index, chan_id;
+
+	/* Find out the hart that originated the irq */
+	for_each_online_cpu(i) {
+		hartid = cpuid_to_hartid_map(i);
+		if (irq == ipc->cluster_cfg[hartid].irq)
+			break;
+	}
+
+	status_msg.cluster = hartid;
+	memcpy(ipc->cluster_cfg[hartid].buf_base, &status_msg, sizeof(struct mchp_ipc_status));
+
+	ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[hartid].buf_base_addr);
+	if (ret < 0) {
+		dev_err_ratelimited(ipc->dev, "could not get IHC irq status ret=%d\n", ret);
+		return IRQ_HANDLED;
+	}
+
+	memcpy(&status_msg, ipc->cluster_cfg[hartid].buf_base, sizeof(struct mchp_ipc_status));
+
+	/*
+	 * Iterate over each bit set in the IHC interrupt status register (IRQ_STATUS) to identify
+	 * the channel(s) that have a message to be processed/acknowledged.
+	 * The bits are organized in alternating format, where each pair of bits represents
+	 * the status of the message present and message clear interrupts for each cluster/hart
+	 * (from hart 0 to hart 5). Each cluster can have up to 5 fixed channels associated.
+	 */
+
+	for_each_set_bit(i, (unsigned long *)&status_msg.status, IRQ_STATUS_BITS) {
+		/* Find out the destination hart that triggered the interrupt */
+		chan_index = i / 2;
+
+		/*
+		 * The IP has no loopback channels, so we need to decrement the index when
+		 * the target hart has a greater index than our own
+		 */
+		if (chan_index >= status_msg.cluster)
+			chan_index--;
+
+		/*
+		 * Calculate the channel id given the hart and channel index. Channel IDs
+		 * are unique across all clusters of an IPC, and iterate contiguously
+		 * across all clusters.
+		 */
+		chan_id = status_msg.cluster * (NUM_CHANS_PER_CLUSTER + chan_index);
+
+		chan = &ipc->chans[chan_id];
+		chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+
+		if (i % 2 == 0) {
+			mchp_ipc_prepare_receive_req(chan);
+			ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_RECEIVE, chan_id,
+						     chan_info->buf_base_rx_addr);
+			if (ret < 0)
+				continue;
+
+			mchp_ipc_process_received_data(chan, &ipc_msg);
+			mbox_chan_received_data(&ipc->chans[chan_id], (void *)&ipc_msg);
+
+		} else {
+			ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_RECEIVE, chan_id,
+						     chan_info->buf_base_rx_addr);
+			mbox_chan_txdone(&ipc->chans[chan_id], ret);
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static int mchp_ipc_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+	const struct mchp_ipc_msg *msg = data;
+	struct mchp_ipc_sbi_msg sbi_payload;
+
+	memcpy(chan_info->msg_buf_tx, msg->buf, msg->size);
+	sbi_payload.buf_addr = chan_info->msg_buf_tx_addr;
+	sbi_payload.size = msg->size;
+	memcpy(chan_info->buf_base_tx, &sbi_payload, sizeof(sbi_payload));
+
+	return mchp_ipc_sbi_chan_send(SBI_EXT_IPC_SEND, chan_info->id, chan_info->buf_base_tx_addr);
+}
+
+static int mchp_ipc_startup(struct mbox_chan *chan)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+	struct mchp_ipc_sbi_mbox *ipc = to_mchp_ipc_mbox(chan->mbox);
+	struct mchp_ipc_init ch_init_msg;
+	int ret;
+
+	/*
+	 * The TX base buffer is used to transmit two types of messages:
+	 * - struct mchp_ipc_init to initialize the channel
+	 * - struct mchp_ipc_sbi_msg to transmit user data/payload
+	 * Ensure the TX buffer size is large enough to accommodate either message type.
+	 */
+	size_t max_size = max(sizeof(struct mchp_ipc_init), sizeof(struct mchp_ipc_sbi_msg));
+
+	chan_info->buf_base_tx = kmalloc(max_size, GFP_KERNEL);
+	if (!chan_info->buf_base_tx) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	chan_info->buf_base_tx_addr = __pa(chan_info->buf_base_tx);
+
+	chan_info->buf_base_rx = kmalloc(max_size, GFP_KERNEL);
+	if (!chan_info->buf_base_rx) {
+		ret = -ENOMEM;
+		goto fail_free_buf_base_tx;
+	}
+
+	chan_info->buf_base_rx_addr = __pa(chan_info->buf_base_rx);
+
+	ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_CH_INIT, chan_info->id,
+				     chan_info->buf_base_tx_addr);
+	if (ret < 0) {
+		dev_err(ipc->dev, "channel %u init failed\n", chan_info->id);
+		goto fail_free_buf_base_rx;
+	}
+
+	memcpy(&ch_init_msg, chan_info->buf_base_tx, sizeof(struct mchp_ipc_init));
+	chan_info->max_msg_size = ch_init_msg.max_msg_size;
+
+	chan_info->msg_buf_tx = kmalloc(chan_info->max_msg_size, GFP_KERNEL);
+	if (!chan_info->msg_buf_tx) {
+		ret = -ENOMEM;
+		goto fail_free_buf_base_rx;
+	}
+
+	chan_info->msg_buf_tx_addr = __pa(chan_info->msg_buf_tx);
+
+	chan_info->msg_buf_rx = kmalloc(chan_info->max_msg_size, GFP_KERNEL);
+	if (!chan_info->msg_buf_rx) {
+		ret = -ENOMEM;
+		goto fail_free_buf_msg_tx;
+	}
+
+	chan_info->msg_buf_rx_addr = __pa(chan_info->msg_buf_rx);
+
+	switch (ipc->hw_type) {
+	case MIV_IHC:
+		return 0;
+	default:
+		goto fail_free_buf_msg_rx;
+	}
+
+	if (ret) {
+		dev_err(ipc->dev, "failed to register interrupt(s)\n");
+		goto fail_free_buf_msg_rx;
+	}
+
+	return ret;
+
+fail_free_buf_msg_rx:
+	kfree(chan_info->msg_buf_rx);
+fail_free_buf_msg_tx:
+	kfree(chan_info->msg_buf_tx);
+fail_free_buf_base_rx:
+	kfree(chan_info->buf_base_rx);
+fail_free_buf_base_tx:
+	kfree(chan_info->buf_base_tx);
+fail:
+	return ret;
+}
+
+static void mchp_ipc_shutdown(struct mbox_chan *chan)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+
+	kfree(chan_info->buf_base_tx);
+	kfree(chan_info->buf_base_rx);
+	kfree(chan_info->msg_buf_tx);
+	kfree(chan_info->msg_buf_rx);
+}
+
+static const struct mbox_chan_ops mchp_ipc_ops = {
+	.startup = mchp_ipc_startup,
+	.send_data = mchp_ipc_send_data,
+	.shutdown = mchp_ipc_shutdown,
+};
+
+static struct mbox_chan *mchp_ipc_mbox_xlate(struct mbox_controller *controller,
+					     const struct of_phandle_args *spec)
+{
+	struct mchp_ipc_sbi_mbox *ipc = to_mchp_ipc_mbox(controller);
+	unsigned int chan_id = spec->args[0];
+
+	if (chan_id >= ipc->controller.num_chans) {
+		dev_err(ipc->dev, "invalid channel id %d\n", chan_id);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return &ipc->chans[chan_id];
+}
+
+static int mchp_ipc_get_cluster_aggr_irq(struct mchp_ipc_sbi_mbox *ipc)
+{
+	struct platform_device *pdev = to_platform_device(ipc->dev);
+	char *irq_name;
+	int cpuid, ret;
+	unsigned long hartid;
+	bool irq_found = false;
+
+	for_each_online_cpu(cpuid) {
+		hartid = cpuid_to_hartid_map(cpuid);
+		irq_name = devm_kasprintf(ipc->dev, GFP_KERNEL, "hart-%lu", hartid);
+		ret = platform_get_irq_byname_optional(pdev, irq_name);
+		if (ret <= 0)
+			continue;
+
+		ipc->cluster_cfg[hartid].irq = ret;
+		ret = devm_request_irq(ipc->dev, ipc->cluster_cfg[hartid].irq,
+				       mchp_ipc_cluster_aggr_isr, IRQF_SHARED,
+				       "miv-ihc-irq", ipc);
+		if (ret)
+			return ret;
+
+		ipc->cluster_cfg[hartid].buf_base = devm_kmalloc(ipc->dev,
+								 sizeof(struct mchp_ipc_status),
+								 GFP_KERNEL);
+
+		if (!ipc->cluster_cfg[hartid].buf_base)
+			return -ENOMEM;
+
+		ipc->cluster_cfg[hartid].buf_base_addr = __pa(ipc->cluster_cfg[hartid].buf_base);
+
+		irq_found = true;
+	}
+
+	return irq_found;
+}
+
+static int mchp_ipc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mchp_ipc_mbox_info ipc_info;
+	struct mchp_ipc_sbi_mbox *ipc;
+	struct mchp_ipc_sbi_chan *priv;
+	bool irq_avail = false;
+	int ret;
+	u32 chan_id;
+
+	ret = sbi_probe_extension(SBI_EXT_MICROCHIP_TECHNOLOGY);
+	if (ret <= 0)
+		return dev_err_probe(dev, ret, "Microchip SBI extension not detected\n");
+
+	ipc = devm_kzalloc(dev, sizeof(*ipc), GFP_KERNEL);
+	if (!ipc)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ipc);
+
+	ipc->buf_base = devm_kmalloc(dev, sizeof(struct mchp_ipc_mbox_info), GFP_KERNEL);
+	if (!ipc->buf_base)
+		return -ENOMEM;
+
+	ipc->buf_base_addr = __pa(ipc->buf_base);
+
+	ret = mchp_ipc_sbi_send(SBI_EXT_IPC_PROBE, ipc->buf_base_addr);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "could not probe IPC SBI service\n");
+
+	memcpy(&ipc_info, ipc->buf_base, sizeof(struct mchp_ipc_mbox_info));
+	ipc->controller.num_chans = ipc_info.num_channels;
+	ipc->hw_type = ipc_info.hw_type;
+
+	ipc->chans = devm_kcalloc(dev, ipc->controller.num_chans, sizeof(*ipc->chans), GFP_KERNEL);
+	if (!ipc->chans)
+		return -ENOMEM;
+
+	ipc->dev = dev;
+	ipc->controller.txdone_irq = true;
+	ipc->controller.dev = ipc->dev;
+	ipc->controller.ops = &mchp_ipc_ops;
+	ipc->controller.chans = ipc->chans;
+	ipc->controller.of_xlate = mchp_ipc_mbox_xlate;
+
+	for (chan_id = 0; chan_id < ipc->controller.num_chans; chan_id++) {
+		priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
+		if (!priv)
+			return -ENOMEM;
+
+		ipc->chans[chan_id].con_priv = priv;
+		priv->id = chan_id;
+	}
+
+	if (ipc->hw_type == MIV_IHC) {
+		ipc->cluster_cfg = devm_kcalloc(dev, num_online_cpus(),
+						sizeof(struct mchp_ipc_cluster_cfg),
+						GFP_KERNEL);
+		if (!ipc->cluster_cfg)
+			return -ENOMEM;
+
+		if (mchp_ipc_get_cluster_aggr_irq(ipc))
+			irq_avail = true;
+	}
+
+	if (!irq_avail)
+		return dev_err_probe(dev, -ENODEV, "missing interrupt property\n");
+
+	ret = devm_mbox_controller_register(dev, &ipc->controller);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				    "Inter-Processor communication (IPC) registration failed\n");
+
+	return 0;
+}
+
+static const struct of_device_id mchp_ipc_of_match[] = {
+	{.compatible = "microchip,sbi-ipc", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, mchp_ipc_of_match);
+
+static struct platform_driver mchp_ipc_driver = {
+	.driver = {
+		.name = "microchip_ipc",
+		.of_match_table = mchp_ipc_of_match,
+	},
+	.probe = mchp_ipc_probe,
+};
+
+module_platform_driver(mchp_ipc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Valentina Fernandez <valentina.fernandezalanis at microchip.com>");
+MODULE_DESCRIPTION("Microchip Inter-Processor Communication (IPC) driver");
diff --git a/include/linux/mailbox/mchp-ipc.h b/include/linux/mailbox/mchp-ipc.h
new file mode 100644
index 000000000000..f084ac9e291b
--- /dev/null
+++ b/include/linux/mailbox/mchp-ipc.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *Copyright (c) 2024 Microchip Technology Inc. All rights reserved.
+ */
+
+#ifndef _LINUX_MCHP_IPC_H_
+#define _LINUX_MCHP_IPC_H_
+
+#include <linux/mailbox_controller.h>
+#include <linux/types.h>
+
+struct mchp_ipc_msg {
+	u32 *buf;
+	u16 size;
+};
+
+struct mchp_ipc_sbi_chan {
+	void *buf_base_tx;
+	void *buf_base_rx;
+	void *msg_buf_tx;
+	void *msg_buf_rx;
+	phys_addr_t buf_base_tx_addr;
+	phys_addr_t buf_base_rx_addr;
+	phys_addr_t msg_buf_tx_addr;
+	phys_addr_t msg_buf_rx_addr;
+	int chan_aggregated_irq;
+	int mp_irq;
+	int mc_irq;
+	u32 id;
+	u32 max_msg_size;
+};
+
+#endif /* _LINUX_MCHP_IPC_H_ */
-- 
2.34.1



From tjeznach at rivosinc.com  Tue Nov  5 10:42:25 2024
From: tjeznach at rivosinc.com (Tomasz Jeznach)
Date: Tue, 5 Nov 2024 10:42:25 -0800
Subject: [PATCH] iommu: Switch back to struct platform_driver::remove()
In-Reply-To: <6b5b4f25-0f42-4f83-b6b5-82c1adbefe83@arm.com>
References: <20241104064650.799122-2-u.kleine-koenig@baylibre.com> <6b5b4f25-0f42-4f83-b6b5-82c1adbefe83@arm.com>
Message-ID: <CAH2o1u77TViePZ2eh+FY7oQXxFAp+SEVM38ROP1uKfeMZ9E7hg@mail.gmail.com>

> > diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
> > index da336863f152..382ba2841849 100644
> > --- a/drivers/iommu/riscv/iommu-platform.c
> > +++ b/drivers/iommu/riscv/iommu-platform.c
> > @@ -81,7 +81,7 @@ static const struct of_device_id riscv_iommu_of_match[] = {
> >
> >   static struct platform_driver riscv_iommu_platform_driver = {
> >       .probe = riscv_iommu_platform_probe,
> > -     .remove_new = riscv_iommu_platform_remove,
> > +     .remove = riscv_iommu_platform_remove,
> >       .driver = {
> >               .name = "riscv,iommu",
> >               .of_match_table = riscv_iommu_of_match,
> > diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
> > index a2f4ffe6d949..e84806eee281 100644
> > --- a/drivers/iommu/sprd-iommu.c
> > +++ b/drivers/iommu/sprd-iommu.c
> > @@ -531,7 +531,7 @@ static struct platform_driver sprd_iommu_driver = {
> >               .suppress_bind_attrs = true,
> >       },
> >       .probe  = sprd_iommu_probe,
> > -     .remove_new = sprd_iommu_remove,
> > +     .remove = sprd_iommu_remove,
> >   };
> >   module_platform_driver(sprd_iommu_driver);
> >
> > base-commit: c88416ba074a8913cf6d61b789dd834bbca6681c
>

Thanks, LGTM for iommu/riscv part of the patch.

Reviewed-by: Tomasz Jeznach <tjeznach at rivosinc.com>


From nathan at kernel.org  Tue Nov  5 11:04:27 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Tue, 5 Nov 2024 12:04:27 -0700
Subject: [PATCH v7 6/8] x86/module: prepare module loading for ROX
 allocations of text
In-Reply-To: <ZynDAhW0lKCfOqZl@kernel.org>
References: <20241023162711.2579610-1-rppt@kernel.org>
 <20241023162711.2579610-7-rppt@kernel.org>
 <20241104232741.GA3843610@thelio-3990X>
 <ZynDAhW0lKCfOqZl@kernel.org>
Message-ID: <20241105190427.GA2903209@thelio-3990X>

On Tue, Nov 05, 2024 at 09:02:26AM +0200, Mike Rapoport wrote:
> There's a silly mistake in cfi_rewrite_endbr() in that commit, the patch
> below should fix it. Can you please test?

Yup, that was it! All my machines boot with this diff applied on top of
next-20241105, so with that fixed, I think we are all good here.

Tested-by: Nathan Chancellor <nathan at kernel.org>

> diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
> index 3407efc26528..243843e44e89 100644
> --- a/arch/x86/kernel/alternative.c
> +++ b/arch/x86/kernel/alternative.c
> @@ -1241,7 +1241,7 @@ static void cfi_rewrite_endbr(s32 *start, s32 *end, struct module *mod)
>  		void *addr = (void *)s + *s;
>  		void *wr_addr = module_writable_address(mod, addr);
>  
> -		poison_endbr(addr+16, wr_addr, false);
> +		poison_endbr(addr + 16, wr_addr + 16, false);
>  	}
>  }

Cheers,
Nathan


From unicorn_wang at outlook.com  Tue Nov  5 17:12:30 2024
From: unicorn_wang at outlook.com (Chen Wang)
Date: Wed, 6 Nov 2024 09:12:30 +0800
Subject: [GIT PULL] RISC-V Sophgo Devicetrees for v6.13
Message-ID: <MA0P287MB2822DC23E1EE47A5C7D41476FE532@MA0P287MB2822.INDP287.PROD.OUTLOOK.COM>

Hey Arnd,

Please pull dt changes for RISC-V/Sophgo.

Thanks,
Chen.

The following changes since commit 9852d85ec9d492ebef56dc5f229416c925758edc:

 ? Linux 6.12-rc1 (2024-09-29 15:06:19 -0700)

are available in the Git repository at:

 ? https://github.com/sophgo/linux.git tags/riscv-sophgo-dt-for-v6.13

for you to fetch changes up to b5cf65cc0fd00aa30ff218ec8170dd48e3cbe78d:

 ? riscv: dts: sophgo: Add emmc support for Huashan Pi (2024-11-02 
19:19:08 +0800)

----------------------------------------------------------------
RISC-V Devicetrees for v6.13

Sophgo:
Add pinctrl support for CV1800B & CV1812H.
Add SARADC support for CV1800B.
Add initial LicheeRV-Nano/SG2002.
Add emmc/sdio support for Huashan-Pi/CV1812H.
Add power-key support for PioneerBox/SG2042.

Signed-off-by: Chen Wang <unicorn_wang at outlook.com>

----------------------------------------------------------------
Chen Wang (1):
 ????? riscv: sophgo: dts: add power key for pioneer box

Inochi Amaoto (4):
 ????? riscv: dts: sophgo: cv1800b: add pinctrl support
 ????? riscv: dts: sophgo: cv1812h: add pinctrl support
 ????? riscv: dts: sophgo: Add sdio configuration for Huashan Pi
 ????? riscv: dts: sophgo: Add emmc support for Huashan Pi

Thomas Bonnefille (4):
 ????? riscv: dts: sophgo: Add initial SG2002 SoC device tree
 ????? riscv: dts: sophgo: Add LicheeRV Nano board device tree
 ????? riscv: dts: sophgo: Add SARADC description for Sophgo CV1800B
 ????? riscv: dts: sophgo: fix pinctrl base-address

 ?arch/riscv/boot/dts/sophgo/Makefile?????????????????? |? 1 +
 ?arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts????? | 49 
+++++++++++++++++++++++++++++++++++++++++++++++++
 ?arch/riscv/boot/dts/sophgo/cv1800b.dtsi?????????????? | 10 ++++++++++
 ?arch/riscv/boot/dts/sophgo/cv1812h-huashan-pi.dts???? | 23 
+++++++++++++++++++++++
 ?arch/riscv/boot/dts/sophgo/cv1812h.dtsi?????????????? | 11 +++++++++++
 ?arch/riscv/boot/dts/sophgo/cv181x.dtsi??????????????? | 21 
+++++++++++++++++++++
 ?arch/riscv/boot/dts/sophgo/cv18xx.dtsi??????????????? | 32 
++++++++++++++++++++++++++++++++
 ?arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts | 95 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ?arch/riscv/boot/dts/sophgo/sg2002.dtsi??????????????? | 43 
+++++++++++++++++++++++++++++++++++++++++++
 ?arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts?? | 15 +++++++++++++++
 ?10 files changed, 300 insertions(+)
 ?create mode 100644 arch/riscv/boot/dts/sophgo/cv181x.dtsi
 ?create mode 100644 arch/riscv/boot/dts/sophgo/sg2002-licheerv-nano-b.dts
 ?create mode 100644 arch/riscv/boot/dts/sophgo/sg2002.dtsi





From patchwork-bot+netdevbpf at kernel.org  Tue Nov  5 18:00:30 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 06 Nov 2024 02:00:30 +0000
Subject: [PATCH net-next v7 0/2] Add the dwmac driver support for T-HEAD
 TH1520 SoC
In-Reply-To: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>
References: <20241103-th1520-gmac-v7-0-ef094a30169c@tenstorrent.com>
Message-ID: <173085843050.764350.5609116722213276708.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Sun, 03 Nov 2024 08:57:58 -0800 you wrote:
> This series adds support for dwmac gigabit ethernet in the T-Head TH1520
> RISC-V SoC used on boards like BeagleV Ahead and the LicheePi 4A.
> 
> The gigabit ethernet on these boards does need pinctrl support to mux
> the necessary pads. The pinctrl-th1520 driver, pinctrl binding, and
> related dts patches are in linux-next. However, they are not yet in
> net-next/main.
> 
> [...]

Here is the summary with links:
  - [net-next,v7,1/2] dt-bindings: net: Add T-HEAD dwmac support
    https://git.kernel.org/netdev/net-next/c/f920ce04c399
  - [net-next,v7,2/2] net: stmmac: Add glue layer for T-HEAD TH1520 SoC
    https://git.kernel.org/netdev/net-next/c/33a1a01e3afa

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From sashal at kernel.org  Tue Nov  5 18:07:30 2024
From: sashal at kernel.org (Sasha Levin)
Date: Tue,  5 Nov 2024 21:07:30 -0500
Subject: FAILED: Patch "riscv: Do not use fortify in early code" failed to apply to v6.11-stable tree
Message-ID: <20241106020731.164192-1-sashal@kernel.org>

The patch below does not apply to the v6.11-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable at vger.kernel.org>.

Thanks,
Sasha

------------------ original commit in Linus's tree ------------------

>From afedc3126e11ff1404b32e538657b68022e933ca Mon Sep 17 00:00:00 2001
From: Alexandre Ghiti <alexghiti at rivosinc.com>
Date: Wed, 9 Oct 2024 09:27:49 +0200
Subject: [PATCH] riscv: Do not use fortify in early code

Early code designates the code executed when the MMU is not yet enabled,
and this comes with some limitations (see
Documentation/arch/riscv/boot.rst, section "Pre-MMU execution").

FORTIFY_SOURCE must be disabled then since it can trigger kernel panics
as reported in [1].

Reported-by: Jason Montleon <jmontleo at redhat.com>
Closes: https://lore.kernel.org/linux-riscv/CAJD_bPJes4QhmXY5f63GHV9B9HFkSCoaZjk-qCT2NGS7Q9HODg at mail.gmail.com/ [1]
Fixes: a35707c3d850 ("riscv: add memory-type errata for T-Head")
Fixes: 26e7aacb83df ("riscv: Allow to downgrade paging mode from the command line")
Cc: stable at vger.kernel.org
Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Link: https://lore.kernel.org/r/20241009072749.45006-1-alexghiti at rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>
---
 arch/riscv/errata/Makefile    | 6 ++++++
 arch/riscv/kernel/Makefile    | 5 +++++
 arch/riscv/kernel/pi/Makefile | 6 +++++-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
index 8a27394851233..f0da9d7b39c37 100644
--- a/arch/riscv/errata/Makefile
+++ b/arch/riscv/errata/Makefile
@@ -2,6 +2,12 @@ ifdef CONFIG_RELOCATABLE
 KBUILD_CFLAGS += -fno-pie
 endif
 
+ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
+ifdef CONFIG_FORTIFY_SOURCE
+KBUILD_CFLAGS += -D__NO_FORTIFY
+endif
+endif
+
 obj-$(CONFIG_ERRATA_ANDES) += andes/
 obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
 obj-$(CONFIG_ERRATA_THEAD) += thead/
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 7f88cc4931f5c..69dc8aaab3fb3 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -36,6 +36,11 @@ KASAN_SANITIZE_alternative.o := n
 KASAN_SANITIZE_cpufeature.o := n
 KASAN_SANITIZE_sbi_ecall.o := n
 endif
+ifdef CONFIG_FORTIFY_SOURCE
+CFLAGS_alternative.o += -D__NO_FORTIFY
+CFLAGS_cpufeature.o += -D__NO_FORTIFY
+CFLAGS_sbi_ecall.o += -D__NO_FORTIFY
+endif
 endif
 
 extra-y += vmlinux.lds
diff --git a/arch/riscv/kernel/pi/Makefile b/arch/riscv/kernel/pi/Makefile
index d5bf1bc7de62e..81d69d45c06c3 100644
--- a/arch/riscv/kernel/pi/Makefile
+++ b/arch/riscv/kernel/pi/Makefile
@@ -16,8 +16,12 @@ KBUILD_CFLAGS	:= $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
 KBUILD_CFLAGS	+= -mcmodel=medany
 
 CFLAGS_cmdline_early.o += -D__NO_FORTIFY
-CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
 CFLAGS_fdt_early.o += -D__NO_FORTIFY
+# lib/string.c already defines __NO_FORTIFY
+CFLAGS_ctype.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
+CFLAGS_archrandom_early.o += -D__NO_FORTIFY
 
 $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
 			       --remove-section=.note.gnu.property \
-- 
2.43.0






From sashal at kernel.org  Tue Nov  5 18:08:35 2024
From: sashal at kernel.org (Sasha Levin)
Date: Tue,  5 Nov 2024 21:08:35 -0500
Subject: FAILED: Patch "riscv: Do not use fortify in early code" failed to apply to v6.11-stable tree
Message-ID: <20241106020836.164319-1-sashal@kernel.org>

The patch below does not apply to the v6.11-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable at vger.kernel.org>.

Thanks,
Sasha

------------------ original commit in Linus's tree ------------------

>From afedc3126e11ff1404b32e538657b68022e933ca Mon Sep 17 00:00:00 2001
From: Alexandre Ghiti <alexghiti at rivosinc.com>
Date: Wed, 9 Oct 2024 09:27:49 +0200
Subject: [PATCH] riscv: Do not use fortify in early code

Early code designates the code executed when the MMU is not yet enabled,
and this comes with some limitations (see
Documentation/arch/riscv/boot.rst, section "Pre-MMU execution").

FORTIFY_SOURCE must be disabled then since it can trigger kernel panics
as reported in [1].

Reported-by: Jason Montleon <jmontleo at redhat.com>
Closes: https://lore.kernel.org/linux-riscv/CAJD_bPJes4QhmXY5f63GHV9B9HFkSCoaZjk-qCT2NGS7Q9HODg at mail.gmail.com/ [1]
Fixes: a35707c3d850 ("riscv: add memory-type errata for T-Head")
Fixes: 26e7aacb83df ("riscv: Allow to downgrade paging mode from the command line")
Cc: stable at vger.kernel.org
Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Link: https://lore.kernel.org/r/20241009072749.45006-1-alexghiti at rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>
---
 arch/riscv/errata/Makefile    | 6 ++++++
 arch/riscv/kernel/Makefile    | 5 +++++
 arch/riscv/kernel/pi/Makefile | 6 +++++-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
index 8a27394851233..f0da9d7b39c37 100644
--- a/arch/riscv/errata/Makefile
+++ b/arch/riscv/errata/Makefile
@@ -2,6 +2,12 @@ ifdef CONFIG_RELOCATABLE
 KBUILD_CFLAGS += -fno-pie
 endif
 
+ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
+ifdef CONFIG_FORTIFY_SOURCE
+KBUILD_CFLAGS += -D__NO_FORTIFY
+endif
+endif
+
 obj-$(CONFIG_ERRATA_ANDES) += andes/
 obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
 obj-$(CONFIG_ERRATA_THEAD) += thead/
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 7f88cc4931f5c..69dc8aaab3fb3 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -36,6 +36,11 @@ KASAN_SANITIZE_alternative.o := n
 KASAN_SANITIZE_cpufeature.o := n
 KASAN_SANITIZE_sbi_ecall.o := n
 endif
+ifdef CONFIG_FORTIFY_SOURCE
+CFLAGS_alternative.o += -D__NO_FORTIFY
+CFLAGS_cpufeature.o += -D__NO_FORTIFY
+CFLAGS_sbi_ecall.o += -D__NO_FORTIFY
+endif
 endif
 
 extra-y += vmlinux.lds
diff --git a/arch/riscv/kernel/pi/Makefile b/arch/riscv/kernel/pi/Makefile
index d5bf1bc7de62e..81d69d45c06c3 100644
--- a/arch/riscv/kernel/pi/Makefile
+++ b/arch/riscv/kernel/pi/Makefile
@@ -16,8 +16,12 @@ KBUILD_CFLAGS	:= $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
 KBUILD_CFLAGS	+= -mcmodel=medany
 
 CFLAGS_cmdline_early.o += -D__NO_FORTIFY
-CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
 CFLAGS_fdt_early.o += -D__NO_FORTIFY
+# lib/string.c already defines __NO_FORTIFY
+CFLAGS_ctype.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
+CFLAGS_archrandom_early.o += -D__NO_FORTIFY
 
 $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
 			       --remove-section=.note.gnu.property \
-- 
2.43.0






From sashal at kernel.org  Tue Nov  5 18:08:39 2024
From: sashal at kernel.org (Sasha Levin)
Date: Tue,  5 Nov 2024 21:08:39 -0500
Subject: FAILED: Patch "RISC-V: disallow gcc + rust builds" failed to apply to v6.11-stable tree
Message-ID: <20241106020840.164364-1-sashal@kernel.org>

The patch below does not apply to the v6.11-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable at vger.kernel.org>.

Thanks,
Sasha

------------------ original commit in Linus's tree ------------------

>From 33549fcf37ec461f398f0a41e1c9948be2e5aca4 Mon Sep 17 00:00:00 2001
From: Conor Dooley <conor.dooley at microchip.com>
Date: Tue, 1 Oct 2024 12:28:13 +0100
Subject: [PATCH] RISC-V: disallow gcc + rust builds

During the discussion before supporting rust on riscv, it was decided
not to support gcc yet, due to differences in extension handling
compared to llvm (only the version of libclang matching the c compiler
is supported). Recently Jason Montleon reported [1] that building with
gcc caused build issues, due to unsupported arguments being passed to
libclang. After some discussion between myself and Miguel, it is better
to disable gcc + rust builds to match the original intent, and
subsequently support it when an appropriate set of extensions can be
deduced from the version of libclang.

Closes: https://lore.kernel.org/all/20240917000848.720765-2-jmontleo at redhat.com/ [1]
Link: https://lore.kernel.org/all/20240926-battering-revolt-6c6a7827413e at spud/ [2]
Fixes: 70a57b247251a ("RISC-V: enable building 64-bit kernels with rust support")
Cc: stable at vger.kernel.org
Reported-by: Jason Montleon <jmontleo at redhat.com>
Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
Acked-by: Miguel Ojeda <ojeda at kernel.org>
Reviewed-by: Nathan Chancellor <nathan at kernel.org>
Link: https://lore.kernel.org/r/20241001-playlist-deceiving-16ece2f440f5 at spud
Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>
---
 Documentation/rust/arch-support.rst | 2 +-
 arch/riscv/Kconfig                  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index 750ff371570a0..54be7ddf3e57a 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -17,7 +17,7 @@ Architecture   Level of support  Constraints
 =============  ================  ==============================================
 ``arm64``      Maintained        Little Endian only.
 ``loongarch``  Maintained        \-
-``riscv``      Maintained        ``riscv64`` only.
+``riscv``      Maintained        ``riscv64`` and LLVM/Clang only.
 ``um``         Maintained        \-
 ``x86``        Maintained        ``x86_64`` only.
 =============  ================  ==============================================
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 62545946ecf43..f4c570538d55b 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -177,7 +177,7 @@ config RISCV
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RETHOOK if !XIP_KERNEL
 	select HAVE_RSEQ
-	select HAVE_RUST if RUSTC_SUPPORTS_RISCV
+	select HAVE_RUST if RUSTC_SUPPORTS_RISCV && CC_IS_CLANG
 	select HAVE_SAMPLE_FTRACE_DIRECT
 	select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
 	select HAVE_STACKPROTECTOR
-- 
2.43.0






From sashal at kernel.org  Tue Nov  5 18:09:04 2024
From: sashal at kernel.org (Sasha Levin)
Date: Tue,  5 Nov 2024 21:09:04 -0500
Subject: FAILED: Patch "riscv: Do not use fortify in early code" failed to apply to v6.6-stable tree
Message-ID: <20241106020905.164658-1-sashal@kernel.org>

The patch below does not apply to the v6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable at vger.kernel.org>.

Thanks,
Sasha

------------------ original commit in Linus's tree ------------------

>From afedc3126e11ff1404b32e538657b68022e933ca Mon Sep 17 00:00:00 2001
From: Alexandre Ghiti <alexghiti at rivosinc.com>
Date: Wed, 9 Oct 2024 09:27:49 +0200
Subject: [PATCH] riscv: Do not use fortify in early code

Early code designates the code executed when the MMU is not yet enabled,
and this comes with some limitations (see
Documentation/arch/riscv/boot.rst, section "Pre-MMU execution").

FORTIFY_SOURCE must be disabled then since it can trigger kernel panics
as reported in [1].

Reported-by: Jason Montleon <jmontleo at redhat.com>
Closes: https://lore.kernel.org/linux-riscv/CAJD_bPJes4QhmXY5f63GHV9B9HFkSCoaZjk-qCT2NGS7Q9HODg at mail.gmail.com/ [1]
Fixes: a35707c3d850 ("riscv: add memory-type errata for T-Head")
Fixes: 26e7aacb83df ("riscv: Allow to downgrade paging mode from the command line")
Cc: stable at vger.kernel.org
Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Link: https://lore.kernel.org/r/20241009072749.45006-1-alexghiti at rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>
---
 arch/riscv/errata/Makefile    | 6 ++++++
 arch/riscv/kernel/Makefile    | 5 +++++
 arch/riscv/kernel/pi/Makefile | 6 +++++-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
index 8a27394851233..f0da9d7b39c37 100644
--- a/arch/riscv/errata/Makefile
+++ b/arch/riscv/errata/Makefile
@@ -2,6 +2,12 @@ ifdef CONFIG_RELOCATABLE
 KBUILD_CFLAGS += -fno-pie
 endif
 
+ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
+ifdef CONFIG_FORTIFY_SOURCE
+KBUILD_CFLAGS += -D__NO_FORTIFY
+endif
+endif
+
 obj-$(CONFIG_ERRATA_ANDES) += andes/
 obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
 obj-$(CONFIG_ERRATA_THEAD) += thead/
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 7f88cc4931f5c..69dc8aaab3fb3 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -36,6 +36,11 @@ KASAN_SANITIZE_alternative.o := n
 KASAN_SANITIZE_cpufeature.o := n
 KASAN_SANITIZE_sbi_ecall.o := n
 endif
+ifdef CONFIG_FORTIFY_SOURCE
+CFLAGS_alternative.o += -D__NO_FORTIFY
+CFLAGS_cpufeature.o += -D__NO_FORTIFY
+CFLAGS_sbi_ecall.o += -D__NO_FORTIFY
+endif
 endif
 
 extra-y += vmlinux.lds
diff --git a/arch/riscv/kernel/pi/Makefile b/arch/riscv/kernel/pi/Makefile
index d5bf1bc7de62e..81d69d45c06c3 100644
--- a/arch/riscv/kernel/pi/Makefile
+++ b/arch/riscv/kernel/pi/Makefile
@@ -16,8 +16,12 @@ KBUILD_CFLAGS	:= $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
 KBUILD_CFLAGS	+= -mcmodel=medany
 
 CFLAGS_cmdline_early.o += -D__NO_FORTIFY
-CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
 CFLAGS_fdt_early.o += -D__NO_FORTIFY
+# lib/string.c already defines __NO_FORTIFY
+CFLAGS_ctype.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
+CFLAGS_archrandom_early.o += -D__NO_FORTIFY
 
 $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
 			       --remove-section=.note.gnu.property \
-- 
2.43.0






From sashal at kernel.org  Tue Nov  5 18:10:21 2024
From: sashal at kernel.org (Sasha Levin)
Date: Tue,  5 Nov 2024 21:10:21 -0500
Subject: FAILED: Patch "riscv: Do not use fortify in early code" failed to apply to v6.1-stable tree
Message-ID: <20241106021021.180341-1-sashal@kernel.org>

The patch below does not apply to the v6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable at vger.kernel.org>.

Thanks,
Sasha

------------------ original commit in Linus's tree ------------------

>From afedc3126e11ff1404b32e538657b68022e933ca Mon Sep 17 00:00:00 2001
From: Alexandre Ghiti <alexghiti at rivosinc.com>
Date: Wed, 9 Oct 2024 09:27:49 +0200
Subject: [PATCH] riscv: Do not use fortify in early code

Early code designates the code executed when the MMU is not yet enabled,
and this comes with some limitations (see
Documentation/arch/riscv/boot.rst, section "Pre-MMU execution").

FORTIFY_SOURCE must be disabled then since it can trigger kernel panics
as reported in [1].

Reported-by: Jason Montleon <jmontleo at redhat.com>
Closes: https://lore.kernel.org/linux-riscv/CAJD_bPJes4QhmXY5f63GHV9B9HFkSCoaZjk-qCT2NGS7Q9HODg at mail.gmail.com/ [1]
Fixes: a35707c3d850 ("riscv: add memory-type errata for T-Head")
Fixes: 26e7aacb83df ("riscv: Allow to downgrade paging mode from the command line")
Cc: stable at vger.kernel.org
Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Link: https://lore.kernel.org/r/20241009072749.45006-1-alexghiti at rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>
---
 arch/riscv/errata/Makefile    | 6 ++++++
 arch/riscv/kernel/Makefile    | 5 +++++
 arch/riscv/kernel/pi/Makefile | 6 +++++-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
index 8a27394851233..f0da9d7b39c37 100644
--- a/arch/riscv/errata/Makefile
+++ b/arch/riscv/errata/Makefile
@@ -2,6 +2,12 @@ ifdef CONFIG_RELOCATABLE
 KBUILD_CFLAGS += -fno-pie
 endif
 
+ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
+ifdef CONFIG_FORTIFY_SOURCE
+KBUILD_CFLAGS += -D__NO_FORTIFY
+endif
+endif
+
 obj-$(CONFIG_ERRATA_ANDES) += andes/
 obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
 obj-$(CONFIG_ERRATA_THEAD) += thead/
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 7f88cc4931f5c..69dc8aaab3fb3 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -36,6 +36,11 @@ KASAN_SANITIZE_alternative.o := n
 KASAN_SANITIZE_cpufeature.o := n
 KASAN_SANITIZE_sbi_ecall.o := n
 endif
+ifdef CONFIG_FORTIFY_SOURCE
+CFLAGS_alternative.o += -D__NO_FORTIFY
+CFLAGS_cpufeature.o += -D__NO_FORTIFY
+CFLAGS_sbi_ecall.o += -D__NO_FORTIFY
+endif
 endif
 
 extra-y += vmlinux.lds
diff --git a/arch/riscv/kernel/pi/Makefile b/arch/riscv/kernel/pi/Makefile
index d5bf1bc7de62e..81d69d45c06c3 100644
--- a/arch/riscv/kernel/pi/Makefile
+++ b/arch/riscv/kernel/pi/Makefile
@@ -16,8 +16,12 @@ KBUILD_CFLAGS	:= $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
 KBUILD_CFLAGS	+= -mcmodel=medany
 
 CFLAGS_cmdline_early.o += -D__NO_FORTIFY
-CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
 CFLAGS_fdt_early.o += -D__NO_FORTIFY
+# lib/string.c already defines __NO_FORTIFY
+CFLAGS_ctype.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt.o += -D__NO_FORTIFY
+CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY
+CFLAGS_archrandom_early.o += -D__NO_FORTIFY
 
 $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
 			       --remove-section=.note.gnu.property \
-- 
2.43.0






From sashal at kernel.org  Tue Nov  5 18:13:23 2024
From: sashal at kernel.org (Sasha Levin)
Date: Tue,  5 Nov 2024 21:13:23 -0500
Subject: FAILED: Patch "riscv: vdso: Prevent the compiler from inserting calls to memset()" failed to apply to v5.4-stable tree
Message-ID: <20241106021323.183560-1-sashal@kernel.org>

The patch below does not apply to the v5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable at vger.kernel.org>.

Thanks,
Sasha

------------------ original commit in Linus's tree ------------------

>From bf40167d54d55d4b54d0103713d86a8638fb9290 Mon Sep 17 00:00:00 2001
From: Alexandre Ghiti <alexghiti at rivosinc.com>
Date: Wed, 16 Oct 2024 10:36:24 +0200
Subject: [PATCH] riscv: vdso: Prevent the compiler from inserting calls to
 memset()

The compiler is smart enough to insert a call to memset() in
riscv_vdso_get_cpus(), which generates a dynamic relocation.

So prevent this by using -fno-builtin option.

Fixes: e2c0cdfba7f6 ("RISC-V: User-facing API")
Cc: stable at vger.kernel.org
Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Guo Ren <guoren at kernel.org>
Link: https://lore.kernel.org/r/20241016083625.136311-2-alexghiti at rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>
---
 arch/riscv/kernel/vdso/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
index 960feb1526caa..3f1c4b2d0b064 100644
--- a/arch/riscv/kernel/vdso/Makefile
+++ b/arch/riscv/kernel/vdso/Makefile
@@ -18,6 +18,7 @@ obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
 
 ccflags-y := -fno-stack-protector
 ccflags-y += -DDISABLE_BRANCH_PROFILING
+ccflags-y += -fno-builtin
 
 ifneq ($(c-gettimeofday-y),)
   CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
-- 
2.43.0






From sashal at kernel.org  Tue Nov  5 18:14:12 2024
From: sashal at kernel.org (Sasha Levin)
Date: Tue,  5 Nov 2024 21:14:12 -0500
Subject: FAILED: Patch "riscv: vdso: Prevent the compiler from inserting calls to memset()" failed to apply to v4.19-stable tree
Message-ID: <20241106021412.184114-1-sashal@kernel.org>

The patch below does not apply to the v4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable at vger.kernel.org>.

Thanks,
Sasha

------------------ original commit in Linus's tree ------------------

>From bf40167d54d55d4b54d0103713d86a8638fb9290 Mon Sep 17 00:00:00 2001
From: Alexandre Ghiti <alexghiti at rivosinc.com>
Date: Wed, 16 Oct 2024 10:36:24 +0200
Subject: [PATCH] riscv: vdso: Prevent the compiler from inserting calls to
 memset()

The compiler is smart enough to insert a call to memset() in
riscv_vdso_get_cpus(), which generates a dynamic relocation.

So prevent this by using -fno-builtin option.

Fixes: e2c0cdfba7f6 ("RISC-V: User-facing API")
Cc: stable at vger.kernel.org
Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Guo Ren <guoren at kernel.org>
Link: https://lore.kernel.org/r/20241016083625.136311-2-alexghiti at rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>
---
 arch/riscv/kernel/vdso/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
index 960feb1526caa..3f1c4b2d0b064 100644
--- a/arch/riscv/kernel/vdso/Makefile
+++ b/arch/riscv/kernel/vdso/Makefile
@@ -18,6 +18,7 @@ obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
 
 ccflags-y := -fno-stack-protector
 ccflags-y += -DDISABLE_BRANCH_PROFILING
+ccflags-y += -fno-builtin
 
 ifneq ($(c-gettimeofday-y),)
   CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
-- 
2.43.0






From ruanjinjie at huawei.com  Tue Nov  5 18:34:00 2024
From: ruanjinjie at huawei.com (Jinjie Ruan)
Date: Wed, 6 Nov 2024 10:34:00 +0800
Subject: [RESEND PATCH V4 2/3] riscv: mm: Add soft-dirty page tracking
 support
In-Reply-To: <d1a84096-9722-47f1-ad8e-671144a3d109@ghiti.fr>
References: <20240830011101.3189522-1-zhangchunyan@iscas.ac.cn>
 <20240830011101.3189522-3-zhangchunyan@iscas.ac.cn>
 <c4fbc62f-e398-1229-c1b1-7bab30e4460e@huawei.com>
 <CAAfSe-vDtJKeSeUgpeJM0ZQe4XKdKz_Rgz2TQkPb4giPBLsOdw@mail.gmail.com>
 <d1a84096-9722-47f1-ad8e-671144a3d109@ghiti.fr>
Message-ID: <473f5db8-3fb6-6160-fb4b-4561befe56c0@huawei.com>



On 2024/11/5 21:14, Alexandre Ghiti wrote:
> On 30/08/2024 04:31, Chunyan Zhang wrote:
>> Hi Jinjie,
>>
>> On Fri, 30 Aug 2024 at 09:31, Jinjie Ruan <ruanjinjie at huawei.com> wrote:
>>>
>>>
>>> On 2024/8/30 9:11, Chunyan Zhang wrote:
>>>> The PTE bit(9) is reserved for software, now used by DEVMAP,
>>>> this patch reuse bit(9) for soft-dirty which is enabled only
>>>> if !CONFIG_ARCH_HAS_PTE_DEVMAP, in other words, soft-dirty
>>>> and devmap will be mutually exclusive on RISC-V.
>>>>
>>>> To add swap PTE soft-dirty tracking, we borrow bit (4) which is
>>>> available for swap PTEs on RISC-V systems.
>>>>
>>>> Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
>>>> ---
>>>> ? arch/riscv/Kconfig??????????????????? | 27 ++++++++++-
>>>> ? arch/riscv/include/asm/pgtable-bits.h | 12 +++++
>>>> ? arch/riscv/include/asm/pgtable.h????? | 69
>>>> ++++++++++++++++++++++++++-
>>>> ? 3 files changed, 106 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
>>>> index 0f3cd7c3a436..f1460fc01cd4 100644
>>>> --- a/arch/riscv/Kconfig
>>>> +++ b/arch/riscv/Kconfig
>>>> @@ -39,7 +39,6 @@ config RISCV
>>>> ?????? select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
>>>> ?????? select ARCH_HAS_PMEM_API
>>>> ?????? select ARCH_HAS_PREPARE_SYNC_CORE_CMD
>>>> -???? select ARCH_HAS_PTE_DEVMAP if 64BIT && MMU
>>>> ?????? select ARCH_HAS_PTE_SPECIAL
>>>> ?????? select ARCH_HAS_SET_DIRECT_MAP if MMU
>>>> ?????? select ARCH_HAS_SET_MEMORY if MMU
>>>> @@ -948,6 +947,32 @@ config RANDOMIZE_BASE
>>>>
>>>> ??????????? If unsure, say N.
>>>>
>>>> +choice
>>>> +???? prompt "PET RSW Bit(9) used for"
>>>> +???? default RISCV_HAS_PTE_DEVMEP
>>>> +???? depends on MMU && 64BIT
>>>> +???? help
>>>> +?????? RISC-V PTE bit(9) is reserved for software, and used by more
>>>> than
>>>> +?????? one kernel features which cannot be supported at the same time.
>>>> +?????? So we have to select one for it.
>>>> +
>>>> +config RISCV_HAS_PTE_DEVMEP
>>>> +???? bool "DEVMAP mark"
>>>> +???? select ARCH_HAS_PTE_DEVMAP
>>>> +???? help
>>>> +?????? The PTE bit(9) is used for DEVMAP mark. ZONE_DEVICE pages
>>>> need DEVMAP
>>>> +?????? PTEs support to function.
>>>> +
>>>> +?????? So if you want to use ZONE_DEVICE, select this.
>>>> +
>>>> +config RISCV_HAS_SOFT_DIRTY
>>>> +???? bool "soft dirty"
>>>> +???? select HAVE_ARCH_SOFT_DIRTY
>>>> +???? help
>>>> +?????? The PTE bit(9) is used for soft-dirty tracking.
>>>> +
>>>> +endchoice
>>>> +
>>> Hi, ARCH_HAS_PTE_DEVMAP will be removed in following patch, I guess
>>> riscv will too:
>>>
>>> https://lore.kernel.org/all/47c26640cd85f3db2e0a2796047199bb984d1b3f.1719386613.git-series.apopple at nvidia.com/
>> Thanks for sharing, I didn't notice this.
>> It looks like we should remove PTE_DEVMAP first and then add soft
>> dirty and uffd_wp.
> 
> 
> I have not seen any progress in the removal of PTE_DEVMAP so I'd say we
> should keep going with your patchset and we can still remove devmap later.

Sure, it is time to keep going on.

I started by implementing a patch similar to multiplexing bit 9, but
considering the above remove PTE_DEVMAP patch, so just gave it up.

> 
> Thanks,
> 
> Alex
> 
> 
>>
>> Thanks,
>> Chunyan
>>
>>>> ? endmenu # "Kernel features"
>>>>
>>>> ? menu "Boot options"
>>>> diff --git a/arch/riscv/include/asm/pgtable-bits.h
>>>> b/arch/riscv/include/asm/pgtable-bits.h
>>>> index 5bcc73430829..c6d51fe9fc6f 100644
>>>> --- a/arch/riscv/include/asm/pgtable-bits.h
>>>> +++ b/arch/riscv/include/asm/pgtable-bits.h
>>>> @@ -26,6 +26,18 @@
>>>> ? #define _PAGE_DEVMAP 0
>>>> ? #endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
>>>>
>>>> +#ifdef CONFIG_MEM_SOFT_DIRTY
>>>> +#define _PAGE_SOFT_DIRTY???? (1 << 9)??? /* RSW: 0x2 for software
>>>> dirty tracking */
>>>> +/*
>>>> + * BIT 4 is not involved into swap entry computation, so we
>>>> + * can borrow it for swap page soft-dirty tracking.
>>>> + */
>>>> +#define _PAGE_SWP_SOFT_DIRTY _PAGE_USER
>>>> +#else
>>>> +#define _PAGE_SOFT_DIRTY???? 0
>>>> +#define _PAGE_SWP_SOFT_DIRTY 0
>>>> +#endif /* CONFIG_MEM_SOFT_DIRTY */
>>>> +
>>>> ? #define _PAGE_TABLE???? _PAGE_PRESENT
>>>>
>>>> ? /*
>>>> diff --git a/arch/riscv/include/asm/pgtable.h
>>>> b/arch/riscv/include/asm/pgtable.h
>>>> index 089f3c9f56a3..d41507919ef2 100644
>>>> --- a/arch/riscv/include/asm/pgtable.h
>>>> +++ b/arch/riscv/include/asm/pgtable.h
>>>> @@ -428,7 +428,7 @@ static inline pte_t pte_mkwrite_novma(pte_t pte)
>>>>
>>>> ? static inline pte_t pte_mkdirty(pte_t pte)
>>>> ? {
>>>> -???? return __pte(pte_val(pte) | _PAGE_DIRTY);
>>>> +???? return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
>>>> ? }
>>>>
>>>> ? static inline pte_t pte_mkclean(pte_t pte)
>>>> @@ -461,6 +461,38 @@ static inline pte_t pte_mkhuge(pte_t pte)
>>>> ?????? return pte;
>>>> ? }
>>>>
>>>> +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
>>>> +static inline int pte_soft_dirty(pte_t pte)
>>>> +{
>>>> +???? return pte_val(pte) & _PAGE_SOFT_DIRTY;
>>>> +}
>>>> +
>>>> +static inline pte_t pte_mksoft_dirty(pte_t pte)
>>>> +{
>>>> +???? return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY);
>>>> +}
>>>> +
>>>> +static inline pte_t pte_clear_soft_dirty(pte_t pte)
>>>> +{
>>>> +???? return __pte(pte_val(pte) & ~(_PAGE_SOFT_DIRTY));
>>>> +}
>>>> +
>>>> +static inline int pte_swp_soft_dirty(pte_t pte)
>>>> +{
>>>> +???? return pte_val(pte) & _PAGE_SWP_SOFT_DIRTY;
>>>> +}
>>>> +
>>>> +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
>>>> +{
>>>> +???? return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY);
>>>> +}
>>>> +
>>>> +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
>>>> +{
>>>> +???? return __pte(pte_val(pte) & ~(_PAGE_SWP_SOFT_DIRTY));
>>>> +}
>>>> +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
>>>> +
>>>> ? #ifdef CONFIG_RISCV_ISA_SVNAPOT
>>>> ? #define pte_leaf_size(pte)?? (pte_napot(pte)
>>>> ??????????????????????????????? \
>>>> ??????????????????????????????????????
>>>> napot_cont_size(napot_cont_order(pte)) :\
>>>> @@ -751,6 +783,40 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
>>>> ?????? return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
>>>> ? }
>>>>
>>>> +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
>>>> +static inline int pmd_soft_dirty(pmd_t pmd)
>>>> +{
>>>> +???? return pte_soft_dirty(pmd_pte(pmd));
>>>> +}
>>>> +
>>>> +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
>>>> +{
>>>> +???? return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
>>>> +}
>>>> +
>>>> +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
>>>> +{
>>>> +???? return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
>>>> +}
>>>> +
>>>> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
>>>> +static inline int pmd_swp_soft_dirty(pmd_t pmd)
>>>> +{
>>>> +???? return pte_swp_soft_dirty(pmd_pte(pmd));
>>>> +}
>>>> +
>>>> +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
>>>> +{
>>>> +???? return pte_pmd(pte_swp_mksoft_dirty(pmd_pte(pmd)));
>>>> +}
>>>> +
>>>> +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
>>>> +{
>>>> +???? return pte_pmd(pte_swp_clear_soft_dirty(pmd_pte(pmd)));
>>>> +}
>>>> +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
>>>> +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
>>>> +
>>>> ? static inline void set_pmd_at(struct mm_struct *mm, unsigned long
>>>> addr,
>>>> ?????????????????????????????? pmd_t *pmdp, pmd_t pmd)
>>>> ? {
>>>> @@ -841,6 +907,7 @@ extern pmd_t pmdp_collapse_flush(struct
>>>> vm_area_struct *vma,
>>>> ?? * Format of swap PTE:
>>>> ?? *?? bit??????????? 0:?????? _PAGE_PRESENT (zero)
>>>> ?? *?? bit?????? 1 to 3:?????? _PAGE_LEAF (zero)
>>>> + *?? bit??????????? 4:?????? _PAGE_SWP_SOFT_DIRTY
>>>> ?? *?? bit??????????? 5:?????? _PAGE_PROT_NONE (zero)
>>>> ?? *?? bit??????????? 6:?????? exclusive marker
>>>> ?? *?? bits????? 7 to 11:????? swap type
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv


From zhang.lyra at gmail.com  Tue Nov  5 22:32:29 2024
From: zhang.lyra at gmail.com (Chunyan Zhang)
Date: Wed, 6 Nov 2024 14:32:29 +0800
Subject: [RESEND PATCH V4 1/3] riscv: mm: Prepare for reusing PTE RSW bit(9)
In-Reply-To: <bedac8d9-4ba4-427c-9323-edcdbd7876ee@ghiti.fr>
References: <20240830011101.3189522-1-zhangchunyan@iscas.ac.cn>
 <20240830011101.3189522-2-zhangchunyan@iscas.ac.cn> <bedac8d9-4ba4-427c-9323-edcdbd7876ee@ghiti.fr>
Message-ID: <CAAfSe-u9L21e=x6i3oX2qCKSLLQw8p8fyuJwnLTijdHx_A-gnQ@mail.gmail.com>

Hi Alex,

On Tue, 5 Nov 2024 at 20:45, Alexandre Ghiti <alex at ghiti.fr> wrote:
>
> Hi Chunyan,
>
> On 30/08/2024 03:10, Chunyan Zhang wrote:
> > The PTE bit(9) on RISC-V is reserved for software, it is used by DEVMAP
> > now which has to be disabled if we want to use bit(9) for other features,
> > since there's no more free PTE bit on RISC-V now.
> >
> > So to make ARCH_HAS_PTE_DEVMAP selectable, this patch uses it as
> > the build condition of devmap definitions.
> >
> > Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
> > ---
> >   arch/riscv/include/asm/pgtable-64.h   | 2 +-
> >   arch/riscv/include/asm/pgtable-bits.h | 6 ++++++
> >   2 files changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
> > index 0897dd99ab8d..babb8d2b0f0b 100644
> > --- a/arch/riscv/include/asm/pgtable-64.h
> > +++ b/arch/riscv/include/asm/pgtable-64.h
> > @@ -398,7 +398,7 @@ static inline struct page *pgd_page(pgd_t pgd)
> >   #define p4d_offset p4d_offset
> >   p4d_t *p4d_offset(pgd_t *pgd, unsigned long address);
> >
> > -#ifdef CONFIG_TRANSPARENT_HUGEPAGE
> > +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && defined(CONFIG_ARCH_HAS_PTE_DEVMAP)
> >   static inline int pte_devmap(pte_t pte);
> >   static inline pte_t pmd_pte(pmd_t pmd);
> >
> > diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
> > index a8f5205cea54..5bcc73430829 100644
> > --- a/arch/riscv/include/asm/pgtable-bits.h
> > +++ b/arch/riscv/include/asm/pgtable-bits.h
> > @@ -19,7 +19,13 @@
> >   #define _PAGE_SOFT      (3 << 8)    /* Reserved for software */
> >
> >   #define _PAGE_SPECIAL   (1 << 8)    /* RSW: 0x1 */
> > +
> > +#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
> >   #define _PAGE_DEVMAP    (1 << 9)    /* RSW, devmap */
> > +#else
> > +#define _PAGE_DEVMAP 0
> > +#endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
> > +
> >   #define _PAGE_TABLE     _PAGE_PRESENT
> >
> >   /*
>
>
> There is a small inconsistency in our code: pte_devmap() is protected by
> a #ifdef but pte_mkdevmap() is not, I guess that's why you had to define

pte_devmap() is defined in include/linux/mm.h as well, we have to use
#ifdef to avoid compile error since we will change the
CONFIG_ARCH_HAS_PTE_DEVMAP to be selectable on riscv.

> _PAGE_DEVMAP if !CONFIG_ARCH_HAS_PTE_DEVMAP.
>
> I'd be in favor of removing the #ifdef around pte_devmap() too.

So we cannot remove the #ifdef here, the compiler would report
redefinition errors if CONFIG_ARCH_HAS_PTE_DEVMAP is not selected.

Thanks for the review,
Chunyan


From zhang.lyra at gmail.com  Tue Nov  5 22:41:15 2024
From: zhang.lyra at gmail.com (Chunyan Zhang)
Date: Wed, 6 Nov 2024 14:41:15 +0800
Subject: [RESEND PATCH V4 2/3] riscv: mm: Add soft-dirty page tracking support
In-Reply-To: <97898777-8129-4ce9-8ae4-9d4bbc2a5a26@ghiti.fr>
References: <20240830011101.3189522-1-zhangchunyan@iscas.ac.cn>
 <20240830011101.3189522-3-zhangchunyan@iscas.ac.cn> <97898777-8129-4ce9-8ae4-9d4bbc2a5a26@ghiti.fr>
Message-ID: <CAAfSe-tN8OwPfq+7OJ-QZmPKnu6_YO3J+bR5R8HWENMA-n-J9A@mail.gmail.com>

On Tue, 5 Nov 2024 at 21:13, Alexandre Ghiti <alex at ghiti.fr> wrote:
>
> On 30/08/2024 03:11, Chunyan Zhang wrote:
> > The PTE bit(9) is reserved for software, now used by DEVMAP,
> > this patch reuse bit(9) for soft-dirty which is enabled only
>
>
> s/reuse/reuses
>
>
> > if !CONFIG_ARCH_HAS_PTE_DEVMAP, in other words, soft-dirty
> > and devmap will be mutually exclusive on RISC-V.
> >
> > To add swap PTE soft-dirty tracking, we borrow bit (4) which is
> > available for swap PTEs on RISC-V systems.
> >
> > Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
> > ---
> >   arch/riscv/Kconfig                    | 27 ++++++++++-
> >   arch/riscv/include/asm/pgtable-bits.h | 12 +++++
> >   arch/riscv/include/asm/pgtable.h      | 69 ++++++++++++++++++++++++++-
> >   3 files changed, 106 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > index 0f3cd7c3a436..f1460fc01cd4 100644
> > --- a/arch/riscv/Kconfig
> > +++ b/arch/riscv/Kconfig
> > @@ -39,7 +39,6 @@ config RISCV
> >       select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
> >       select ARCH_HAS_PMEM_API
> >       select ARCH_HAS_PREPARE_SYNC_CORE_CMD
> > -     select ARCH_HAS_PTE_DEVMAP if 64BIT && MMU
> >       select ARCH_HAS_PTE_SPECIAL
> >       select ARCH_HAS_SET_DIRECT_MAP if MMU
> >       select ARCH_HAS_SET_MEMORY if MMU
> > @@ -948,6 +947,32 @@ config RANDOMIZE_BASE
> >
> >             If unsure, say N.
> >
> > +choice
> > +     prompt "PET RSW Bit(9) used for"
>
>
> I would say: "PTE RSW bit(9) usage"
>
>
> > +     default RISCV_HAS_PTE_DEVMEP
>
>
> s/DEVMEP/DEVMAP
>
>
> > +     depends on MMU && 64BIT
> > +     help
> > +       RISC-V PTE bit(9) is reserved for software, and used by more than
> > +       one kernel features which cannot be supported at the same time.
>
>
> s/features/feature
>
>
> > +       So we have to select one for it.
> > +
> > +config RISCV_HAS_PTE_DEVMEP
> > +     bool "DEVMAP mark"
>
>
> I would say simply "devmap"

Ok, only "devmap" without the following "mark", right?

>
>
> > +     select ARCH_HAS_PTE_DEVMAP
> > +     help
> > +       The PTE bit(9) is used for DEVMAP mark. ZONE_DEVICE pages need DEVMAP
>
>
> "is used for devmap...pages need devmap"
>
>
> > +       PTEs support to function.
> > +
> > +       So if you want to use ZONE_DEVICE, select this.
> > +
> > +config RISCV_HAS_SOFT_DIRTY
> > +     bool "soft dirty"
>
>
> s/soft dirty/soft-dirty
>
>
> > +     select HAVE_ARCH_SOFT_DIRTY
> > +     help
> > +       The PTE bit(9) is used for soft-dirty tracking.
> > +
> > +endchoice
> > +
> >   endmenu # "Kernel features"
> >
> >   menu "Boot options"
> > diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
> > index 5bcc73430829..c6d51fe9fc6f 100644
> > --- a/arch/riscv/include/asm/pgtable-bits.h
> > +++ b/arch/riscv/include/asm/pgtable-bits.h
> > @@ -26,6 +26,18 @@
> >   #define _PAGE_DEVMAP        0
> >   #endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
> >
> > +#ifdef CONFIG_MEM_SOFT_DIRTY
>
>
> For consistency with CONFIG_ARCH_HAS_PTE_DEVMAP, I would use
> CONFIG_HAVE_ARCH_SOFT_DIRTY

CONFIG_MEM_SOFT_DIRTY is not equal to the CONFIG_HAVE_ARCH_SOFT_DIRTY,
 the latter is one of its dependencies.

If CONFIG_HAVE_ARCH_SOFT_DIRTY  is selected, but CONFIG_MEM_SOFT_DIRTY
is not, the bit(9) should not be set/cleared by pte soft_dirty APIs?

Also considering x86 is using CONFIG_MEM_SOFT_DIRTY here, should we
keep the same?

>
>
> > +#define _PAGE_SOFT_DIRTY     (1 << 9)    /* RSW: 0x2 for software dirty tracking */
> > +/*
> > + * BIT 4 is not involved into swap entry computation, so we
> > + * can borrow it for swap page soft-dirty tracking.
> > + */
> > +#define _PAGE_SWP_SOFT_DIRTY _PAGE_USER
> > +#else
> > +#define _PAGE_SOFT_DIRTY     0
> > +#define _PAGE_SWP_SOFT_DIRTY 0
> > +#endif /* CONFIG_MEM_SOFT_DIRTY */
>
>
> Same here.
>
>
> > +
> >   #define _PAGE_TABLE     _PAGE_PRESENT
> >
> >   /*
> > diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> > index 089f3c9f56a3..d41507919ef2 100644
> > --- a/arch/riscv/include/asm/pgtable.h
> > +++ b/arch/riscv/include/asm/pgtable.h
> > @@ -428,7 +428,7 @@ static inline pte_t pte_mkwrite_novma(pte_t pte)
> >
> >   static inline pte_t pte_mkdirty(pte_t pte)
> >   {
> > -     return __pte(pte_val(pte) | _PAGE_DIRTY);
> > +     return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
> >   }
> >
> >   static inline pte_t pte_mkclean(pte_t pte)
> > @@ -461,6 +461,38 @@ static inline pte_t pte_mkhuge(pte_t pte)
> >       return pte;
> >   }
> >
> > +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
> > +static inline int pte_soft_dirty(pte_t pte)
> > +{
> > +     return pte_val(pte) & _PAGE_SOFT_DIRTY;
> > +}
> > +
> > +static inline pte_t pte_mksoft_dirty(pte_t pte)
> > +{
> > +     return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY);
> > +}
> > +
> > +static inline pte_t pte_clear_soft_dirty(pte_t pte)
> > +{
> > +     return __pte(pte_val(pte) & ~(_PAGE_SOFT_DIRTY));
> > +}
> > +
> > +static inline int pte_swp_soft_dirty(pte_t pte)
> > +{
> > +     return pte_val(pte) & _PAGE_SWP_SOFT_DIRTY;
> > +}
> > +
> > +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
> > +{
> > +     return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY);
> > +}
> > +
> > +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
> > +{
> > +     return __pte(pte_val(pte) & ~(_PAGE_SWP_SOFT_DIRTY));
> > +}
> > +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
> > +
> >   #ifdef CONFIG_RISCV_ISA_SVNAPOT
> >   #define pte_leaf_size(pte)  (pte_napot(pte) ?                               \
> >                                       napot_cont_size(napot_cont_order(pte)) :\
> > @@ -751,6 +783,40 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
> >       return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
> >   }
> >
> > +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
> > +static inline int pmd_soft_dirty(pmd_t pmd)
> > +{
> > +     return pte_soft_dirty(pmd_pte(pmd));
> > +}
> > +
> > +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
> > +{
> > +     return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
> > +}
> > +
> > +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
> > +{
> > +     return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
> > +}
> > +
> > +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> > +static inline int pmd_swp_soft_dirty(pmd_t pmd)
> > +{
> > +     return pte_swp_soft_dirty(pmd_pte(pmd));
> > +}
> > +
> > +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
> > +{
> > +     return pte_pmd(pte_swp_mksoft_dirty(pmd_pte(pmd)));
> > +}
> > +
> > +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
> > +{
> > +     return pte_pmd(pte_swp_clear_soft_dirty(pmd_pte(pmd)));
> > +}
> > +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
> > +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
> > +
> >   static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
> >                               pmd_t *pmdp, pmd_t pmd)
> >   {
> > @@ -841,6 +907,7 @@ extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
> >    * Format of swap PTE:
> >    *  bit            0:       _PAGE_PRESENT (zero)
> >    *  bit       1 to 3:       _PAGE_LEAF (zero)
> > + *   bit            4:       _PAGE_SWP_SOFT_DIRTY
> >    *  bit            5:       _PAGE_PROT_NONE (zero)
> >    *  bit            6:       exclusive marker
> >    *  bits      7 to 11:      swap type
>
>
> Apart from the minor things above, the rest looks good so you can add:
>
> Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks for the review,
Chunyan


From zhang.lyra at gmail.com  Tue Nov  5 22:42:12 2024
From: zhang.lyra at gmail.com (Chunyan Zhang)
Date: Wed, 6 Nov 2024 14:42:12 +0800
Subject: [RESEND PATCH V4 2/3] riscv: mm: Add soft-dirty page tracking support
In-Reply-To: <d1a84096-9722-47f1-ad8e-671144a3d109@ghiti.fr>
References: <20240830011101.3189522-1-zhangchunyan@iscas.ac.cn>
 <20240830011101.3189522-3-zhangchunyan@iscas.ac.cn> <c4fbc62f-e398-1229-c1b1-7bab30e4460e@huawei.com>
 <CAAfSe-vDtJKeSeUgpeJM0ZQe4XKdKz_Rgz2TQkPb4giPBLsOdw@mail.gmail.com> <d1a84096-9722-47f1-ad8e-671144a3d109@ghiti.fr>
Message-ID: <CAAfSe-vidGeJVvqhdNrP7iv+ShYocseQ1PFkfaJ33ZFmjghgVQ@mail.gmail.com>

Hi Alex,

On Tue, 5 Nov 2024 at 21:14, Alexandre Ghiti <alex at ghiti.fr> wrote:
>
> On 30/08/2024 04:31, Chunyan Zhang wrote:
> > Hi Jinjie,
> >
> > On Fri, 30 Aug 2024 at 09:31, Jinjie Ruan <ruanjinjie at huawei.com> wrote:
> >>
> >>
> >> On 2024/8/30 9:11, Chunyan Zhang wrote:
> >>> The PTE bit(9) is reserved for software, now used by DEVMAP,
> >>> this patch reuse bit(9) for soft-dirty which is enabled only
> >>> if !CONFIG_ARCH_HAS_PTE_DEVMAP, in other words, soft-dirty
> >>> and devmap will be mutually exclusive on RISC-V.
> >>>
> >>> To add swap PTE soft-dirty tracking, we borrow bit (4) which is
> >>> available for swap PTEs on RISC-V systems.
> >>>
> >>> Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
> >>> ---
> >>>   arch/riscv/Kconfig                    | 27 ++++++++++-
> >>>   arch/riscv/include/asm/pgtable-bits.h | 12 +++++
> >>>   arch/riscv/include/asm/pgtable.h      | 69 ++++++++++++++++++++++++++-
> >>>   3 files changed, 106 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> >>> index 0f3cd7c3a436..f1460fc01cd4 100644
> >>> --- a/arch/riscv/Kconfig
> >>> +++ b/arch/riscv/Kconfig
> >>> @@ -39,7 +39,6 @@ config RISCV
> >>>        select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
> >>>        select ARCH_HAS_PMEM_API
> >>>        select ARCH_HAS_PREPARE_SYNC_CORE_CMD
> >>> -     select ARCH_HAS_PTE_DEVMAP if 64BIT && MMU
> >>>        select ARCH_HAS_PTE_SPECIAL
> >>>        select ARCH_HAS_SET_DIRECT_MAP if MMU
> >>>        select ARCH_HAS_SET_MEMORY if MMU
> >>> @@ -948,6 +947,32 @@ config RANDOMIZE_BASE
> >>>
> >>>             If unsure, say N.
> >>>
> >>> +choice
> >>> +     prompt "PET RSW Bit(9) used for"
> >>> +     default RISCV_HAS_PTE_DEVMEP
> >>> +     depends on MMU && 64BIT
> >>> +     help
> >>> +       RISC-V PTE bit(9) is reserved for software, and used by more than
> >>> +       one kernel features which cannot be supported at the same time.
> >>> +       So we have to select one for it.
> >>> +
> >>> +config RISCV_HAS_PTE_DEVMEP
> >>> +     bool "DEVMAP mark"
> >>> +     select ARCH_HAS_PTE_DEVMAP
> >>> +     help
> >>> +       The PTE bit(9) is used for DEVMAP mark. ZONE_DEVICE pages need DEVMAP
> >>> +       PTEs support to function.
> >>> +
> >>> +       So if you want to use ZONE_DEVICE, select this.
> >>> +
> >>> +config RISCV_HAS_SOFT_DIRTY
> >>> +     bool "soft dirty"
> >>> +     select HAVE_ARCH_SOFT_DIRTY
> >>> +     help
> >>> +       The PTE bit(9) is used for soft-dirty tracking.
> >>> +
> >>> +endchoice
> >>> +
> >> Hi, ARCH_HAS_PTE_DEVMAP will be removed in following patch, I guess
> >> riscv will too:
> >>
> >> https://lore.kernel.org/all/47c26640cd85f3db2e0a2796047199bb984d1b3f.1719386613.git-series.apopple at nvidia.com/
> > Thanks for sharing, I didn't notice this.
> > It looks like we should remove PTE_DEVMAP first and then add soft
> > dirty and uffd_wp.
>
>
> I have not seen any progress in the removal of PTE_DEVMAP so I'd say we
> should keep going with your patchset and we can still remove devmap later.

Okay, then I will update the patchset with addressing your comments.

Thanks for the review,
Chunyan


>
> Thanks,
>
> Alex
>
>
> >
> > Thanks,
> > Chunyan
> >
> >>>   endmenu # "Kernel features"
> >>>
> >>>   menu "Boot options"
> >>> diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
> >>> index 5bcc73430829..c6d51fe9fc6f 100644
> >>> --- a/arch/riscv/include/asm/pgtable-bits.h
> >>> +++ b/arch/riscv/include/asm/pgtable-bits.h
> >>> @@ -26,6 +26,18 @@
> >>>   #define _PAGE_DEVMAP 0
> >>>   #endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
> >>>
> >>> +#ifdef CONFIG_MEM_SOFT_DIRTY
> >>> +#define _PAGE_SOFT_DIRTY     (1 << 9)    /* RSW: 0x2 for software dirty tracking */
> >>> +/*
> >>> + * BIT 4 is not involved into swap entry computation, so we
> >>> + * can borrow it for swap page soft-dirty tracking.
> >>> + */
> >>> +#define _PAGE_SWP_SOFT_DIRTY _PAGE_USER
> >>> +#else
> >>> +#define _PAGE_SOFT_DIRTY     0
> >>> +#define _PAGE_SWP_SOFT_DIRTY 0
> >>> +#endif /* CONFIG_MEM_SOFT_DIRTY */
> >>> +
> >>>   #define _PAGE_TABLE     _PAGE_PRESENT
> >>>
> >>>   /*
> >>> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> >>> index 089f3c9f56a3..d41507919ef2 100644
> >>> --- a/arch/riscv/include/asm/pgtable.h
> >>> +++ b/arch/riscv/include/asm/pgtable.h
> >>> @@ -428,7 +428,7 @@ static inline pte_t pte_mkwrite_novma(pte_t pte)
> >>>
> >>>   static inline pte_t pte_mkdirty(pte_t pte)
> >>>   {
> >>> -     return __pte(pte_val(pte) | _PAGE_DIRTY);
> >>> +     return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
> >>>   }
> >>>
> >>>   static inline pte_t pte_mkclean(pte_t pte)
> >>> @@ -461,6 +461,38 @@ static inline pte_t pte_mkhuge(pte_t pte)
> >>>        return pte;
> >>>   }
> >>>
> >>> +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
> >>> +static inline int pte_soft_dirty(pte_t pte)
> >>> +{
> >>> +     return pte_val(pte) & _PAGE_SOFT_DIRTY;
> >>> +}
> >>> +
> >>> +static inline pte_t pte_mksoft_dirty(pte_t pte)
> >>> +{
> >>> +     return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY);
> >>> +}
> >>> +
> >>> +static inline pte_t pte_clear_soft_dirty(pte_t pte)
> >>> +{
> >>> +     return __pte(pte_val(pte) & ~(_PAGE_SOFT_DIRTY));
> >>> +}
> >>> +
> >>> +static inline int pte_swp_soft_dirty(pte_t pte)
> >>> +{
> >>> +     return pte_val(pte) & _PAGE_SWP_SOFT_DIRTY;
> >>> +}
> >>> +
> >>> +static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
> >>> +{
> >>> +     return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY);
> >>> +}
> >>> +
> >>> +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
> >>> +{
> >>> +     return __pte(pte_val(pte) & ~(_PAGE_SWP_SOFT_DIRTY));
> >>> +}
> >>> +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
> >>> +
> >>>   #ifdef CONFIG_RISCV_ISA_SVNAPOT
> >>>   #define pte_leaf_size(pte)   (pte_napot(pte) ?                               \
> >>>                                        napot_cont_size(napot_cont_order(pte)) :\
> >>> @@ -751,6 +783,40 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
> >>>        return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
> >>>   }
> >>>
> >>> +#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
> >>> +static inline int pmd_soft_dirty(pmd_t pmd)
> >>> +{
> >>> +     return pte_soft_dirty(pmd_pte(pmd));
> >>> +}
> >>> +
> >>> +static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
> >>> +{
> >>> +     return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
> >>> +}
> >>> +
> >>> +static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
> >>> +{
> >>> +     return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
> >>> +}
> >>> +
> >>> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> >>> +static inline int pmd_swp_soft_dirty(pmd_t pmd)
> >>> +{
> >>> +     return pte_swp_soft_dirty(pmd_pte(pmd));
> >>> +}
> >>> +
> >>> +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
> >>> +{
> >>> +     return pte_pmd(pte_swp_mksoft_dirty(pmd_pte(pmd)));
> >>> +}
> >>> +
> >>> +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
> >>> +{
> >>> +     return pte_pmd(pte_swp_clear_soft_dirty(pmd_pte(pmd)));
> >>> +}
> >>> +#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
> >>> +#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
> >>> +
> >>>   static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
> >>>                                pmd_t *pmdp, pmd_t pmd)
> >>>   {
> >>> @@ -841,6 +907,7 @@ extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
> >>>    * Format of swap PTE:
> >>>    *   bit            0:       _PAGE_PRESENT (zero)
> >>>    *   bit       1 to 3:       _PAGE_LEAF (zero)
> >>> + *   bit            4:       _PAGE_SWP_SOFT_DIRTY
> >>>    *   bit            5:       _PAGE_PROT_NONE (zero)
> >>>    *   bit            6:       exclusive marker
> >>>    *   bits      7 to 11:      swap type
> > _______________________________________________
> > linux-riscv mailing list
> > linux-riscv at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-riscv


From mpe at ellerman.id.au  Tue Nov  5 23:06:35 2024
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Wed, 06 Nov 2024 18:06:35 +1100
Subject: [PATCH 00/28] vdso: Preparations for generic data storage
In-Reply-To: <e33569c8-1591-462c-9388-4a514e156bfa@csgroup.eu>
References: <20241010-vdso-generic-base-v1-0-b64f0842d512@linutronix.de>
 <871pzxzuny.ffs@tglx> <e33569c8-1591-462c-9388-4a514e156bfa@csgroup.eu>
Message-ID: <877c9glu2s.fsf@mpe.ellerman.id.au>

Christophe Leroy <christophe.leroy at csgroup.eu> writes:
> Le 30/10/2024 ? 12:39, Thomas Gleixner a ?crit?:
>> Folks!
>> 
>> On Thu, Oct 10 2024 at 09:01, Thomas Wei?schuh wrote:
>>> Historically each architecture defined their own datapage to store the
>>> VDSO data. This stands in contrast to the generic nature of the VDSO
>>> code itself.
>>> We plan to introduce a generic framework for the management of the VDSO
>>> data storage that can be used by all architectures and which works
>>> together with the existing generic VDSO code.
>>>
>>> Before that is possible align the different architectures by
>>> standardizing on the existing generic infrastructure and moving things
>>> out of the VDSO data page which does not belong there.
>>>
>>> Patches	 1- 2:	csky
>>> Patch	    3:	s390
>>> Patches	 4- 5:	arm64
>>> Patch	    6:	riscv
>>> Patch	    7:	arm
>>> Patch	    8:	LoongArch
>>> Patch	    9:	MIPS
>>> Patches 10-20:	x86
>>> Patches 21-27:	powerpc
>>> Patch      28: 	Renamings to avoid a name clash with the new code.
>> 
>> As this has been sitting for two weeks now without major comments, I'm
>> planning to merge that through the tip tree tomorrow.
>
> To avoid any future conflicts with powerpc tree, I suggest you merge 
> https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git 
> topic/vdso into your tree before applying this series.

I thought the same, but there actually isn't any conflict at the moment
between the two trees.

Some of Thomas W's later changes to convert arches to generic VDSO
storage do conflict, but they look to be destined for the next merge
window.

cheers


From troymitchell988 at gmail.com  Tue Nov  5 23:58:10 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Wed, 6 Nov 2024 15:58:10 +0800
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <846b4f2a-602e-431e-affc-0e995db5eee5@sifive.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <846b4f2a-602e-431e-affc-0e995db5eee5@sifive.com>
Message-ID: <9dfb250c-d8a1-4536-8658-48b3a2585abd@gmail.com>


On 2024/11/2 11:48, Samuel Holland wrote:
> Hi Troy,
> 
> On 2024-10-28 12:32 AM, Troy Mitchell wrote:
>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
>> and supports FIFO transmission.
>>
>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>> ---
>>  .../bindings/i2c/spacemit,k1-i2c.yaml         | 51 +++++++++++++++++++
>>  1 file changed, 51 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>> new file mode 100644
>> index 000000000000..57af66f494e7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>> @@ -0,0 +1,51 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: I2C controller embedded in SpacemiT's K1 SoC
>> +
>> +maintainers:
>> +  - Troy Mitchell <troymitchell988 at gmail.com>
>> +
>> +properties:
>> +  compatible:
>> +    const: spacemit,k1-i2c
>> +
>> +  reg:
>> +    maxItems: 2
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    maxItems: 1
> 
> Looking at the K1 user manual (9.1.4.77 RCPU I2C0 CLOCK RESET CONTROL
> REGISTER(RCPU_I2C0_CLK_RST)), I see two clocks (pclk, fclk) and a reset, which
> looks to be standard across the peripherals in this SoC. Please be sure that the
> binding covers all resources needed to use this peripheral.RCPU stands for Real-time CPU, which is typically used for low power consumption
applications.
We should be using the APBC_TWSIx_CLK_RST register, but it's not listed in the
user manual. However, you can find this register referenced in the K1 clock patch:
https://lore.kernel.org/all/SEYPR01MB4221AA2CA9C91A695FEFA777D7602 at SEYPR01MB4221.apcprd01.prod.exchangelabs.com/

Also, to see how to enable the I2C clock in the device tree (note that the
spacemit,apb_clock property is unused in the driver), check out the example here:
https://gitee.com/bianbu-linux/linux-6.1/blob/bl-v1.0.y/arch/riscv/boot/dts/spacemit/k1-x.dtsi#L1048

> 
>> +
>> +  clock-frequency:
>> +    description:
>> +      Desired I2C bus clock frequency in Hz. As only fast and high-speed
>> +      modes are supported by hardware, possible values are 100000 and 400000.
>> +    enum: [100000, 400000]
> 
> This looks wrong. In the manual I see:
> 
> * Supports standard-mode operation up to 100 Kbps
> * Supports fast-mode operation up to 400Kbps
> * Supports high-speed mode (HS mode) slave operation up to 3.4Mbps(High-speed
> I2C only)
> * Supports high-speed mode (HS mode) master operation up to 3.3 Mbps (High-speed
> I2C only)
> 
> So even ignoring HS mode, 100 kHz and 400 kHz are only the maximums, not fixed
> frequencies.
okay. I will fix it in next version.
and should I keep to ignore high-speed mode here?
if not, how about this:

  clock-frequency:
    description:
      Desired I2C bus clock frequency in Hz.
      K1 supports standard, fast, high-speed modes, from 1 to 3300000.
    default: 100000
    minimum: 1
    maximum: 3300000

> 
> Regards,
> Samuel
> 
>> +    default: 100000
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - interrupts
>> +  - clocks
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    i2c at d4010800 {
>> +        compatible = "spacemit,k1-i2c";
>> +        reg = <0x0 0xd4010800 0x0 0x38>;
>> +        interrupt-parent = <&plic>;
>> +        interrupts = <36>;
>> +        clocks = <&ccu 90>;
>> +        clock-frequency = <100000>;
>> +    };
>> +
>> +...
> 

-- 
Troy Mitchell


From troymitchell988 at gmail.com  Tue Nov  5 23:59:48 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Wed, 6 Nov 2024 15:59:48 +0800
Subject: [PATCH v2 0/2] riscv: spacemit: add i2c support to K1 SoC
In-Reply-To: <o55tg4zybyfroh7on7b6pxwbkw46fgafryzlc2gczmgecxr4ph@lptxs2timypu>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <stpzkggfwseaqy6kbppiog4xfbpq4r2jwix2nvredbmmjqzbsi@wkllt4jlingv>
 <edfaccd7-ac96-47fc-a174-912c8aaf0f5e@gmail.com>
 <o55tg4zybyfroh7on7b6pxwbkw46fgafryzlc2gczmgecxr4ph@lptxs2timypu>
Message-ID: <97096021-db00-4b4c-98f7-4c4a11f2c144@gmail.com>

On 2024/11/5 22:21, Andi Shyti wrote:
> Hy Troy,
> 
> On Mon, Nov 04, 2024 at 08:23:23PM +0800, Troy Mitchell wrote:
>> On 2024/10/31 19:43, Andi Shyti wrote:
>>> Hi Tony,
> 
> Sorry, I misread your name :-/
It doesn't matter
> 
>>> On Mon, Oct 28, 2024 at 01:32:18PM +0800, Troy Mitchell wrote:
>>>> Hi all,
>>>>
>>>> This patch implements I2C driver for the SpacemiT K1 SoC,
>>>> providing basic support for I2C read/write communication which
>>>> compatible with standard I2C bus specifications.
>>>>
>>>> In this version, the driver defaults to use fast-speed-mode and
>>>> interrupts for transmission, and does not support DMA, high-speed mode, or FIFO.
>>>>
>>>> The docs of I2C can be found here, in chapter 16.1 I2C [1]
>>>>
>>>> Link: https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#part5 [1]
>>>>
>>>> Troy Mitchell (2):
>>>>   dt-bindings: i2c: spacemit: add support for K1 SoC
>>>>   i2c: spacemit: add support for SpacemiT K1 SoC
>>>
>>> As Krzysztof has asked, please do provide the changelog, it's
>>> important to track the progress of your series.
>> I saw a compilation warning sent to me by the robot, and I've
>> fixed the warning. Should I resend V2 with the changelog
>> what I miss or send V3?
> 
> Please send a v3. When there are compilation issues, normally
> patches are less keen to be reviewed.
> 
> You can add the changelog in the Patch 0/2 to avoid editing all
> the .patch files.
Thanks! I'll send v3 after I get a response from Samuel.
> 
> Thanks,
> Andi

-- 
Troy Mitchell


From conor at kernel.org  Wed Nov  6 04:56:25 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 6 Nov 2024 12:56:25 +0000
Subject: [PATCH v1 08/11] clk: move meson clk-regmap implementation to
 common code
In-Reply-To: <20241003-tacking-ladylike-dfe2b633e647@spud>
References: <20241002-private-unequal-33cfa6101338@spud>
 <20241002-hula-unwashed-1c4ddbadbec2@spud>
 <2b49c4df-a34a-42c5-8d44-9e47da630fe8@linaro.org>
 <1jwmiqsks3.fsf@starbuckisacylon.baylibre.com>
 <20241003-tacking-ladylike-dfe2b633e647@spud>
Message-ID: <20241106-freefall-slider-db379b05821e@spud>

Stephen,

On Thu, Oct 03, 2024 at 12:33:40PM +0100, Conor Dooley wrote:
> On Wed, Oct 02, 2024 at 03:21:16PM +0200, Jerome Brunet wrote:
> > On Wed 02 Oct 2024 at 13:20, Neil Armstrong <neil.armstrong at linaro.org> wrote:
> > 
> > > On 02/10/2024 12:48, Conor Dooley wrote:
> > >> From: Conor Dooley <conor.dooley at microchip.com>
> > >> I like this one better than qualcomms and wish to use it for the
> > >> PolarFire SoC clock drivers.
> > >> Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
> > >> ---
> > >>   drivers/clk/Kconfig                           |  4 ++
> > >>   drivers/clk/Makefile                          |  1 +
> > >>   drivers/clk/{meson => }/clk-regmap.c          |  2 +-
> > >>   drivers/clk/meson/Kconfig                     | 46 +++++++++----------
> > >>   drivers/clk/meson/Makefile                    |  1 -
> > >>   drivers/clk/meson/a1-peripherals.c            |  2 +-
> > >>   drivers/clk/meson/a1-pll.c                    |  2 +-
> > >>   drivers/clk/meson/axg-aoclk.c                 |  2 +-
> > >>   drivers/clk/meson/axg-audio.c                 |  2 +-
> > >>   drivers/clk/meson/axg.c                       |  2 +-
> > >>   drivers/clk/meson/c3-peripherals.c            |  2 +-
> > >>   drivers/clk/meson/c3-pll.c                    |  2 +-
> > >>   drivers/clk/meson/clk-cpu-dyndiv.c            |  2 +-
> > >>   drivers/clk/meson/clk-dualdiv.c               |  2 +-
> > >>   drivers/clk/meson/clk-mpll.c                  |  2 +-
> > >>   drivers/clk/meson/clk-phase.c                 |  2 +-
> > >>   drivers/clk/meson/clk-pll.c                   |  2 +-
> > >>   drivers/clk/meson/g12a-aoclk.c                |  2 +-
> > >>   drivers/clk/meson/g12a.c                      |  2 +-
> > >>   drivers/clk/meson/gxbb-aoclk.c                |  2 +-
> > >>   drivers/clk/meson/gxbb.c                      |  2 +-
> > >>   drivers/clk/meson/meson-aoclk.h               |  2 +-
> > >>   drivers/clk/meson/meson-eeclk.c               |  2 +-
> > >>   drivers/clk/meson/meson-eeclk.h               |  2 +-
> > >>   drivers/clk/meson/meson8-ddr.c                |  2 +-
> > >>   drivers/clk/meson/meson8b.c                   |  2 +-
> > >>   drivers/clk/meson/s4-peripherals.c            |  2 +-
> > >>   drivers/clk/meson/s4-pll.c                    |  2 +-
> > >>   drivers/clk/meson/sclk-div.c                  |  2 +-
> > >>   drivers/clk/meson/vclk.h                      |  2 +-
> > >>   drivers/clk/meson/vid-pll-div.c               |  2 +-
> > >>   .../meson => include/linux/clk}/clk-regmap.h  |  0
> > >>   32 files changed, 53 insertions(+), 53 deletions(-)
> > >>   rename drivers/clk/{meson => }/clk-regmap.c (99%)
> > >>   rename {drivers/clk/meson => include/linux/clk}/clk-regmap.h (100%)
> > >> 
> > > <snip>
> > >
> > > I don't have objections, but I think Stephen didn't like the idea
> > > a few years ago, but perhaps it has changed...
> > >
> > > Anyway, take my:
> > > Acked-by: Neil Armstrong <neil.armstrong at linaro.org>
> > 
> > We had a similar discussion 3y ago indeed:
> > https://lore.kernel.org/linux-clk/162734682512.2368309.12015873010777083014 at swboyd.mtv.corp.google.com/
> > 
> > There are needs for a common regmap backed clocks indeed, but allowing
> > meson flavored regmap clocks to spread in the kernel was not really the
> > prefered way to do it. 
> 
> Cool, thanks for that link.
> 
> > IIRC, Stephen's idea was more the bring regmap support in clk-gate.c,
> > clk-mux, etc ... I'm not quite sure how make iomem and regmap co-exist
> > in a manageable/maintainable way within those drivers (without adding yet
> > another level of abstraction I mean) ? Silently creating a regmap maybe
> > ? but that's probably a bit heavy. I did not really had time to dig more
> > on this, I guess no one did.
> 
> I guess I have some motivation to looking into it at the moment. I had
> my reservations about the Meson approach too, liking it more than
> Qualcomm's didn't mean I completely liked it.
> It was already my intention to implement point b of your mail, had the
> general idea here been acceptable, cos that's a divergence from how the
> generic clock types (that the driver in question currently uses) work.
> And on that note, I just noticed I left the mild-annoyance variable name
> "sigh" in the submitted driver changes, which I had used for the
> clk_regmap struct that your point b in the link relates to.
> 
> > I don't really have a preference one way or the other but if it is going
> > to be exposed in 'include/linux', we need to be sure that's how we want
> > to do it. With clocks poping in many driver subsystems, it will
> > difficult to change afterward. 
> 
> Yeah, I agree. I didn't expect this to go in right away, and I also
> didn't want to surge ahead on some rework of the clock types, were
> people to hate even the reuse.

Hmm, so how (in-)complete of a regmap implementation can I get away
with? I only need clk-gate and clk-divider for this patchset...

Shoving the regmap into the clk structs makes things pretty trivial as I
don't need to do anything special in any function other than
clk_*_readl()/clk_*_writel() and the registration code. A flag isn't
even needed to determine if a clock is a regmap one I don't think, since
you can just check if the regmap pointer is non-NULL. My use case doesn't
actually need the registration code changes either as, currently, only reg
gets set at runtime, but leaving that out is a level of incomplete I'd not
let myself away with.
Obviously shoving the extra members into the clk structs has the downside
of taking up a pointer and a offset worth of memory for each clock of
that type registered, but it is substantially easier to support devices
with multiple regmaps that way. Probably moot though since the approach you
suggested in the thread linked above that implements a clk_hw_get_regmap()
has to store a pointer to the regmap's identifier which would take up an
identical amount of memory.

I don't really care which way you want it done, both are pretty easy to
implement if I can get away with just doing so for the two standard
clock types that I am using - is it okay to just do those two?

Cheers,
Conor.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241106/75a3ad1b/attachment.sig>

From conor at kernel.org  Wed Nov  6 05:11:29 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed,  6 Nov 2024 13:11:29 +0000
Subject: [for 6.11 PATCH] RISC-V: disallow gcc + rust builds
Message-ID: <20241106-happily-unknotted-9984b07a414e@spud>

From: Conor Dooley <conor.dooley at microchip.com>

commit 33549fcf37ec461f398f0a41e1c9948be2e5aca4 upstream

During the discussion before supporting rust on riscv, it was decided
not to support gcc yet, due to differences in extension handling
compared to llvm (only the version of libclang matching the c compiler
is supported). Recently Jason Montleon reported [1] that building with
gcc caused build issues, due to unsupported arguments being passed to
libclang. After some discussion between myself and Miguel, it is better
to disable gcc + rust builds to match the original intent, and
subsequently support it when an appropriate set of extensions can be
deduced from the version of libclang.

Closes: https://lore.kernel.org/all/20240917000848.720765-2-jmontleo at redhat.com/ [1]
Link: https://lore.kernel.org/all/20240926-battering-revolt-6c6a7827413e at spud/ [2]
Fixes: 70a57b247251a ("RISC-V: enable building 64-bit kernels with rust support")
Cc: stable at vger.kernel.org
Reported-by: Jason Montleon <jmontleo at redhat.com>
Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
Acked-by: Miguel Ojeda <ojeda at kernel.org>
Reviewed-by: Nathan Chancellor <nathan at kernel.org>
Link: https://lore.kernel.org/r/20241001-playlist-deceiving-16ece2f440f5 at spud
Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>
Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
---
 Documentation/rust/arch-support.rst | 2 +-
 arch/riscv/Kconfig                  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index 750ff371570a..54be7ddf3e57 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -17,7 +17,7 @@ Architecture   Level of support  Constraints
 =============  ================  ==============================================
 ``arm64``      Maintained        Little Endian only.
 ``loongarch``  Maintained        \-
-``riscv``      Maintained        ``riscv64`` only.
+``riscv``      Maintained        ``riscv64`` and LLVM/Clang only.
 ``um``         Maintained        \-
 ``x86``        Maintained        ``x86_64`` only.
 =============  ================  ==============================================
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index d11c2479d8e1..6651a5cbdc27 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -172,7 +172,7 @@ config RISCV
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RETHOOK if !XIP_KERNEL
 	select HAVE_RSEQ
-	select HAVE_RUST if 64BIT
+	select HAVE_RUST if 64BIT && CC_IS_CLANG
 	select HAVE_SAMPLE_FTRACE_DIRECT
 	select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
 	select HAVE_STACKPROTECTOR
-- 
2.45.2



From conor at kernel.org  Wed Nov  6 05:12:23 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 6 Nov 2024 13:12:23 +0000
Subject: FAILED: Patch "RISC-V: disallow gcc + rust builds" failed to
 apply to v6.11-stable tree
In-Reply-To: <20241106020840.164364-1-sashal@kernel.org>
References: <20241106020840.164364-1-sashal@kernel.org>
Message-ID: <20241106-undead-cupbearer-a22f27c8b9e2@spud>

On Tue, Nov 05, 2024 at 09:08:39PM -0500, Sasha Levin wrote:
> The patch below does not apply to the v6.11-stable tree.
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git commit
> id to <stable at vger.kernel.org>.

I sent 20241106-happily-unknotted-9984b07a414e at spud that should be a
6.11 viable version of this change.

Cheers,
Conor.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241106/dc1ae23c/attachment.sig>

From conor at kernel.org  Wed Nov  6 08:26:02 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 6 Nov 2024 16:26:02 +0000
Subject: [PATCH v5 2/2] PCI: microchip: rework reg region handing to
 support using either instance 1 or 2
In-Reply-To: <20241105171828.GA1474726@bhelgaas>
References: <20241104-stabilize-friday-94705c3dc244@spud>
 <20241105171828.GA1474726@bhelgaas>
Message-ID: <20241106-eats-anthology-657e2238e271@spud>

On Tue, Nov 05, 2024 at 11:18:28AM -0600, Bjorn Helgaas wrote:
> On Mon, Nov 04, 2024 at 11:18:43AM +0000, Conor Dooley wrote:
> > On Fri, Nov 01, 2024 at 02:51:29PM -0500, Bjorn Helgaas wrote:
> > > On Wed, Aug 14, 2024 at 09:08:42AM +0100, Conor Dooley wrote:
> > > > From: Conor Dooley <conor.dooley at microchip.com>
> > > > 
> > > > The PCI host controller on PolarFire SoC has multiple "instances", each
> > > > with their own bridge and ctrl address spaces. The original binding has
> > > > an "apb" register region, and it is expected to be set to the base
> > > > address of the host controllers register space. Defines in the driver
> > > > were used to compute the addresses of the bridge and ctrl address ranges
> > > > corresponding to instance1. Some customers want to use instance0 however
> > > > and that requires changing the defines in the driver, which is clearly
> > > > not a portable solution.
> > > 
> > > The subject mentions "instance 1 or 2".
> > > 
> > > This paragraph implies adding support for "instance0" ("customers want
> > > to use instance0").
> > > 
> > > The DT patch suggests that we're adding support for "instance2"
> > > ("customers want to use instance2").
> > > 
> > > Both patches suggest that the existing support is for "instance 1".
> > > 
> > > Maybe what's being added is "instance 2", and this commit log should
> > > s/instance0/instance 2/ ?  And probably s/instance1/instance 1/ so the
> > > style is consistent?
> > 
> > Hmm no, it would be s/instance1/instance 2/ & s/instance0/instance 1/.
> > The indices are 1-based, not 0-based.
> > 
> > > Is this a "pick one or the other but not both" situation, or does this
> > > device support two independent PCIe controllers?
> > > 
> > > I first thought this driver supported a single PCIe controller, and
> > > you were adding support for a second independent controller.
> > 
> > I don't know if they are fully independent (Daire would have to confirm)
> > but as far as the driver in linux is concerned they are. As far as I
> > know, you could operate both instances at the same time, but I've not
> > heard of any customer that is actually doing that nor tested it myself.
> > Operating both instances would require another node in the devicetree,
> > which should work fine given the private data structs are allocated at
> > runtime. I think the config space is shared.
> > 
> > > But the fact that you say "the [singular] host controller on
> > > PolarFire", and you're not changing mc_host_probe() to call
> > > pci_host_common_probe() more than once makes me think there is only a
> > > single PCIe controller, and for some reason you can choose to operate
> > > it using either register set 1 or register set 2.
> > 
> > The wording I've used mostly stems from conversations with Daire. We've
> > kinda been saying that there's a single controller with two root port
> > instances. 
> 
> If these are two separate Root Ports, can we call them "Root Ports"
> instead of "instances"?  Common terminology makes for common
> understanding.

Sure.

> > Each root port instance is connected to different IOs,
> > they're more than just different registers for accessing the same thing.
> 
> Sounds like some customers use Root Port 1 and others use Root Port 2,
> maybe based on things like which pins are more convenient to route.

Aye, the user that motivated the patchset uses a very small package and
was not able to use root port 1 for that reason.

> I would very much like to reword these commit logs using as much
> standard PCIe terminology as possible.  Most of these native PCIe
> controller drivers have Root Complex and Root Port concepts all mixed
> together, and anything we can do to standardize them will be a
> benefit.

I can do that tomorrow.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241106/3de6ffba/attachment.sig>

From derekmn at amazon.com  Wed Nov  6 09:04:27 2024
From: derekmn at amazon.com (Manwaring, Derek)
Date: Wed, 6 Nov 2024 10:04:27 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <DM8PR11MB57509ED04CB0730680735AC9E7512@DM8PR11MB5750.namprd11.prod.outlook.com>
References: <DM8PR11MB57509ED04CB0730680735AC9E7512@DM8PR11MB5750.namprd11.prod.outlook.com>
Message-ID: <7ad5d114-3d19-4c33-bb3c-7f8940ad114e@amazon.com>

On 2024-11-04 at 08:33+0000, Elena Reshetova wrote:
> This statement *is* for integrity section. We have a separate TDX guidance
> on side-channels (including speculative) [3] and some speculative attacks
> that affect confidentiality (for example spectre v1) are listed as not covered
> by TDX but remaining SW responsibility (as they are now).

Thanks for the additional info, Elena. Given that clarification, I
definitely see direct map removal and TDX as complementary.

Derek


From ajones at ventanamicro.com  Wed Nov  6 09:51:03 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Wed,  6 Nov 2024 18:51:03 +0100
Subject: [PATCH 0/2] iommu/riscv: Add platform msi support
Message-ID: <20241106175102.219923-4-ajones@ventanamicro.com>

The first patch is fix for an issue found while preparing the second.
The second patch adds MSI support for a platform IOMMU. The patches
may be tested with QEMU when including [1].

Based on linux-next commit 5b913f5d7d7f ("Add linux-next specific files for 20241106")

[1] https://lore.kernel.org/all/20241106133407.604587-1-dbarboza at ventanamicro.com/


Andrew Jones (2):
  iommu/riscv: Free irq vectors on pci remove
  iommu/riscv: Add support for platform msi

 drivers/iommu/riscv/iommu-pci.c      |   1 +
 drivers/iommu/riscv/iommu-platform.c | 102 ++++++++++++++++++++++-----
 2 files changed, 85 insertions(+), 18 deletions(-)

-- 
2.47.0



From ajones at ventanamicro.com  Wed Nov  6 09:51:04 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Wed,  6 Nov 2024 18:51:04 +0100
Subject: [PATCH 1/2] iommu/riscv: Free irq vectors on pci remove
In-Reply-To: <20241106175102.219923-4-ajones@ventanamicro.com>
References: <20241106175102.219923-4-ajones@ventanamicro.com>
Message-ID: <20241106175102.219923-5-ajones@ventanamicro.com>

riscv_iommu_pci_probe() calls pci_alloc_irq_vectors() which
states pci_free_irq_vectors() must be called on cleanup.

Fixes: 68682e9578fb ("iommu/riscv: Add RISC-V IOMMU PCIe device driver")
Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/iommu/riscv/iommu-pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/riscv/iommu-pci.c b/drivers/iommu/riscv/iommu-pci.c
index c7a89143014c..25a27e627a0e 100644
--- a/drivers/iommu/riscv/iommu-pci.c
+++ b/drivers/iommu/riscv/iommu-pci.c
@@ -99,6 +99,7 @@ static void riscv_iommu_pci_remove(struct pci_dev *pdev)
 	struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev);
 
 	riscv_iommu_remove(iommu);
+	pci_free_irq_vectors(pdev);
 }
 
 static const struct pci_device_id riscv_iommu_pci_tbl[] = {
-- 
2.47.0



From ajones at ventanamicro.com  Wed Nov  6 09:51:05 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Wed,  6 Nov 2024 18:51:05 +0100
Subject: [PATCH 2/2] iommu/riscv: Add support for platform msi
In-Reply-To: <20241106175102.219923-4-ajones@ventanamicro.com>
References: <20241106175102.219923-4-ajones@ventanamicro.com>
Message-ID: <20241106175102.219923-6-ajones@ventanamicro.com>

Apply platform_device_msi_init_and_alloc_irqs() to add support for
MSIs when the IOMMU is a platform device.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/iommu/riscv/iommu-platform.c | 102 ++++++++++++++++++++++-----
 1 file changed, 84 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
index da336863f152..89aa622bcbde 100644
--- a/drivers/iommu/riscv/iommu-platform.c
+++ b/drivers/iommu/riscv/iommu-platform.c
@@ -11,18 +11,41 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/msi.h>
 
 #include "iommu-bits.h"
 #include "iommu.h"
 
+static void riscv_iommu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
+{
+	struct device *dev = msi_desc_to_dev(desc);
+	struct riscv_iommu_device *iommu = dev_get_drvdata(dev);
+	u16 idx = desc->msi_index;
+	u64 addr;
+
+	addr = ((u64)msg->address_hi << 32) | msg->address_lo;
+
+	if (addr != (addr & RISCV_IOMMU_MSI_CFG_TBL_ADDR))
+		pr_warn_once("uh oh, the IOMMU can't send MSIs to 0x%llx, sending to 0x%llx instead\n",
+			     addr, addr & RISCV_IOMMU_MSI_CFG_TBL_ADDR);
+
+	addr &= RISCV_IOMMU_MSI_CFG_TBL_ADDR;
+
+	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_ADDR(idx), addr);
+	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_DATA(idx), msg->data);
+	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_CTRL(idx), 0);
+}
+
 static int riscv_iommu_platform_probe(struct platform_device *pdev)
 {
+	enum riscv_iommu_igs_settings igs;
 	struct device *dev = &pdev->dev;
 	struct riscv_iommu_device *iommu = NULL;
 	struct resource *res = NULL;
-	int vec;
+	int vec, ret;
 
 	iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL);
 	if (!iommu)
@@ -40,16 +63,6 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	iommu->caps = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_CAPABILITIES);
 	iommu->fctl = riscv_iommu_readl(iommu, RISCV_IOMMU_REG_FCTL);
 
-	/* For now we only support WSI */
-	switch (FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps)) {
-	case RISCV_IOMMU_CAPABILITIES_IGS_WSI:
-	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
-		break;
-	default:
-		return dev_err_probe(dev, -ENODEV,
-				     "unable to use wire-signaled interrupts\n");
-	}
-
 	iommu->irqs_count = platform_irq_count(pdev);
 	if (iommu->irqs_count <= 0)
 		return dev_err_probe(dev, -ENODEV,
@@ -57,13 +70,60 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT)
 		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT;
 
-	for (vec = 0; vec < iommu->irqs_count; vec++)
-		iommu->irqs[vec] = platform_get_irq(pdev, vec);
+	igs = FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps);
+	switch (igs) {
+	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
+	case RISCV_IOMMU_CAPABILITIES_IGS_MSI:
+		if (is_of_node(dev->fwnode))
+			of_msi_configure(dev, to_of_node(dev->fwnode));
+
+		if (!dev_get_msi_domain(dev)) {
+			dev_warn(dev, "failed to find an MSI domain");
+			goto msi_fail;
+		}
+
+		ret = platform_device_msi_init_and_alloc_irqs(dev, iommu->irqs_count,
+							      riscv_iommu_write_msi_msg);
+		if (ret) {
+			dev_warn(dev, "failed to allocate MSIs");
+			goto msi_fail;
+		}
+
+		for (vec = 0; vec < iommu->irqs_count; vec++)
+			iommu->irqs[vec] = msi_get_virq(dev, vec);
+
+		/* Enable message-signaled interrupts, fctl.WSI */
+		if (iommu->fctl & RISCV_IOMMU_FCTL_WSI) {
+			iommu->fctl ^= RISCV_IOMMU_FCTL_WSI;
+			riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
+		}
+
+		dev_info(dev, "using MSIs\n");
+		break;
+
+msi_fail:
+		if (igs != RISCV_IOMMU_CAPABILITIES_IGS_BOTH) {
+			dev_warn(dev, "\n");
+			return dev_err_probe(dev, -ENODEV,
+					     "unable to use wire-signaled interrupts\n");
+		}
+
+		dev_warn(dev, " - falling back to wired irqs\n");
+		fallthrough;
 
-	/* Enable wire-signaled interrupts, fctl.WSI */
-	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
-		iommu->fctl |= RISCV_IOMMU_FCTL_WSI;
-		riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
+	case RISCV_IOMMU_CAPABILITIES_IGS_WSI:
+		for (vec = 0; vec < iommu->irqs_count; vec++)
+			iommu->irqs[vec] = platform_get_irq(pdev, vec);
+
+		/* Enable wire-signaled interrupts, fctl.WSI */
+		if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
+			iommu->fctl |= RISCV_IOMMU_FCTL_WSI;
+			riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
+		}
+		dev_info(dev, "using wire-signaled interrupts\n");
+		break;
+	default:
+		return dev_err_probe(dev, -ENODEV, "invalid IGS\n");
 	}
 
 	return riscv_iommu_init(iommu);
@@ -71,7 +131,13 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 
 static void riscv_iommu_platform_remove(struct platform_device *pdev)
 {
-	riscv_iommu_remove(dev_get_drvdata(&pdev->dev));
+	struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev);
+	bool msi = !(iommu->fctl & RISCV_IOMMU_FCTL_WSI);
+
+	riscv_iommu_remove(iommu);
+
+	if (msi)
+		platform_device_msi_free_irqs_all(&pdev->dev);
 };
 
 static const struct of_device_id riscv_iommu_of_match[] = {
-- 
2.47.0



From tjeznach at rivosinc.com  Wed Nov  6 11:00:55 2024
From: tjeznach at rivosinc.com (Tomasz Jeznach)
Date: Wed, 6 Nov 2024 11:00:55 -0800
Subject: [PATCH 1/2] iommu/riscv: Free irq vectors on pci remove
In-Reply-To: <20241106175102.219923-5-ajones@ventanamicro.com>
References: <20241106175102.219923-4-ajones@ventanamicro.com> <20241106175102.219923-5-ajones@ventanamicro.com>
Message-ID: <CAH2o1u5ttY+0d4v8U=H-PwLUHZo5uMxxCQ5NAXudOQvUUMcpfA@mail.gmail.com>

On Wed, Nov 6, 2024 at 9:51?AM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> riscv_iommu_pci_probe() calls pci_alloc_irq_vectors() which
> states pci_free_irq_vectors() must be called on cleanup.
>
> Fixes: 68682e9578fb ("iommu/riscv: Add RISC-V IOMMU PCIe device driver")
> Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
> ---
>  drivers/iommu/riscv/iommu-pci.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/iommu/riscv/iommu-pci.c b/drivers/iommu/riscv/iommu-pci.c
> index c7a89143014c..25a27e627a0e 100644
> --- a/drivers/iommu/riscv/iommu-pci.c
> +++ b/drivers/iommu/riscv/iommu-pci.c
> @@ -99,6 +99,7 @@ static void riscv_iommu_pci_remove(struct pci_dev *pdev)
>         struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev);
>
>         riscv_iommu_remove(iommu);
> +       pci_free_irq_vectors(pdev);
>  }
>
>  static const struct pci_device_id riscv_iommu_pci_tbl[] = {
> --
> 2.47.0
>

Andrew, interrupt release call pci_free_irq_vectors() should already
be called by device
managed resources framework, with unwind action callback pcim_msi_release().

Callback is registered during vectors allocation:
 pci_alloc_irq_vectors_affinity()
  __pci_enable_msix_range()
   pci_setup_msi_context()
    pcim_setup_msi_release()

This driver enables device resources management with initial call to
pcim_enable_device().

Are there any conditions / testing sequence the release function is not called?

Thanks,
- Tomasz


From bjorn at kernel.org  Wed Nov  6 11:32:06 2024
From: bjorn at kernel.org (=?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?=)
Date: Wed,  6 Nov 2024 20:32:06 +0100
Subject: [PATCH] tools: Override makefile ARCH variable if defined, but empty
Message-ID: <20241106193208.290067-1-bjorn@kernel.org>

From: Bj?rn T?pel <bjorn at rivosinc.com>

There are a number of tools (bpftool, selftests), that require a
"bootstrap" build. Here, a bootstrap build is a build host variant of
a target. E.g., assume that you're performing a bpftool cross-build on
x86 to riscv, a bootstrap build would then be an x86 variant of
bpftool. The typical way to perform the host build variant, is to pass
"ARCH=" in a sub-make. However, if a variable has been set with a
command argument, then ordinary assignments in the makefile are
ignored.

This side-effect results in that ARCH, and variables depending on ARCH
are not set.

Workaround by overriding ARCH to the host arch, if ARCH is empty.

Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
---
 tools/scripts/Makefile.arch | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/scripts/Makefile.arch b/tools/scripts/Makefile.arch
index f6a50f06dfc4..eabfe9f411d9 100644
--- a/tools/scripts/Makefile.arch
+++ b/tools/scripts/Makefile.arch
@@ -7,8 +7,8 @@ HOSTARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
                                   -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
                                   -e s/riscv.*/riscv/ -e s/loongarch.*/loongarch/)
 
-ifndef ARCH
-ARCH := $(HOSTARCH)
+ifeq ($(strip $(ARCH)),)
+override ARCH := $(HOSTARCH)
 endif
 
 SRCARCH := $(ARCH)

base-commit: 7758b206117dab9894f0bcb8333f8e4731c5065a
-- 
2.45.2



From samuel.holland at sifive.com  Wed Nov  6 11:45:23 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Wed, 6 Nov 2024 13:45:23 -0600
Subject: [PATCH 2/2] iommu/riscv: Add support for platform msi
In-Reply-To: <20241106175102.219923-6-ajones@ventanamicro.com>
References: <20241106175102.219923-4-ajones@ventanamicro.com>
 <20241106175102.219923-6-ajones@ventanamicro.com>
Message-ID: <d92ab280-bd1f-4145-8164-cebab1980f20@sifive.com>

Hi Drew,

On 2024-11-06 11:51 AM, Andrew Jones wrote:
> Apply platform_device_msi_init_and_alloc_irqs() to add support for
> MSIs when the IOMMU is a platform device.
> 
> Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
> ---
>  drivers/iommu/riscv/iommu-platform.c | 102 ++++++++++++++++++++++-----
>  1 file changed, 84 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
> index da336863f152..89aa622bcbde 100644
> --- a/drivers/iommu/riscv/iommu-platform.c
> +++ b/drivers/iommu/riscv/iommu-platform.c
> @@ -11,18 +11,41 @@
>   */
>  
>  #include <linux/kernel.h>
> +#include <linux/of_irq.h>
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
> +#include <linux/msi.h>

If you respin, please keep these sorted.

>  
>  #include "iommu-bits.h"
>  #include "iommu.h"
>  
> +static void riscv_iommu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
> +{
> +	struct device *dev = msi_desc_to_dev(desc);
> +	struct riscv_iommu_device *iommu = dev_get_drvdata(dev);
> +	u16 idx = desc->msi_index;
> +	u64 addr;
> +
> +	addr = ((u64)msg->address_hi << 32) | msg->address_lo;
> +
> +	if (addr != (addr & RISCV_IOMMU_MSI_CFG_TBL_ADDR))
> +		pr_warn_once("uh oh, the IOMMU can't send MSIs to 0x%llx, sending to 0x%llx instead\n",
> +			     addr, addr & RISCV_IOMMU_MSI_CFG_TBL_ADDR);

Can this use dev_warn_once()? And should it really be only a warning?
Configuring the IOMMU to write to some other address seems dangerous. I guess
there's no clean way to handle this error, since this function cannot fail, and
irq_chip_compose_msi_msg() isn't supposed to fail either.

> +
> +	addr &= RISCV_IOMMU_MSI_CFG_TBL_ADDR;
> +
> +	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_ADDR(idx), addr);
> +	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_DATA(idx), msg->data);
> +	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_CTRL(idx), 0);
> +}
> +
>  static int riscv_iommu_platform_probe(struct platform_device *pdev)
>  {
> +	enum riscv_iommu_igs_settings igs;
>  	struct device *dev = &pdev->dev;
>  	struct riscv_iommu_device *iommu = NULL;
>  	struct resource *res = NULL;
> -	int vec;
> +	int vec, ret;
>  
>  	iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL);
>  	if (!iommu)
> @@ -40,16 +63,6 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
>  	iommu->caps = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_CAPABILITIES);
>  	iommu->fctl = riscv_iommu_readl(iommu, RISCV_IOMMU_REG_FCTL);
>  
> -	/* For now we only support WSI */
> -	switch (FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps)) {
> -	case RISCV_IOMMU_CAPABILITIES_IGS_WSI:
> -	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
> -		break;
> -	default:
> -		return dev_err_probe(dev, -ENODEV,
> -				     "unable to use wire-signaled interrupts\n");
> -	}
> -
>  	iommu->irqs_count = platform_irq_count(pdev);
>  	if (iommu->irqs_count <= 0)
>  		return dev_err_probe(dev, -ENODEV,
> @@ -57,13 +70,60 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
>  	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT)
>  		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT;
>  
> -	for (vec = 0; vec < iommu->irqs_count; vec++)
> -		iommu->irqs[vec] = platform_get_irq(pdev, vec);
> +	igs = FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps);
> +	switch (igs) {
> +	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
> +	case RISCV_IOMMU_CAPABILITIES_IGS_MSI:
> +		if (is_of_node(dev->fwnode))
> +			of_msi_configure(dev, to_of_node(dev->fwnode));
> +
> +		if (!dev_get_msi_domain(dev)) {
> +			dev_warn(dev, "failed to find an MSI domain");
> +			goto msi_fail;
> +		}
> +
> +		ret = platform_device_msi_init_and_alloc_irqs(dev, iommu->irqs_count,
> +							      riscv_iommu_write_msi_msg);
> +		if (ret) {
> +			dev_warn(dev, "failed to allocate MSIs");
> +			goto msi_fail;
> +		}
> +
> +		for (vec = 0; vec < iommu->irqs_count; vec++)
> +			iommu->irqs[vec] = msi_get_virq(dev, vec);
> +
> +		/* Enable message-signaled interrupts, fctl.WSI */
> +		if (iommu->fctl & RISCV_IOMMU_FCTL_WSI) {
> +			iommu->fctl ^= RISCV_IOMMU_FCTL_WSI;
> +			riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
> +		}
> +
> +		dev_info(dev, "using MSIs\n");
> +		break;
> +
> +msi_fail:
> +		if (igs != RISCV_IOMMU_CAPABILITIES_IGS_BOTH) {
> +			dev_warn(dev, "\n");
> +			return dev_err_probe(dev, -ENODEV,
> +					     "unable to use wire-signaled interrupts\n");

Is the dev_warn() just to call attention to the following error? There's no
guarantee that these two messages will be printed adjacently.

> +		}
> +
> +		dev_warn(dev, " - falling back to wired irqs\n");

No need for the extra hyphen here.

Regards,
Samuel

> +		fallthrough;
>  
> -	/* Enable wire-signaled interrupts, fctl.WSI */
> -	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
> -		iommu->fctl |= RISCV_IOMMU_FCTL_WSI;
> -		riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
> +	case RISCV_IOMMU_CAPABILITIES_IGS_WSI:
> +		for (vec = 0; vec < iommu->irqs_count; vec++)
> +			iommu->irqs[vec] = platform_get_irq(pdev, vec);
> +
> +		/* Enable wire-signaled interrupts, fctl.WSI */
> +		if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
> +			iommu->fctl |= RISCV_IOMMU_FCTL_WSI;
> +			riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
> +		}
> +		dev_info(dev, "using wire-signaled interrupts\n");
> +		break;
> +	default:
> +		return dev_err_probe(dev, -ENODEV, "invalid IGS\n");
>  	}
>  
>  	return riscv_iommu_init(iommu);
> @@ -71,7 +131,13 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
>  
>  static void riscv_iommu_platform_remove(struct platform_device *pdev)
>  {
> -	riscv_iommu_remove(dev_get_drvdata(&pdev->dev));
> +	struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev);
> +	bool msi = !(iommu->fctl & RISCV_IOMMU_FCTL_WSI);
> +
> +	riscv_iommu_remove(iommu);
> +
> +	if (msi)
> +		platform_device_msi_free_irqs_all(&pdev->dev);
>  };
>  
>  static const struct of_device_id riscv_iommu_of_match[] = {



From andrii.nakryiko at gmail.com  Wed Nov  6 14:04:01 2024
From: andrii.nakryiko at gmail.com (Andrii Nakryiko)
Date: Wed, 6 Nov 2024 14:04:01 -0800
Subject: [PATCH bpf-next 1/2] libbpf: Add missing per-arch include path
In-Reply-To: <87bjyvpa6h.fsf@all.your.base.are.belong.to.us>
References: <20240927131355.350918-1-bjorn@kernel.org> <172835823300.66789.3704854116445399222.git-patchwork-notify@kernel.org>
 <87bjyvpa6h.fsf@all.your.base.are.belong.to.us>
Message-ID: <CAEf4BzZbq9OwSGi4pdb5_q8YkErfFiQFKYXg3g1rjpdejafx+Q@mail.gmail.com>

On Mon, Nov 4, 2024 at 2:26?AM Bj?rn T?pel <bjorn at kernel.org> wrote:
>
> patchwork-bot+netdevbpf at kernel.org writes:
>
> > Hello:
> >
> > This series was applied to bpf/bpf-next.git (master)
> > by Andrii Nakryiko <andrii at kernel.org>:
> >
> > On Fri, 27 Sep 2024 15:13:52 +0200 you wrote:
> >> From: Bj?rn T?pel <bjorn at rivosinc.com>
> >>
> >> libbpf does not include the per-arch tools include path, e.g.
> >> tools/arch/riscv/include. Some architectures depend those files to
> >> build properly.
> >>
> >> Include tools/arch/$(SUBARCH)/include in the libbpf build.
> >>
> >> [...]
> >
> > Here is the summary with links:
> >   - [bpf-next,1/2] libbpf: Add missing per-arch include path
> >     https://git.kernel.org/bpf/bpf-next/c/710fbca820c7
> >   - [bpf-next,2/2] selftests: bpf: Add missing per-arch include path
> >     https://git.kernel.org/bpf/bpf-next/c/19090f0306f1
>
> Andrii, I just noted that this landed into bpf-next, and not bpf
> (fixes).

Hi Bjorn,

Yes, libbpf and selftests fixes are generally applied through
bpf-next, unless the issue is pretty bad and immediate.

I'm sorry, but unfortunately it's too late now to move those patches
as it's now been more than a month since they landed. For the future,
please let us know ASAP if you think patches were misrouted. I think
we are stuck with the need to do a stable backport for these, sorry.

>
> RISC-V libbpf/perf needs this fix in 6.12 to properly build. Would it be
> possible to have it in the bpf tree, and have it land in 6.12-rc7?
>
> Andreas that has a similar fix [1].
>
>
> Bj?rn
>
> [1] https://lore.kernel.org/linux-riscv/mvm5xq44bqh.fsf at suse.de/


From samuel.holland at sifive.com  Wed Nov  6 16:29:56 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Wed, 6 Nov 2024 18:29:56 -0600
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <9dfb250c-d8a1-4536-8658-48b3a2585abd@gmail.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <846b4f2a-602e-431e-affc-0e995db5eee5@sifive.com>
 <9dfb250c-d8a1-4536-8658-48b3a2585abd@gmail.com>
Message-ID: <a9f59ffb-23e9-4c83-8d44-4c766e32b3bf@sifive.com>

Hi Troy,

On 2024-11-06 1:58 AM, Troy Mitchell wrote:
> On 2024/11/2 11:48, Samuel Holland wrote:
>> On 2024-10-28 12:32 AM, Troy Mitchell wrote:
>>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
>>> and supports FIFO transmission.
>>>
>>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>>> ---
>>>  .../bindings/i2c/spacemit,k1-i2c.yaml         | 51 +++++++++++++++++++
>>>  1 file changed, 51 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>> new file mode 100644
>>> index 000000000000..57af66f494e7
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>> @@ -0,0 +1,51 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: I2C controller embedded in SpacemiT's K1 SoC
>>> +
>>> +maintainers:
>>> +  - Troy Mitchell <troymitchell988 at gmail.com>
>>> +
>>> +properties:
>>> +  compatible:
>>> +    const: spacemit,k1-i2c
>>> +
>>> +  reg:
>>> +    maxItems: 2
>>> +
>>> +  interrupts:
>>> +    maxItems: 1
>>> +
>>> +  clocks:
>>> +    maxItems: 1
>>
>> Looking at the K1 user manual (9.1.4.77 RCPU I2C0 CLOCK RESET CONTROL
>> REGISTER(RCPU_I2C0_CLK_RST)), I see two clocks (pclk, fclk) and a reset, which
>> looks to be standard across the peripherals in this SoC. Please be sure that the
>> binding covers all resources needed to use this peripheral.
>
> RCPU stands for Real-time CPU, which is typically used for low power consumption
> applications.
> We should be using the APBC_TWSIx_CLK_RST register, but it's not listed in the
> user manual. However, you can find this register referenced in the K1 clock patch:
> https://lore.kernel.org/all/SEYPR01MB4221AA2CA9C91A695FEFA777D7602 at SEYPR01MB4221.apcprd01.prod.exchangelabs.com/

Ah, well that driver is missing most of the bus clocks. For example, from a
quick comparison with the manual, the driver includes sdh_axi_aclk, but misses
all of the PWM APB clocks at APBC_PWMx_CLK_RST bit 0.

If the clock gate exists in the hardware, even if it is enabled by default, it
needs to be modeled in the devicetree.

> Also, to see how to enable the I2C clock in the device tree (note that the
> spacemit,apb_clock property is unused in the driver), check out the example here:
> https://gitee.com/bianbu-linux/linux-6.1/blob/bl-v1.0.y/arch/riscv/boot/dts/spacemit/k1-x.dtsi#L1048

The devicetree describes the hardware, irrespective of which features the driver
may or may not use.

>>> +
>>> +  clock-frequency:
>>> +    description:
>>> +      Desired I2C bus clock frequency in Hz. As only fast and high-speed
>>> +      modes are supported by hardware, possible values are 100000 and 400000.
>>> +    enum: [100000, 400000]
>>
>> This looks wrong. In the manual I see:
>>
>> * Supports standard-mode operation up to 100 Kbps
>> * Supports fast-mode operation up to 400Kbps
>> * Supports high-speed mode (HS mode) slave operation up to 3.4Mbps(High-speed
>> I2C only)
>> * Supports high-speed mode (HS mode) master operation up to 3.3 Mbps (High-speed
>> I2C only)
>>
>> So even ignoring HS mode, 100 kHz and 400 kHz are only the maximums, not fixed
>> frequencies.
> okay. I will fix it in next version.
> and should I keep to ignore high-speed mode here?
> if not, how about this:
> 
>   clock-frequency:
>     description:
>       Desired I2C bus clock frequency in Hz.
>       K1 supports standard, fast, high-speed modes, from 1 to 3300000.
>     default: 100000
>     minimum: 1
>     maximum: 3300000

I don't know if high-speed mode should be included, since it requires some extra
negotiation to use. Assuming it should be, that looks reasonable.

Regards,
Samuel

>>
>> Regards,
>> Samuel
>>
>>> +    default: 100000
>>> +
>>> +required:
>>> +  - compatible
>>> +  - reg
>>> +  - interrupts
>>> +  - clocks
>>> +
>>> +unevaluatedProperties: false
>>> +
>>> +examples:
>>> +  - |
>>> +    i2c at d4010800 {
>>> +        compatible = "spacemit,k1-i2c";
>>> +        reg = <0x0 0xd4010800 0x0 0x38>;
>>> +        interrupt-parent = <&plic>;
>>> +        interrupts = <36>;
>>> +        clocks = <&ccu 90>;
>>> +        clock-frequency = <100000>;
>>> +    };
>>> +
>>> +...
>>
> 



From troymitchell988 at gmail.com  Wed Nov  6 17:57:53 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Thu, 7 Nov 2024 09:57:53 +0800
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <a9f59ffb-23e9-4c83-8d44-4c766e32b3bf@sifive.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <846b4f2a-602e-431e-affc-0e995db5eee5@sifive.com>
 <9dfb250c-d8a1-4536-8658-48b3a2585abd@gmail.com>
 <a9f59ffb-23e9-4c83-8d44-4c766e32b3bf@sifive.com>
Message-ID: <53898c38-1ae4-476b-9782-fdef41a5c932@gmail.com>


On 2024/11/7 08:29, Samuel Holland wrote:
> Hi Troy,
> 
> On 2024-11-06 1:58 AM, Troy Mitchell wrote:
>> On 2024/11/2 11:48, Samuel Holland wrote:
>>> On 2024-10-28 12:32 AM, Troy Mitchell wrote:
>>>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
>>>> and supports FIFO transmission.
>>>>
>>>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>>>> ---
>>>>  .../bindings/i2c/spacemit,k1-i2c.yaml         | 51 +++++++++++++++++++
>>>>  1 file changed, 51 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>>> new file mode 100644
>>>> index 000000000000..57af66f494e7
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>>> @@ -0,0 +1,51 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: I2C controller embedded in SpacemiT's K1 SoC
>>>> +
>>>> +maintainers:
>>>> +  - Troy Mitchell <troymitchell988 at gmail.com>
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    const: spacemit,k1-i2c
>>>> +
>>>> +  reg:
>>>> +    maxItems: 2
>>>> +
>>>> +  interrupts:
>>>> +    maxItems: 1
>>>> +
>>>> +  clocks:
>>>> +    maxItems: 1
>>>
>>> Looking at the K1 user manual (9.1.4.77 RCPU I2C0 CLOCK RESET CONTROL
>>> REGISTER(RCPU_I2C0_CLK_RST)), I see two clocks (pclk, fclk) and a reset, which
>>> looks to be standard across the peripherals in this SoC. Please be sure that the
>>> binding covers all resources needed to use this peripheral.
>>
>> RCPU stands for Real-time CPU, which is typically used for low power consumption
>> applications.
>> We should be using the APBC_TWSIx_CLK_RST register, but it's not listed in the
>> user manual. However, you can find this register referenced in the K1 clock patch:
>> https://lore.kernel.org/all/SEYPR01MB4221AA2CA9C91A695FEFA777D7602 at SEYPR01MB4221.apcprd01.prod.exchangelabs.com/
> 
> Ah, well that driver is missing most of the bus clocks. For example, from a
> quick comparison with the manual, the driver includes sdh_axi_aclk, but misses
> all of the PWM APB clocks at APBC_PWMx_CLK_RST bit 0.
> 
> If the clock gate exists in the hardware, even if it is enabled by default, it
> needs to be modeled in the devicetree.
I think you mean `APBCSCR`? It will keep enable all time.Just a difference in
frequency.

Should I add it in clockc property? If yes, how about this:
    clocks:
        maxItems: 1

and in dts example:
    i2c at d4010800 {
	...
        clocks = <&clk_apbc>, <&ccu 90>;
	clock-names = "clk_apbc", "clk_twsi";
        ...
    };
But one thing is, apbc_twsi is the sub-clock of clk_apbc, is this a duplicate
listing?
> 
>> Also, to see how to enable the I2C clock in the device tree (note that the
>> spacemit,apb_clock property is unused in the driver), check out the example here:
>> https://gitee.com/bianbu-linux/linux-6.1/blob/bl-v1.0.y/arch/riscv/boot/dts/spacemit/k1-x.dtsi#L1048
> 
> The devicetree describes the hardware, irrespective of which features the driver
> may or may not use.
> 
>>>> +
>>>> +  clock-frequency:
>>>> +    description:
>>>> +      Desired I2C bus clock frequency in Hz. As only fast and high-speed
>>>> +      modes are supported by hardware, possible values are 100000 and 400000.
>>>> +    enum: [100000, 400000]
>>>
>>> This looks wrong. In the manual I see:
>>>
>>> * Supports standard-mode operation up to 100 Kbps
>>> * Supports fast-mode operation up to 400Kbps
>>> * Supports high-speed mode (HS mode) slave operation up to 3.4Mbps(High-speed
>>> I2C only)
>>> * Supports high-speed mode (HS mode) master operation up to 3.3 Mbps (High-speed
>>> I2C only)
>>>
>>> So even ignoring HS mode, 100 kHz and 400 kHz are only the maximums, not fixed
>>> frequencies.
>> okay. I will fix it in next version.
>> and should I keep to ignore high-speed mode here?
>> if not, how about this:
>>
>>   clock-frequency:
>>     description:
>>       Desired I2C bus clock frequency in Hz.
>>       K1 supports standard, fast, high-speed modes, from 1 to 3300000.
>>     default: 100000
>>     minimum: 1
>>     maximum: 3300000
> 
> I don't know if high-speed mode should be included, since it requires some extra
> negotiation to use. Assuming it should be, that looks reasonable.
thanks.
> 
> Regards,
> Samuel
> 
>>>
>>> Regards,
>>> Samuel
>>>
>>>> +    default: 100000
>>>> +
>>>> +required:
>>>> +  - compatible
>>>> +  - reg
>>>> +  - interrupts
>>>> +  - clocks
>>>> +
>>>> +unevaluatedProperties: false
>>>> +
>>>> +examples:
>>>> +  - |
>>>> +    i2c at d4010800 {
>>>> +        compatible = "spacemit,k1-i2c";
>>>> +        reg = <0x0 0xd4010800 0x0 0x38>;
>>>> +        interrupt-parent = <&plic>;
>>>> +        interrupts = <36>;
>>>> +        clocks = <&ccu 90>;
>>>> +        clock-frequency = <100000>;
>>>> +    };
>>>> +
>>>> +...
>>>
>>
> 

-- 
Troy Mitchell


From gregkh at linuxfoundation.org  Wed Nov  6 22:35:35 2024
From: gregkh at linuxfoundation.org (Greg KH)
Date: Thu, 7 Nov 2024 07:35:35 +0100
Subject: [for 6.11 PATCH] RISC-V: disallow gcc + rust builds
In-Reply-To: <20241106-happily-unknotted-9984b07a414e@spud>
References: <20241106-happily-unknotted-9984b07a414e@spud>
Message-ID: <2024110724-sleek-emptiness-24b3@gregkh>

On Wed, Nov 06, 2024 at 01:11:29PM +0000, Conor Dooley wrote:
> From: Conor Dooley <conor.dooley at microchip.com>
> 
> commit 33549fcf37ec461f398f0a41e1c9948be2e5aca4 upstream

Thanks for the backport, now queued up.

greg k-h



From irogers at google.com  Wed Nov  6 23:15:53 2024
From: irogers at google.com (Ian Rogers)
Date: Wed,  6 Nov 2024 23:15:53 -0800
Subject: [PATCH v1 0/7] Refactor cpuid and metric table lookup code
Message-ID: <20241107071600.9082-1-irogers@google.com>

Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
lookup:
https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
These patches remove a lot of the logic relating CPUIDs to PMUs so
that the PMU isn't part of the question when finding a metric table.
For time reasons, it doesn't go as far as allowing system metrics
without a metric table as a metric table is needed for metrics to
refer to other metrics, and the refactoring of that resolution is a
hassle.

Ian Rogers (7):
  perf header: Move is_cpu_online to numa bench
  perf header: Refactor get_cpuid to take a CPU for ARM
  perf arm64 header: Use cpu argument in get_cpuid
  perf header: Avoid transitive PMU includes
  perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
  perf jevents: Add map_for_cpu
  perf pmu: Move pmu_metrics_table__find and remove ARM override

 tools/perf/arch/arm64/util/arm-spe.c     | 14 +---
 tools/perf/arch/arm64/util/header.c      | 73 ++++++++++-----------
 tools/perf/arch/arm64/util/pmu.c         | 20 ------
 tools/perf/arch/loongarch/util/header.c  |  4 +-
 tools/perf/arch/powerpc/util/header.c    |  4 +-
 tools/perf/arch/riscv/util/header.c      |  4 +-
 tools/perf/arch/s390/util/header.c       |  6 +-
 tools/perf/arch/x86/util/auxtrace.c      |  3 +-
 tools/perf/arch/x86/util/header.c        |  5 +-
 tools/perf/bench/numa.c                  | 51 +++++++++++++++
 tools/perf/builtin-kvm.c                 |  4 +-
 tools/perf/pmu-events/empty-pmu-events.c | 39 ++++++-----
 tools/perf/pmu-events/jevents.py         | 39 ++++++-----
 tools/perf/pmu-events/pmu-events.h       |  2 +-
 tools/perf/tests/expr.c                  |  5 +-
 tools/perf/util/env.c                    |  4 +-
 tools/perf/util/expr.c                   |  6 +-
 tools/perf/util/header.c                 | 82 ++++++++----------------
 tools/perf/util/header.h                 | 23 +++----
 tools/perf/util/pmu.c                    | 25 --------
 tools/perf/util/pmu.h                    |  2 -
 tools/perf/util/probe-event.c            |  1 +
 22 files changed, 187 insertions(+), 229 deletions(-)

-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Wed Nov  6 23:15:54 2024
From: irogers at google.com (Ian Rogers)
Date: Wed,  6 Nov 2024 23:15:54 -0800
Subject: [PATCH v1 1/7] perf header: Move is_cpu_online to numa bench
In-Reply-To: <20241107071600.9082-1-irogers@google.com>
References: <20241107071600.9082-1-irogers@google.com>
Message-ID: <20241107071600.9082-2-irogers@google.com>

The helper function is only used in the NUMA benchmark as typically
online CPUs are determined through
perf_cpu_map__new_online_cpus(). Reduce the scope of the function for
now.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/bench/numa.c  | 51 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/header.c | 51 ----------------------------------------
 tools/perf/util/header.h |  1 -
 3 files changed, 51 insertions(+), 52 deletions(-)

diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 1fbd7c947abc..611451dbc234 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -533,6 +533,57 @@ static int parse_cpu_list(const char *arg)
 	return 0;
 }
 
+/*
+ * Check whether a CPU is online
+ *
+ * Returns:
+ *     1 -> if CPU is online
+ *     0 -> if CPU is offline
+ *    -1 -> error case
+ */
+static int is_cpu_online(unsigned int cpu)
+{
+	char *str;
+	size_t strlen;
+	char buf[256];
+	int status = -1;
+	struct stat statbuf;
+
+	snprintf(buf, sizeof(buf),
+		"/sys/devices/system/cpu/cpu%d", cpu);
+	if (stat(buf, &statbuf) != 0)
+		return 0;
+
+	/*
+	 * Check if /sys/devices/system/cpu/cpux/online file
+	 * exists. Some cases cpu0 won't have online file since
+	 * it is not expected to be turned off generally.
+	 * In kernels without CONFIG_HOTPLUG_CPU, this
+	 * file won't exist
+	 */
+	snprintf(buf, sizeof(buf),
+		"/sys/devices/system/cpu/cpu%d/online", cpu);
+	if (stat(buf, &statbuf) != 0)
+		return 1;
+
+	/*
+	 * Read online file using sysfs__read_str.
+	 * If read or open fails, return -1.
+	 * If read succeeds, return value from file
+	 * which gets stored in "str"
+	 */
+	snprintf(buf, sizeof(buf),
+		"devices/system/cpu/cpu%d/online", cpu);
+
+	if (sysfs__read_str(buf, &str, &strlen) < 0)
+		return status;
+
+	status = atoi(str);
+
+	free(str);
+	return status;
+}
+
 static int parse_setup_cpu_list(void)
 {
 	struct thread_data *td;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a6386d12afd7..55c28e4377ec 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -987,57 +987,6 @@ static int write_dir_format(struct feat_fd *ff,
 	return do_write(ff, &data->dir.version, sizeof(data->dir.version));
 }
 
-/*
- * Check whether a CPU is online
- *
- * Returns:
- *     1 -> if CPU is online
- *     0 -> if CPU is offline
- *    -1 -> error case
- */
-int is_cpu_online(unsigned int cpu)
-{
-	char *str;
-	size_t strlen;
-	char buf[256];
-	int status = -1;
-	struct stat statbuf;
-
-	snprintf(buf, sizeof(buf),
-		"/sys/devices/system/cpu/cpu%d", cpu);
-	if (stat(buf, &statbuf) != 0)
-		return 0;
-
-	/*
-	 * Check if /sys/devices/system/cpu/cpux/online file
-	 * exists. Some cases cpu0 won't have online file since
-	 * it is not expected to be turned off generally.
-	 * In kernels without CONFIG_HOTPLUG_CPU, this
-	 * file won't exist
-	 */
-	snprintf(buf, sizeof(buf),
-		"/sys/devices/system/cpu/cpu%d/online", cpu);
-	if (stat(buf, &statbuf) != 0)
-		return 1;
-
-	/*
-	 * Read online file using sysfs__read_str.
-	 * If read or open fails, return -1.
-	 * If read succeeds, return value from file
-	 * which gets stored in "str"
-	 */
-	snprintf(buf, sizeof(buf),
-		"devices/system/cpu/cpu%d/online", cpu);
-
-	if (sysfs__read_str(buf, &str, &strlen) < 0)
-		return status;
-
-	status = atoi(str);
-
-	free(str);
-	return status;
-}
-
 #ifdef HAVE_LIBBPF_SUPPORT
 static int write_bpf_prog_info(struct feat_fd *ff,
 			       struct evlist *evlist __maybe_unused)
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index a63a361f20f4..e91e89d22537 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -196,7 +196,6 @@ int write_padded(struct feat_fd *fd, const void *bf,
 
 #define MAX_CACHE_LVL 4
 
-int is_cpu_online(unsigned int cpu);
 int build_caches_for_cpu(u32 cpu, struct cpu_cache_level caches[], u32 *cntp);
 
 /*
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Wed Nov  6 23:15:55 2024
From: irogers at google.com (Ian Rogers)
Date: Wed,  6 Nov 2024 23:15:55 -0800
Subject: [PATCH v1 2/7] perf header: Refactor get_cpuid to take a CPU for ARM
In-Reply-To: <20241107071600.9082-1-irogers@google.com>
References: <20241107071600.9082-1-irogers@google.com>
Message-ID: <20241107071600.9082-3-irogers@google.com>

ARM BIG.little has no notion of a constant CPUID for both core
types. To reflect this reality, change the get_cpuid function to also
pass in a possibly unused logical cpu. If the dummy value (-1) is
passed in then ARM can, as currently happens, select the first logical
CPU's "CPUID". The changes to ARM getcpuid happen in a follow up
change.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm64/util/header.c     | 2 +-
 tools/perf/arch/loongarch/util/header.c | 2 +-
 tools/perf/arch/powerpc/util/header.c   | 2 +-
 tools/perf/arch/riscv/util/header.c     | 2 +-
 tools/perf/arch/s390/util/header.c      | 2 +-
 tools/perf/arch/x86/util/auxtrace.c     | 3 ++-
 tools/perf/arch/x86/util/header.c       | 2 +-
 tools/perf/builtin-kvm.c                | 4 +++-
 tools/perf/util/env.c                   | 3 ++-
 tools/perf/util/header.c                | 9 +++++----
 tools/perf/util/header.h                | 2 +-
 11 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index 741df3614a09..760c21784713 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -50,7 +50,7 @@ static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
 	return ret;
 }
 
-int get_cpuid(char *buf, size_t sz)
+int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	struct perf_cpu_map *cpus = perf_cpu_map__new_online_cpus();
 	int ret;
diff --git a/tools/perf/arch/loongarch/util/header.c b/tools/perf/arch/loongarch/util/header.c
index d962dff55512..f1f0b116962d 100644
--- a/tools/perf/arch/loongarch/util/header.c
+++ b/tools/perf/arch/loongarch/util/header.c
@@ -70,7 +70,7 @@ static char *_get_cpuid(void)
 	return cpuid;
 }
 
-int get_cpuid(char *buffer, size_t sz)
+int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	int ret = 0;
 	char *cpuid = _get_cpuid();
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
index 251cdbf58a4d..6d1a63a2922f 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -24,7 +24,7 @@ static bool is_compat_mode(void)
 }
 
 int
-get_cpuid(char *buffer, size_t sz)
+get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	unsigned long pvr;
 	int nb;
diff --git a/tools/perf/arch/riscv/util/header.c b/tools/perf/arch/riscv/util/header.c
index 1b29030021ee..ebac294c877f 100644
--- a/tools/perf/arch/riscv/util/header.c
+++ b/tools/perf/arch/riscv/util/header.c
@@ -81,7 +81,7 @@ static char *_get_cpuid(void)
 	return cpuid;
 }
 
-int get_cpuid(char *buffer, size_t sz)
+int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	char *cpuid = _get_cpuid();
 	int ret = 0;
diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c
index 7933f6871c81..2add1a561242 100644
--- a/tools/perf/arch/s390/util/header.c
+++ b/tools/perf/arch/s390/util/header.c
@@ -27,7 +27,7 @@
 #define SYSINFO		"/proc/sysinfo"
 #define SRVLVL		"/proc/service_levels"
 
-int get_cpuid(char *buffer, size_t sz)
+int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	char *cp, *line = NULL, *line2;
 	char type[8], model[33], version[8], manufacturer[32], authorization[8];
diff --git a/tools/perf/arch/x86/util/auxtrace.c b/tools/perf/arch/x86/util/auxtrace.c
index 354780ff1605..ecbf61a7eb3a 100644
--- a/tools/perf/arch/x86/util/auxtrace.c
+++ b/tools/perf/arch/x86/util/auxtrace.c
@@ -55,11 +55,12 @@ struct auxtrace_record *auxtrace_record__init(struct evlist *evlist,
 					      int *err)
 {
 	char buffer[64];
+	struct perf_cpu cpu = perf_cpu_map__min(evlist->core.all_cpus);
 	int ret;
 
 	*err = 0;
 
-	ret = get_cpuid(buffer, sizeof(buffer));
+	ret = get_cpuid(buffer, sizeof(buffer), cpu);
 	if (ret) {
 		*err = ret;
 		return NULL;
diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c
index a51444a77a5f..690f86cbbb1c 100644
--- a/tools/perf/arch/x86/util/header.c
+++ b/tools/perf/arch/x86/util/header.c
@@ -58,7 +58,7 @@ __get_cpuid(char *buffer, size_t sz, const char *fmt)
 }
 
 int
-get_cpuid(char *buffer, size_t sz)
+get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	return __get_cpuid(buffer, sz, "%s,%u,%u,%u$");
 }
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 099ce3ebf67c..274568d712d1 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1226,7 +1226,9 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm)
 	int err;
 
 	if (kvm->live) {
-		err = get_cpuid(buf, sizeof(buf));
+		struct perf_cpu cpu = {-1};
+
+		err = get_cpuid(buf, sizeof(buf), cpu);
 		if (err != 0) {
 			pr_err("Failed to look up CPU type: %s\n",
 			       str_error_r(err, buf, sizeof(buf)));
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index ccb464026642..93cabdd7ff43 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -373,7 +373,8 @@ int perf_env__read_pmu_mappings(struct perf_env *env)
 int perf_env__read_cpuid(struct perf_env *env)
 {
 	char cpuid[128];
-	int err = get_cpuid(cpuid, sizeof(cpuid));
+	struct perf_cpu cpu = {-1};
+	int err = get_cpuid(cpuid, sizeof(cpuid), cpu);
 
 	if (err)
 		return err;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 55c28e4377ec..60b42ddc3dac 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -856,18 +856,19 @@ int __weak strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
  * default get_cpuid(): nothing gets recorded
  * actual implementation must be in arch/$(SRCARCH)/util/header.c
  */
-int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused)
+int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused,
+		     struct perf_cpu cpu __maybe_unused)
 {
 	return ENOSYS; /* Not implemented */
 }
 
-static int write_cpuid(struct feat_fd *ff,
-		       struct evlist *evlist __maybe_unused)
+static int write_cpuid(struct feat_fd *ff, struct evlist *evlist)
 {
+	struct perf_cpu cpu = perf_cpu_map__min(evlist->core.all_cpus);
 	char buffer[64];
 	int ret;
 
-	ret = get_cpuid(buffer, sizeof(buffer));
+	ret = get_cpuid(buffer, sizeof(buffer), cpu);
 	if (ret)
 		return -1;
 
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index e91e89d22537..b77f89de12dd 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -201,7 +201,7 @@ int build_caches_for_cpu(u32 cpu, struct cpu_cache_level caches[], u32 *cntp);
 /*
  * arch specific callback
  */
-int get_cpuid(char *buffer, size_t sz);
+int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu);
 
 char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused);
 int strcmp_cpuid_str(const char *s1, const char *s2);
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Wed Nov  6 23:15:56 2024
From: irogers at google.com (Ian Rogers)
Date: Wed,  6 Nov 2024 23:15:56 -0800
Subject: [PATCH v1 3/7] perf arm64 header: Use cpu argument in get_cpuid
In-Reply-To: <20241107071600.9082-1-irogers@google.com>
References: <20241107071600.9082-1-irogers@google.com>
Message-ID: <20241107071600.9082-4-irogers@google.com>

Use the cpu to read the MIDR file requested. If the "any" value (-1)
is passed that keep the behavior of returning the first MIDR file that
can be read.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm64/util/header.c | 63 ++++++++++++++---------------
 tools/perf/util/header.h            |  1 +
 2 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index 760c21784713..f0907daad3ae 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -14,55 +14,52 @@
 #define MIDR_REVISION_MASK      GENMASK(3, 0)
 #define MIDR_VARIANT_MASK	GENMASK(23, 20)
 
-static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
+static int _get_cpuid(char *buf, size_t sz, struct perf_cpu cpu)
 {
+	char path[PATH_MAX];
+	FILE *file;
 	const char *sysfs = sysfs__mountpoint();
-	struct perf_cpu cpu;
-	int idx, ret = EINVAL;
 
+	assert(cpu.cpu != -1);
 	if (!sysfs || sz < MIDR_SIZE)
 		return EINVAL;
 
-	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
-		char path[PATH_MAX];
-		FILE *file;
-
-		scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d" MIDR,
-			  sysfs, cpu.cpu);
-
-		file = fopen(path, "r");
-		if (!file) {
-			pr_debug("fopen failed for file %s\n", path);
-			continue;
-		}
-
-		if (!fgets(buf, MIDR_SIZE, file)) {
-			fclose(file);
-			continue;
-		}
-		fclose(file);
+	scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d" MIDR, sysfs, cpu.cpu);
 
-		/* got midr break loop */
-		ret = 0;
-		break;
+	file = fopen(path, "r");
+	if (!file) {
+		pr_debug("fopen failed for file %s\n", path);
+		return EINVAL;
 	}
 
-	return ret;
+	if (!fgets(buf, MIDR_SIZE, file)) {
+		pr_debug("Failed to read file %s\n", path);
+		fclose(file);
+		return EINVAL;
+	}
+	fclose(file);
+	return 0;
 }
 
-int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu __maybe_unused)
+int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu)
 {
-	struct perf_cpu_map *cpus = perf_cpu_map__new_online_cpus();
-	int ret;
+	struct perf_cpu_map *cpus;
+	int idx;
+
+	if (cpu.cpu != -1)
+		return _get_cpuid(buf, sz, cpu);
 
+	cpus = perf_cpu_map__new_online_cpus();
 	if (!cpus)
 		return EINVAL;
 
-	ret = _get_cpuid(buf, sz, cpus);
-
-	perf_cpu_map__put(cpus);
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
+		int ret = _get_cpuid(buf, sz, cpu);
 
-	return ret;
+		if (ret == 0)
+			return 0;
+	}
+	return EINVAL;
 }
 
 char *get_cpuid_str(struct perf_pmu *pmu)
@@ -78,7 +75,7 @@ char *get_cpuid_str(struct perf_pmu *pmu)
 		return NULL;
 
 	/* read midr from list of cpus mapped to this pmu */
-	res = _get_cpuid(buf, MIDR_SIZE, pmu->cpus);
+	res = get_cpuid(buf, MIDR_SIZE, perf_cpu_map__min(pmu->cpus));
 	if (res) {
 		pr_err("failed to get cpuid string for PMU %s\n", pmu->name);
 		free(buf);
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index b77f89de12dd..3bb768455a60 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include "env.h"
 #include "pmu.h"
+#include <perf/cpumap.h>
 
 enum {
 	HEADER_RESERVED		= 0,	/* always cleared */
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Wed Nov  6 23:15:57 2024
From: irogers at google.com (Ian Rogers)
Date: Wed,  6 Nov 2024 23:15:57 -0800
Subject: [PATCH v1 4/7] perf header: Avoid transitive PMU includes
In-Reply-To: <20241107071600.9082-1-irogers@google.com>
References: <20241107071600.9082-1-irogers@google.com>
Message-ID: <20241107071600.9082-5-irogers@google.com>

Currently satisfied via header.h. Note, pmu.h includes parse-events.h.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/expr.c       | 2 ++
 tools/perf/util/env.c         | 1 +
 tools/perf/util/probe-event.c | 1 +
 3 files changed, 4 insertions(+)

diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index e3aa9d4fcf3a..d60f1ac1d720 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -4,6 +4,8 @@
 #include "util/expr.h"
 #include "util/hashmap.h"
 #include "util/header.h"
+#include "util/pmu.h"
+#include "util/pmus.h"
 #include "util/smt.h"
 #include "tests.h"
 #include <math.h>
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index 93cabdd7ff43..e2843ca2edd9 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -12,6 +12,7 @@
 #include <sys/utsname.h>
 #include <stdlib.h>
 #include <string.h>
+#include "pmu.h"
 #include "pmus.h"
 #include "strbuf.h"
 #include "trace/beauty/beauty.h"
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index a580aa2cd512..d399c7e03341 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -40,6 +40,7 @@
 #include "session.h"
 #include "string2.h"
 #include "strbuf.h"
+#include "parse-events.h"
 
 #include <subcmd/pager.h>
 #include <linux/ctype.h>
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Wed Nov  6 23:15:58 2024
From: irogers at google.com (Ian Rogers)
Date: Wed,  6 Nov 2024 23:15:58 -0800
Subject: [PATCH v1 5/7] perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
In-Reply-To: <20241107071600.9082-1-irogers@google.com>
References: <20241107071600.9082-1-irogers@google.com>
Message-ID: <20241107071600.9082-6-irogers@google.com>

On ARM the cpuid is dependent on the core type of the CPU in
question. The PMU was passed for the sake of the CPU map but this
means in places a temporary PMU is created just to pass a CPU
value. Just pass the CPU and fix up the callers.

As there are no longer PMU users in header.h, shuffle forward
declarations earlier to work around build failures.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm64/util/arm-spe.c     | 14 ++------------
 tools/perf/arch/arm64/util/header.c      | 12 ++++--------
 tools/perf/arch/loongarch/util/header.c  |  2 +-
 tools/perf/arch/powerpc/util/header.c    |  2 +-
 tools/perf/arch/riscv/util/header.c      |  2 +-
 tools/perf/arch/s390/util/header.c       |  4 ++--
 tools/perf/arch/x86/util/header.c        |  3 +--
 tools/perf/pmu-events/empty-pmu-events.c |  5 ++++-
 tools/perf/pmu-events/jevents.py         |  5 ++++-
 tools/perf/tests/expr.c                  |  7 +++----
 tools/perf/util/expr.c                   |  6 +++---
 tools/perf/util/header.c                 | 22 +++++++++++++++++++++-
 tools/perf/util/header.h                 | 19 ++++++++++---------
 tools/perf/util/pmu.c                    | 20 --------------------
 tools/perf/util/pmu.h                    |  1 -
 15 files changed, 57 insertions(+), 67 deletions(-)

diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 7ccdea3cd461..22b19dcc6beb 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -23,6 +23,7 @@
 #include "../../../util/debug.h"
 #include "../../../util/auxtrace.h"
 #include "../../../util/record.h"
+#include "../../../util/header.h"
 #include "../../../util/arm-spe.h"
 #include <tools/libc_compat.h> // reallocarray
 
@@ -85,22 +86,11 @@ static int arm_spe_save_cpu_header(struct auxtrace_record *itr,
 	struct arm_spe_recording *sper =
 			container_of(itr, struct arm_spe_recording, itr);
 	struct perf_pmu *pmu = NULL;
-	struct perf_pmu tmp_pmu;
-	char cpu_id_str[16];
 	char *cpuid = NULL;
 	u64 val;
 
-	snprintf(cpu_id_str, sizeof(cpu_id_str), "%d", cpu.cpu);
-	tmp_pmu.cpus = perf_cpu_map__new(cpu_id_str);
-	if (!tmp_pmu.cpus)
-		return -ENOMEM;
-
 	/* Read CPU MIDR */
-	cpuid = perf_pmu__getcpuid(&tmp_pmu);
-
-	/* The CPU map will not be used anymore, release it */
-	perf_cpu_map__put(tmp_pmu.cpus);
-
+	cpuid = get_cpuid_allow_env_override(cpu);
 	if (!cpuid)
 		return -ENOMEM;
 	val = strtol(cpuid, NULL, 16);
diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index f0907daad3ae..f445a2dd6293 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -62,22 +62,18 @@ int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu)
 	return EINVAL;
 }
 
-char *get_cpuid_str(struct perf_pmu *pmu)
+char *get_cpuid_str(struct perf_cpu cpu)
 {
-	char *buf = NULL;
+	char *buf = malloc(MIDR_SIZE);
 	int res;
 
-	if (!pmu || !pmu->cpus)
-		return NULL;
-
-	buf = malloc(MIDR_SIZE);
 	if (!buf)
 		return NULL;
 
 	/* read midr from list of cpus mapped to this pmu */
-	res = get_cpuid(buf, MIDR_SIZE, perf_cpu_map__min(pmu->cpus));
+	res = get_cpuid(buf, MIDR_SIZE, cpu);
 	if (res) {
-		pr_err("failed to get cpuid string for PMU %s\n", pmu->name);
+		pr_err("failed to get cpuid string for CPU %d\n", cpu.cpu);
 		free(buf);
 		buf = NULL;
 	}
diff --git a/tools/perf/arch/loongarch/util/header.c b/tools/perf/arch/loongarch/util/header.c
index f1f0b116962d..0c6d823334a2 100644
--- a/tools/perf/arch/loongarch/util/header.c
+++ b/tools/perf/arch/loongarch/util/header.c
@@ -90,7 +90,7 @@ int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 	return ret;
 }
 
-char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char *get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	return _get_cpuid();
 }
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
index 6d1a63a2922f..c7df534dbf8f 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -42,7 +42,7 @@ get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 }
 
 char *
-get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	char *bufp;
 	unsigned long pvr;
diff --git a/tools/perf/arch/riscv/util/header.c b/tools/perf/arch/riscv/util/header.c
index ebac294c877f..4b839203d4a5 100644
--- a/tools/perf/arch/riscv/util/header.c
+++ b/tools/perf/arch/riscv/util/header.c
@@ -98,7 +98,7 @@ int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 }
 
 char *
-get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	return _get_cpuid();
 }
diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c
index 2add1a561242..db54677a17d2 100644
--- a/tools/perf/arch/s390/util/header.c
+++ b/tools/perf/arch/s390/util/header.c
@@ -137,11 +137,11 @@ int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 	return (nbytes >= sz) ? ENOBUFS : 0;
 }
 
-char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char *get_cpuid_str(struct perf_cpu cpu)
 {
 	char *buf = malloc(128);
 
-	if (buf && get_cpuid(buf, 128))
+	if (buf && get_cpuid(buf, 128, cpu))
 		zfree(&buf);
 	return buf;
 }
diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c
index 690f86cbbb1c..412977f8aa83 100644
--- a/tools/perf/arch/x86/util/header.c
+++ b/tools/perf/arch/x86/util/header.c
@@ -63,8 +63,7 @@ get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 	return __get_cpuid(buffer, sz, "%s,%u,%u,%u$");
 }
 
-char *
-get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char *get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	char *buf = malloc(128);
 
diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index 2b7516946ded..1f7f39a89ffd 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -515,13 +515,16 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
         } last_map_search;
         static bool has_last_result, has_last_map_search;
         const struct pmu_events_map *map = NULL;
+        struct perf_cpu cpu = {-1};
         char *cpuid = NULL;
         size_t i;
 
         if (has_last_result && last_result.pmu == pmu)
                 return last_result.map;
 
-        cpuid = perf_pmu__getcpuid(pmu);
+        if (pmu)
+                cpu = perf_cpu_map__min(pmu->cpus);
+        cpuid = get_cpuid_allow_env_override(cpu);
 
         /*
          * On some platforms which uses cpus map, cpuid can be NULL for
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 6e71b09dbc2a..17cd1b1c6b66 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1031,13 +1031,16 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
         } last_map_search;
         static bool has_last_result, has_last_map_search;
         const struct pmu_events_map *map = NULL;
+        struct perf_cpu cpu = {-1};
         char *cpuid = NULL;
         size_t i;
 
         if (has_last_result && last_result.pmu == pmu)
                 return last_result.map;
 
-        cpuid = perf_pmu__getcpuid(pmu);
+        if (pmu)
+                cpu = perf_cpu_map__min(pmu->cpus);
+        cpuid = get_cpuid_allow_env_override(cpu);
 
         /*
          * On some platforms which uses cpus map, cpuid can be NULL for
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index d60f1ac1d720..41ff1affdfcd 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -4,10 +4,9 @@
 #include "util/expr.h"
 #include "util/hashmap.h"
 #include "util/header.h"
-#include "util/pmu.h"
-#include "util/pmus.h"
 #include "util/smt.h"
 #include "tests.h"
+#include <perf/cpumap.h>
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
@@ -78,8 +77,8 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u
 	struct expr_parse_ctx *ctx;
 	bool is_intel = false;
 	char strcmp_cpuid_buf[256];
-	struct perf_pmu *pmu = perf_pmus__find_core_pmu();
-	char *cpuid = perf_pmu__getcpuid(pmu);
+	struct perf_cpu cpu = {-1};
+	char *cpuid = get_cpuid_allow_env_override(cpu);
 	char *escaped_cpuid1, *escaped_cpuid2;
 
 	TEST_ASSERT_VAL("get_cpuid", cpuid);
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 5e3732bc2fa5..f289044a1f7c 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -8,7 +8,6 @@
 #include "debug.h"
 #include "evlist.h"
 #include "expr.h"
-#include "pmu.h"
 #include "smt.h"
 #include "tool_pmu.h"
 #include <util/expr-bison.h>
@@ -16,6 +15,7 @@
 #include "util/hashmap.h"
 #include "util/header.h"
 #include "util/pmu.h"
+#include <perf/cpumap.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/zalloc.h>
@@ -456,8 +456,8 @@ double expr__strcmp_cpuid_str(const struct expr_parse_ctx *ctx __maybe_unused,
 		       bool compute_ids __maybe_unused, const char *test_id)
 {
 	double ret;
-	struct perf_pmu *pmu = perf_pmus__find_core_pmu();
-	char *cpuid = perf_pmu__getcpuid(pmu);
+	struct perf_cpu cpu = {-1};
+	char *cpuid = get_cpuid_allow_env_override(cpu);
 
 	if (!cpuid)
 		return NAN;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 60b42ddc3dac..06ca5762f61f 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -819,11 +819,31 @@ static int write_group_desc(struct feat_fd *ff,
  * Each architecture should provide a more precise id string that
  * can be use to match the architecture's "mapfile".
  */
-char * __weak get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char * __weak get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	return NULL;
 }
 
+char *get_cpuid_allow_env_override(struct perf_cpu cpu)
+{
+	char *cpuid;
+	static bool printed;
+
+	cpuid = getenv("PERF_CPUID");
+	if (cpuid)
+		cpuid = strdup(cpuid);
+	if (!cpuid)
+		cpuid = get_cpuid_str(cpu);
+	if (!cpuid)
+		return NULL;
+
+	if (!printed) {
+		pr_debug("Using CPUID %s\n", cpuid);
+		printed = true;
+	}
+	return cpuid;
+}
+
 /* Return zero when the cpuid from the mapfile.csv matches the
  * cpuid string generated on this platform.
  * Otherwise return non-zero.
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 3bb768455a60..5201af6305f4 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -10,9 +10,14 @@
 #include <linux/bitmap.h>
 #include <linux/types.h>
 #include "env.h"
-#include "pmu.h"
 #include <perf/cpumap.h>
 
+struct evlist;
+union perf_event;
+struct perf_header;
+struct perf_session;
+struct perf_tool;
+
 enum {
 	HEADER_RESERVED		= 0,	/* always cleared */
 	HEADER_FIRST_FEATURE	= 1,
@@ -92,8 +97,6 @@ struct perf_pipe_file_header {
 	u64				size;
 };
 
-struct perf_header;
-
 int perf_file_header__read(struct perf_file_header *header,
 			   struct perf_header *ph, int fd);
 
@@ -125,11 +128,6 @@ struct perf_header_feature_ops {
 	bool	   synthesize;
 };
 
-struct evlist;
-struct perf_session;
-struct perf_tool;
-union perf_event;
-
 extern const char perf_version_string[];
 
 int perf_session__read_header(struct perf_session *session);
@@ -204,6 +202,9 @@ int build_caches_for_cpu(u32 cpu, struct cpu_cache_level caches[], u32 *cntp);
  */
 int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu);
 
-char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused);
+char *get_cpuid_str(struct perf_cpu cpu);
+
+char *get_cpuid_allow_env_override(struct perf_cpu cpu);
+
 int strcmp_cpuid_str(const char *s1, const char *s2);
 #endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 0789758598c0..514cb865f57b 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -818,26 +818,6 @@ static int is_sysfs_pmu_core(const char *name)
 	return file_available(path);
 }
 
-char *perf_pmu__getcpuid(struct perf_pmu *pmu)
-{
-	char *cpuid;
-	static bool printed;
-
-	cpuid = getenv("PERF_CPUID");
-	if (cpuid)
-		cpuid = strdup(cpuid);
-	if (!cpuid)
-		cpuid = get_cpuid_str(pmu);
-	if (!cpuid)
-		return NULL;
-
-	if (!printed) {
-		pr_debug("Using CPUID %s\n", cpuid);
-		printed = true;
-	}
-	return cpuid;
-}
-
 __weak const struct pmu_metrics_table *pmu_metrics_table__find(void)
 {
 	return perf_pmu__find_metrics_table(NULL);
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index b86b3c3685a2..fba3fc608b64 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -260,7 +260,6 @@ void perf_pmu__arch_init(struct perf_pmu *pmu);
 void pmu_add_cpu_aliases_table(struct perf_pmu *pmu,
 			       const struct pmu_events_table *table);
 
-char *perf_pmu__getcpuid(struct perf_pmu *pmu);
 const struct pmu_metrics_table *pmu_metrics_table__find(void);
 bool pmu_uncore_identifier_match(const char *compat, const char *id);
 
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Wed Nov  6 23:15:59 2024
From: irogers at google.com (Ian Rogers)
Date: Wed,  6 Nov 2024 23:15:59 -0800
Subject: [PATCH v1 6/7] perf jevents: Add map_for_cpu
In-Reply-To: <20241107071600.9082-1-irogers@google.com>
References: <20241107071600.9082-1-irogers@google.com>
Message-ID: <20241107071600.9082-7-irogers@google.com>

The PMU is no longer part of the map finding process and for metrics
doesn't make sense as they lack a PMU.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/pmu-events/empty-pmu-events.c | 20 +++++++++++++-------
 tools/perf/pmu-events/jevents.py         | 20 +++++++++++++-------
 2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index 1f7f39a89ffd..2151e8a43f16 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -503,11 +503,11 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table,
         return 0;
 }
 
-static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+static const struct pmu_events_map *map_for_cpu(struct perf_cpu cpu)
 {
         static struct {
                 const struct pmu_events_map *map;
-                struct perf_pmu *pmu;
+                struct perf_cpu cpu;
         } last_result;
         static struct {
                 const struct pmu_events_map *map;
@@ -515,15 +515,12 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
         } last_map_search;
         static bool has_last_result, has_last_map_search;
         const struct pmu_events_map *map = NULL;
-        struct perf_cpu cpu = {-1};
         char *cpuid = NULL;
         size_t i;
 
-        if (has_last_result && last_result.pmu == pmu)
+        if (has_last_result && last_result.cpu.cpu == cpu.cpu)
                 return last_result.map;
 
-        if (pmu)
-                cpu = perf_cpu_map__min(pmu->cpus);
         cpuid = get_cpuid_allow_env_override(cpu);
 
         /*
@@ -555,12 +552,21 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
                has_last_map_search = true;
         }
 out_update_last_result:
-        last_result.pmu = pmu;
+        last_result.cpu = cpu;
         last_result.map = map;
         has_last_result = true;
         return map;
 }
 
+static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+{
+        struct perf_cpu cpu = {-1};
+
+        if (pmu)
+                cpu = perf_cpu_map__min(pmu->cpus);
+        return map_for_cpu(cpu);
+}
+
 const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
 {
         const struct pmu_events_map *map = map_for_pmu(pmu);
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 17cd1b1c6b66..6d6780ca0889 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1019,11 +1019,11 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table,
         return 0;
 }
 
-static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+static const struct pmu_events_map *map_for_cpu(struct perf_cpu cpu)
 {
         static struct {
                 const struct pmu_events_map *map;
-                struct perf_pmu *pmu;
+                struct perf_cpu cpu;
         } last_result;
         static struct {
                 const struct pmu_events_map *map;
@@ -1031,15 +1031,12 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
         } last_map_search;
         static bool has_last_result, has_last_map_search;
         const struct pmu_events_map *map = NULL;
-        struct perf_cpu cpu = {-1};
         char *cpuid = NULL;
         size_t i;
 
-        if (has_last_result && last_result.pmu == pmu)
+        if (has_last_result && last_result.cpu.cpu == cpu.cpu)
                 return last_result.map;
 
-        if (pmu)
-                cpu = perf_cpu_map__min(pmu->cpus);
         cpuid = get_cpuid_allow_env_override(cpu);
 
         /*
@@ -1071,12 +1068,21 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
                has_last_map_search = true;
         }
 out_update_last_result:
-        last_result.pmu = pmu;
+        last_result.cpu = cpu;
         last_result.map = map;
         has_last_result = true;
         return map;
 }
 
+static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+{
+        struct perf_cpu cpu = {-1};
+
+        if (pmu)
+                cpu = perf_cpu_map__min(pmu->cpus);
+        return map_for_cpu(cpu);
+}
+
 const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
 {
         const struct pmu_events_map *map = map_for_pmu(pmu);
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Wed Nov  6 23:16:00 2024
From: irogers at google.com (Ian Rogers)
Date: Wed,  6 Nov 2024 23:16:00 -0800
Subject: [PATCH v1 7/7] perf pmu: Move pmu_metrics_table__find and remove ARM override
In-Reply-To: <20241107071600.9082-1-irogers@google.com>
References: <20241107071600.9082-1-irogers@google.com>
Message-ID: <20241107071600.9082-8-irogers@google.com>

Move pmu_metrics_table__find to the jevents.py generated pmu-events.c
and remove indirection override for ARM. The movement removes
perf_pmu__find_metrics_table that exists to enable the ARM
override. The ARM override isn't necessary as just the CPUID, not PMU,
is used in the metric table lookup. On non-ARM the CPU argument is
just ignored for the CPUID, for ARM -1 is passed so that the CPUID for
the first logical CPU is read.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm64/util/pmu.c         | 20 --------------------
 tools/perf/pmu-events/empty-pmu-events.c | 20 ++++----------------
 tools/perf/pmu-events/jevents.py         | 20 ++++----------------
 tools/perf/pmu-events/pmu-events.h       |  2 +-
 tools/perf/util/pmu.c                    |  5 -----
 tools/perf/util/pmu.h                    |  1 -
 6 files changed, 9 insertions(+), 59 deletions(-)

diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/pmu.c
index a0964b191fcb..895fb0d0610c 100644
--- a/tools/perf/arch/arm64/util/pmu.c
+++ b/tools/perf/arch/arm64/util/pmu.c
@@ -1,29 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 
-#include <internal/cpumap.h>
-#include "../../../util/cpumap.h"
-#include "../../../util/header.h"
 #include "../../../util/pmu.h"
 #include "../../../util/pmus.h"
 #include "../../../util/tool_pmu.h"
 #include <api/fs/fs.h>
-#include <math.h>
-
-const struct pmu_metrics_table *pmu_metrics_table__find(void)
-{
-	struct perf_pmu *pmu;
-
-	/* Metrics aren't currently supported on heterogeneous Arm systems */
-	if (perf_pmus__num_core_pmus() > 1)
-		return NULL;
-
-	/* Doesn't matter which one here because they'll all be the same */
-	pmu = perf_pmus__find_core_pmu();
-	if (pmu)
-		return perf_pmu__find_metrics_table(pmu);
-
-	return NULL;
-}
 
 u64 tool_pmu__cpu_slots_per_cycle(void)
 {
diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index 2151e8a43f16..1c7a2cfa321f 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -587,24 +587,12 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
         return NULL;
 }
 
-const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
+const struct pmu_metrics_table *pmu_metrics_table__find(void)
 {
-        const struct pmu_events_map *map = map_for_pmu(pmu);
-
-        if (!map)
-                return NULL;
-
-        if (!pmu)
-                return &map->metric_table;
-
-        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
-                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
-                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+        struct perf_cpu cpu = {-1};
+        const struct pmu_events_map *map = map_for_cpu(cpu);
 
-                if (pmu__name_match(pmu, pmu_name))
-                           return &map->metric_table;
-        }
-        return NULL;
+        return map ? &map->metric_table : NULL;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 6d6780ca0889..d781a377757a 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1103,24 +1103,12 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
         return NULL;
 }
 
-const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
+const struct pmu_metrics_table *pmu_metrics_table__find(void)
 {
-        const struct pmu_events_map *map = map_for_pmu(pmu);
-
-        if (!map)
-                return NULL;
-
-        if (!pmu)
-                return &map->metric_table;
-
-        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
-                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
-                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
+        struct perf_cpu cpu = {-1};
+        const struct pmu_events_map *map = map_for_cpu(cpu);
 
-                if (pmu__name_match(pmu, pmu_name))
-                           return &map->metric_table;
-        }
-        return NULL;
+        return map ? &map->metric_table : NULL;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
index 5435ad92180c..675562e6f770 100644
--- a/tools/perf/pmu-events/pmu-events.h
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -103,7 +103,7 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pm
 				     void *data);
 
 const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu);
-const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu);
+const struct pmu_metrics_table *pmu_metrics_table__find(void);
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid);
 const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid);
 int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data);
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 514cb865f57b..45838651b361 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -818,11 +818,6 @@ static int is_sysfs_pmu_core(const char *name)
 	return file_available(path);
 }
 
-__weak const struct pmu_metrics_table *pmu_metrics_table__find(void)
-{
-	return perf_pmu__find_metrics_table(NULL);
-}
-
 /**
  * Return the length of the PMU name not including the suffix for uncore PMUs.
  *
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index fba3fc608b64..7b3e71194e49 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -260,7 +260,6 @@ void perf_pmu__arch_init(struct perf_pmu *pmu);
 void pmu_add_cpu_aliases_table(struct perf_pmu *pmu,
 			       const struct pmu_events_table *table);
 
-const struct pmu_metrics_table *pmu_metrics_table__find(void);
 bool pmu_uncore_identifier_match(const char *compat, const char *id);
 
 int perf_pmu__convert_scale(const char *scale, char **end, double *sval);
-- 
2.47.0.199.ga7371fff76-goog



From xu.yang_2 at nxp.com  Thu Nov  7 01:03:30 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Thu, 7 Nov 2024 17:03:30 +0800
Subject: [PATCH v1 0/7] Refactor cpuid and metric table lookup code
In-Reply-To: <20241107071600.9082-1-irogers@google.com>
References: <20241107071600.9082-1-irogers@google.com>
Message-ID: <20241107082807.ipb7xzqvs24tto2e@hippo>

Hi Ian Rogers,

On Wed, Nov 06, 2024 at 11:15:53PM -0800, Ian Rogers wrote:
> Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
> lookup:
> https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
> These patches remove a lot of the logic relating CPUIDs to PMUs so
> that the PMU isn't part of the question when finding a metric table.
> For time reasons, it doesn't go as far as allowing system metrics
> without a metric table as a metric table is needed for metrics to
> refer to other metrics, and the refactoring of that resolution is a
> hassle.
> 
> Ian Rogers (7):
>   perf header: Move is_cpu_online to numa bench
>   perf header: Refactor get_cpuid to take a CPU for ARM
>   perf arm64 header: Use cpu argument in get_cpuid
>   perf header: Avoid transitive PMU includes
>   perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
>   perf jevents: Add map_for_cpu
>   perf pmu: Move pmu_metrics_table__find and remove ARM override
> 
>  tools/perf/arch/arm64/util/arm-spe.c     | 14 +---
>  tools/perf/arch/arm64/util/header.c      | 73 ++++++++++-----------
>  tools/perf/arch/arm64/util/pmu.c         | 20 ------
>  tools/perf/arch/loongarch/util/header.c  |  4 +-
>  tools/perf/arch/powerpc/util/header.c    |  4 +-
>  tools/perf/arch/riscv/util/header.c      |  4 +-
>  tools/perf/arch/s390/util/header.c       |  6 +-
>  tools/perf/arch/x86/util/auxtrace.c      |  3 +-
>  tools/perf/arch/x86/util/header.c        |  5 +-
>  tools/perf/bench/numa.c                  | 51 +++++++++++++++

Meet error when build perf tool:

  CC      util/levenshtein.o
  CC      tests/mem.o
  CC      util/mmap.o
bench/numa.c: In function ?is_cpu_online?:
bench/numa.c:550:21: error: storage size of ?statbuf? isn?t known
  550 |         struct stat statbuf;
      |                     ^~~~~~~
bench/numa.c:554:13: error: implicit declaration of function ?stat?; did you mean ?strcat?? [-Werror=implicit-function-declaration]
  554 |         if (stat(buf, &statbuf) != 0)
      |             ^~~~
      |             strcat
bench/numa.c:578:13: error: implicit declaration of function ?sysfs__read_str? [-Werror=implicit-function-declaration]
  578 |         if (sysfs__read_str(buf, &str, &strlen) < 0)
      |             ^~~~~~~~~~~~~~~
bench/numa.c:550:21: error: unused variable ?statbuf? [-Werror=unused-variable]
  550 |         struct stat statbuf;
      |                     ^~~~~~~
  CC      tests/cpumap.o
  CC      tests/stat.o

After remove these errors, my issue is disappeared.

Thanks,
Xu Yang

>  tools/perf/builtin-kvm.c                 |  4 +-
>  tools/perf/pmu-events/empty-pmu-events.c | 39 ++++++-----
>  tools/perf/pmu-events/jevents.py         | 39 ++++++-----
>  tools/perf/pmu-events/pmu-events.h       |  2 +-
>  tools/perf/tests/expr.c                  |  5 +-
>  tools/perf/util/env.c                    |  4 +-
>  tools/perf/util/expr.c                   |  6 +-
>  tools/perf/util/header.c                 | 82 ++++++++----------------
>  tools/perf/util/header.h                 | 23 +++----
>  tools/perf/util/pmu.c                    | 25 --------
>  tools/perf/util/pmu.h                    |  2 -
>  tools/perf/util/probe-event.c            |  1 +
>  22 files changed, 187 insertions(+), 229 deletions(-)
> 
> -- 
> 2.47.0.199.ga7371fff76-goog
> 


From jean-philippe at linaro.org  Thu Nov  7 01:13:07 2024
From: jean-philippe at linaro.org (Jean-Philippe Brucker)
Date: Thu, 7 Nov 2024 09:13:07 +0000
Subject: [PATCH] tools: Override makefile ARCH variable if defined, but
 empty
In-Reply-To: <20241106193208.290067-1-bjorn@kernel.org>
References: <20241106193208.290067-1-bjorn@kernel.org>
Message-ID: <20241107091307.GA2016393@myrica>

On Wed, Nov 06, 2024 at 08:32:06PM +0100, Bj?rn T?pel wrote:
> From: Bj?rn T?pel <bjorn at rivosinc.com>
> 
> There are a number of tools (bpftool, selftests), that require a
> "bootstrap" build. Here, a bootstrap build is a build host variant of
> a target. E.g., assume that you're performing a bpftool cross-build on
> x86 to riscv, a bootstrap build would then be an x86 variant of
> bpftool. The typical way to perform the host build variant, is to pass
> "ARCH=" in a sub-make. However, if a variable has been set with a
> command argument, then ordinary assignments in the makefile are
> ignored.
> 
> This side-effect results in that ARCH, and variables depending on ARCH
> are not set.
> 
> Workaround by overriding ARCH to the host arch, if ARCH is empty.
> 
> Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>

Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>

> ---
>  tools/scripts/Makefile.arch | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/scripts/Makefile.arch b/tools/scripts/Makefile.arch
> index f6a50f06dfc4..eabfe9f411d9 100644
> --- a/tools/scripts/Makefile.arch
> +++ b/tools/scripts/Makefile.arch
> @@ -7,8 +7,8 @@ HOSTARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
>                                    -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
>                                    -e s/riscv.*/riscv/ -e s/loongarch.*/loongarch/)
>  
> -ifndef ARCH
> -ARCH := $(HOSTARCH)
> +ifeq ($(strip $(ARCH)),)
> +override ARCH := $(HOSTARCH)
>  endif
>  
>  SRCARCH := $(ARCH)
> 
> base-commit: 7758b206117dab9894f0bcb8333f8e4731c5065a
> -- 
> 2.45.2
> 


From alexghiti at rivosinc.com  Thu Nov  7 02:09:03 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Thu, 7 Nov 2024 11:09:03 +0100
Subject: [PATCH] tools: Override makefile ARCH variable if defined, but empty
In-Reply-To: <20241107091307.GA2016393@myrica>
References: <20241106193208.290067-1-bjorn@kernel.org> <20241107091307.GA2016393@myrica>
Message-ID: <CAHVXubh4A9JY2hVzYW0ES1QxfLL2iYczXBCcr5OXsrYoZcWJKw@mail.gmail.com>

Hi Bj?rn,

On Thu, Nov 7, 2024 at 10:12?AM Jean-Philippe Brucker
<jean-philippe at linaro.org> wrote:
>
> On Wed, Nov 06, 2024 at 08:32:06PM +0100, Bj?rn T?pel wrote:
> > From: Bj?rn T?pel <bjorn at rivosinc.com>
> >
> > There are a number of tools (bpftool, selftests), that require a
> > "bootstrap" build. Here, a bootstrap build is a build host variant of
> > a target. E.g., assume that you're performing a bpftool cross-build on
> > x86 to riscv, a bootstrap build would then be an x86 variant of
> > bpftool. The typical way to perform the host build variant, is to pass
> > "ARCH=" in a sub-make. However, if a variable has been set with a
> > command argument, then ordinary assignments in the makefile are
> > ignored.
> >
> > This side-effect results in that ARCH, and variables depending on ARCH
> > are not set.
> >
> > Workaround by overriding ARCH to the host arch, if ARCH is empty.
> >
> > Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
> > Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
>
> Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
>
> > ---
> >  tools/scripts/Makefile.arch | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/scripts/Makefile.arch b/tools/scripts/Makefile.arch
> > index f6a50f06dfc4..eabfe9f411d9 100644
> > --- a/tools/scripts/Makefile.arch
> > +++ b/tools/scripts/Makefile.arch
> > @@ -7,8 +7,8 @@ HOSTARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
> >                                    -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
> >                                    -e s/riscv.*/riscv/ -e s/loongarch.*/loongarch/)
> >
> > -ifndef ARCH
> > -ARCH := $(HOSTARCH)
> > +ifeq ($(strip $(ARCH)),)
> > +override ARCH := $(HOSTARCH)
> >  endif
> >
> >  SRCARCH := $(ARCH)
> >
> > base-commit: 7758b206117dab9894f0bcb8333f8e4731c5065a
> > --
> > 2.45.2
> >

You can add:

Tested-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex


From conor at kernel.org  Thu Nov  7 02:59:33 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu,  7 Nov 2024 10:59:33 +0000
Subject: [PATCH v6 0/2] PCI: microchip: support using either instance 1 or 2
Message-ID: <20241107-aqueduct-petroleum-c002480ba291@spud>

From: Conor Dooley <conor.dooley at microchip.com>

The current driver and binding for PolarFire SoC's PCI controller assume
that the root port instance in use is instance 1. The second reg
property constitutes the region encompassing both "control" and "bridge"
registers for both instances. In the driver, a fixed offset is applied to
find the base addresses for instance 1's "control" and "bridge"
registers. The BeagleV Fire uses root port instance 2, so something must
be done so that software can differentiate. This series splits the
second reg property in two, with dedicated "control" and "bridge"
entries so that either instance can be used.

Cheers,
Conor.

v6:
- rework commit messages to use Bjorn's preferred "root port" and "root
  complex" wording

v5:
- rebase on top of 6.11-rc1, which brought about a lot of driver change
  due to the plda common driver creation - although little actually
  changed in terms of the lines edited in this patch.

v4:
- fix a cocci warning reported off list about an inconsistent variable
  used between IS_ERR() and PTR_ERR() calls.

v3:
- rename a variable in probe s/axi/apb/

v2:
- try the new reg format before the old one to avoid warnings in the
  good case
- reword $subject for 2/2

CC: Daire McNamara <daire.mcnamara at microchip.com>
CC: Lorenzo Pieralisi <lpieralisi at kernel.org>
CC: Krzysztof Wilczy?ski <kw at linux.com>
CC: Rob Herring <robh at kernel.org>
CC: Bjorn Helgaas <bhelgaas at google.com>
CC: Krzysztof Kozlowski <krzk+dt at kernel.org>
CC: Conor Dooley <conor+dt at kernel.org>
CC: linux-pci at vger.kernel.org
CC: devicetree at vger.kernel.org
CC: linux-kernel at vger.kernel.org
CC: linux-riscv at lists.infradead.org

Conor Dooley (2):
  dt-bindings: PCI: microchip,pcie-host: fix reg properties
  PCI: microchip: rework reg region handing to support using either root
    port 1 or 2

 .../bindings/pci/microchip,pcie-host.yaml     |  11 +-
 .../pci/plda,xpressrich3-axi-common.yaml      |  14 ++-
 .../bindings/pci/starfive,jh7110-pcie.yaml    |   7 ++
 .../pci/controller/plda/pcie-microchip-host.c | 116 +++++++++---------
 4 files changed, 87 insertions(+), 61 deletions(-)

-- 
2.45.2



From conor at kernel.org  Thu Nov  7 02:59:34 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu,  7 Nov 2024 10:59:34 +0000
Subject: [PATCH v6 1/2] dt-bindings: PCI: microchip,pcie-host: fix reg properties
In-Reply-To: <20241107-aqueduct-petroleum-c002480ba291@spud>
References: <20241107-aqueduct-petroleum-c002480ba291@spud>
Message-ID: <20241107-barcode-whinny-b1a4e8834b4f@spud>

From: Conor Dooley <conor.dooley at microchip.com>

The PCI host controller on PolarFire SoC has multiple root port
instances, each with their own bridge and ctrl address spaces. The
original binding has an "apb" register region, and it is expected to
be set to the base address of the root complex' register space. Some
defines in the Linux driver were used to compute the addresses of the
bridge and ctrl address ranges corresponding to root port instance 1.
Some customers want to use root port instance 2 however, which requires
changing the defines in the driver, which is clearly not a portable
solution.

Remove this "apb" register region from the binding and add "bridge" &
"ctrl" regions instead, that will directly communicate the address of
these regions for a specific root port.

Fixes: 6ee6c89aac35 ("dt-bindings: PCI: microchip: Add Microchip PolarFire host binding")
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Acked-by: Daire McNamara <daire.mcnamara at microchip.com>
Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
---
 .../bindings/pci/microchip,pcie-host.yaml          | 11 +++++++++--
 .../bindings/pci/plda,xpressrich3-axi-common.yaml  | 14 ++++++++++----
 .../bindings/pci/starfive,jh7110-pcie.yaml         |  7 +++++++
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
index 612633ba59e2..2e1547569702 100644
--- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
+++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
@@ -17,6 +17,12 @@ properties:
   compatible:
     const: microchip,pcie-host-1.0 # PolarFire
 
+  reg:
+    minItems: 3
+
+  reg-names:
+    minItems: 3
+
   clocks:
     description:
       Fabric Interface Controllers, FICs, are the interface between the FPGA
@@ -62,8 +68,9 @@ examples:
             pcie0: pcie at 2030000000 {
                     compatible = "microchip,pcie-host-1.0";
                     reg = <0x0 0x70000000 0x0 0x08000000>,
-                          <0x0 0x43000000 0x0 0x00010000>;
-                    reg-names = "cfg", "apb";
+                          <0x0 0x43008000 0x0 0x00002000>,
+                          <0x0 0x4300a000 0x0 0x00002000>;
+                    reg-names = "cfg", "bridge", "ctrl";
                     device_type = "pci";
                     #address-cells = <3>;
                     #size-cells = <2>;
diff --git a/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
index 7a57a80052a0..039eecdbd6aa 100644
--- a/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
+++ b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
@@ -18,12 +18,18 @@ allOf:
 
 properties:
   reg:
-    maxItems: 2
+    maxItems: 3
+    minItems: 2
 
   reg-names:
-    items:
-      - const: cfg
-      - const: apb
+    oneOf:
+      - items:
+          - const: cfg
+          - const: apb
+      - items:
+          - const: cfg
+          - const: bridge
+          - const: ctrl
 
   interrupts:
     minItems: 1
diff --git a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
index 67151aaa3948..5f432452c815 100644
--- a/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
@@ -16,6 +16,13 @@ properties:
   compatible:
     const: starfive,jh7110-pcie
 
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    maxItems: 2
+
   clocks:
     items:
       - description: NOC bus clock
-- 
2.45.2



From conor at kernel.org  Thu Nov  7 02:59:35 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu,  7 Nov 2024 10:59:35 +0000
Subject: [PATCH v6 2/2] PCI: microchip: rework reg region handing to support using either root port 1 or 2
In-Reply-To: <20241107-aqueduct-petroleum-c002480ba291@spud>
References: <20241107-aqueduct-petroleum-c002480ba291@spud>
Message-ID: <20241107-surrender-brisket-287d563a5de1@spud>

From: Conor Dooley <conor.dooley at microchip.com>

The PCI host controller on PolarFire SoC has multiple root port
instances, each with their own bridge and ctrl address spaces. The
original binding has an "apb" register region, and it is expected to
be set to the base address of the root complex' register space. Some
defines in the Linux driver were used to compute the addresses of the
bridge and ctrl address ranges corresponding to root port instance 1.
Some customers want to use root port instance 2 however, which requires
changing the defines in the driver, which is clearly not a portable
solution.

The binding has been changed from a single register region to a pair,
corresponding to the bridge and ctrl regions respectively, so modify the
driver to read these regions directly from the devicetree rather than
compute them from the base address of the abp region.

To maintain backwards compatibility with the existing binding, the
driver retains code to handle the "abp" reg and computes the base
address of the bridge and ctrl regions using the defines if it is
present. reg-names has always been a required property, so this is
safe to do.

Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
---
Dropped Daire's Ack due to substantial rebasing.
---
 .../pci/controller/plda/pcie-microchip-host.c | 116 +++++++++---------
 1 file changed, 61 insertions(+), 55 deletions(-)

diff --git a/drivers/pci/controller/plda/pcie-microchip-host.c b/drivers/pci/controller/plda/pcie-microchip-host.c
index 48f60a04b740..57f35290c83b 100644
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
@@ -25,9 +25,6 @@
 #define MC_PCIE1_BRIDGE_ADDR			0x00008000u
 #define MC_PCIE1_CTRL_ADDR			0x0000a000u
 
-#define MC_PCIE_BRIDGE_ADDR			(MC_PCIE1_BRIDGE_ADDR)
-#define MC_PCIE_CTRL_ADDR			(MC_PCIE1_CTRL_ADDR)
-
 /* PCIe Controller Phy Regs */
 #define SEC_ERROR_EVENT_CNT			0x20
 #define DED_ERROR_EVENT_CNT			0x24
@@ -128,7 +125,6 @@
 	[EVENT_LOCAL_ ## x] = { __stringify(x), s }
 
 #define PCIE_EVENT(x) \
-	.base = MC_PCIE_CTRL_ADDR, \
 	.offset = PCIE_EVENT_INT, \
 	.mask_offset = PCIE_EVENT_INT, \
 	.mask_high = 1, \
@@ -136,7 +132,6 @@
 	.enb_mask = PCIE_EVENT_INT_ENB_MASK
 
 #define SEC_EVENT(x) \
-	.base = MC_PCIE_CTRL_ADDR, \
 	.offset = SEC_ERROR_INT, \
 	.mask_offset = SEC_ERROR_INT_MASK, \
 	.mask = SEC_ERROR_INT_ ## x ## _INT, \
@@ -144,7 +139,6 @@
 	.enb_mask = 0
 
 #define DED_EVENT(x) \
-	.base = MC_PCIE_CTRL_ADDR, \
 	.offset = DED_ERROR_INT, \
 	.mask_offset = DED_ERROR_INT_MASK, \
 	.mask_high = 1, \
@@ -152,7 +146,6 @@
 	.enb_mask = 0
 
 #define LOCAL_EVENT(x) \
-	.base = MC_PCIE_BRIDGE_ADDR, \
 	.offset = ISTATUS_LOCAL, \
 	.mask_offset = IMASK_LOCAL, \
 	.mask_high = 0, \
@@ -179,7 +172,8 @@ struct event_map {
 
 struct mc_pcie {
 	struct plda_pcie_rp plda;
-	void __iomem *axi_base_addr;
+	void __iomem *bridge_base_addr;
+	void __iomem *ctrl_base_addr;
 };
 
 struct cause {
@@ -253,7 +247,6 @@ static struct event_map local_status_to_event[] = {
 };
 
 static struct {
-	u32 base;
 	u32 offset;
 	u32 mask;
 	u32 shift;
@@ -325,8 +318,7 @@ static inline u32 reg_to_event(u32 reg, struct event_map field)
 
 static u32 pcie_events(struct mc_pcie *port)
 {
-	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
-	u32 reg = readl_relaxed(ctrl_base_addr + PCIE_EVENT_INT);
+	u32 reg = readl_relaxed(port->ctrl_base_addr + PCIE_EVENT_INT);
 	u32 val = 0;
 	int i;
 
@@ -338,8 +330,7 @@ static u32 pcie_events(struct mc_pcie *port)
 
 static u32 sec_errors(struct mc_pcie *port)
 {
-	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
-	u32 reg = readl_relaxed(ctrl_base_addr + SEC_ERROR_INT);
+	u32 reg = readl_relaxed(port->ctrl_base_addr + SEC_ERROR_INT);
 	u32 val = 0;
 	int i;
 
@@ -351,8 +342,7 @@ static u32 sec_errors(struct mc_pcie *port)
 
 static u32 ded_errors(struct mc_pcie *port)
 {
-	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
-	u32 reg = readl_relaxed(ctrl_base_addr + DED_ERROR_INT);
+	u32 reg = readl_relaxed(port->ctrl_base_addr + DED_ERROR_INT);
 	u32 val = 0;
 	int i;
 
@@ -364,8 +354,7 @@ static u32 ded_errors(struct mc_pcie *port)
 
 static u32 local_events(struct mc_pcie *port)
 {
-	void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
-	u32 reg = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+	u32 reg = readl_relaxed(port->bridge_base_addr + ISTATUS_LOCAL);
 	u32 val = 0;
 	int i;
 
@@ -412,8 +401,12 @@ static void mc_ack_event_irq(struct irq_data *data)
 	void __iomem *addr;
 	u32 mask;
 
-	addr = mc_port->axi_base_addr + event_descs[event].base +
-		event_descs[event].offset;
+	if (event_descs[event].offset == ISTATUS_LOCAL)
+		addr = mc_port->bridge_base_addr;
+	else
+		addr = mc_port->ctrl_base_addr;
+
+	addr += event_descs[event].offset;
 	mask = event_descs[event].mask;
 	mask |= event_descs[event].enb_mask;
 
@@ -429,8 +422,12 @@ static void mc_mask_event_irq(struct irq_data *data)
 	u32 mask;
 	u32 val;
 
-	addr = mc_port->axi_base_addr + event_descs[event].base +
-		event_descs[event].mask_offset;
+	if (event_descs[event].offset == ISTATUS_LOCAL)
+		addr = mc_port->bridge_base_addr;
+	else
+		addr = mc_port->ctrl_base_addr;
+
+	addr += event_descs[event].mask_offset;
 	mask = event_descs[event].mask;
 	if (event_descs[event].enb_mask) {
 		mask <<= PCIE_EVENT_INT_ENB_SHIFT;
@@ -460,8 +457,12 @@ static void mc_unmask_event_irq(struct irq_data *data)
 	u32 mask;
 	u32 val;
 
-	addr = mc_port->axi_base_addr + event_descs[event].base +
-		event_descs[event].mask_offset;
+	if (event_descs[event].offset == ISTATUS_LOCAL)
+		addr = mc_port->bridge_base_addr;
+	else
+		addr = mc_port->ctrl_base_addr;
+
+	addr += event_descs[event].mask_offset;
 	mask = event_descs[event].mask;
 
 	if (event_descs[event].enb_mask)
@@ -554,26 +555,20 @@ static const struct plda_event mc_event = {
 
 static inline void mc_clear_secs(struct mc_pcie *port)
 {
-	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
-
-	writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
+	writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, port->ctrl_base_addr +
 		       SEC_ERROR_INT);
-	writel_relaxed(0, ctrl_base_addr + SEC_ERROR_EVENT_CNT);
+	writel_relaxed(0, port->ctrl_base_addr + SEC_ERROR_EVENT_CNT);
 }
 
 static inline void mc_clear_deds(struct mc_pcie *port)
 {
-	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
-
-	writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
+	writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, port->ctrl_base_addr +
 		       DED_ERROR_INT);
-	writel_relaxed(0, ctrl_base_addr + DED_ERROR_EVENT_CNT);
+	writel_relaxed(0, port->ctrl_base_addr + DED_ERROR_EVENT_CNT);
 }
 
 static void mc_disable_interrupts(struct mc_pcie *port)
 {
-	void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
-	void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
 	u32 val;
 
 	/* Ensure ECC bypass is enabled */
@@ -581,22 +576,22 @@ static void mc_disable_interrupts(struct mc_pcie *port)
 	      ECC_CONTROL_RX_RAM_ECC_BYPASS |
 	      ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS |
 	      ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS;
-	writel_relaxed(val, ctrl_base_addr + ECC_CONTROL);
+	writel_relaxed(val, port->ctrl_base_addr + ECC_CONTROL);
 
 	/* Disable SEC errors and clear any outstanding */
-	writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
+	writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, port->ctrl_base_addr +
 		       SEC_ERROR_INT_MASK);
 	mc_clear_secs(port);
 
 	/* Disable DED errors and clear any outstanding */
-	writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
+	writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, port->ctrl_base_addr +
 		       DED_ERROR_INT_MASK);
 	mc_clear_deds(port);
 
 	/* Disable local interrupts and clear any outstanding */
-	writel_relaxed(0, bridge_base_addr + IMASK_LOCAL);
-	writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_LOCAL);
-	writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_MSI);
+	writel_relaxed(0, port->bridge_base_addr + IMASK_LOCAL);
+	writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_LOCAL);
+	writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_MSI);
 
 	/* Disable PCIe events and clear any outstanding */
 	val = PCIE_EVENT_INT_L2_EXIT_INT |
@@ -605,11 +600,11 @@ static void mc_disable_interrupts(struct mc_pcie *port)
 	      PCIE_EVENT_INT_L2_EXIT_INT_MASK |
 	      PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK |
 	      PCIE_EVENT_INT_DLUP_EXIT_INT_MASK;
-	writel_relaxed(val, ctrl_base_addr + PCIE_EVENT_INT);
+	writel_relaxed(val, port->ctrl_base_addr + PCIE_EVENT_INT);
 
 	/* Disable host interrupts and clear any outstanding */
-	writel_relaxed(0, bridge_base_addr + IMASK_HOST);
-	writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+	writel_relaxed(0, port->bridge_base_addr + IMASK_HOST);
+	writel_relaxed(GENMASK(31, 0), port->bridge_base_addr + ISTATUS_HOST);
 }
 
 static int mc_platform_init(struct pci_config_window *cfg)
@@ -617,12 +612,10 @@ static int mc_platform_init(struct pci_config_window *cfg)
 	struct device *dev = cfg->parent;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
-	void __iomem *bridge_base_addr =
-		port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
 	int ret;
 
 	/* Configure address translation table 0 for PCIe config space */
-	plda_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
+	plda_pcie_setup_window(port->bridge_base_addr, 0, cfg->res.start,
 			       cfg->res.start,
 			       resource_size(&cfg->res));
 
@@ -649,7 +642,7 @@ static int mc_platform_init(struct pci_config_window *cfg)
 static int mc_host_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	void __iomem *bridge_base_addr;
+	void __iomem *apb_base_addr;
 	struct plda_pcie_rp *plda;
 	int ret;
 	u32 val;
@@ -661,30 +654,43 @@ static int mc_host_probe(struct platform_device *pdev)
 	plda = &port->plda;
 	plda->dev = dev;
 
-	port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
-	if (IS_ERR(port->axi_base_addr))
-		return PTR_ERR(port->axi_base_addr);
+	port->bridge_base_addr = devm_platform_ioremap_resource_byname(pdev, "bridge");
+	port->ctrl_base_addr = devm_platform_ioremap_resource_byname(pdev, "ctrl");
+	if (!IS_ERR(port->bridge_base_addr) && !IS_ERR(port->ctrl_base_addr))
+		goto addrs_set;
 
+	/*
+	 * The original, incorrect, binding that lumped the control and
+	 * bridge addresses together still needs to be handled by the driver.
+	 */
+	apb_base_addr = devm_platform_ioremap_resource_byname(pdev, "apb");
+	if (IS_ERR(apb_base_addr))
+		return dev_err_probe(dev, PTR_ERR(apb_base_addr),
+				     "both legacy apb register and ctrl/bridge regions missing");
+
+	port->bridge_base_addr = apb_base_addr + MC_PCIE1_BRIDGE_ADDR;
+	port->ctrl_base_addr = apb_base_addr + MC_PCIE1_CTRL_ADDR;
+
+addrs_set:
 	mc_disable_interrupts(port);
 
-	bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
-	plda->bridge_addr = bridge_base_addr;
+	plda->bridge_addr = port->bridge_base_addr;
 	plda->num_events = NUM_EVENTS;
 
 	/* Allow enabling MSI by disabling MSI-X */
-	val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+	val = readl(port->bridge_base_addr + PCIE_PCI_IRQ_DW0);
 	val &= ~MSIX_CAP_MASK;
-	writel(val, bridge_base_addr + PCIE_PCI_IRQ_DW0);
+	writel(val, port->bridge_base_addr + PCIE_PCI_IRQ_DW0);
 
 	/* Pick num vectors from bitfile programmed onto FPGA fabric */
-	val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+	val = readl(port->bridge_base_addr + PCIE_PCI_IRQ_DW0);
 	val &= NUM_MSI_MSGS_MASK;
 	val >>= NUM_MSI_MSGS_SHIFT;
 
 	plda->msi.num_vectors = 1 << val;
 
 	/* Pick vector address from design */
-	plda->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
+	plda->msi.vector_phy = readl_relaxed(port->bridge_base_addr + IMSI_ADDR);
 
 	ret = mc_pcie_init_clks(dev);
 	if (ret) {
-- 
2.45.2



From bjorn at kernel.org  Thu Nov  7 06:32:42 2024
From: bjorn at kernel.org (=?UTF-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Thu, 7 Nov 2024 15:32:42 +0100
Subject: [PATCH bpf-next 1/2] libbpf: Add missing per-arch include path
In-Reply-To: <CAEf4BzZbq9OwSGi4pdb5_q8YkErfFiQFKYXg3g1rjpdejafx+Q@mail.gmail.com>
References: <20240927131355.350918-1-bjorn@kernel.org> <172835823300.66789.3704854116445399222.git-patchwork-notify@kernel.org>
 <87bjyvpa6h.fsf@all.your.base.are.belong.to.us> <CAEf4BzZbq9OwSGi4pdb5_q8YkErfFiQFKYXg3g1rjpdejafx+Q@mail.gmail.com>
Message-ID: <CAJ+HfNjiuhOyw2r9+e=CRMXrq_NjP5Sq4oT1tc_vhTZ_HkY7zQ@mail.gmail.com>

On Wed, 6 Nov 2024 at 23:04, Andrii Nakryiko <andrii.nakryiko at gmail.com> wrote:
> I'm sorry, but unfortunately it's too late now to move those patches
> as it's now been more than a month since they landed. For the future,
> please let us know ASAP if you think patches were misrouted. I think
> we are stuck with the need to do a stable backport for these, sorry.

Yeah, realize that it's really late. Thanks for getting back, and
noted for the future.

Cheers,
Bj?rn


From helgaas at kernel.org  Thu Nov  7 06:57:15 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 7 Nov 2024 08:57:15 -0600
Subject: [PATCH v6 0/2] PCI: microchip: support using either instance 1
 or 2
In-Reply-To: <20241107-aqueduct-petroleum-c002480ba291@spud>
Message-ID: <20241107145715.GA1613568@bhelgaas>

On Thu, Nov 07, 2024 at 10:59:33AM +0000, Conor Dooley wrote:
> From: Conor Dooley <conor.dooley at microchip.com>
> 
> The current driver and binding for PolarFire SoC's PCI controller assume
> that the root port instance in use is instance 1. The second reg
> property constitutes the region encompassing both "control" and "bridge"
> registers for both instances. In the driver, a fixed offset is applied to
> find the base addresses for instance 1's "control" and "bridge"
> registers. The BeagleV Fire uses root port instance 2, so something must
> be done so that software can differentiate. This series splits the
> second reg property in two, with dedicated "control" and "bridge"
> entries so that either instance can be used.
> 
> Cheers,
> Conor.
> 
> v6:
> - rework commit messages to use Bjorn's preferred "root port" and "root
>   complex" wording
> 
> v5:
> - rebase on top of 6.11-rc1, which brought about a lot of driver change
>   due to the plda common driver creation - although little actually
>   changed in terms of the lines edited in this patch.
> 
> v4:
> - fix a cocci warning reported off list about an inconsistent variable
>   used between IS_ERR() and PTR_ERR() calls.
> 
> v3:
> - rename a variable in probe s/axi/apb/
> 
> v2:
> - try the new reg format before the old one to avoid warnings in the
>   good case
> - reword $subject for 2/2
> 
> CC: Daire McNamara <daire.mcnamara at microchip.com>
> CC: Lorenzo Pieralisi <lpieralisi at kernel.org>
> CC: Krzysztof Wilczy?ski <kw at linux.com>
> CC: Rob Herring <robh at kernel.org>
> CC: Bjorn Helgaas <bhelgaas at google.com>
> CC: Krzysztof Kozlowski <krzk+dt at kernel.org>
> CC: Conor Dooley <conor+dt at kernel.org>
> CC: linux-pci at vger.kernel.org
> CC: devicetree at vger.kernel.org
> CC: linux-kernel at vger.kernel.org
> CC: linux-riscv at lists.infradead.org
> 
> Conor Dooley (2):
>   dt-bindings: PCI: microchip,pcie-host: fix reg properties
>   PCI: microchip: rework reg region handing to support using either root
>     port 1 or 2
> 
>  .../bindings/pci/microchip,pcie-host.yaml     |  11 +-
>  .../pci/plda,xpressrich3-axi-common.yaml      |  14 ++-
>  .../bindings/pci/starfive,jh7110-pcie.yaml    |   7 ++
>  .../pci/controller/plda/pcie-microchip-host.c | 116 +++++++++---------
>  4 files changed, 87 insertions(+), 61 deletions(-)

Thanks!  The patches themselves are unchanged between v5 and v6.  I
replaced the v5 patches on pci/controller/microchip with these.

I also capitalized "Root Port" and "Root Complex" to give a hint that
they are proper nouns defined by the PCIe spec.


From irogers at google.com  Thu Nov  7 07:57:21 2024
From: irogers at google.com (Ian Rogers)
Date: Thu, 7 Nov 2024 07:57:21 -0800
Subject: [PATCH v1 0/7] Refactor cpuid and metric table lookup code
In-Reply-To: <20241107082807.ipb7xzqvs24tto2e@hippo>
References: <20241107071600.9082-1-irogers@google.com> <20241107082807.ipb7xzqvs24tto2e@hippo>
Message-ID: <CAP-5=fXn3GSR88=UVqZ6zxsuv6s+ZBMGY1A0U8D-_oU4sm10kQ@mail.gmail.com>

On Thu, Nov 7, 2024 at 1:05?AM Xu Yang <xu.yang_2 at nxp.com> wrote:
>
> Hi Ian Rogers,
>
> On Wed, Nov 06, 2024 at 11:15:53PM -0800, Ian Rogers wrote:
> > Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
> > lookup:
> > https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
> > These patches remove a lot of the logic relating CPUIDs to PMUs so
> > that the PMU isn't part of the question when finding a metric table.
> > For time reasons, it doesn't go as far as allowing system metrics
> > without a metric table as a metric table is needed for metrics to
> > refer to other metrics, and the refactoring of that resolution is a
> > hassle.
> >
> > Ian Rogers (7):
> >   perf header: Move is_cpu_online to numa bench
> >   perf header: Refactor get_cpuid to take a CPU for ARM
> >   perf arm64 header: Use cpu argument in get_cpuid
> >   perf header: Avoid transitive PMU includes
> >   perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
> >   perf jevents: Add map_for_cpu
> >   perf pmu: Move pmu_metrics_table__find and remove ARM override
> >
> >  tools/perf/arch/arm64/util/arm-spe.c     | 14 +---
> >  tools/perf/arch/arm64/util/header.c      | 73 ++++++++++-----------
> >  tools/perf/arch/arm64/util/pmu.c         | 20 ------
> >  tools/perf/arch/loongarch/util/header.c  |  4 +-
> >  tools/perf/arch/powerpc/util/header.c    |  4 +-
> >  tools/perf/arch/riscv/util/header.c      |  4 +-
> >  tools/perf/arch/s390/util/header.c       |  6 +-
> >  tools/perf/arch/x86/util/auxtrace.c      |  3 +-
> >  tools/perf/arch/x86/util/header.c        |  5 +-
> >  tools/perf/bench/numa.c                  | 51 +++++++++++++++
>
> Meet error when build perf tool:
>
>   CC      util/levenshtein.o
>   CC      tests/mem.o
>   CC      util/mmap.o
> bench/numa.c: In function ?is_cpu_online?:
> bench/numa.c:550:21: error: storage size of ?statbuf? isn?t known
>   550 |         struct stat statbuf;
>       |                     ^~~~~~~
> bench/numa.c:554:13: error: implicit declaration of function ?stat?; did you mean ?strcat?? [-Werror=implicit-function-declaration]
>   554 |         if (stat(buf, &statbuf) != 0)
>       |             ^~~~
>       |             strcat
> bench/numa.c:578:13: error: implicit declaration of function ?sysfs__read_str? [-Werror=implicit-function-declaration]
>   578 |         if (sysfs__read_str(buf, &str, &strlen) < 0)
>       |             ^~~~~~~~~~~~~~~
> bench/numa.c:550:21: error: unused variable ?statbuf? [-Werror=unused-variable]
>   550 |         struct stat statbuf;
>       |                     ^~~~~~~
>   CC      tests/cpumap.o
>   CC      tests/stat.o
>
> After remove these errors, my issue is disappeared.

Thanks, I'll fix this in v2. I'll also add your patch to the front for
the sake of backport fixing. If you could provide tags for my changes
it would be appreciated.

Thanks,
Ian


From irogers at google.com  Thu Nov  7 08:20:27 2024
From: irogers at google.com (Ian Rogers)
Date: Thu,  7 Nov 2024 08:20:27 -0800
Subject: [PATCH v2 0/8] Refactor cpuid and metric table lookup code
Message-ID: <20241107162035.52206-1-irogers@google.com>

Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
lookup:
https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
These patches remove a lot of the logic relating CPUIDs to PMUs so
that the PMU isn't part of the question when finding a metric table.
For time reasons, it doesn't go as far as allowing system metrics
without a metric table as a metric table is needed for metrics to
refer to other metrics, and the refactoring of that resolution is a
hassle.

Ian Rogers (7):
  perf header: Move is_cpu_online to numa bench
  perf header: Refactor get_cpuid to take a CPU for ARM
  perf arm64 header: Use cpu argument in get_cpuid
  perf header: Avoid transitive PMU includes
  perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
  perf jevents: Add map_for_cpu
  perf pmu: Move pmu_metrics_table__find and remove ARM override

Xu Yang (1):
  perf jevents: fix breakage when do perf stat on system metric

 tools/perf/arch/arm64/util/arm-spe.c     | 14 +---
 tools/perf/arch/arm64/util/header.c      | 73 ++++++++++-----------
 tools/perf/arch/arm64/util/pmu.c         | 20 ------
 tools/perf/arch/loongarch/util/header.c  |  4 +-
 tools/perf/arch/powerpc/util/header.c    |  4 +-
 tools/perf/arch/riscv/util/header.c      |  4 +-
 tools/perf/arch/s390/util/header.c       |  6 +-
 tools/perf/arch/x86/util/auxtrace.c      |  3 +-
 tools/perf/arch/x86/util/header.c        |  5 +-
 tools/perf/bench/numa.c                  | 53 +++++++++++++++
 tools/perf/builtin-kvm.c                 |  4 +-
 tools/perf/pmu-events/empty-pmu-events.c | 39 ++++++-----
 tools/perf/pmu-events/jevents.py         | 39 ++++++-----
 tools/perf/pmu-events/pmu-events.h       |  2 +-
 tools/perf/tests/expr.c                  |  5 +-
 tools/perf/util/env.c                    |  4 +-
 tools/perf/util/expr.c                   |  6 +-
 tools/perf/util/header.c                 | 82 ++++++++----------------
 tools/perf/util/header.h                 | 23 +++----
 tools/perf/util/pmu.c                    | 25 --------
 tools/perf/util/pmu.h                    |  2 -
 tools/perf/util/probe-event.c            |  1 +
 22 files changed, 189 insertions(+), 229 deletions(-)

-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Thu Nov  7 08:20:28 2024
From: irogers at google.com (Ian Rogers)
Date: Thu,  7 Nov 2024 08:20:28 -0800
Subject: [PATCH v2 1/8] perf jevents: fix breakage when do perf stat on system metric
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <20241107162035.52206-2-irogers@google.com>

From: Xu Yang <xu.yang_2 at nxp.com>

When do perf stat on sys metric, perf tool output nothing now:
$ perf stat -a -M imx95_ddr_read.all -I 1000
$

This command runs on an arm64 machine and the Soc has one DDR hw pmu
except one armv8_cortex_a55 pmu. Their maps show as follows:

const struct pmu_events_map pmu_events_map[] = {
{
	.arch = "arm64",
	.cpuid = "0x00000000410fd050",
	.event_table = {
		.pmus = pmu_events__arm_cortex_a55,
		.num_pmus = ARRAY_SIZE(pmu_events__arm_cortex_a55)
	},
	.metric_table = {
		.pmus = NULL,
		.num_pmus = 0
	}
},

static const struct pmu_sys_events pmu_sys_event_tables[] = {
{
	.event_table = {
		.pmus = pmu_events__freescale_imx95_sys,
		.num_pmus = ARRAY_SIZE(pmu_events__freescale_imx95_sys)
	},
	.metric_table = {
		.pmus = pmu_metrics__freescale_imx95_sys,
		.num_pmus = ARRAY_SIZE(pmu_metrics__freescale_imx95_sys)
	},
	.name = "pmu_events__freescale_imx95_sys",
},

Currently, pmu_metrics_table__find() will return NULL when only do perf
stat on sys metric. Then parse_groups() will never be called to parse
sys metric_name, finally perf tool will exit directly. This should be a
common problem. To fix the issue, this will keep the logic before commit
f20c15d13f01 ("perf pmu-events: Remember the perf_events_map for a PMU")
to return a empty metric table rather than a NULL pointer. This should
be fine since the removed part just check if the table match provided
metric_name. Without these code, the code in parse_groups() will also
check the validity of metrci_name too.

Fixes: f20c15d13f01 ("perf pmu-events: Remember the perf_events_map for a PMU")
Cc: stable at vger.kernel.org
Signed-off-by: Xu Yang <xu.yang_2 at nxp.com>
Acked-by: Ian Rogers <irogers at google.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/pmu-events/empty-pmu-events.c | 12 +-----------
 tools/perf/pmu-events/jevents.py         | 12 +-----------
 2 files changed, 2 insertions(+), 22 deletions(-)

diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index 2b7516946ded..b8719dab264d 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -585,17 +585,7 @@ const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pm
         if (!map)
                 return NULL;
 
-        if (!pmu)
-                return &map->metric_table;
-
-        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
-                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
-                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
-
-                if (pmu__name_match(pmu, pmu_name))
-                           return &map->metric_table;
-        }
-        return NULL;
+	return &map->metric_table;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 6e71b09dbc2a..70f4fd5395fb 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1101,17 +1101,7 @@ const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pm
         if (!map)
                 return NULL;
 
-        if (!pmu)
-                return &map->metric_table;
-
-        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
-                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
-                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
-
-                if (pmu__name_match(pmu, pmu_name))
-                           return &map->metric_table;
-        }
-        return NULL;
+	return &map->metric_table;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Thu Nov  7 08:20:29 2024
From: irogers at google.com (Ian Rogers)
Date: Thu,  7 Nov 2024 08:20:29 -0800
Subject: [PATCH v2 2/8] perf header: Move is_cpu_online to numa bench
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <20241107162035.52206-3-irogers@google.com>

The helper function is only used in the NUMA benchmark as typically
online CPUs are determined through
perf_cpu_map__new_online_cpus(). Reduce the scope of the function for
now.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/bench/numa.c  | 53 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/header.c | 51 --------------------------------------
 tools/perf/util/header.h |  1 -
 3 files changed, 53 insertions(+), 52 deletions(-)

diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 1fbd7c947abc..19be2aaf4dc0 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -27,6 +27,7 @@
 #include <sys/resource.h>
 #include <sys/wait.h>
 #include <sys/prctl.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <linux/kernel.h>
 #include <linux/time64.h>
@@ -35,6 +36,7 @@
 
 #include "../util/header.h"
 #include "../util/mutex.h"
+#include <api/fs/fs.h>
 #include <numa.h>
 #include <numaif.h>
 
@@ -533,6 +535,57 @@ static int parse_cpu_list(const char *arg)
 	return 0;
 }
 
+/*
+ * Check whether a CPU is online
+ *
+ * Returns:
+ *     1 -> if CPU is online
+ *     0 -> if CPU is offline
+ *    -1 -> error case
+ */
+static int is_cpu_online(unsigned int cpu)
+{
+	char *str;
+	size_t strlen;
+	char buf[256];
+	int status = -1;
+	struct stat statbuf;
+
+	snprintf(buf, sizeof(buf),
+		"/sys/devices/system/cpu/cpu%d", cpu);
+	if (stat(buf, &statbuf) != 0)
+		return 0;
+
+	/*
+	 * Check if /sys/devices/system/cpu/cpux/online file
+	 * exists. Some cases cpu0 won't have online file since
+	 * it is not expected to be turned off generally.
+	 * In kernels without CONFIG_HOTPLUG_CPU, this
+	 * file won't exist
+	 */
+	snprintf(buf, sizeof(buf),
+		"/sys/devices/system/cpu/cpu%d/online", cpu);
+	if (stat(buf, &statbuf) != 0)
+		return 1;
+
+	/*
+	 * Read online file using sysfs__read_str.
+	 * If read or open fails, return -1.
+	 * If read succeeds, return value from file
+	 * which gets stored in "str"
+	 */
+	snprintf(buf, sizeof(buf),
+		"devices/system/cpu/cpu%d/online", cpu);
+
+	if (sysfs__read_str(buf, &str, &strlen) < 0)
+		return status;
+
+	status = atoi(str);
+
+	free(str);
+	return status;
+}
+
 static int parse_setup_cpu_list(void)
 {
 	struct thread_data *td;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a6386d12afd7..55c28e4377ec 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -987,57 +987,6 @@ static int write_dir_format(struct feat_fd *ff,
 	return do_write(ff, &data->dir.version, sizeof(data->dir.version));
 }
 
-/*
- * Check whether a CPU is online
- *
- * Returns:
- *     1 -> if CPU is online
- *     0 -> if CPU is offline
- *    -1 -> error case
- */
-int is_cpu_online(unsigned int cpu)
-{
-	char *str;
-	size_t strlen;
-	char buf[256];
-	int status = -1;
-	struct stat statbuf;
-
-	snprintf(buf, sizeof(buf),
-		"/sys/devices/system/cpu/cpu%d", cpu);
-	if (stat(buf, &statbuf) != 0)
-		return 0;
-
-	/*
-	 * Check if /sys/devices/system/cpu/cpux/online file
-	 * exists. Some cases cpu0 won't have online file since
-	 * it is not expected to be turned off generally.
-	 * In kernels without CONFIG_HOTPLUG_CPU, this
-	 * file won't exist
-	 */
-	snprintf(buf, sizeof(buf),
-		"/sys/devices/system/cpu/cpu%d/online", cpu);
-	if (stat(buf, &statbuf) != 0)
-		return 1;
-
-	/*
-	 * Read online file using sysfs__read_str.
-	 * If read or open fails, return -1.
-	 * If read succeeds, return value from file
-	 * which gets stored in "str"
-	 */
-	snprintf(buf, sizeof(buf),
-		"devices/system/cpu/cpu%d/online", cpu);
-
-	if (sysfs__read_str(buf, &str, &strlen) < 0)
-		return status;
-
-	status = atoi(str);
-
-	free(str);
-	return status;
-}
-
 #ifdef HAVE_LIBBPF_SUPPORT
 static int write_bpf_prog_info(struct feat_fd *ff,
 			       struct evlist *evlist __maybe_unused)
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index a63a361f20f4..e91e89d22537 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -196,7 +196,6 @@ int write_padded(struct feat_fd *fd, const void *bf,
 
 #define MAX_CACHE_LVL 4
 
-int is_cpu_online(unsigned int cpu);
 int build_caches_for_cpu(u32 cpu, struct cpu_cache_level caches[], u32 *cntp);
 
 /*
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Thu Nov  7 08:20:30 2024
From: irogers at google.com (Ian Rogers)
Date: Thu,  7 Nov 2024 08:20:30 -0800
Subject: [PATCH v2 3/8] perf header: Refactor get_cpuid to take a CPU for ARM
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <20241107162035.52206-4-irogers@google.com>

ARM BIG.little has no notion of a constant CPUID for both core
types. To reflect this reality, change the get_cpuid function to also
pass in a possibly unused logical cpu. If the dummy value (-1) is
passed in then ARM can, as currently happens, select the first logical
CPU's "CPUID". The changes to ARM getcpuid happen in a follow up
change.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm64/util/header.c     | 2 +-
 tools/perf/arch/loongarch/util/header.c | 2 +-
 tools/perf/arch/powerpc/util/header.c   | 2 +-
 tools/perf/arch/riscv/util/header.c     | 2 +-
 tools/perf/arch/s390/util/header.c      | 2 +-
 tools/perf/arch/x86/util/auxtrace.c     | 3 ++-
 tools/perf/arch/x86/util/header.c       | 2 +-
 tools/perf/builtin-kvm.c                | 4 +++-
 tools/perf/util/env.c                   | 3 ++-
 tools/perf/util/header.c                | 9 +++++----
 tools/perf/util/header.h                | 2 +-
 11 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index 741df3614a09..760c21784713 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -50,7 +50,7 @@ static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
 	return ret;
 }
 
-int get_cpuid(char *buf, size_t sz)
+int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	struct perf_cpu_map *cpus = perf_cpu_map__new_online_cpus();
 	int ret;
diff --git a/tools/perf/arch/loongarch/util/header.c b/tools/perf/arch/loongarch/util/header.c
index d962dff55512..f1f0b116962d 100644
--- a/tools/perf/arch/loongarch/util/header.c
+++ b/tools/perf/arch/loongarch/util/header.c
@@ -70,7 +70,7 @@ static char *_get_cpuid(void)
 	return cpuid;
 }
 
-int get_cpuid(char *buffer, size_t sz)
+int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	int ret = 0;
 	char *cpuid = _get_cpuid();
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
index 251cdbf58a4d..6d1a63a2922f 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -24,7 +24,7 @@ static bool is_compat_mode(void)
 }
 
 int
-get_cpuid(char *buffer, size_t sz)
+get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	unsigned long pvr;
 	int nb;
diff --git a/tools/perf/arch/riscv/util/header.c b/tools/perf/arch/riscv/util/header.c
index 1b29030021ee..ebac294c877f 100644
--- a/tools/perf/arch/riscv/util/header.c
+++ b/tools/perf/arch/riscv/util/header.c
@@ -81,7 +81,7 @@ static char *_get_cpuid(void)
 	return cpuid;
 }
 
-int get_cpuid(char *buffer, size_t sz)
+int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	char *cpuid = _get_cpuid();
 	int ret = 0;
diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c
index 7933f6871c81..2add1a561242 100644
--- a/tools/perf/arch/s390/util/header.c
+++ b/tools/perf/arch/s390/util/header.c
@@ -27,7 +27,7 @@
 #define SYSINFO		"/proc/sysinfo"
 #define SRVLVL		"/proc/service_levels"
 
-int get_cpuid(char *buffer, size_t sz)
+int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	char *cp, *line = NULL, *line2;
 	char type[8], model[33], version[8], manufacturer[32], authorization[8];
diff --git a/tools/perf/arch/x86/util/auxtrace.c b/tools/perf/arch/x86/util/auxtrace.c
index 354780ff1605..ecbf61a7eb3a 100644
--- a/tools/perf/arch/x86/util/auxtrace.c
+++ b/tools/perf/arch/x86/util/auxtrace.c
@@ -55,11 +55,12 @@ struct auxtrace_record *auxtrace_record__init(struct evlist *evlist,
 					      int *err)
 {
 	char buffer[64];
+	struct perf_cpu cpu = perf_cpu_map__min(evlist->core.all_cpus);
 	int ret;
 
 	*err = 0;
 
-	ret = get_cpuid(buffer, sizeof(buffer));
+	ret = get_cpuid(buffer, sizeof(buffer), cpu);
 	if (ret) {
 		*err = ret;
 		return NULL;
diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c
index a51444a77a5f..690f86cbbb1c 100644
--- a/tools/perf/arch/x86/util/header.c
+++ b/tools/perf/arch/x86/util/header.c
@@ -58,7 +58,7 @@ __get_cpuid(char *buffer, size_t sz, const char *fmt)
 }
 
 int
-get_cpuid(char *buffer, size_t sz)
+get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 {
 	return __get_cpuid(buffer, sz, "%s,%u,%u,%u$");
 }
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 099ce3ebf67c..274568d712d1 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1226,7 +1226,9 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm)
 	int err;
 
 	if (kvm->live) {
-		err = get_cpuid(buf, sizeof(buf));
+		struct perf_cpu cpu = {-1};
+
+		err = get_cpuid(buf, sizeof(buf), cpu);
 		if (err != 0) {
 			pr_err("Failed to look up CPU type: %s\n",
 			       str_error_r(err, buf, sizeof(buf)));
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index ccb464026642..93cabdd7ff43 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -373,7 +373,8 @@ int perf_env__read_pmu_mappings(struct perf_env *env)
 int perf_env__read_cpuid(struct perf_env *env)
 {
 	char cpuid[128];
-	int err = get_cpuid(cpuid, sizeof(cpuid));
+	struct perf_cpu cpu = {-1};
+	int err = get_cpuid(cpuid, sizeof(cpuid), cpu);
 
 	if (err)
 		return err;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 55c28e4377ec..60b42ddc3dac 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -856,18 +856,19 @@ int __weak strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
  * default get_cpuid(): nothing gets recorded
  * actual implementation must be in arch/$(SRCARCH)/util/header.c
  */
-int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused)
+int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused,
+		     struct perf_cpu cpu __maybe_unused)
 {
 	return ENOSYS; /* Not implemented */
 }
 
-static int write_cpuid(struct feat_fd *ff,
-		       struct evlist *evlist __maybe_unused)
+static int write_cpuid(struct feat_fd *ff, struct evlist *evlist)
 {
+	struct perf_cpu cpu = perf_cpu_map__min(evlist->core.all_cpus);
 	char buffer[64];
 	int ret;
 
-	ret = get_cpuid(buffer, sizeof(buffer));
+	ret = get_cpuid(buffer, sizeof(buffer), cpu);
 	if (ret)
 		return -1;
 
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index e91e89d22537..b77f89de12dd 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -201,7 +201,7 @@ int build_caches_for_cpu(u32 cpu, struct cpu_cache_level caches[], u32 *cntp);
 /*
  * arch specific callback
  */
-int get_cpuid(char *buffer, size_t sz);
+int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu);
 
 char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused);
 int strcmp_cpuid_str(const char *s1, const char *s2);
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Thu Nov  7 08:20:31 2024
From: irogers at google.com (Ian Rogers)
Date: Thu,  7 Nov 2024 08:20:31 -0800
Subject: [PATCH v2 4/8] perf arm64 header: Use cpu argument in get_cpuid
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <20241107162035.52206-5-irogers@google.com>

Use the cpu to read the MIDR file requested. If the "any" value (-1)
is passed that keep the behavior of returning the first MIDR file that
can be read.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm64/util/header.c | 63 ++++++++++++++---------------
 tools/perf/util/header.h            |  1 +
 2 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index 760c21784713..f0907daad3ae 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -14,55 +14,52 @@
 #define MIDR_REVISION_MASK      GENMASK(3, 0)
 #define MIDR_VARIANT_MASK	GENMASK(23, 20)
 
-static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
+static int _get_cpuid(char *buf, size_t sz, struct perf_cpu cpu)
 {
+	char path[PATH_MAX];
+	FILE *file;
 	const char *sysfs = sysfs__mountpoint();
-	struct perf_cpu cpu;
-	int idx, ret = EINVAL;
 
+	assert(cpu.cpu != -1);
 	if (!sysfs || sz < MIDR_SIZE)
 		return EINVAL;
 
-	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
-		char path[PATH_MAX];
-		FILE *file;
-
-		scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d" MIDR,
-			  sysfs, cpu.cpu);
-
-		file = fopen(path, "r");
-		if (!file) {
-			pr_debug("fopen failed for file %s\n", path);
-			continue;
-		}
-
-		if (!fgets(buf, MIDR_SIZE, file)) {
-			fclose(file);
-			continue;
-		}
-		fclose(file);
+	scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d" MIDR, sysfs, cpu.cpu);
 
-		/* got midr break loop */
-		ret = 0;
-		break;
+	file = fopen(path, "r");
+	if (!file) {
+		pr_debug("fopen failed for file %s\n", path);
+		return EINVAL;
 	}
 
-	return ret;
+	if (!fgets(buf, MIDR_SIZE, file)) {
+		pr_debug("Failed to read file %s\n", path);
+		fclose(file);
+		return EINVAL;
+	}
+	fclose(file);
+	return 0;
 }
 
-int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu __maybe_unused)
+int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu)
 {
-	struct perf_cpu_map *cpus = perf_cpu_map__new_online_cpus();
-	int ret;
+	struct perf_cpu_map *cpus;
+	int idx;
+
+	if (cpu.cpu != -1)
+		return _get_cpuid(buf, sz, cpu);
 
+	cpus = perf_cpu_map__new_online_cpus();
 	if (!cpus)
 		return EINVAL;
 
-	ret = _get_cpuid(buf, sz, cpus);
-
-	perf_cpu_map__put(cpus);
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
+		int ret = _get_cpuid(buf, sz, cpu);
 
-	return ret;
+		if (ret == 0)
+			return 0;
+	}
+	return EINVAL;
 }
 
 char *get_cpuid_str(struct perf_pmu *pmu)
@@ -78,7 +75,7 @@ char *get_cpuid_str(struct perf_pmu *pmu)
 		return NULL;
 
 	/* read midr from list of cpus mapped to this pmu */
-	res = _get_cpuid(buf, MIDR_SIZE, pmu->cpus);
+	res = get_cpuid(buf, MIDR_SIZE, perf_cpu_map__min(pmu->cpus));
 	if (res) {
 		pr_err("failed to get cpuid string for PMU %s\n", pmu->name);
 		free(buf);
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index b77f89de12dd..3bb768455a60 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include "env.h"
 #include "pmu.h"
+#include <perf/cpumap.h>
 
 enum {
 	HEADER_RESERVED		= 0,	/* always cleared */
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Thu Nov  7 08:20:32 2024
From: irogers at google.com (Ian Rogers)
Date: Thu,  7 Nov 2024 08:20:32 -0800
Subject: [PATCH v2 5/8] perf header: Avoid transitive PMU includes
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <20241107162035.52206-6-irogers@google.com>

Currently satisfied via header.h. Note, pmu.h includes parse-events.h.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/expr.c       | 2 ++
 tools/perf/util/env.c         | 1 +
 tools/perf/util/probe-event.c | 1 +
 3 files changed, 4 insertions(+)

diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index e3aa9d4fcf3a..d60f1ac1d720 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -4,6 +4,8 @@
 #include "util/expr.h"
 #include "util/hashmap.h"
 #include "util/header.h"
+#include "util/pmu.h"
+#include "util/pmus.h"
 #include "util/smt.h"
 #include "tests.h"
 #include <math.h>
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index 93cabdd7ff43..e2843ca2edd9 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -12,6 +12,7 @@
 #include <sys/utsname.h>
 #include <stdlib.h>
 #include <string.h>
+#include "pmu.h"
 #include "pmus.h"
 #include "strbuf.h"
 #include "trace/beauty/beauty.h"
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index a580aa2cd512..d399c7e03341 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -40,6 +40,7 @@
 #include "session.h"
 #include "string2.h"
 #include "strbuf.h"
+#include "parse-events.h"
 
 #include <subcmd/pager.h>
 #include <linux/ctype.h>
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Thu Nov  7 08:20:33 2024
From: irogers at google.com (Ian Rogers)
Date: Thu,  7 Nov 2024 08:20:33 -0800
Subject: [PATCH v2 6/8] perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <20241107162035.52206-7-irogers@google.com>

On ARM the cpuid is dependent on the core type of the CPU in
question. The PMU was passed for the sake of the CPU map but this
means in places a temporary PMU is created just to pass a CPU
value. Just pass the CPU and fix up the callers.

As there are no longer PMU users in header.h, shuffle forward
declarations earlier to work around build failures.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm64/util/arm-spe.c     | 14 ++------------
 tools/perf/arch/arm64/util/header.c      | 12 ++++--------
 tools/perf/arch/loongarch/util/header.c  |  2 +-
 tools/perf/arch/powerpc/util/header.c    |  2 +-
 tools/perf/arch/riscv/util/header.c      |  2 +-
 tools/perf/arch/s390/util/header.c       |  4 ++--
 tools/perf/arch/x86/util/header.c        |  3 +--
 tools/perf/pmu-events/empty-pmu-events.c |  5 ++++-
 tools/perf/pmu-events/jevents.py         |  5 ++++-
 tools/perf/tests/expr.c                  |  7 +++----
 tools/perf/util/expr.c                   |  6 +++---
 tools/perf/util/header.c                 | 22 +++++++++++++++++++++-
 tools/perf/util/header.h                 | 19 ++++++++++---------
 tools/perf/util/pmu.c                    | 20 --------------------
 tools/perf/util/pmu.h                    |  1 -
 15 files changed, 57 insertions(+), 67 deletions(-)

diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c
index 7ccdea3cd461..22b19dcc6beb 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -23,6 +23,7 @@
 #include "../../../util/debug.h"
 #include "../../../util/auxtrace.h"
 #include "../../../util/record.h"
+#include "../../../util/header.h"
 #include "../../../util/arm-spe.h"
 #include <tools/libc_compat.h> // reallocarray
 
@@ -85,22 +86,11 @@ static int arm_spe_save_cpu_header(struct auxtrace_record *itr,
 	struct arm_spe_recording *sper =
 			container_of(itr, struct arm_spe_recording, itr);
 	struct perf_pmu *pmu = NULL;
-	struct perf_pmu tmp_pmu;
-	char cpu_id_str[16];
 	char *cpuid = NULL;
 	u64 val;
 
-	snprintf(cpu_id_str, sizeof(cpu_id_str), "%d", cpu.cpu);
-	tmp_pmu.cpus = perf_cpu_map__new(cpu_id_str);
-	if (!tmp_pmu.cpus)
-		return -ENOMEM;
-
 	/* Read CPU MIDR */
-	cpuid = perf_pmu__getcpuid(&tmp_pmu);
-
-	/* The CPU map will not be used anymore, release it */
-	perf_cpu_map__put(tmp_pmu.cpus);
-
+	cpuid = get_cpuid_allow_env_override(cpu);
 	if (!cpuid)
 		return -ENOMEM;
 	val = strtol(cpuid, NULL, 16);
diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c
index f0907daad3ae..f445a2dd6293 100644
--- a/tools/perf/arch/arm64/util/header.c
+++ b/tools/perf/arch/arm64/util/header.c
@@ -62,22 +62,18 @@ int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu)
 	return EINVAL;
 }
 
-char *get_cpuid_str(struct perf_pmu *pmu)
+char *get_cpuid_str(struct perf_cpu cpu)
 {
-	char *buf = NULL;
+	char *buf = malloc(MIDR_SIZE);
 	int res;
 
-	if (!pmu || !pmu->cpus)
-		return NULL;
-
-	buf = malloc(MIDR_SIZE);
 	if (!buf)
 		return NULL;
 
 	/* read midr from list of cpus mapped to this pmu */
-	res = get_cpuid(buf, MIDR_SIZE, perf_cpu_map__min(pmu->cpus));
+	res = get_cpuid(buf, MIDR_SIZE, cpu);
 	if (res) {
-		pr_err("failed to get cpuid string for PMU %s\n", pmu->name);
+		pr_err("failed to get cpuid string for CPU %d\n", cpu.cpu);
 		free(buf);
 		buf = NULL;
 	}
diff --git a/tools/perf/arch/loongarch/util/header.c b/tools/perf/arch/loongarch/util/header.c
index f1f0b116962d..0c6d823334a2 100644
--- a/tools/perf/arch/loongarch/util/header.c
+++ b/tools/perf/arch/loongarch/util/header.c
@@ -90,7 +90,7 @@ int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 	return ret;
 }
 
-char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char *get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	return _get_cpuid();
 }
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
index 6d1a63a2922f..c7df534dbf8f 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -42,7 +42,7 @@ get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 }
 
 char *
-get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	char *bufp;
 	unsigned long pvr;
diff --git a/tools/perf/arch/riscv/util/header.c b/tools/perf/arch/riscv/util/header.c
index ebac294c877f..4b839203d4a5 100644
--- a/tools/perf/arch/riscv/util/header.c
+++ b/tools/perf/arch/riscv/util/header.c
@@ -98,7 +98,7 @@ int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 }
 
 char *
-get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	return _get_cpuid();
 }
diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c
index 2add1a561242..db54677a17d2 100644
--- a/tools/perf/arch/s390/util/header.c
+++ b/tools/perf/arch/s390/util/header.c
@@ -137,11 +137,11 @@ int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 	return (nbytes >= sz) ? ENOBUFS : 0;
 }
 
-char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char *get_cpuid_str(struct perf_cpu cpu)
 {
 	char *buf = malloc(128);
 
-	if (buf && get_cpuid(buf, 128))
+	if (buf && get_cpuid(buf, 128, cpu))
 		zfree(&buf);
 	return buf;
 }
diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c
index 690f86cbbb1c..412977f8aa83 100644
--- a/tools/perf/arch/x86/util/header.c
+++ b/tools/perf/arch/x86/util/header.c
@@ -63,8 +63,7 @@ get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused)
 	return __get_cpuid(buffer, sz, "%s,%u,%u,%u$");
 }
 
-char *
-get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char *get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	char *buf = malloc(128);
 
diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index b8719dab264d..51ca8d61c15d 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -515,13 +515,16 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
         } last_map_search;
         static bool has_last_result, has_last_map_search;
         const struct pmu_events_map *map = NULL;
+        struct perf_cpu cpu = {-1};
         char *cpuid = NULL;
         size_t i;
 
         if (has_last_result && last_result.pmu == pmu)
                 return last_result.map;
 
-        cpuid = perf_pmu__getcpuid(pmu);
+        if (pmu)
+                cpu = perf_cpu_map__min(pmu->cpus);
+        cpuid = get_cpuid_allow_env_override(cpu);
 
         /*
          * On some platforms which uses cpus map, cpuid can be NULL for
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 70f4fd5395fb..b5ff872e2beb 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1031,13 +1031,16 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
         } last_map_search;
         static bool has_last_result, has_last_map_search;
         const struct pmu_events_map *map = NULL;
+        struct perf_cpu cpu = {-1};
         char *cpuid = NULL;
         size_t i;
 
         if (has_last_result && last_result.pmu == pmu)
                 return last_result.map;
 
-        cpuid = perf_pmu__getcpuid(pmu);
+        if (pmu)
+                cpu = perf_cpu_map__min(pmu->cpus);
+        cpuid = get_cpuid_allow_env_override(cpu);
 
         /*
          * On some platforms which uses cpus map, cpuid can be NULL for
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index d60f1ac1d720..41ff1affdfcd 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -4,10 +4,9 @@
 #include "util/expr.h"
 #include "util/hashmap.h"
 #include "util/header.h"
-#include "util/pmu.h"
-#include "util/pmus.h"
 #include "util/smt.h"
 #include "tests.h"
+#include <perf/cpumap.h>
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
@@ -78,8 +77,8 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u
 	struct expr_parse_ctx *ctx;
 	bool is_intel = false;
 	char strcmp_cpuid_buf[256];
-	struct perf_pmu *pmu = perf_pmus__find_core_pmu();
-	char *cpuid = perf_pmu__getcpuid(pmu);
+	struct perf_cpu cpu = {-1};
+	char *cpuid = get_cpuid_allow_env_override(cpu);
 	char *escaped_cpuid1, *escaped_cpuid2;
 
 	TEST_ASSERT_VAL("get_cpuid", cpuid);
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 5e3732bc2fa5..f289044a1f7c 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -8,7 +8,6 @@
 #include "debug.h"
 #include "evlist.h"
 #include "expr.h"
-#include "pmu.h"
 #include "smt.h"
 #include "tool_pmu.h"
 #include <util/expr-bison.h>
@@ -16,6 +15,7 @@
 #include "util/hashmap.h"
 #include "util/header.h"
 #include "util/pmu.h"
+#include <perf/cpumap.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/zalloc.h>
@@ -456,8 +456,8 @@ double expr__strcmp_cpuid_str(const struct expr_parse_ctx *ctx __maybe_unused,
 		       bool compute_ids __maybe_unused, const char *test_id)
 {
 	double ret;
-	struct perf_pmu *pmu = perf_pmus__find_core_pmu();
-	char *cpuid = perf_pmu__getcpuid(pmu);
+	struct perf_cpu cpu = {-1};
+	char *cpuid = get_cpuid_allow_env_override(cpu);
 
 	if (!cpuid)
 		return NAN;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 60b42ddc3dac..06ca5762f61f 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -819,11 +819,31 @@ static int write_group_desc(struct feat_fd *ff,
  * Each architecture should provide a more precise id string that
  * can be use to match the architecture's "mapfile".
  */
-char * __weak get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
+char * __weak get_cpuid_str(struct perf_cpu cpu __maybe_unused)
 {
 	return NULL;
 }
 
+char *get_cpuid_allow_env_override(struct perf_cpu cpu)
+{
+	char *cpuid;
+	static bool printed;
+
+	cpuid = getenv("PERF_CPUID");
+	if (cpuid)
+		cpuid = strdup(cpuid);
+	if (!cpuid)
+		cpuid = get_cpuid_str(cpu);
+	if (!cpuid)
+		return NULL;
+
+	if (!printed) {
+		pr_debug("Using CPUID %s\n", cpuid);
+		printed = true;
+	}
+	return cpuid;
+}
+
 /* Return zero when the cpuid from the mapfile.csv matches the
  * cpuid string generated on this platform.
  * Otherwise return non-zero.
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 3bb768455a60..5201af6305f4 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -10,9 +10,14 @@
 #include <linux/bitmap.h>
 #include <linux/types.h>
 #include "env.h"
-#include "pmu.h"
 #include <perf/cpumap.h>
 
+struct evlist;
+union perf_event;
+struct perf_header;
+struct perf_session;
+struct perf_tool;
+
 enum {
 	HEADER_RESERVED		= 0,	/* always cleared */
 	HEADER_FIRST_FEATURE	= 1,
@@ -92,8 +97,6 @@ struct perf_pipe_file_header {
 	u64				size;
 };
 
-struct perf_header;
-
 int perf_file_header__read(struct perf_file_header *header,
 			   struct perf_header *ph, int fd);
 
@@ -125,11 +128,6 @@ struct perf_header_feature_ops {
 	bool	   synthesize;
 };
 
-struct evlist;
-struct perf_session;
-struct perf_tool;
-union perf_event;
-
 extern const char perf_version_string[];
 
 int perf_session__read_header(struct perf_session *session);
@@ -204,6 +202,9 @@ int build_caches_for_cpu(u32 cpu, struct cpu_cache_level caches[], u32 *cntp);
  */
 int get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu);
 
-char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused);
+char *get_cpuid_str(struct perf_cpu cpu);
+
+char *get_cpuid_allow_env_override(struct perf_cpu cpu);
+
 int strcmp_cpuid_str(const char *s1, const char *s2);
 #endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 0789758598c0..514cb865f57b 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -818,26 +818,6 @@ static int is_sysfs_pmu_core(const char *name)
 	return file_available(path);
 }
 
-char *perf_pmu__getcpuid(struct perf_pmu *pmu)
-{
-	char *cpuid;
-	static bool printed;
-
-	cpuid = getenv("PERF_CPUID");
-	if (cpuid)
-		cpuid = strdup(cpuid);
-	if (!cpuid)
-		cpuid = get_cpuid_str(pmu);
-	if (!cpuid)
-		return NULL;
-
-	if (!printed) {
-		pr_debug("Using CPUID %s\n", cpuid);
-		printed = true;
-	}
-	return cpuid;
-}
-
 __weak const struct pmu_metrics_table *pmu_metrics_table__find(void)
 {
 	return perf_pmu__find_metrics_table(NULL);
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index b86b3c3685a2..fba3fc608b64 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -260,7 +260,6 @@ void perf_pmu__arch_init(struct perf_pmu *pmu);
 void pmu_add_cpu_aliases_table(struct perf_pmu *pmu,
 			       const struct pmu_events_table *table);
 
-char *perf_pmu__getcpuid(struct perf_pmu *pmu);
 const struct pmu_metrics_table *pmu_metrics_table__find(void);
 bool pmu_uncore_identifier_match(const char *compat, const char *id);
 
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Thu Nov  7 08:20:34 2024
From: irogers at google.com (Ian Rogers)
Date: Thu,  7 Nov 2024 08:20:34 -0800
Subject: [PATCH v2 7/8] perf jevents: Add map_for_cpu
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <20241107162035.52206-8-irogers@google.com>

The PMU is no longer part of the map finding process and for metrics
doesn't make sense as they lack a PMU.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/pmu-events/empty-pmu-events.c | 20 +++++++++++++-------
 tools/perf/pmu-events/jevents.py         | 20 +++++++++++++-------
 2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index 51ca8d61c15d..17306e316a3c 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -503,11 +503,11 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table,
         return 0;
 }
 
-static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+static const struct pmu_events_map *map_for_cpu(struct perf_cpu cpu)
 {
         static struct {
                 const struct pmu_events_map *map;
-                struct perf_pmu *pmu;
+                struct perf_cpu cpu;
         } last_result;
         static struct {
                 const struct pmu_events_map *map;
@@ -515,15 +515,12 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
         } last_map_search;
         static bool has_last_result, has_last_map_search;
         const struct pmu_events_map *map = NULL;
-        struct perf_cpu cpu = {-1};
         char *cpuid = NULL;
         size_t i;
 
-        if (has_last_result && last_result.pmu == pmu)
+        if (has_last_result && last_result.cpu.cpu == cpu.cpu)
                 return last_result.map;
 
-        if (pmu)
-                cpu = perf_cpu_map__min(pmu->cpus);
         cpuid = get_cpuid_allow_env_override(cpu);
 
         /*
@@ -555,12 +552,21 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
                has_last_map_search = true;
         }
 out_update_last_result:
-        last_result.pmu = pmu;
+        last_result.cpu = cpu;
         last_result.map = map;
         has_last_result = true;
         return map;
 }
 
+static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+{
+        struct perf_cpu cpu = {-1};
+
+        if (pmu)
+                cpu = perf_cpu_map__min(pmu->cpus);
+        return map_for_cpu(cpu);
+}
+
 const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
 {
         const struct pmu_events_map *map = map_for_pmu(pmu);
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index b5ff872e2beb..e44b72e56ac3 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1019,11 +1019,11 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table,
         return 0;
 }
 
-static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+static const struct pmu_events_map *map_for_cpu(struct perf_cpu cpu)
 {
         static struct {
                 const struct pmu_events_map *map;
-                struct perf_pmu *pmu;
+                struct perf_cpu cpu;
         } last_result;
         static struct {
                 const struct pmu_events_map *map;
@@ -1031,15 +1031,12 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
         } last_map_search;
         static bool has_last_result, has_last_map_search;
         const struct pmu_events_map *map = NULL;
-        struct perf_cpu cpu = {-1};
         char *cpuid = NULL;
         size_t i;
 
-        if (has_last_result && last_result.pmu == pmu)
+        if (has_last_result && last_result.cpu.cpu == cpu.cpu)
                 return last_result.map;
 
-        if (pmu)
-                cpu = perf_cpu_map__min(pmu->cpus);
         cpuid = get_cpuid_allow_env_override(cpu);
 
         /*
@@ -1071,12 +1068,21 @@ static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
                has_last_map_search = true;
         }
 out_update_last_result:
-        last_result.pmu = pmu;
+        last_result.cpu = cpu;
         last_result.map = map;
         has_last_result = true;
         return map;
 }
 
+static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
+{
+        struct perf_cpu cpu = {-1};
+
+        if (pmu)
+                cpu = perf_cpu_map__min(pmu->cpus);
+        return map_for_cpu(cpu);
+}
+
 const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
 {
         const struct pmu_events_map *map = map_for_pmu(pmu);
-- 
2.47.0.199.ga7371fff76-goog



From irogers at google.com  Thu Nov  7 08:20:35 2024
From: irogers at google.com (Ian Rogers)
Date: Thu,  7 Nov 2024 08:20:35 -0800
Subject: [PATCH v2 8/8] perf pmu: Move pmu_metrics_table__find and remove ARM override
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <20241107162035.52206-9-irogers@google.com>

Move pmu_metrics_table__find to the jevents.py generated pmu-events.c
and remove indirection override for ARM. The movement removes
perf_pmu__find_metrics_table that exists to enable the ARM
override. The ARM override isn't necessary as just the CPUID, not PMU,
is used in the metric table lookup. On non-ARM the CPU argument is
just ignored for the CPUID, for ARM -1 is passed so that the CPUID for
the first logical CPU is read.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm64/util/pmu.c         | 20 --------------------
 tools/perf/pmu-events/empty-pmu-events.c | 10 ++++------
 tools/perf/pmu-events/jevents.py         | 10 ++++------
 tools/perf/pmu-events/pmu-events.h       |  2 +-
 tools/perf/util/pmu.c                    |  5 -----
 tools/perf/util/pmu.h                    |  1 -
 6 files changed, 9 insertions(+), 39 deletions(-)

diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/pmu.c
index a0964b191fcb..895fb0d0610c 100644
--- a/tools/perf/arch/arm64/util/pmu.c
+++ b/tools/perf/arch/arm64/util/pmu.c
@@ -1,29 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 
-#include <internal/cpumap.h>
-#include "../../../util/cpumap.h"
-#include "../../../util/header.h"
 #include "../../../util/pmu.h"
 #include "../../../util/pmus.h"
 #include "../../../util/tool_pmu.h"
 #include <api/fs/fs.h>
-#include <math.h>
-
-const struct pmu_metrics_table *pmu_metrics_table__find(void)
-{
-	struct perf_pmu *pmu;
-
-	/* Metrics aren't currently supported on heterogeneous Arm systems */
-	if (perf_pmus__num_core_pmus() > 1)
-		return NULL;
-
-	/* Doesn't matter which one here because they'll all be the same */
-	pmu = perf_pmus__find_core_pmu();
-	if (pmu)
-		return perf_pmu__find_metrics_table(pmu);
-
-	return NULL;
-}
 
 u64 tool_pmu__cpu_slots_per_cycle(void)
 {
diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
index 17306e316a3c..1c7a2cfa321f 100644
--- a/tools/perf/pmu-events/empty-pmu-events.c
+++ b/tools/perf/pmu-events/empty-pmu-events.c
@@ -587,14 +587,12 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
         return NULL;
 }
 
-const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
+const struct pmu_metrics_table *pmu_metrics_table__find(void)
 {
-        const struct pmu_events_map *map = map_for_pmu(pmu);
-
-        if (!map)
-                return NULL;
+        struct perf_cpu cpu = {-1};
+        const struct pmu_events_map *map = map_for_cpu(cpu);
 
-	return &map->metric_table;
+        return map ? &map->metric_table : NULL;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index e44b72e56ac3..d781a377757a 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -1103,14 +1103,12 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
         return NULL;
 }
 
-const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
+const struct pmu_metrics_table *pmu_metrics_table__find(void)
 {
-        const struct pmu_events_map *map = map_for_pmu(pmu);
-
-        if (!map)
-                return NULL;
+        struct perf_cpu cpu = {-1};
+        const struct pmu_events_map *map = map_for_cpu(cpu);
 
-	return &map->metric_table;
+        return map ? &map->metric_table : NULL;
 }
 
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
index 5435ad92180c..675562e6f770 100644
--- a/tools/perf/pmu-events/pmu-events.h
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -103,7 +103,7 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pm
 				     void *data);
 
 const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu);
-const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu);
+const struct pmu_metrics_table *pmu_metrics_table__find(void);
 const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid);
 const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid);
 int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data);
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 514cb865f57b..45838651b361 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -818,11 +818,6 @@ static int is_sysfs_pmu_core(const char *name)
 	return file_available(path);
 }
 
-__weak const struct pmu_metrics_table *pmu_metrics_table__find(void)
-{
-	return perf_pmu__find_metrics_table(NULL);
-}
-
 /**
  * Return the length of the PMU name not including the suffix for uncore PMUs.
  *
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index fba3fc608b64..7b3e71194e49 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -260,7 +260,6 @@ void perf_pmu__arch_init(struct perf_pmu *pmu);
 void pmu_add_cpu_aliases_table(struct perf_pmu *pmu,
 			       const struct pmu_events_table *table);
 
-const struct pmu_metrics_table *pmu_metrics_table__find(void);
 bool pmu_uncore_identifier_match(const char *compat, const char *id);
 
 int perf_pmu__convert_scale(const char *scale, char **end, double *sval);
-- 
2.47.0.199.ga7371fff76-goog



From ajones at ventanamicro.com  Thu Nov  7 08:35:19 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 7 Nov 2024 17:35:19 +0100
Subject: [PATCH 1/2] iommu/riscv: Free irq vectors on pci remove
In-Reply-To: <CAH2o1u5ttY+0d4v8U=H-PwLUHZo5uMxxCQ5NAXudOQvUUMcpfA@mail.gmail.com>
References: <20241106175102.219923-4-ajones@ventanamicro.com>
 <20241106175102.219923-5-ajones@ventanamicro.com>
 <CAH2o1u5ttY+0d4v8U=H-PwLUHZo5uMxxCQ5NAXudOQvUUMcpfA@mail.gmail.com>
Message-ID: <20241107-4570ae5b32599c6ff96b5241@orel>

On Wed, Nov 06, 2024 at 11:00:55AM -0800, Tomasz Jeznach wrote:
> On Wed, Nov 6, 2024 at 9:51?AM Andrew Jones <ajones at ventanamicro.com> wrote:
> >
> > riscv_iommu_pci_probe() calls pci_alloc_irq_vectors() which
> > states pci_free_irq_vectors() must be called on cleanup.
> >
> > Fixes: 68682e9578fb ("iommu/riscv: Add RISC-V IOMMU PCIe device driver")
> > Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
> > ---
> >  drivers/iommu/riscv/iommu-pci.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/iommu/riscv/iommu-pci.c b/drivers/iommu/riscv/iommu-pci.c
> > index c7a89143014c..25a27e627a0e 100644
> > --- a/drivers/iommu/riscv/iommu-pci.c
> > +++ b/drivers/iommu/riscv/iommu-pci.c
> > @@ -99,6 +99,7 @@ static void riscv_iommu_pci_remove(struct pci_dev *pdev)
> >         struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev);
> >
> >         riscv_iommu_remove(iommu);
> > +       pci_free_irq_vectors(pdev);
> >  }
> >
> >  static const struct pci_device_id riscv_iommu_pci_tbl[] = {
> > --
> > 2.47.0
> >
> 
> Andrew, interrupt release call pci_free_irq_vectors() should already
> be called by device
> managed resources framework, with unwind action callback pcim_msi_release().
> 
> Callback is registered during vectors allocation:
>  pci_alloc_irq_vectors_affinity()
>   __pci_enable_msix_range()
>    pci_setup_msi_context()
>     pcim_setup_msi_release()
> 
> This driver enables device resources management with initial call to
> pcim_enable_device().

Ah, thank you for the education and inspiration to look closer at how this
works. It was easy to confirm with a WARN in pci_free_irq_vectors() and an
echo 1 to the IOMMU device's remove sysfs node.

> 
> Are there any conditions / testing sequence the release function is not called?

No, not that I know of, this was just my knee jerk decision to mimic the
call pairing I was doing on the platform side to the pci side. Sorry for
the noise, this patch can be dropped.

Thanks,
drew


From ajones at ventanamicro.com  Thu Nov  7 08:41:39 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 7 Nov 2024 17:41:39 +0100
Subject: [PATCH 2/2] iommu/riscv: Add support for platform msi
In-Reply-To: <d92ab280-bd1f-4145-8164-cebab1980f20@sifive.com>
References: <20241106175102.219923-4-ajones@ventanamicro.com>
 <20241106175102.219923-6-ajones@ventanamicro.com>
 <d92ab280-bd1f-4145-8164-cebab1980f20@sifive.com>
Message-ID: <20241107-dcdcb332d980a7120e9518ac@orel>

On Wed, Nov 06, 2024 at 01:45:23PM -0600, Samuel Holland wrote:
> Hi Drew,
> 
> On 2024-11-06 11:51 AM, Andrew Jones wrote:
> > Apply platform_device_msi_init_and_alloc_irqs() to add support for
> > MSIs when the IOMMU is a platform device.
> > 
> > Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
> > ---
> >  drivers/iommu/riscv/iommu-platform.c | 102 ++++++++++++++++++++++-----
> >  1 file changed, 84 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
> > index da336863f152..89aa622bcbde 100644
> > --- a/drivers/iommu/riscv/iommu-platform.c
> > +++ b/drivers/iommu/riscv/iommu-platform.c
> > @@ -11,18 +11,41 @@
> >   */
> >  
> >  #include <linux/kernel.h>
> > +#include <linux/of_irq.h>
> >  #include <linux/of_platform.h>
> >  #include <linux/platform_device.h>
> > +#include <linux/msi.h>
> 
> If you respin, please keep these sorted.

Sure

> 
> >  
> >  #include "iommu-bits.h"
> >  #include "iommu.h"
> >  
> > +static void riscv_iommu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
> > +{
> > +	struct device *dev = msi_desc_to_dev(desc);
> > +	struct riscv_iommu_device *iommu = dev_get_drvdata(dev);
> > +	u16 idx = desc->msi_index;
> > +	u64 addr;
> > +
> > +	addr = ((u64)msg->address_hi << 32) | msg->address_lo;
> > +
> > +	if (addr != (addr & RISCV_IOMMU_MSI_CFG_TBL_ADDR))
> > +		pr_warn_once("uh oh, the IOMMU can't send MSIs to 0x%llx, sending to 0x%llx instead\n",
> > +			     addr, addr & RISCV_IOMMU_MSI_CFG_TBL_ADDR);
> 
> Can this use dev_warn_once()? And should it really be only a warning?
> Configuring the IOMMU to write to some other address seems dangerous. I guess
> there's no clean way to handle this error, since this function cannot fail, and
> irq_chip_compose_msi_msg() isn't supposed to fail either.

I'll change it to a dev_err_once().

> 
> > +
> > +	addr &= RISCV_IOMMU_MSI_CFG_TBL_ADDR;
> > +
> > +	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_ADDR(idx), addr);
> > +	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_DATA(idx), msg->data);
> > +	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_CTRL(idx), 0);
> > +}
> > +
> >  static int riscv_iommu_platform_probe(struct platform_device *pdev)
> >  {
> > +	enum riscv_iommu_igs_settings igs;
> >  	struct device *dev = &pdev->dev;
> >  	struct riscv_iommu_device *iommu = NULL;
> >  	struct resource *res = NULL;
> > -	int vec;
> > +	int vec, ret;
> >  
> >  	iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL);
> >  	if (!iommu)
> > @@ -40,16 +63,6 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
> >  	iommu->caps = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_CAPABILITIES);
> >  	iommu->fctl = riscv_iommu_readl(iommu, RISCV_IOMMU_REG_FCTL);
> >  
> > -	/* For now we only support WSI */
> > -	switch (FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps)) {
> > -	case RISCV_IOMMU_CAPABILITIES_IGS_WSI:
> > -	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
> > -		break;
> > -	default:
> > -		return dev_err_probe(dev, -ENODEV,
> > -				     "unable to use wire-signaled interrupts\n");
> > -	}
> > -
> >  	iommu->irqs_count = platform_irq_count(pdev);
> >  	if (iommu->irqs_count <= 0)
> >  		return dev_err_probe(dev, -ENODEV,
> > @@ -57,13 +70,60 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
> >  	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT)
> >  		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT;
> >  
> > -	for (vec = 0; vec < iommu->irqs_count; vec++)
> > -		iommu->irqs[vec] = platform_get_irq(pdev, vec);
> > +	igs = FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps);
> > +	switch (igs) {
> > +	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
> > +	case RISCV_IOMMU_CAPABILITIES_IGS_MSI:
> > +		if (is_of_node(dev->fwnode))
> > +			of_msi_configure(dev, to_of_node(dev->fwnode));
> > +
> > +		if (!dev_get_msi_domain(dev)) {
> > +			dev_warn(dev, "failed to find an MSI domain");
> > +			goto msi_fail;
> > +		}
> > +
> > +		ret = platform_device_msi_init_and_alloc_irqs(dev, iommu->irqs_count,
> > +							      riscv_iommu_write_msi_msg);
> > +		if (ret) {
> > +			dev_warn(dev, "failed to allocate MSIs");
> > +			goto msi_fail;
> > +		}
> > +
> > +		for (vec = 0; vec < iommu->irqs_count; vec++)
> > +			iommu->irqs[vec] = msi_get_virq(dev, vec);
> > +
> > +		/* Enable message-signaled interrupts, fctl.WSI */
> > +		if (iommu->fctl & RISCV_IOMMU_FCTL_WSI) {
> > +			iommu->fctl ^= RISCV_IOMMU_FCTL_WSI;
> > +			riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
> > +		}
> > +
> > +		dev_info(dev, "using MSIs\n");
> > +		break;
> > +
> > +msi_fail:
> > +		if (igs != RISCV_IOMMU_CAPABILITIES_IGS_BOTH) {
> > +			dev_warn(dev, "\n");
> > +			return dev_err_probe(dev, -ENODEV,
> > +					     "unable to use wire-signaled interrupts\n");
> 
> Is the dev_warn() just to call attention to the following error? There's no
> guarantee that these two messages will be printed adjacently.

I'll drop the dev_warn since it was supposed to tie in with the dev_warn
above which was missing its endline on purpose, but your statement about
avoiding split logs means I should probably just do a complete log above
and complete logs here and...

> 
> > +		}
> > +
> > +		dev_warn(dev, " - falling back to wired irqs\n");
> 
> No need for the extra hyphen here.

...here, which also means the hyphen should be dropped.
> 
> Regards,
> Samuel

Thanks,
drew

> 
> > +		fallthrough;
> >  
> > -	/* Enable wire-signaled interrupts, fctl.WSI */
> > -	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
> > -		iommu->fctl |= RISCV_IOMMU_FCTL_WSI;
> > -		riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
> > +	case RISCV_IOMMU_CAPABILITIES_IGS_WSI:
> > +		for (vec = 0; vec < iommu->irqs_count; vec++)
> > +			iommu->irqs[vec] = platform_get_irq(pdev, vec);
> > +
> > +		/* Enable wire-signaled interrupts, fctl.WSI */
> > +		if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
> > +			iommu->fctl |= RISCV_IOMMU_FCTL_WSI;
> > +			riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
> > +		}
> > +		dev_info(dev, "using wire-signaled interrupts\n");
> > +		break;
> > +	default:
> > +		return dev_err_probe(dev, -ENODEV, "invalid IGS\n");
> >  	}
> >  
> >  	return riscv_iommu_init(iommu);
> > @@ -71,7 +131,13 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
> >  
> >  static void riscv_iommu_platform_remove(struct platform_device *pdev)
> >  {
> > -	riscv_iommu_remove(dev_get_drvdata(&pdev->dev));
> > +	struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev);
> > +	bool msi = !(iommu->fctl & RISCV_IOMMU_FCTL_WSI);
> > +
> > +	riscv_iommu_remove(iommu);
> > +
> > +	if (msi)
> > +		platform_device_msi_free_irqs_all(&pdev->dev);
> >  };
> >  
> >  static const struct of_device_id riscv_iommu_of_match[] = {
> 


From conor at kernel.org  Thu Nov  7 08:54:55 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 7 Nov 2024 16:54:55 +0000
Subject: [PATCH v6 0/2] PCI: microchip: support using either instance 1
 or 2
In-Reply-To: <20241107145715.GA1613568@bhelgaas>
References: <20241107-aqueduct-petroleum-c002480ba291@spud>
 <20241107145715.GA1613568@bhelgaas>
Message-ID: <20241107-applied-landscape-18094319130e@spud>

On Thu, Nov 07, 2024 at 08:57:15AM -0600, Bjorn Helgaas wrote:
> On Thu, Nov 07, 2024 at 10:59:33AM +0000, Conor Dooley wrote:
> > From: Conor Dooley <conor.dooley at microchip.com>
> > 
> > The current driver and binding for PolarFire SoC's PCI controller assume
> > that the root port instance in use is instance 1. The second reg
> > property constitutes the region encompassing both "control" and "bridge"
> > registers for both instances. In the driver, a fixed offset is applied to
> > find the base addresses for instance 1's "control" and "bridge"
> > registers. The BeagleV Fire uses root port instance 2, so something must
> > be done so that software can differentiate. This series splits the
> > second reg property in two, with dedicated "control" and "bridge"
> > entries so that either instance can be used.
> > 
> > Cheers,
> > Conor.
> > 
> > v6:
> > - rework commit messages to use Bjorn's preferred "root port" and "root
> >   complex" wording
> > 
> > v5:
> > - rebase on top of 6.11-rc1, which brought about a lot of driver change
> >   due to the plda common driver creation - although little actually
> >   changed in terms of the lines edited in this patch.
> > 
> > v4:
> > - fix a cocci warning reported off list about an inconsistent variable
> >   used between IS_ERR() and PTR_ERR() calls.
> > 
> > v3:
> > - rename a variable in probe s/axi/apb/
> > 
> > v2:
> > - try the new reg format before the old one to avoid warnings in the
> >   good case
> > - reword $subject for 2/2
> > 
> > CC: Daire McNamara <daire.mcnamara at microchip.com>
> > CC: Lorenzo Pieralisi <lpieralisi at kernel.org>
> > CC: Krzysztof Wilczy?ski <kw at linux.com>
> > CC: Rob Herring <robh at kernel.org>
> > CC: Bjorn Helgaas <bhelgaas at google.com>
> > CC: Krzysztof Kozlowski <krzk+dt at kernel.org>
> > CC: Conor Dooley <conor+dt at kernel.org>
> > CC: linux-pci at vger.kernel.org
> > CC: devicetree at vger.kernel.org
> > CC: linux-kernel at vger.kernel.org
> > CC: linux-riscv at lists.infradead.org
> > 
> > Conor Dooley (2):
> >   dt-bindings: PCI: microchip,pcie-host: fix reg properties
> >   PCI: microchip: rework reg region handing to support using either root
> >     port 1 or 2
> > 
> >  .../bindings/pci/microchip,pcie-host.yaml     |  11 +-
> >  .../pci/plda,xpressrich3-axi-common.yaml      |  14 ++-
> >  .../bindings/pci/starfive,jh7110-pcie.yaml    |   7 ++
> >  .../pci/controller/plda/pcie-microchip-host.c | 116 +++++++++---------
> >  4 files changed, 87 insertions(+), 61 deletions(-)
> 
> Thanks!  The patches themselves are unchanged between v5 and v6.  I
> replaced the v5 patches on pci/controller/microchip with these.
> 
> I also capitalized "Root Port" and "Root Complex" to give a hint that
> they are proper nouns defined by the PCIe spec.

Cool, thanks for doing that.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241107/14a3fcef/attachment.sig>

From irogers at google.com  Thu Nov  7 10:51:58 2024
From: irogers at google.com (Ian Rogers)
Date: Thu, 7 Nov 2024 10:51:58 -0800
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is provided
In-Reply-To: <20241026121758.143259-1-irogers@google.com>
References: <20241026121758.143259-1-irogers@google.com>
Message-ID: <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>

On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
>
> At the RISC-V summit the topic of avoiding event data being in the
> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
> events being the priority when no PMU is provided so that legacy
> events maybe supported via json. Originally Mark Rutland also
> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
> M? processors, but James Clark more recently tested this and believes
> the driver issues there may not have existed or have been resolved. In
> any case, it is inconsistent that with a PMU event names avoid legacy
> encodings, but when wildcarding PMUs (ie without a PMU with the event
> name) the legacy encodings have priority.
>
> The patch doing this work was reverted in a v6.10 release candidate
> as, even though the patch was posted for weeks and had been on
> linux-next for weeks without issue, Linus was in the habit of using
> explicit legacy events with unsupported precision options on his
> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
> where ARM decided to call the events bus_cycles and cycles, the latter
> being also a legacy event name. ARM haven't renamed the cycles event
> to a more consistent cpu_cycles and avoided the problem. With these
> changes the problematic event will now be skipped, a large warning
> produced, and perf record will continue for the other PMU events. This
> solution was proposed by Arnaldo.
>
> Two minor changes have been added to help with the error message and
> to work around issues occurring with "perf stat metrics (shadow stat)
> test".
>
> The patches have only been tested on my x86 non-hybrid laptop.

Hi Atish and James,

Could I get your tags for this series?

The patches were originally motivated by wanting to make the behavior
of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
wildcarded to "cpu" in the first case. This was divergent because of
ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
type>, config=<encoding from event>) when a PMU name was given. This
aligns with RISC-V wanting to use json encodings to avoid complexity
in the PMU driver.

James, could you show the neoverse with the cmn PMU behavior for perf
record of "cycles:pp" due to sensitivities there.

Thanks,
Ian




> Ian Rogers (4):
>   perf evsel: Add pmu_name helper
>   perf stat: Fix find_stat for mixed legacy/non-legacy events
>   perf record: Skip don't fail for events that don't open
>   perf parse-events: Reapply "Prefer sysfs/JSON hardware events over
>     legacy"
>
>  tools/perf/builtin-record.c    | 22 +++++++---
>  tools/perf/util/evsel.c        | 10 +++++
>  tools/perf/util/evsel.h        |  1 +
>  tools/perf/util/parse-events.c | 26 +++++++++---
>  tools/perf/util/parse-events.l | 76 +++++++++++++++++-----------------
>  tools/perf/util/parse-events.y | 60 ++++++++++++++++++---------
>  tools/perf/util/pmus.c         | 20 +++++++--
>  tools/perf/util/stat-shadow.c  |  3 +-
>  8 files changed, 145 insertions(+), 73 deletions(-)
>
> --
> 2.47.0.163.g1226f6d8fa-goog
>


From namhyung at kernel.org  Thu Nov  7 11:18:50 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Thu, 7 Nov 2024 11:18:50 -0800
Subject: [PATCH v2 16/31] perf dwarf-regs: Pass accurate disassembly
 machine to get_dwarf_regnum
In-Reply-To: <CAP-5=fU4hTL1hfB7-FpMnFopJJriZAOXY_8iakW5yHC_gfhTWg@mail.gmail.com>
References: <20241005195541.380070-1-irogers@google.com>
 <20241005195541.380070-17-irogers@google.com>
 <20241007170755.03697b9178ed3dcac24dfa21@kernel.org>
 <CAP-5=fU4hTL1hfB7-FpMnFopJJriZAOXY_8iakW5yHC_gfhTWg@mail.gmail.com>
Message-ID: <Zy0SmlDrmksra_OD@google.com>

Hello,

Sorry for the late reply.

On Mon, Oct 07, 2024 at 08:46:59AM -0700, Ian Rogers wrote:
> On Mon, Oct 7, 2024 at 1:08?AM Masami Hiramatsu <mhiramat at kernel.org> wrote:
> >
> > On Sat,  5 Oct 2024 12:55:26 -0700
> > Ian Rogers <irogers at google.com> wrote:
> >
> > > Rather than pass 0/EM_NONE, use the value computed in the disasm
> > > struct arch. Switch the EM_NONE case to EM_HOST, rewriting EM_NONE if
> > > it were passed to get_dwarf_regnum. Pass a flags value as
> > > architectures like csky need the flags to determine the ABI variant.
> > >
> >
> > Does this change the command output when we use it for cross-build
> > environment? E.g. remote arch is different from host arch? If so,
> > please add output examples with/without this change.
> 
> The cases where this would apply are small as get_arch_regnum is only
> implemented for x86. get_dwarf_regnum likewise only works for x86 and
> it is only called by annotate.

Yep, it's used only in the data type profiling.  I don't expect it to
work in the cross environment yet.  This change moves it closer to the
working state though. :)


> In this code without this patch the behavior is to return -ENOTSUP, ie
> the code is set up to fail and this code just makes it not fail for
> the x86 case (when not on x86) with code that is well tested on x86.
> The code exists as x86 registers may be the same dwarf number but have
> different names: e.g. rax, eax, ax, al. I'm not sure this reaches a
> high complexity level for extensive testing. I'll see if I can grab an
> x86 perf.data file to analyze on ARM, but I don't think doing this
> should gate the series.

Yep, as I said it's not supported yet and I don't think that's the goal
of this patch series.  So probably it's ok to merge it without the
extensive testing.

Thanks,
Namhyung

> 
> > > Signed-off-by: Ian Rogers <irogers at google.com>
> > > ---
> > >  tools/perf/util/annotate.c           | 6 +++---
> > >  tools/perf/util/dwarf-regs.c         | 8 ++++++--
> > >  tools/perf/util/include/dwarf-regs.h | 5 +++--
> > >  3 files changed, 12 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> > > index 37ce43c4eb8f..b1d98da79be8 100644
> > > --- a/tools/perf/util/annotate.c
> > > +++ b/tools/perf/util/annotate.c
> > > @@ -2292,7 +2292,7 @@ static int extract_reg_offset(struct arch *arch, const char *str,
> > >       if (regname == NULL)
> > >               return -1;
> > >
> > > -     op_loc->reg1 = get_dwarf_regnum(regname, 0);
> > > +     op_loc->reg1 = get_dwarf_regnum(regname, arch->e_machine, arch->e_flags);
> > >       free(regname);
> > >
> > >       /* Get the second register */
> > > @@ -2305,7 +2305,7 @@ static int extract_reg_offset(struct arch *arch, const char *str,
> > >               if (regname == NULL)
> > >                       return -1;
> > >
> > > -             op_loc->reg2 = get_dwarf_regnum(regname, 0);
> > > +             op_loc->reg2 = get_dwarf_regnum(regname, arch->e_machine, arch->e_flags);
> > >               free(regname);
> > >       }
> > >       return 0;
> > > @@ -2405,7 +2405,7 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl,
> > >                               return -1;
> > >
> > >                       if (*s == arch->objdump.register_char)
> > > -                             op_loc->reg1 = get_dwarf_regnum(s, 0);
> > > +                             op_loc->reg1 = get_dwarf_regnum(s, arch->e_machine, arch->e_flags);
> > >                       else if (*s == arch->objdump.imm_char) {
> > >                               op_loc->offset = strtol(s + 1, &p, 0);
> > >                               if (p && p != s + 1)
> > > diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> > > index 7c01bc4d7e5b..1321387f6948 100644
> > > --- a/tools/perf/util/dwarf-regs.c
> > > +++ b/tools/perf/util/dwarf-regs.c
> > > @@ -70,7 +70,7 @@ __weak int get_arch_regnum(const char *name __maybe_unused)
> > >  }
> > >
> > >  /* Return DWARF register number from architecture register name */
> > > -int get_dwarf_regnum(const char *name, unsigned int machine)
> > > +int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags __maybe_unused)
> > >  {
> > >       char *regname = strdup(name);
> > >       int reg = -1;
> > > @@ -84,8 +84,12 @@ int get_dwarf_regnum(const char *name, unsigned int machine)
> > >       if (p)
> > >               *p = '\0';
> > >
> > > +     if (machine == EM_NONE) {
> > > +             /* Generic arch - use host arch */
> > > +             machine = EM_HOST;
> > > +     }
> > >       switch (machine) {
> > > -     case EM_NONE:   /* Generic arch - use host arch */
> > > +     case EM_HOST:
> > >               reg = get_arch_regnum(regname);
> > >               break;
> > >       default:
> > > diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> > > index f4f87ded5e3d..ee0a734564c7 100644
> > > --- a/tools/perf/util/include/dwarf-regs.h
> > > +++ b/tools/perf/util/include/dwarf-regs.h
> > > @@ -93,12 +93,13 @@ int get_arch_regnum(const char *name);
> > >   * name: architecture register name
> > >   * machine: ELF machine signature (EM_*)
> > >   */
> > > -int get_dwarf_regnum(const char *name, unsigned int machine);
> > > +int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags);
> > >
> > >  #else /* HAVE_LIBDW_SUPPORT */
> > >
> > >  static inline int get_dwarf_regnum(const char *name __maybe_unused,
> > > -                                unsigned int machine __maybe_unused)
> > > +                                unsigned int machine __maybe_unused,
> > > +                                unsigned int flags __maybe_unused)
> > >  {
> > >       return -1;
> > >  }
> > > --
> > > 2.47.0.rc0.187.ge670bccf7e-goog
> > >
> >
> >
> > --
> > Masami Hiramatsu (Google) <mhiramat at kernel.org>


From namhyung at kernel.org  Thu Nov  7 11:24:59 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Thu, 7 Nov 2024 11:24:59 -0800
Subject: [PATCH v2 17/31] perf dwarf-regs: Pass ELF flags to
 get_dwarf_regstr
In-Reply-To: <CAP-5=fVmD-M-ZOinkWZ7AOtfRHqo89gFtDeeatwufq0TcBiZUA@mail.gmail.com>
References: <20241005195541.380070-1-irogers@google.com>
 <20241005195541.380070-18-irogers@google.com>
 <20241007170927.f30fced63c5e777628bea311@kernel.org>
 <CAP-5=fVmD-M-ZOinkWZ7AOtfRHqo89gFtDeeatwufq0TcBiZUA@mail.gmail.com>
Message-ID: <Zy0UCxKmD3_mQmNh@google.com>

On Mon, Oct 07, 2024 at 08:05:23AM -0700, Ian Rogers wrote:
> On Mon, Oct 7, 2024 at 1:09?AM Masami Hiramatsu <mhiramat at kernel.org> wrote:
> >
> > On Sat,  5 Oct 2024 12:55:27 -0700
> > Ian Rogers <irogers at google.com> wrote:
> >
> > > Pass a flags value as architectures like csky need the flags to
> > > determine the ABI variant.
> > >
> >
> > Same here. I need some examples of this chaneg.
> 
> The code here was already using the ELF machine, so dwarf-regs.c
> functions would already support cross building. There is the addition
> of ELF flags as on csky the registers change depending on the ABI
> version in the ELF flags.

I think it's used by the probe-finder only which won't support
cross-arch environment.  So probably no changes to users at this point.

Thanks,
Namhyung



From namhyung at kernel.org  Thu Nov  7 11:29:34 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Thu, 7 Nov 2024 11:29:34 -0800
Subject: [PATCH v3 00/20] Remove PERF_HAVE_DWARF_REGS
In-Reply-To: <20241017002520.59124-1-irogers@google.com>
References: <20241017002520.59124-1-irogers@google.com>
Message-ID: <Zy0VHro3wE-ZTKsq@google.com>

Hi all,

On Wed, Oct 16, 2024 at 05:25:00PM -0700, Ian Rogers wrote:
> These changes are on top of:
> https://lore.kernel.org/lkml/20241017001354.56973-1-irogers at google.com/
> 
> Prior to these patches PERF_HAVE_DWARF_REGS indicated the presence of
> dwarf-regs.c in the arch directory. dwarf-regs.c provided upto 4
> functions:
> 
> 1) regs_query_register_offset would translate a register name into a
> pt_regs offset and was used by BPF prologues. BPF prologues existed
> for BPF events and support for these was removed many releases ago.
> This code was dead and could be removed.
> 
> 2) get_arch_regstr duplicated get_dwarf_regstr and so it could be
> removed.  The case for csky was a little more complicated as the ABI
> controlled the string. The callers of get_dwarf_regstr were updated to
> also pass the ELF flags so that on csky the ABI appropriate table
> could be used. As the argument is only used on csky this a no-op for
> everything else.
> 
> 3) get_arch_regnum translated a register name back to a dwarf number
> and only existed on x86 where "al", "ax", "eax" and "rax" could all
> mean register 0. This code was moved to util with similar
> machine/flags logic to get_arch_regstr and for consistency with it.
> 
> 4) get_powerpc_regs a PowerPC specific function used by annotate that
> should really be in util.
> 
> 2 and 3 required the wiring through of the ELF machine and flags in
> callers to get_dwarf_regstr and get_dwarf_regnum. When these values
> weren't dependent on an ELF file a new EM_HOST and EF_HOST were added
> to give the host ELF machine and flags. These 2 #defines got rid of
> the existing separate arch files and #ifdefs.
> 
> v3: These files were separated from the rest of the v2 libdw clean up
>     in:
> https://lore.kernel.org/lkml/CAP-5=fVZH3L-6y_sxLwSmT8WyMXDMFnuqUksNULdQYJCPNBFYw at mail.gmail.com/
> 
> Ian Rogers (20):
>   perf bpf-prologue: Remove unused file
>   perf dwarf-regs: Remove PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
>   perf dwarf-regs: Add EM_HOST and EF_HOST defines
>   perf disasm: Add e_machine/e_flags to struct arch
>   perf dwarf-regs: Pass accurate disassembly machine to get_dwarf_regnum
>   perf dwarf-regs: Pass ELF flags to get_dwarf_regstr
>   perf dwarf-regs: Move x86 dwarf-regs out of arch
>   perf arm64: Remove dwarf-regs.c
>   perf arm: Remove dwarf-regs.c
>   perf dwarf-regs: Move csky dwarf-regs out of arch
>   perf loongarch: Remove dwarf-regs.c
>   perf mips: Remove dwarf-regs.c
>   perf dwarf-regs: Move powerpc dwarf-regs out of arch
>   perf riscv: Remove dwarf-regs.c and add dwarf-regs-table.h
>   perf s390: Remove dwarf-regs.c
>   perf sh: Remove dwarf-regs.c
>   perf sparc: Remove dwarf-regs.c
>   perf xtensa: Remove dwarf-regs.c
>   perf dwarf-regs: Remove get_arch_regstr code
>   perf build: Remove PERF_HAVE_DWARF_REGS

These look all good and I'm about to apply the series.

Masami, do you have any remaining concerns?  It'd be nice if you can
give your Reviewed-by.

Thanks,
Namhyug

> 
>  tools/perf/Makefile.config                    |  17 +-
>  tools/perf/arch/arc/annotate/instructions.c   |   2 +
>  tools/perf/arch/arm/Makefile                  |   3 -
>  tools/perf/arch/arm/annotate/instructions.c   |   2 +
>  tools/perf/arch/arm/util/Build                |   2 -
>  tools/perf/arch/arm/util/dwarf-regs.c         |  61 -------
>  tools/perf/arch/arm64/Makefile                |   4 -
>  tools/perf/arch/arm64/annotate/instructions.c |   2 +
>  tools/perf/arch/arm64/util/Build              |   1 -
>  tools/perf/arch/arm64/util/dwarf-regs.c       |  92 -----------
>  tools/perf/arch/csky/Makefile                 |   4 -
>  tools/perf/arch/csky/annotate/instructions.c  |   7 +-
>  tools/perf/arch/csky/util/Build               |   1 -
>  tools/perf/arch/loongarch/Makefile            |   4 -
>  .../arch/loongarch/annotate/instructions.c    |   2 +
>  tools/perf/arch/loongarch/util/Build          |   1 -
>  tools/perf/arch/loongarch/util/dwarf-regs.c   |  44 -----
>  tools/perf/arch/mips/Makefile                 |   4 -
>  tools/perf/arch/mips/annotate/instructions.c  |   2 +
>  tools/perf/arch/mips/util/Build               |   1 -
>  tools/perf/arch/mips/util/dwarf-regs.c        |  38 -----
>  tools/perf/arch/powerpc/Makefile              |   5 -
>  .../perf/arch/powerpc/annotate/instructions.c |   2 +
>  tools/perf/arch/powerpc/util/Build            |   1 -
>  tools/perf/arch/powerpc/util/dwarf-regs.c     | 153 ------------------
>  tools/perf/arch/riscv/Makefile                |   5 +-
>  .../arch/riscv/include/dwarf-regs-table.h     |  42 +++++
>  tools/perf/arch/riscv/util/Build              |   1 -
>  tools/perf/arch/riscv/util/dwarf-regs.c       |  72 ---------
>  .../perf/arch/riscv64/annotate/instructions.c |   2 +
>  tools/perf/arch/s390/Makefile                 |   4 -
>  tools/perf/arch/s390/annotate/instructions.c  |   2 +
>  tools/perf/arch/s390/util/Build               |   1 -
>  tools/perf/arch/s390/util/dwarf-regs.c        |  43 -----
>  tools/perf/arch/sh/Build                      |   1 -
>  tools/perf/arch/sh/Makefile                   |   4 -
>  tools/perf/arch/sh/util/Build                 |   1 -
>  tools/perf/arch/sh/util/dwarf-regs.c          |  41 -----
>  tools/perf/arch/sparc/Build                   |   1 -
>  tools/perf/arch/sparc/Makefile                |   4 -
>  tools/perf/arch/sparc/annotate/instructions.c |   2 +
>  tools/perf/arch/sparc/util/Build              |   1 -
>  tools/perf/arch/sparc/util/dwarf-regs.c       |  39 -----
>  tools/perf/arch/x86/Makefile                  |   4 -
>  tools/perf/arch/x86/annotate/instructions.c   |   3 +-
>  tools/perf/arch/x86/util/Build                |   3 -
>  tools/perf/arch/x86/util/dwarf-regs.c         | 153 ------------------
>  tools/perf/arch/xtensa/Build                  |   1 -
>  tools/perf/arch/xtensa/Makefile               |   4 -
>  tools/perf/arch/xtensa/util/Build             |   1 -
>  tools/perf/arch/xtensa/util/dwarf-regs.c      |  21 ---
>  tools/perf/util/Build                         |   3 +
>  tools/perf/util/annotate.c                    |   6 +-
>  tools/perf/util/bpf-prologue.h                |  37 -----
>  tools/perf/util/disasm.h                      |   4 +
>  .../dwarf-regs.c => util/dwarf-regs-csky.c}   |  19 +--
>  tools/perf/util/dwarf-regs-powerpc.c          |  61 +++++++
>  tools/perf/util/dwarf-regs-x86.c              |  50 ++++++
>  tools/perf/util/dwarf-regs.c                  |  38 +++--
>  tools/perf/util/include/dwarf-regs.h          | 110 ++++++++++---
>  tools/perf/util/probe-finder.c                |  13 +-
>  tools/perf/util/probe-finder.h                |   3 +-
>  62 files changed, 328 insertions(+), 927 deletions(-)
>  delete mode 100644 tools/perf/arch/arm/util/dwarf-regs.c
>  delete mode 100644 tools/perf/arch/arm64/util/dwarf-regs.c
>  delete mode 100644 tools/perf/arch/csky/Makefile
>  delete mode 100644 tools/perf/arch/loongarch/util/dwarf-regs.c
>  delete mode 100644 tools/perf/arch/mips/util/dwarf-regs.c
>  delete mode 100644 tools/perf/arch/powerpc/util/dwarf-regs.c
>  create mode 100644 tools/perf/arch/riscv/include/dwarf-regs-table.h
>  delete mode 100644 tools/perf/arch/riscv/util/dwarf-regs.c
>  delete mode 100644 tools/perf/arch/s390/util/dwarf-regs.c
>  delete mode 100644 tools/perf/arch/sh/Build
>  delete mode 100644 tools/perf/arch/sh/Makefile
>  delete mode 100644 tools/perf/arch/sh/util/Build
>  delete mode 100644 tools/perf/arch/sh/util/dwarf-regs.c
>  delete mode 100644 tools/perf/arch/sparc/Build
>  delete mode 100644 tools/perf/arch/sparc/util/Build
>  delete mode 100644 tools/perf/arch/sparc/util/dwarf-regs.c
>  delete mode 100644 tools/perf/arch/x86/util/dwarf-regs.c
>  delete mode 100644 tools/perf/arch/xtensa/Build
>  delete mode 100644 tools/perf/arch/xtensa/Makefile
>  delete mode 100644 tools/perf/arch/xtensa/util/Build
>  delete mode 100644 tools/perf/arch/xtensa/util/dwarf-regs.c
>  delete mode 100644 tools/perf/util/bpf-prologue.h
>  rename tools/perf/{arch/csky/util/dwarf-regs.c => util/dwarf-regs-csky.c} (74%)
>  create mode 100644 tools/perf/util/dwarf-regs-powerpc.c
>  create mode 100644 tools/perf/util/dwarf-regs-x86.c
> 
> -- 
> 2.47.0.105.g07ac214952-goog
> 


From charlie at rivosinc.com  Thu Nov  7 14:38:03 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 07 Nov 2024 14:38:03 -0800
Subject: [PATCH for-next] riscv: Fix default misaligned access trap
Message-ID: <20241107-fix_handle_misaligned_load-v1-1-07d7852c9991@rivosinc.com>

Commit d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses
supported") removed the default handlers for handle_misaligned_load()
and handle_misaligned_store(). When the kernel is compiled without
RISCV_SCALAR_MISALIGNED, these handlers are never defined, causing
compilation errors.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Fixes: d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses supported")
---
 arch/riscv/include/asm/entry-common.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/riscv/include/asm/entry-common.h b/arch/riscv/include/asm/entry-common.h
index 7b32d2b08bb6..c2808561df81 100644
--- a/arch/riscv/include/asm/entry-common.h
+++ b/arch/riscv/include/asm/entry-common.h
@@ -25,7 +25,19 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
 void handle_page_fault(struct pt_regs *regs);
 void handle_break(struct pt_regs *regs);
 
+#ifdef CONFIG_RISCV_SCALAR_MISALIGNED
 int handle_misaligned_load(struct pt_regs *regs);
 int handle_misaligned_store(struct pt_regs *regs);
+#else
+static inline int handle_misaligned_load(struct pt_regs *regs)
+{
+	return -1;
+}
+
+static inline int handle_misaligned_store(struct pt_regs *regs)
+{
+	return -1;
+}
+#endif
 
 #endif /* _ASM_RISCV_ENTRY_COMMON_H */

---
base-commit: 74741a050b79d31d8d2eeee12c77736596d0a6b2
change-id: 20241107-fix_handle_misaligned_load-8be86cb0806e
-- 
- Charlie



From mhiramat at kernel.org  Thu Nov  7 16:00:40 2024
From: mhiramat at kernel.org (Masami Hiramatsu (Google))
Date: Fri, 8 Nov 2024 09:00:40 +0900
Subject: [PATCH v3 00/20] Remove PERF_HAVE_DWARF_REGS
In-Reply-To: <Zy0VHro3wE-ZTKsq@google.com>
References: <20241017002520.59124-1-irogers@google.com>
	<Zy0VHro3wE-ZTKsq@google.com>
Message-ID: <20241108090040.463cb3f0820e7ac22d1bb6c2@kernel.org>

Hi,

On Thu, 7 Nov 2024 11:29:34 -0800
Namhyung Kim <namhyung at kernel.org> wrote:

> Hi all,
> 
> On Wed, Oct 16, 2024 at 05:25:00PM -0700, Ian Rogers wrote:
> > These changes are on top of:
> > https://lore.kernel.org/lkml/20241017001354.56973-1-irogers at google.com/
> > 
> > Prior to these patches PERF_HAVE_DWARF_REGS indicated the presence of
> > dwarf-regs.c in the arch directory. dwarf-regs.c provided upto 4
> > functions:
> > 
> > 1) regs_query_register_offset would translate a register name into a
> > pt_regs offset and was used by BPF prologues. BPF prologues existed
> > for BPF events and support for these was removed many releases ago.
> > This code was dead and could be removed.
> > 
> > 2) get_arch_regstr duplicated get_dwarf_regstr and so it could be
> > removed.  The case for csky was a little more complicated as the ABI
> > controlled the string. The callers of get_dwarf_regstr were updated to
> > also pass the ELF flags so that on csky the ABI appropriate table
> > could be used. As the argument is only used on csky this a no-op for
> > everything else.
> > 
> > 3) get_arch_regnum translated a register name back to a dwarf number
> > and only existed on x86 where "al", "ax", "eax" and "rax" could all
> > mean register 0. This code was moved to util with similar
> > machine/flags logic to get_arch_regstr and for consistency with it.
> > 
> > 4) get_powerpc_regs a PowerPC specific function used by annotate that
> > should really be in util.
> > 
> > 2 and 3 required the wiring through of the ELF machine and flags in
> > callers to get_dwarf_regstr and get_dwarf_regnum. When these values
> > weren't dependent on an ELF file a new EM_HOST and EF_HOST were added
> > to give the host ELF machine and flags. These 2 #defines got rid of
> > the existing separate arch files and #ifdefs.
> > 
> > v3: These files were separated from the rest of the v2 libdw clean up
> >     in:
> > https://lore.kernel.org/lkml/CAP-5=fVZH3L-6y_sxLwSmT8WyMXDMFnuqUksNULdQYJCPNBFYw at mail.gmail.com/
> > 
> > Ian Rogers (20):
> >   perf bpf-prologue: Remove unused file
> >   perf dwarf-regs: Remove PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
> >   perf dwarf-regs: Add EM_HOST and EF_HOST defines
> >   perf disasm: Add e_machine/e_flags to struct arch
> >   perf dwarf-regs: Pass accurate disassembly machine to get_dwarf_regnum
> >   perf dwarf-regs: Pass ELF flags to get_dwarf_regstr
> >   perf dwarf-regs: Move x86 dwarf-regs out of arch
> >   perf arm64: Remove dwarf-regs.c
> >   perf arm: Remove dwarf-regs.c
> >   perf dwarf-regs: Move csky dwarf-regs out of arch
> >   perf loongarch: Remove dwarf-regs.c
> >   perf mips: Remove dwarf-regs.c
> >   perf dwarf-regs: Move powerpc dwarf-regs out of arch
> >   perf riscv: Remove dwarf-regs.c and add dwarf-regs-table.h
> >   perf s390: Remove dwarf-regs.c
> >   perf sh: Remove dwarf-regs.c
> >   perf sparc: Remove dwarf-regs.c
> >   perf xtensa: Remove dwarf-regs.c
> >   perf dwarf-regs: Remove get_arch_regstr code
> >   perf build: Remove PERF_HAVE_DWARF_REGS
> 
> These look all good and I'm about to apply the series.
> 
> Masami, do you have any remaining concerns?  It'd be nice if you can
> give your Reviewed-by.

I think it looks good to me.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>

Thank you,

> 
> Thanks,
> Namhyug
> 
> > 
> >  tools/perf/Makefile.config                    |  17 +-
> >  tools/perf/arch/arc/annotate/instructions.c   |   2 +
> >  tools/perf/arch/arm/Makefile                  |   3 -
> >  tools/perf/arch/arm/annotate/instructions.c   |   2 +
> >  tools/perf/arch/arm/util/Build                |   2 -
> >  tools/perf/arch/arm/util/dwarf-regs.c         |  61 -------
> >  tools/perf/arch/arm64/Makefile                |   4 -
> >  tools/perf/arch/arm64/annotate/instructions.c |   2 +
> >  tools/perf/arch/arm64/util/Build              |   1 -
> >  tools/perf/arch/arm64/util/dwarf-regs.c       |  92 -----------
> >  tools/perf/arch/csky/Makefile                 |   4 -
> >  tools/perf/arch/csky/annotate/instructions.c  |   7 +-
> >  tools/perf/arch/csky/util/Build               |   1 -
> >  tools/perf/arch/loongarch/Makefile            |   4 -
> >  .../arch/loongarch/annotate/instructions.c    |   2 +
> >  tools/perf/arch/loongarch/util/Build          |   1 -
> >  tools/perf/arch/loongarch/util/dwarf-regs.c   |  44 -----
> >  tools/perf/arch/mips/Makefile                 |   4 -
> >  tools/perf/arch/mips/annotate/instructions.c  |   2 +
> >  tools/perf/arch/mips/util/Build               |   1 -
> >  tools/perf/arch/mips/util/dwarf-regs.c        |  38 -----
> >  tools/perf/arch/powerpc/Makefile              |   5 -
> >  .../perf/arch/powerpc/annotate/instructions.c |   2 +
> >  tools/perf/arch/powerpc/util/Build            |   1 -
> >  tools/perf/arch/powerpc/util/dwarf-regs.c     | 153 ------------------
> >  tools/perf/arch/riscv/Makefile                |   5 +-
> >  .../arch/riscv/include/dwarf-regs-table.h     |  42 +++++
> >  tools/perf/arch/riscv/util/Build              |   1 -
> >  tools/perf/arch/riscv/util/dwarf-regs.c       |  72 ---------
> >  .../perf/arch/riscv64/annotate/instructions.c |   2 +
> >  tools/perf/arch/s390/Makefile                 |   4 -
> >  tools/perf/arch/s390/annotate/instructions.c  |   2 +
> >  tools/perf/arch/s390/util/Build               |   1 -
> >  tools/perf/arch/s390/util/dwarf-regs.c        |  43 -----
> >  tools/perf/arch/sh/Build                      |   1 -
> >  tools/perf/arch/sh/Makefile                   |   4 -
> >  tools/perf/arch/sh/util/Build                 |   1 -
> >  tools/perf/arch/sh/util/dwarf-regs.c          |  41 -----
> >  tools/perf/arch/sparc/Build                   |   1 -
> >  tools/perf/arch/sparc/Makefile                |   4 -
> >  tools/perf/arch/sparc/annotate/instructions.c |   2 +
> >  tools/perf/arch/sparc/util/Build              |   1 -
> >  tools/perf/arch/sparc/util/dwarf-regs.c       |  39 -----
> >  tools/perf/arch/x86/Makefile                  |   4 -
> >  tools/perf/arch/x86/annotate/instructions.c   |   3 +-
> >  tools/perf/arch/x86/util/Build                |   3 -
> >  tools/perf/arch/x86/util/dwarf-regs.c         | 153 ------------------
> >  tools/perf/arch/xtensa/Build                  |   1 -
> >  tools/perf/arch/xtensa/Makefile               |   4 -
> >  tools/perf/arch/xtensa/util/Build             |   1 -
> >  tools/perf/arch/xtensa/util/dwarf-regs.c      |  21 ---
> >  tools/perf/util/Build                         |   3 +
> >  tools/perf/util/annotate.c                    |   6 +-
> >  tools/perf/util/bpf-prologue.h                |  37 -----
> >  tools/perf/util/disasm.h                      |   4 +
> >  .../dwarf-regs.c => util/dwarf-regs-csky.c}   |  19 +--
> >  tools/perf/util/dwarf-regs-powerpc.c          |  61 +++++++
> >  tools/perf/util/dwarf-regs-x86.c              |  50 ++++++
> >  tools/perf/util/dwarf-regs.c                  |  38 +++--
> >  tools/perf/util/include/dwarf-regs.h          | 110 ++++++++++---
> >  tools/perf/util/probe-finder.c                |  13 +-
> >  tools/perf/util/probe-finder.h                |   3 +-
> >  62 files changed, 328 insertions(+), 927 deletions(-)
> >  delete mode 100644 tools/perf/arch/arm/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/arch/arm64/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/arch/csky/Makefile
> >  delete mode 100644 tools/perf/arch/loongarch/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/arch/mips/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/arch/powerpc/util/dwarf-regs.c
> >  create mode 100644 tools/perf/arch/riscv/include/dwarf-regs-table.h
> >  delete mode 100644 tools/perf/arch/riscv/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/arch/s390/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/arch/sh/Build
> >  delete mode 100644 tools/perf/arch/sh/Makefile
> >  delete mode 100644 tools/perf/arch/sh/util/Build
> >  delete mode 100644 tools/perf/arch/sh/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/arch/sparc/Build
> >  delete mode 100644 tools/perf/arch/sparc/util/Build
> >  delete mode 100644 tools/perf/arch/sparc/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/arch/x86/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/arch/xtensa/Build
> >  delete mode 100644 tools/perf/arch/xtensa/Makefile
> >  delete mode 100644 tools/perf/arch/xtensa/util/Build
> >  delete mode 100644 tools/perf/arch/xtensa/util/dwarf-regs.c
> >  delete mode 100644 tools/perf/util/bpf-prologue.h
> >  rename tools/perf/{arch/csky/util/dwarf-regs.c => util/dwarf-regs-csky.c} (74%)
> >  create mode 100644 tools/perf/util/dwarf-regs-powerpc.c
> >  create mode 100644 tools/perf/util/dwarf-regs-x86.c
> > 
> > -- 
> > 2.47.0.105.g07ac214952-goog
> > 


-- 
Masami Hiramatsu (Google) <mhiramat at kernel.org>


From drew at pdp7.com  Thu Nov  7 18:36:04 2024
From: drew at pdp7.com (Drew Fustini)
Date: Thu, 7 Nov 2024 18:36:04 -0800
Subject: [PATCH net-next v4 3/3] riscv: dts: thead: Add TH1520 ethernet
 nodes
In-Reply-To: <20241020-th1520-dwmac-v4-3-c77acd33ccef@tenstorrent.com>
References: <20241020-th1520-dwmac-v4-0-c77acd33ccef@tenstorrent.com>
 <20241020-th1520-dwmac-v4-3-c77acd33ccef@tenstorrent.com>
Message-ID: <Zy15FJZrOFA2t687@x1>

On Sun, Oct 20, 2024 at 07:36:02PM -0700, Drew Fustini wrote:
> From: Emil Renner Berthing <emil.renner.berthing at canonical.com>
> 
> Add gmac, mdio, and phy nodes to enable the gigabit Ethernet ports on
> the BeagleV Ahead and Sipeed Lichee Pi 4a boards.
> 
> Signed-off-by: Emil Renner Berthing <emil.renner.berthing at canonical.com>
> [drew: change apb registers from syscon to second reg of gmac node,
>        add phy reset delay properties for beaglev ahead]
> Signed-off-by: Drew Fustini <dfustini at tenstorrent.com>
> ---
>  arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts |  91 ++++++++++++++++
>  .../boot/dts/thead/th1520-lichee-module-4a.dtsi    | 119 +++++++++++++++++++++
>  arch/riscv/boot/dts/thead/th1520.dtsi              |  50 +++++++++
>  3 files changed, 260 insertions(+)
> 
> diff --git a/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts b/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
> index 86feb3df02c8..21c33f165ba9 100644
> --- a/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
> +++ b/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
> @@ -15,6 +15,7 @@ / {
>  	compatible = "beagle,beaglev-ahead", "thead,th1520";
>  
>  	aliases {
> +		ethernet0 = &gmac0;
>  		gpio0 = &gpio0;
>  		gpio1 = &gpio1;
>  		gpio2 = &gpio2;
> @@ -98,6 +99,25 @@ &emmc {
>  	status = "okay";
>  };
>  
> +&gmac0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac0_pins>;
> +	phy-handle = <&phy0>;
> +	phy-mode = "rgmii-id";
> +	status = "okay";
> +};
> +
> +&mdio0 {
> +	phy0: ethernet-phy at 1 {
> +		reg = <1>;
> +		interrupt-parent = <&gpio3>;
> +		interrupts = <22 IRQ_TYPE_LEVEL_LOW>;
> +		reset-gpios = <&gpio3 21 GPIO_ACTIVE_LOW>;
> +		reset-delay-us = <10000>;
> +		reset-post-delay-us = <50000>;
> +	};
> +};
> +
>  &padctrl_aosys {
>  	led_pins: led-0 {
>  		led-pins {
> @@ -116,6 +136,77 @@ led-pins {
>  };
>  
>  &padctrl0_apsys {
> +	gmac0_pins: gmac0-0 {
> +		tx-pins {
> +			pins = "GMAC0_TX_CLK",
> +			       "GMAC0_TXEN",
> +			       "GMAC0_TXD0",
> +			       "GMAC0_TXD1",
> +			       "GMAC0_TXD2",
> +			       "GMAC0_TXD3";
> +			function = "gmac0";
> +			bias-disable;
> +			drive-strength = <25>;
> +			input-disable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +
> +		rx-pins {
> +			pins = "GMAC0_RX_CLK",
> +			       "GMAC0_RXDV",
> +			       "GMAC0_RXD0",
> +			       "GMAC0_RXD1",
> +			       "GMAC0_RXD2",
> +			       "GMAC0_RXD3";
> +			function = "gmac0";
> +			bias-disable;
> +			drive-strength = <1>;
> +			input-enable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +
> +		mdc-pins {
> +			pins = "GMAC0_MDC";
> +			function = "gmac0";
> +			bias-disable;
> +			drive-strength = <13>;
> +			input-disable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +
> +		mdio-pins {
> +			pins = "GMAC0_MDIO";
> +			function = "gmac0";
> +			bias-disable;
> +			drive-strength = <13>;
> +			input-enable;
> +			input-schmitt-enable;
> +			slew-rate = <0>;
> +		};
> +
> +		phy-reset-pins {
> +			pins = "GMAC0_COL"; /* GPIO3_21 */
> +			bias-disable;
> +			drive-strength = <3>;
> +			input-disable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +
> +		phy-interrupt-pins {
> +			pins = "GMAC0_CRS"; /* GPIO3_22 */
> +			function = "gpio";
> +			bias-pull-up;
> +			drive-strength = <1>;
> +			input-enable;
> +			input-schmitt-enable;
> +			slew-rate = <0>;
> +		};
> +	};
> +
>  	uart0_pins: uart0-0 {
>  		tx-pins {
>  			pins = "UART0_TXD";
> diff --git a/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi b/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
> index 724d9645471d..8e76b63e0100 100644
> --- a/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
> +++ b/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
> @@ -11,6 +11,11 @@ / {
>  	model = "Sipeed Lichee Module 4A";
>  	compatible = "sipeed,lichee-module-4a", "thead,th1520";
>  
> +	aliases {
> +		ethernet0 = &gmac0;
> +		ethernet1 = &gmac1;
> +	};
> +
>  	memory at 0 {
>  		device_type = "memory";
>  		reg = <0x0 0x00000000 0x2 0x00000000>;
> @@ -45,6 +50,22 @@ &emmc {
>  	status = "okay";
>  };
>  
> +&gmac0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac0_pins>, <&mdio0_pins>;
> +	phy-handle = <&phy0>;
> +	phy-mode = "rgmii-id";
> +	status = "okay";
> +};
> +
> +&gmac1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac1_pins>;
> +	phy-handle = <&phy1>;
> +	phy-mode = "rgmii-id";
> +	status = "okay";
> +};
> +
>  &gpio0 {
>  	gpio-line-names = "", "", "", "", "", "", "", "", "", "",
>  			  "", "", "", "", "", "", "", "", "", "",
> @@ -78,6 +99,104 @@ &gpio3 {
>  			  "GPIO10";
>  };
>  
> +&mdio0 {
> +	phy0: ethernet-phy at 1 {
> +		reg = <1>;
> +	};
> +
> +	phy1: ethernet-phy at 2 {
> +		reg = <2>;
> +	};
> +};
> +
> +&padctrl0_apsys {
> +	gmac0_pins: gmac0-0 {
> +		tx-pins {
> +			pins = "GMAC0_TX_CLK",
> +			       "GMAC0_TXEN",
> +			       "GMAC0_TXD0",
> +			       "GMAC0_TXD1",
> +			       "GMAC0_TXD2",
> +			       "GMAC0_TXD3";
> +			function = "gmac0";
> +			bias-disable;
> +			drive-strength = <25>;
> +			input-disable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +
> +		rx-pins {
> +			pins = "GMAC0_RX_CLK",
> +			       "GMAC0_RXDV",
> +			       "GMAC0_RXD0",
> +			       "GMAC0_RXD1",
> +			       "GMAC0_RXD2",
> +			       "GMAC0_RXD3";
> +			function = "gmac0";
> +			bias-disable;
> +			drive-strength = <1>;
> +			input-enable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +	};
> +
> +	gmac1_pins: gmac1-0 {
> +		tx-pins {
> +			pins = "GPIO2_18", /* GMAC1_TX_CLK */
> +			       "GPIO2_20", /* GMAC1_TXEN */
> +			       "GPIO2_21", /* GMAC1_TXD0 */
> +			       "GPIO2_22", /* GMAC1_TXD1 */
> +			       "GPIO2_23", /* GMAC1_TXD2 */
> +			       "GPIO2_24"; /* GMAC1_TXD3 */
> +			function = "gmac1";
> +			bias-disable;
> +			drive-strength = <25>;
> +			input-disable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +
> +		rx-pins {
> +			pins = "GPIO2_19", /* GMAC1_RX_CLK */
> +			       "GPIO2_25", /* GMAC1_RXDV */
> +			       "GPIO2_30", /* GMAC1_RXD0 */
> +			       "GPIO2_31", /* GMAC1_RXD1 */
> +			       "GPIO3_0",  /* GMAC1_RXD2 */
> +			       "GPIO3_1";  /* GMAC1_RXD3 */
> +			function = "gmac1";
> +			bias-disable;
> +			drive-strength = <1>;
> +			input-enable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +	};
> +
> +	mdio0_pins: mdio0-0 {
> +		mdc-pins {
> +			pins = "GMAC0_MDC";
> +			function = "gmac0";
> +			bias-disable;
> +			drive-strength = <13>;
> +			input-disable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +
> +		mdio-pins {
> +			pins = "GMAC0_MDIO";
> +			function = "gmac0";
> +			bias-disable;
> +			drive-strength = <13>;
> +			input-enable;
> +			input-schmitt-enable;
> +			slew-rate = <0>;
> +		};
> +	};
> +};
> +
>  &sdio0 {
>  	bus-width = <4>;
>  	max-frequency = <198000000>;
> diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
> index cd835aea07d2..acfe030e803a 100644
> --- a/arch/riscv/boot/dts/thead/th1520.dtsi
> +++ b/arch/riscv/boot/dts/thead/th1520.dtsi
> @@ -223,6 +223,12 @@ aonsys_clk: clock-73728000 {
>  		#clock-cells = <0>;
>  	};
>  
> +	stmmac_axi_config: stmmac-axi-config {
> +		snps,wr_osr_lmt = <15>;
> +		snps,rd_osr_lmt = <15>;
> +		snps,blen = <0 0 64 32 0 0 0>;
> +	};
> +
>  	soc {
>  		compatible = "simple-bus";
>  		interrupt-parent = <&plic>;
> @@ -274,6 +280,50 @@ uart0: serial at ffe7014000 {
>  			status = "disabled";
>  		};
>  
> +		gmac1: ethernet at ffe7060000 {
> +			compatible = "thead,th1520-gmac", "snps,dwmac-3.70a";
> +			reg = <0xff 0xe7060000 0x0 0x2000>, <0xff 0xec004000 0x0 0x1000>;
> +			reg-names = "dwmac", "apb";
> +			interrupts = <67 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "macirq";
> +			clocks = <&clk CLK_GMAC_AXI>, <&clk CLK_GMAC1>;
> +			clock-names = "stmmaceth", "pclk";
> +			snps,pbl = <32>;
> +			snps,fixed-burst;
> +			snps,multicast-filter-bins = <64>;
> +			snps,perfect-filter-entries = <32>;
> +			snps,axi-config = <&stmmac_axi_config>;
> +			status = "disabled";
> +
> +			mdio1: mdio {
> +				compatible = "snps,dwmac-mdio";
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +		};
> +
> +		gmac0: ethernet at ffe7070000 {
> +			compatible = "thead,th1520-gmac", "snps,dwmac-3.70a";
> +			reg = <0xff 0xe7070000 0x0 0x2000>, <0xff 0xec003000 0x0 0x1000>;
> +			reg-names = "dwmac", "apb";
> +			interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "macirq";
> +			clocks = <&clk CLK_GMAC_AXI>, <&clk CLK_GMAC0>;
> +			clock-names = "stmmaceth", "pclk";
> +			snps,pbl = <32>;
> +			snps,fixed-burst;
> +			snps,multicast-filter-bins = <64>;
> +			snps,perfect-filter-entries = <32>;
> +			snps,axi-config = <&stmmac_axi_config>;
> +			status = "disabled";
> +
> +			mdio0: mdio {
> +				compatible = "snps,dwmac-mdio";
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +		};
> +
>  		emmc: mmc at ffe7080000 {
>  			compatible = "thead,th1520-dwcmshc";
>  			reg = <0xff 0xe7080000 0x0 0x10000>;
> 
> -- 
> 2.34.1
> 

The dwmac-thead driver and dt binding have been applied to net-next [1]
so I have now applied this dts patch to thead-dt-for-next [2].

-Drew

[1] https://lore.kernel.org/linux-riscv/173085843050.764350.5609116722213276708.git-patchwork-notify at kernel.org/
[2] https://github.com/pdp7/linux/commit/7e756671a664b73b2a3c0cc37fd25abf6bcd851e


From xu.yang_2 at nxp.com  Thu Nov  7 18:55:35 2024
From: xu.yang_2 at nxp.com (Xu Yang)
Date: Fri, 8 Nov 2024 10:55:35 +0800
Subject: [PATCH v2 0/8] Refactor cpuid and metric table lookup code
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <20241108025535.wfhke3btch5af4fu@hippo>

On Thu, Nov 07, 2024 at 08:20:27AM -0800, Ian Rogers wrote:
> Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
> lookup:
> https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
> These patches remove a lot of the logic relating CPUIDs to PMUs so
> that the PMU isn't part of the question when finding a metric table.
> For time reasons, it doesn't go as far as allowing system metrics
> without a metric table as a metric table is needed for metrics to
> refer to other metrics, and the refactoring of that resolution is a
> hassle.

For this patchset:
Tested-by: Xu Yang <xu.yang_2 at nxp.com>

Thanks,
Xu Yang

> 
> Ian Rogers (7):
>   perf header: Move is_cpu_online to numa bench
>   perf header: Refactor get_cpuid to take a CPU for ARM
>   perf arm64 header: Use cpu argument in get_cpuid
>   perf header: Avoid transitive PMU includes
>   perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
>   perf jevents: Add map_for_cpu
>   perf pmu: Move pmu_metrics_table__find and remove ARM override
> 
> Xu Yang (1):
>   perf jevents: fix breakage when do perf stat on system metric
> 
>  tools/perf/arch/arm64/util/arm-spe.c     | 14 +---
>  tools/perf/arch/arm64/util/header.c      | 73 ++++++++++-----------
>  tools/perf/arch/arm64/util/pmu.c         | 20 ------
>  tools/perf/arch/loongarch/util/header.c  |  4 +-
>  tools/perf/arch/powerpc/util/header.c    |  4 +-
>  tools/perf/arch/riscv/util/header.c      |  4 +-
>  tools/perf/arch/s390/util/header.c       |  6 +-
>  tools/perf/arch/x86/util/auxtrace.c      |  3 +-
>  tools/perf/arch/x86/util/header.c        |  5 +-
>  tools/perf/bench/numa.c                  | 53 +++++++++++++++
>  tools/perf/builtin-kvm.c                 |  4 +-
>  tools/perf/pmu-events/empty-pmu-events.c | 39 ++++++-----
>  tools/perf/pmu-events/jevents.py         | 39 ++++++-----
>  tools/perf/pmu-events/pmu-events.h       |  2 +-
>  tools/perf/tests/expr.c                  |  5 +-
>  tools/perf/util/env.c                    |  4 +-
>  tools/perf/util/expr.c                   |  6 +-
>  tools/perf/util/header.c                 | 82 ++++++++----------------
>  tools/perf/util/header.h                 | 23 +++----
>  tools/perf/util/pmu.c                    | 25 --------
>  tools/perf/util/pmu.h                    |  2 -
>  tools/perf/util/probe-event.c            |  1 +
>  22 files changed, 189 insertions(+), 229 deletions(-)
> 
> -- 
> 2.47.0.199.ga7371fff76-goog
> 


From linus.walleij at linaro.org  Fri Nov  8 00:23:50 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 8 Nov 2024 09:23:50 +0100
Subject: [PATCH] dt-bindings: pinctrl: correct typo of description for cv1800
In-Reply-To: <20241029012312.3448287-1-unicornxw@gmail.com>
References: <20241029012312.3448287-1-unicornxw@gmail.com>
Message-ID: <CACRpkdZB1RT=ATC1RKosjVyj2G1v4F8NYEPOTpfW16vmTG5y4w@mail.gmail.com>

On Tue, Oct 29, 2024 at 2:23?AM Chen Wang <unicornxw at gmail.com> wrote:

> From: Chen Wang <unicorn_wang at outlook.com>
>
> It should be PINMUX/PINMUX2, not GPIOMUX/GPIOMUX2, see
> <dt-bindings/pinctrl/pinctrl-cv1800b.h>.
>
> Fixes: 64aa494de6fa ("dt-bindings: pinctrl: Add pinctrl for Sophgo CV1800 series SoC.")
> Signed-off-by: Chen Wang <unicorn_wang at outlook.com>

Patch applied!

Yours,
Linus Walleij


From linus.walleij at linaro.org  Fri Nov  8 00:24:23 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 8 Nov 2024 09:24:23 +0100
Subject: [PATCH] dt-bindings: pinctrl: correct typo of description for cv1800
In-Reply-To: <MA0P287MB282298E7A00528040BBEC5DEFE512@MA0P287MB2822.INDP287.PROD.OUTLOOK.COM>
References: <20241029012312.3448287-1-unicornxw@gmail.com> <MA0P287MB282298E7A00528040BBEC5DEFE512@MA0P287MB2822.INDP287.PROD.OUTLOOK.COM>
Message-ID: <CACRpkdYGhrzB9Jv_fFOFd-dMJEGD0zyuXZ7-Xhae6N-DYBF3zA@mail.gmail.com>

On Mon, Nov 4, 2024 at 2:52?AM Chen Wang <unicorn_wang at outlook.com> wrote:

> Will you pick this fixes and PR for 6.12?
>
> Or I will take this over and PR this for 6.13 due to it is a minor text
> change.

I have queued it for v6.13 because it is not urgent.

Yours,
Linus Walleij


From conor at kernel.org  Fri Nov  8 01:37:55 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 8 Nov 2024 09:37:55 +0000
Subject: [GIT PULL] RISC-V Devicetrees for v6.13
Message-ID: <20241108-washboard-material-6b9ff196063d@spud>

Hey,

Please pull a handful of changes, mostly for StarFive.
Branch is based on rc3 instead of rc1 as I'd usually do, because rc{1,2}
was not booting for me.

Cheers,
Conor.

The following changes since commit 8e929cb546ee42c9a61d24fae60605e9e3192354:

  Linux 6.12-rc3 (2024-10-13 14:33:32 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ tags/riscv-dt-for-v6.13

for you to fetch changes up to c8b72c301dbe71a7a55298d542dff7b2c3612765:

  riscv: dts: starfive: add DeepComputing FML13V01 board device tree (2024-10-31 12:22:53 +0000)

----------------------------------------------------------------
RISC-V Devicetrees for v6.13

StarFive:
Support for the DeepComputing FML13V01, a Framework laptop compatible
with a JH7110. This board is fairly different to the more standard SBCs
offerings that the kernel already supports, so there's also some
refactoring of jh7110-common.dtsi to move out nodes unused on the new
board.

Spacemit:
A vendor prefix I grabbed from the basic support series, since its
dependencies are not yet ready but peripheral drivers have started being
merged.

Signed-off-by: Conor Dooley <conor.dooley at microchip.com>

----------------------------------------------------------------
Guodong Xu (2):
      riscv: dts: starfive: jh7110-common: revised device node
      riscv: dts: starfive: jh7110-common: move usb0 config to board dts

Sandie Cao (3):
      dt-bindings: vendor: add deepcomputing
      dt-bindings: riscv: starfive: add deepcomputing,fml13v01
      riscv: dts: starfive: add DeepComputing FML13V01 board device tree

Yangyu Chen (1):
      dt-bindings: vendor-prefixes: add spacemit

 .../devicetree/bindings/riscv/starfive.yaml        |  1 +
 .../devicetree/bindings/vendor-prefixes.yaml       |  4 ++++
 arch/riscv/boot/dts/starfive/Makefile              |  1 +
 arch/riscv/boot/dts/starfive/jh7110-common.dtsi    | 10 ---------
 .../dts/starfive/jh7110-deepcomputing-fml13v01.dts | 17 +++++++++++++++
 arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts | 22 +++++++++++++++++++
 .../boot/dts/starfive/jh7110-pine64-star64.dts     | 22 +++++++++++++++++++
 .../dts/starfive/jh7110-starfive-visionfive-2.dtsi | 25 ++++++++++++++++++++++
 8 files changed, 92 insertions(+), 10 deletions(-)
 create mode 100644 arch/riscv/boot/dts/starfive/jh7110-deepcomputing-fml13v01.dts
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241108/33a42247/attachment.sig>

From elena.reshetova at intel.com  Fri Nov  8 02:36:42 2024
From: elena.reshetova at intel.com (Reshetova, Elena)
Date: Fri, 8 Nov 2024 10:36:42 +0000
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <7ad5d114-3d19-4c33-bb3c-7f8940ad114e@amazon.com>
References: <DM8PR11MB57509ED04CB0730680735AC9E7512@DM8PR11MB5750.namprd11.prod.outlook.com>
 <7ad5d114-3d19-4c33-bb3c-7f8940ad114e@amazon.com>
Message-ID: <DM8PR11MB57505F62D149EF153F89B8BAE75D2@DM8PR11MB5750.namprd11.prod.outlook.com>

 
> On 2024-11-04 at 08:33+0000, Elena Reshetova wrote:
> > This statement *is* for integrity section. We have a separate TDX guidance
> > on side-channels (including speculative) [3] and some speculative attacks
> > that affect confidentiality (for example spectre v1) are listed as not covered
> > by TDX but remaining SW responsibility (as they are now).
> 
> Thanks for the additional info, Elena. Given that clarification, I
> definitely see direct map removal and TDX as complementary.

Jus to clarify to make sure my comment is not misunderstood.
What I meant is that we cannot generally assume that confidentiality
leaks from CoCo guests to host/VMM via speculative channels
are completely impossible. Spectre V1 is a prime example of such a
possible leak. Dave also elaborated on other potential vectors earlier.

The usefulness of direct map removal for CoCo guests as a concrete
mitigation for certain types of memory attacks must be precisely
evaluated per each attack vector, attack vector direction (host -> guest,
guest ->host, etc) and per each countermeasure that CoCo vendors
provide for each such case. I don't know if there is any existing study
that examines this for major CoCo vendors. I think this is what must
be done for this work in order to have a strong reasoning for its usefulness.

Best Regards,
Elena.



From anup at brainfault.org  Fri Nov  8 03:37:34 2024
From: anup at brainfault.org (Anup Patel)
Date: Fri, 8 Nov 2024 17:07:34 +0530
Subject: [GIT PULL] KVM/riscv changes for 6.13
Message-ID: <CAAhSdy1iTNc5QG34ceebMzA137-pNGzTva33VQ83j-yMoaw8Fg@mail.gmail.com>

Hi Paolo,

We have the following KVM RISC-V changes for 6.13:
1) Accelerate KVM RISC-V when running as a guest
2) Perf support to collect KVM guest statistics from host side

In addition, the pointer masking support (Ssnpm and
Smnpm) for KVM guest is going through the RISC-V tree.

I also have Svade and Svadu support for host and guest
in my queue which I will send in the second week of the
merge window to avoid conflict with the RISC-V tree.

Please pull.

Regards,
Anup

The following changes since commit 81983758430957d9a5cb3333fe324fd70cf63e7e:

  Linux 6.12-rc5 (2024-10-27 12:52:02 -1000)

are available in the Git repository at:

  https://github.com/kvm-riscv/linux.git tags/kvm-riscv-6.13-1

for you to fetch changes up to 332fa4a802b16ccb727199da685294f85f9880cb:

  riscv: kvm: Fix out-of-bounds array access (2024-11-05 13:27:32 +0530)

----------------------------------------------------------------
KVM/riscv changes for 6.13

- Accelerate KVM RISC-V when running as a guest
- Perf support to collect KVM guest statistics from host side

----------------------------------------------------------------
Anup Patel (13):
      RISC-V: KVM: Order the object files alphabetically
      RISC-V: KVM: Save/restore HSTATUS in C source
      RISC-V: KVM: Save/restore SCOUNTEREN in C source
      RISC-V: KVM: Break down the __kvm_riscv_switch_to() into macros
      RISC-V: KVM: Replace aia_set_hvictl() with aia_hvictl_value()
      RISC-V: KVM: Don't setup SGEI for zero guest external interrupts
      RISC-V: Add defines for the SBI nested acceleration extension
      RISC-V: KVM: Add common nested acceleration support
      RISC-V: KVM: Use nacl_csr_xyz() for accessing H-extension CSRs
      RISC-V: KVM: Use nacl_csr_xyz() for accessing AIA CSRs
      RISC-V: KVM: Use SBI sync SRET call when available
      RISC-V: KVM: Save trap CSRs in kvm_riscv_vcpu_enter_exit()
      RISC-V: KVM: Use NACL HFENCEs for KVM request based HFENCEs

Bj?rn T?pel (1):
      riscv: kvm: Fix out-of-bounds array access

Quan Zhou (2):
      riscv: perf: add guest vs host distinction
      riscv: KVM: add basic support for host vs guest profiling

Yong-Xuan Wang (1):
      RISC-V: KVM: Fix APLIC in_clrip and clripnum write emulation

 arch/riscv/include/asm/kvm_host.h   |  10 ++
 arch/riscv/include/asm/kvm_nacl.h   | 245 ++++++++++++++++++++++++++++++++++++
 arch/riscv/include/asm/perf_event.h |   6 +
 arch/riscv/include/asm/sbi.h        | 120 ++++++++++++++++++
 arch/riscv/kernel/perf_callchain.c  |  38 ++++++
 arch/riscv/kvm/Kconfig              |   1 +
 arch/riscv/kvm/Makefile             |  27 ++--
 arch/riscv/kvm/aia.c                | 114 +++++++++++------
 arch/riscv/kvm/aia_aplic.c          |   3 +-
 arch/riscv/kvm/main.c               |  63 +++++++++-
 arch/riscv/kvm/mmu.c                |   4 +-
 arch/riscv/kvm/nacl.c               | 152 ++++++++++++++++++++++
 arch/riscv/kvm/tlb.c                |  57 ++++++---
 arch/riscv/kvm/vcpu.c               | 191 +++++++++++++++++++++-------
 arch/riscv/kvm/vcpu_sbi.c           |  11 +-
 arch/riscv/kvm/vcpu_switch.S        | 137 ++++++++++++--------
 arch/riscv/kvm/vcpu_timer.c         |  28 ++---
 17 files changed, 1022 insertions(+), 185 deletions(-)
 create mode 100644 arch/riscv/include/asm/kvm_nacl.h
 create mode 100644 arch/riscv/kvm/nacl.c


From james.clark at linaro.org  Fri Nov  8 04:16:43 2024
From: james.clark at linaro.org (James Clark)
Date: Fri, 8 Nov 2024 12:16:43 +0000
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is
 provided
In-Reply-To: <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
References: <20241026121758.143259-1-irogers@google.com>
 <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
Message-ID: <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org>



On 07/11/2024 18:51, Ian Rogers wrote:
> On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
>>
>> At the RISC-V summit the topic of avoiding event data being in the
>> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
>> events being the priority when no PMU is provided so that legacy
>> events maybe supported via json. Originally Mark Rutland also
>> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
>> M? processors, but James Clark more recently tested this and believes
>> the driver issues there may not have existed or have been resolved. In
>> any case, it is inconsistent that with a PMU event names avoid legacy
>> encodings, but when wildcarding PMUs (ie without a PMU with the event
>> name) the legacy encodings have priority.
>>
>> The patch doing this work was reverted in a v6.10 release candidate
>> as, even though the patch was posted for weeks and had been on
>> linux-next for weeks without issue, Linus was in the habit of using
>> explicit legacy events with unsupported precision options on his
>> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
>> where ARM decided to call the events bus_cycles and cycles, the latter
>> being also a legacy event name. ARM haven't renamed the cycles event
>> to a more consistent cpu_cycles and avoided the problem. With these
>> changes the problematic event will now be skipped, a large warning
>> produced, and perf record will continue for the other PMU events. This
>> solution was proposed by Arnaldo.
>>
>> Two minor changes have been added to help with the error message and
>> to work around issues occurring with "perf stat metrics (shadow stat)
>> test".
>>
>> The patches have only been tested on my x86 non-hybrid laptop.
> 
> Hi Atish and James,
> 
> Could I get your tags for this series?
> 
> The patches were originally motivated by wanting to make the behavior
> of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
> wildcarded to "cpu" in the first case. This was divergent because of
> ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
> config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
> type>, config=<encoding from event>) when a PMU name was given. This
> aligns with RISC-V wanting to use json encodings to avoid complexity
> in the PMU driver.
> 

I couldn't find the thread, but I remember fairly recently it was 
mentioned that RISC-V would be supporting the legacy events after all, 
maybe it was a comment from Atish? I'm not sure if that changes the 
requirements for this or not?

I still can't really imagine how tooling would work if every tool has to 
maintain the mappings of basic events like instructions and branches. 
For example all the perf_event_open tests in ltp use the legacy events.

And wouldn't porting existing software to RISC-V would be an issue if it 
doesn't behave in a similar way to what's there already?

> James, could you show the neoverse with the cmn PMU behavior for perf
> record of "cycles:pp" due to sensitivities there.
> 

Yep I can check this on Monday.

> Thanks,
> Ian
> 


> 
> 
> 
>> Ian Rogers (4):
>>    perf evsel: Add pmu_name helper
>>    perf stat: Fix find_stat for mixed legacy/non-legacy events
>>    perf record: Skip don't fail for events that don't open
>>    perf parse-events: Reapply "Prefer sysfs/JSON hardware events over
>>      legacy"
>>
>>   tools/perf/builtin-record.c    | 22 +++++++---
>>   tools/perf/util/evsel.c        | 10 +++++
>>   tools/perf/util/evsel.h        |  1 +
>>   tools/perf/util/parse-events.c | 26 +++++++++---
>>   tools/perf/util/parse-events.l | 76 +++++++++++++++++-----------------
>>   tools/perf/util/parse-events.y | 60 ++++++++++++++++++---------
>>   tools/perf/util/pmus.c         | 20 +++++++--
>>   tools/perf/util/stat-shadow.c  |  3 +-
>>   8 files changed, 145 insertions(+), 73 deletions(-)
>>
>> --
>> 2.47.0.163.g1226f6d8fa-goog
>>


From tglx at linutronix.de  Fri Nov  8 06:25:13 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 08 Nov 2024 15:25:13 +0100
Subject: [PATCH] kernel/irq/proc: performance: replace seq_printf with
 seq_put_decimal_ull_width
In-Reply-To: <20241103080552.4787-1-00107082@163.com>
References: <20241103080552.4787-1-00107082@163.com>
Message-ID: <87r07lol9y.ffs@tglx>

David!

On Sun, Nov 03 2024 at 16:05, David Wang wrote:

$Subject: [PATCH] kernel/irq/proc: performance: ...

That's not a valid subsystem prefix.

> seq_printf is costy, when stress reading /proc/interrupts, profiling indicates
> seq_printf takes about ~47% of show_interrupts samples:

Also please follow the documentation for denoting functions in change
logs:

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#function-references-in-changelogs

>  arch/alpha/kernel/irq.c     |   8 +--
>  arch/arm/kernel/smp.c       |   4 +-
>  arch/arm64/kernel/smp.c     |   3 +-
>  arch/csky/kernel/smp.c      |   4 +-
>  arch/loongarch/kernel/smp.c |   2 +-
>  arch/parisc/kernel/irq.c    |  34 ++++++------
>  arch/powerpc/kernel/irq.c   |  44 ++++++++--------
>  arch/riscv/kernel/smp.c     |   3 +-
>  arch/sh/kernel/irq.c        |   4 +-
>  arch/sparc/kernel/irq_32.c  |  12 ++---
>  arch/sparc/kernel/irq_64.c  |   4 +-
>  arch/x86/kernel/irq.c       | 100 ++++++++++++++++++------------------
>  arch/xtensa/kernel/irq.c    |   2 +-
>  arch/xtensa/kernel/smp.c    |   4 +-
>  kernel/irq/proc.c           |   6 ++-

There is no dependency on these changes. So please split them up into
seperate patches for core and the individual architectures.

Thanks,

        tglx


From 00107082 at 163.com  Fri Nov  8 07:28:00 2024
From: 00107082 at 163.com (David Wang)
Date: Fri, 8 Nov 2024 23:28:00 +0800 (CST)
Subject: [PATCH] kernel/irq/proc: performance: replace seq_printf with
 seq_put_decimal_ull_width
In-Reply-To: <87r07lol9y.ffs@tglx>
References: <20241103080552.4787-1-00107082@163.com> <87r07lol9y.ffs@tglx>
Message-ID: <3319cd6e.b980.1930c63b1e5.Coremail.00107082@163.com>

Hi,  

At 2024-11-08 22:25:13, "Thomas Gleixner" <tglx at linutronix.de> wrote:
>David!
>
>On Sun, Nov 03 2024 at 16:05, David Wang wrote:
>
>$Subject: [PATCH] kernel/irq/proc: performance: ...
>
>That's not a valid subsystem prefix.

copy that~

>
>> seq_printf is costy, when stress reading /proc/interrupts, profiling indicates
>> seq_printf takes about ~47% of show_interrupts samples:
>
>Also please follow the documentation for denoting functions in change
>logs:
>
>https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#function-references-in-changelogs
>

copy that~

>>  arch/alpha/kernel/irq.c     |   8 +--
>>  arch/arm/kernel/smp.c       |   4 +-
>>  arch/arm64/kernel/smp.c     |   3 +-
>>  arch/csky/kernel/smp.c      |   4 +-
>>  arch/loongarch/kernel/smp.c |   2 +-
>>  arch/parisc/kernel/irq.c    |  34 ++++++------
>>  arch/powerpc/kernel/irq.c   |  44 ++++++++--------
>>  arch/riscv/kernel/smp.c     |   3 +-
>>  arch/sh/kernel/irq.c        |   4 +-
>>  arch/sparc/kernel/irq_32.c  |  12 ++---
>>  arch/sparc/kernel/irq_64.c  |   4 +-
>>  arch/x86/kernel/irq.c       | 100 ++++++++++++++++++------------------
>>  arch/xtensa/kernel/irq.c    |   2 +-
>>  arch/xtensa/kernel/smp.c    |   4 +-
>>  kernel/irq/proc.c           |   6 ++-
>
>There is no dependency on these changes. So please split them up into
>seperate patches for core and the individual architectures.an

Thanks for all the review, I will make a patchset for this.
>
>Thanks,
>
>        tglx


David

From 00107082 at 163.com  Fri Nov  8 08:25:03 2024
From: 00107082 at 163.com (David Wang)
Date: Sat,  9 Nov 2024 00:25:03 +0800
Subject: [PATCH 12/13] riscv/irq: use seq_put_decimal_ull_width() for decimal values
Message-ID: <20241108162503.9914-1-00107082@163.com>

Performance improvement for reading /proc/interrupts on arch riscv

Signed-off-by: David Wang <00107082 at 163.com>
---
 arch/riscv/kernel/smp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index c180a647a30e..f1e9c3db094c 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -226,7 +226,8 @@ void show_ipi_stats(struct seq_file *p, int prec)
 		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
 			   prec >= 4 ? " " : "");
 		for_each_online_cpu(cpu)
-			seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu));
+			seq_put_decimal_ull_width(p, " ",
+						  irq_desc_kstat_cpu(ipi_desc[i], cpu), 10);
 		seq_printf(p, " %s\n", ipi_names[i]);
 	}
 }
-- 
2.39.2



From pbonzini at redhat.com  Fri Nov  8 09:15:19 2024
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Fri, 8 Nov 2024 18:15:19 +0100
Subject: [GIT PULL] KVM/riscv changes for 6.13
In-Reply-To: <CAAhSdy1iTNc5QG34ceebMzA137-pNGzTva33VQ83j-yMoaw8Fg@mail.gmail.com>
References: <CAAhSdy1iTNc5QG34ceebMzA137-pNGzTva33VQ83j-yMoaw8Fg@mail.gmail.com>
Message-ID: <626d3780-73bd-496b-9503-e09bfb293bb0@redhat.com>

On 11/8/24 12:37, Anup Patel wrote:
> Hi Paolo,
> 
> We have the following KVM RISC-V changes for 6.13:
> 1) Accelerate KVM RISC-V when running as a guest
> 2) Perf support to collect KVM guest statistics from host side
> 
> In addition, the pointer masking support (Ssnpm and
> Smnpm) for KVM guest is going through the RISC-V tree.
> 
> I also have Svade and Svadu support for host and guest
> in my queue which I will send in the second week of the
> merge window to avoid conflict with the RISC-V tree.
> 
> Please pull.

Pulled, thanks.

Paolo

> Regards,
> Anup
> 
> The following changes since commit 81983758430957d9a5cb3333fe324fd70cf63e7e:
> 
>    Linux 6.12-rc5 (2024-10-27 12:52:02 -1000)
> 
> are available in the Git repository at:
> 
>    https://github.com/kvm-riscv/linux.git tags/kvm-riscv-6.13-1
> 
> for you to fetch changes up to 332fa4a802b16ccb727199da685294f85f9880cb:
> 
>    riscv: kvm: Fix out-of-bounds array access (2024-11-05 13:27:32 +0530)
> 
> ----------------------------------------------------------------
> KVM/riscv changes for 6.13
> 
> - Accelerate KVM RISC-V when running as a guest
> - Perf support to collect KVM guest statistics from host side
> 
> ----------------------------------------------------------------
> Anup Patel (13):
>        RISC-V: KVM: Order the object files alphabetically
>        RISC-V: KVM: Save/restore HSTATUS in C source
>        RISC-V: KVM: Save/restore SCOUNTEREN in C source
>        RISC-V: KVM: Break down the __kvm_riscv_switch_to() into macros
>        RISC-V: KVM: Replace aia_set_hvictl() with aia_hvictl_value()
>        RISC-V: KVM: Don't setup SGEI for zero guest external interrupts
>        RISC-V: Add defines for the SBI nested acceleration extension
>        RISC-V: KVM: Add common nested acceleration support
>        RISC-V: KVM: Use nacl_csr_xyz() for accessing H-extension CSRs
>        RISC-V: KVM: Use nacl_csr_xyz() for accessing AIA CSRs
>        RISC-V: KVM: Use SBI sync SRET call when available
>        RISC-V: KVM: Save trap CSRs in kvm_riscv_vcpu_enter_exit()
>        RISC-V: KVM: Use NACL HFENCEs for KVM request based HFENCEs
> 
> Bj?rn T?pel (1):
>        riscv: kvm: Fix out-of-bounds array access
> 
> Quan Zhou (2):
>        riscv: perf: add guest vs host distinction
>        riscv: KVM: add basic support for host vs guest profiling
> 
> Yong-Xuan Wang (1):
>        RISC-V: KVM: Fix APLIC in_clrip and clripnum write emulation
> 
>   arch/riscv/include/asm/kvm_host.h   |  10 ++
>   arch/riscv/include/asm/kvm_nacl.h   | 245 ++++++++++++++++++++++++++++++++++++
>   arch/riscv/include/asm/perf_event.h |   6 +
>   arch/riscv/include/asm/sbi.h        | 120 ++++++++++++++++++
>   arch/riscv/kernel/perf_callchain.c  |  38 ++++++
>   arch/riscv/kvm/Kconfig              |   1 +
>   arch/riscv/kvm/Makefile             |  27 ++--
>   arch/riscv/kvm/aia.c                | 114 +++++++++++------
>   arch/riscv/kvm/aia_aplic.c          |   3 +-
>   arch/riscv/kvm/main.c               |  63 +++++++++-
>   arch/riscv/kvm/mmu.c                |   4 +-
>   arch/riscv/kvm/nacl.c               | 152 ++++++++++++++++++++++
>   arch/riscv/kvm/tlb.c                |  57 ++++++---
>   arch/riscv/kvm/vcpu.c               | 191 +++++++++++++++++++++-------
>   arch/riscv/kvm/vcpu_sbi.c           |  11 +-
>   arch/riscv/kvm/vcpu_switch.S        | 137 ++++++++++++--------
>   arch/riscv/kvm/vcpu_timer.c         |  28 ++---
>   17 files changed, 1022 insertions(+), 185 deletions(-)
>   create mode 100644 arch/riscv/include/asm/kvm_nacl.h
>   create mode 100644 arch/riscv/kvm/nacl.c
> 



From namhyung at kernel.org  Fri Nov  8 09:33:47 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 8 Nov 2024 09:33:47 -0800
Subject: [PATCH v3 04/20] perf disasm: Add e_machine/e_flags to struct
 arch
In-Reply-To: <20241017002520.59124-5-irogers@google.com>
References: <20241017002520.59124-1-irogers@google.com>
 <20241017002520.59124-5-irogers@google.com>
Message-ID: <Zy5Le-xn4gzQ2WLo@google.com>

On Wed, Oct 16, 2024 at 05:25:04PM -0700, Ian Rogers wrote:
> Currently functions like get_dwarf_regnum only work with the host
> architecture. Carry the elf machine and flags in struct arch so that
> in disassembly these can be used to allow cross platform disassembly.
> 
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/arch/arc/annotate/instructions.c       | 2 ++
>  tools/perf/arch/arm/annotate/instructions.c       | 2 ++
>  tools/perf/arch/arm64/annotate/instructions.c     | 2 ++
>  tools/perf/arch/csky/annotate/instructions.c      | 7 ++++++-
>  tools/perf/arch/loongarch/annotate/instructions.c | 2 ++
>  tools/perf/arch/mips/annotate/instructions.c      | 2 ++
>  tools/perf/arch/powerpc/annotate/instructions.c   | 2 ++
>  tools/perf/arch/riscv64/annotate/instructions.c   | 2 ++
>  tools/perf/arch/s390/annotate/instructions.c      | 2 ++
>  tools/perf/arch/sparc/annotate/instructions.c     | 2 ++
>  tools/perf/arch/x86/annotate/instructions.c       | 3 ++-
>  tools/perf/util/disasm.h                          | 4 ++++
>  12 files changed, 30 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/arch/arc/annotate/instructions.c b/tools/perf/arch/arc/annotate/instructions.c
> index 2f00e995c7e3..e5619770a1af 100644
> --- a/tools/perf/arch/arc/annotate/instructions.c
> +++ b/tools/perf/arch/arc/annotate/instructions.c
> @@ -5,5 +5,7 @@ static int arc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  {
>  	arch->initialized = true;
>  	arch->objdump.comment_char = ';';
> +	arch->e_machine = EM_ARC;
> +	arch->e_flags = 0;
>  	return 0;
>  }
> diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c
> index 2ff6cedeb9c5..cf91a43362b0 100644
> --- a/tools/perf/arch/arm/annotate/instructions.c
> +++ b/tools/perf/arch/arm/annotate/instructions.c
> @@ -53,6 +53,8 @@ static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  	arch->associate_instruction_ops   = arm__associate_instruction_ops;
>  	arch->objdump.comment_char	  = ';';
>  	arch->objdump.skip_functions_char = '+';
> +	arch->e_machine = EM_ARM;
> +	arch->e_flags = 0;
>  	return 0;
>  
>  out_free_call:
> diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c
> index f86d9f4798bd..d465d093e7eb 100644
> --- a/tools/perf/arch/arm64/annotate/instructions.c
> +++ b/tools/perf/arch/arm64/annotate/instructions.c
> @@ -113,6 +113,8 @@ static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  	arch->associate_instruction_ops   = arm64__associate_instruction_ops;
>  	arch->objdump.comment_char	  = '/';
>  	arch->objdump.skip_functions_char = '+';
> +	arch->e_machine = EM_AARCH64;
> +	arch->e_flags = 0;
>  	return 0;
>  
>  out_free_call:
> diff --git a/tools/perf/arch/csky/annotate/instructions.c b/tools/perf/arch/csky/annotate/instructions.c
> index 5337bfb7d5fc..14270311d215 100644
> --- a/tools/perf/arch/csky/annotate/instructions.c
> +++ b/tools/perf/arch/csky/annotate/instructions.c
> @@ -43,6 +43,11 @@ static int csky__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  	arch->initialized = true;
>  	arch->objdump.comment_char = '/';
>  	arch->associate_instruction_ops = csky__associate_ins_ops;
> -
> +	arch->e_machine = EM_CSKY;
> +#if defined(__CSKYABIV2__)
> +	arch->e_flags = EF_CSKY_ABIV2;
> +#else
> +	arch->e_flags = EF_CSKY_ABIV1;
> +#endif

By moving this into the general code, it should take care of old systems
that doesn't have the macro.

  In file included from util/disasm.c:109:                                        
  /linux/tools/perf/arch/csky/annotate/instructions.c: In function 'csky__annotate_init':
  /linux/tools/perf/arch/csky/annotate/instructions.c:50:25: error: 'EF_CSKY_ABIV1' undeclared (first use in this function)
     50 |         arch->e_flags = EF_CSKY_ABIV1;                                  
        |                         ^~~~~~~~~~~~~                                   
  /linux/tools/perf/arch/csky/annotate/instructions.c:50:25: note: each undeclared identifier is reported only once for each function it appears in

Also, I think __CSKYABIV2__ is defined only when the host is csky.  So
it'll use ABI v1 on cross env.  I'm not sure if it's a problem.  We may
need to save the ABI somewhere in the metadata later.

Thanks,
Namhyung


>  	return 0;
>  }
> diff --git a/tools/perf/arch/loongarch/annotate/instructions.c b/tools/perf/arch/loongarch/annotate/instructions.c
> index ab43b1ab51e3..70262d5f1444 100644
> --- a/tools/perf/arch/loongarch/annotate/instructions.c
> +++ b/tools/perf/arch/loongarch/annotate/instructions.c
> @@ -131,6 +131,8 @@ int loongarch__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  		arch->associate_instruction_ops = loongarch__associate_ins_ops;
>  		arch->initialized = true;
>  		arch->objdump.comment_char = '#';
> +		arch->e_machine = EM_LOONGARCH;
> +		arch->e_flags = 0;
>  	}
>  
>  	return 0;
> diff --git a/tools/perf/arch/mips/annotate/instructions.c b/tools/perf/arch/mips/annotate/instructions.c
> index 340993f2a897..b50b46c613d6 100644
> --- a/tools/perf/arch/mips/annotate/instructions.c
> +++ b/tools/perf/arch/mips/annotate/instructions.c
> @@ -40,6 +40,8 @@ int mips__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  		arch->associate_instruction_ops = mips__associate_ins_ops;
>  		arch->initialized = true;
>  		arch->objdump.comment_char = '#';
> +		arch->e_machine = EM_MIPS;
> +		arch->e_flags = 0;
>  	}
>  
>  	return 0;
> diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/arch/powerpc/annotate/instructions.c
> index 54478cf5cccc..ca567cfdcbdb 100644
> --- a/tools/perf/arch/powerpc/annotate/instructions.c
> +++ b/tools/perf/arch/powerpc/annotate/instructions.c
> @@ -309,6 +309,8 @@ static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  		arch->associate_instruction_ops = powerpc__associate_instruction_ops;
>  		arch->objdump.comment_char      = '#';
>  		annotate_opts.show_asm_raw = true;
> +		arch->e_machine = EM_PPC;
> +		arch->e_flags = 0;
>  	}
>  
>  	return 0;
> diff --git a/tools/perf/arch/riscv64/annotate/instructions.c b/tools/perf/arch/riscv64/annotate/instructions.c
> index 869a0eb28953..55cf911633f8 100644
> --- a/tools/perf/arch/riscv64/annotate/instructions.c
> +++ b/tools/perf/arch/riscv64/annotate/instructions.c
> @@ -28,6 +28,8 @@ int riscv64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  		arch->associate_instruction_ops = riscv64__associate_ins_ops;
>  		arch->initialized = true;
>  		arch->objdump.comment_char = '#';
> +		arch->e_machine = EM_RISCV;
> +		arch->e_flags = 0;
>  	}
>  
>  	return 0;
> diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c
> index eeac25cca699..c61193f1e096 100644
> --- a/tools/perf/arch/s390/annotate/instructions.c
> +++ b/tools/perf/arch/s390/annotate/instructions.c
> @@ -166,6 +166,8 @@ static int s390__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  			if (s390__cpuid_parse(arch, cpuid))
>  				err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING;
>  		}
> +		arch->e_machine = EM_S390;
> +		arch->e_flags = 0;
>  	}
>  
>  	return err;
> diff --git a/tools/perf/arch/sparc/annotate/instructions.c b/tools/perf/arch/sparc/annotate/instructions.c
> index 2614c010c235..68c31580ccfc 100644
> --- a/tools/perf/arch/sparc/annotate/instructions.c
> +++ b/tools/perf/arch/sparc/annotate/instructions.c
> @@ -163,6 +163,8 @@ static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>  		arch->initialized = true;
>  		arch->associate_instruction_ops = sparc__associate_instruction_ops;
>  		arch->objdump.comment_char = '#';
> +		arch->e_machine = EM_SPARC;
> +		arch->e_flags = 0;
>  	}
>  
>  	return 0;
> diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/x86/annotate/instructions.c
> index c869abe3c31d..ae94b1f0b9cc 100644
> --- a/tools/perf/arch/x86/annotate/instructions.c
> +++ b/tools/perf/arch/x86/annotate/instructions.c
> @@ -202,7 +202,8 @@ static int x86__annotate_init(struct arch *arch, char *cpuid)
>  		if (x86__cpuid_parse(arch, cpuid))
>  			err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING;
>  	}
> -
> +	arch->e_machine = EM_X86_64;
> +	arch->e_flags = 0;
>  	arch->initialized = true;
>  	return err;
>  }
> diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h
> index 486c269b29ba..c135db2416b5 100644
> --- a/tools/perf/util/disasm.h
> +++ b/tools/perf/util/disasm.h
> @@ -44,6 +44,10 @@ struct arch {
>  				struct data_loc_info *dloc, Dwarf_Die *cu_die,
>  				struct disasm_line *dl);
>  #endif
> +	/** @e_machine: ELF machine associated with arch. */
> +	unsigned int e_machine;
> +	/** @e_flags: Optional ELF flags associated with arch. */
> +	unsigned int e_flags;
>  };
>  
>  struct ins {
> -- 
> 2.47.0.105.g07ac214952-goog
> 


From irogers at google.com  Fri Nov  8 10:19:52 2024
From: irogers at google.com (Ian Rogers)
Date: Fri, 8 Nov 2024 10:19:52 -0800
Subject: [PATCH v3 04/20] perf disasm: Add e_machine/e_flags to struct arch
In-Reply-To: <Zy5Le-xn4gzQ2WLo@google.com>
References: <20241017002520.59124-1-irogers@google.com> <20241017002520.59124-5-irogers@google.com>
 <Zy5Le-xn4gzQ2WLo@google.com>
Message-ID: <CAP-5=fXe-gJ6pXwdTgGqScCR+mKS2FBfVDsbih7vL-1kPKAvaA@mail.gmail.com>

On Fri, Nov 8, 2024 at 9:33?AM Namhyung Kim <namhyung at kernel.org> wrote:
>
> On Wed, Oct 16, 2024 at 05:25:04PM -0700, Ian Rogers wrote:
> > Currently functions like get_dwarf_regnum only work with the host
> > architecture. Carry the elf machine and flags in struct arch so that
> > in disassembly these can be used to allow cross platform disassembly.
> >
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >  tools/perf/arch/arc/annotate/instructions.c       | 2 ++
> >  tools/perf/arch/arm/annotate/instructions.c       | 2 ++
> >  tools/perf/arch/arm64/annotate/instructions.c     | 2 ++
> >  tools/perf/arch/csky/annotate/instructions.c      | 7 ++++++-
> >  tools/perf/arch/loongarch/annotate/instructions.c | 2 ++
> >  tools/perf/arch/mips/annotate/instructions.c      | 2 ++
> >  tools/perf/arch/powerpc/annotate/instructions.c   | 2 ++
> >  tools/perf/arch/riscv64/annotate/instructions.c   | 2 ++
> >  tools/perf/arch/s390/annotate/instructions.c      | 2 ++
> >  tools/perf/arch/sparc/annotate/instructions.c     | 2 ++
> >  tools/perf/arch/x86/annotate/instructions.c       | 3 ++-
> >  tools/perf/util/disasm.h                          | 4 ++++
> >  12 files changed, 30 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/perf/arch/arc/annotate/instructions.c b/tools/perf/arch/arc/annotate/instructions.c
> > index 2f00e995c7e3..e5619770a1af 100644
> > --- a/tools/perf/arch/arc/annotate/instructions.c
> > +++ b/tools/perf/arch/arc/annotate/instructions.c
> > @@ -5,5 +5,7 @@ static int arc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> >  {
> >       arch->initialized = true;
> >       arch->objdump.comment_char = ';';
> > +     arch->e_machine = EM_ARC;
> > +     arch->e_flags = 0;
> >       return 0;
> >  }
> > diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c
> > index 2ff6cedeb9c5..cf91a43362b0 100644
> > --- a/tools/perf/arch/arm/annotate/instructions.c
> > +++ b/tools/perf/arch/arm/annotate/instructions.c
> > @@ -53,6 +53,8 @@ static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> >       arch->associate_instruction_ops   = arm__associate_instruction_ops;
> >       arch->objdump.comment_char        = ';';
> >       arch->objdump.skip_functions_char = '+';
> > +     arch->e_machine = EM_ARM;
> > +     arch->e_flags = 0;
> >       return 0;
> >
> >  out_free_call:
> > diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c
> > index f86d9f4798bd..d465d093e7eb 100644
> > --- a/tools/perf/arch/arm64/annotate/instructions.c
> > +++ b/tools/perf/arch/arm64/annotate/instructions.c
> > @@ -113,6 +113,8 @@ static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> >       arch->associate_instruction_ops   = arm64__associate_instruction_ops;
> >       arch->objdump.comment_char        = '/';
> >       arch->objdump.skip_functions_char = '+';
> > +     arch->e_machine = EM_AARCH64;
> > +     arch->e_flags = 0;
> >       return 0;
> >
> >  out_free_call:
> > diff --git a/tools/perf/arch/csky/annotate/instructions.c b/tools/perf/arch/csky/annotate/instructions.c
> > index 5337bfb7d5fc..14270311d215 100644
> > --- a/tools/perf/arch/csky/annotate/instructions.c
> > +++ b/tools/perf/arch/csky/annotate/instructions.c
> > @@ -43,6 +43,11 @@ static int csky__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> >       arch->initialized = true;
> >       arch->objdump.comment_char = '/';
> >       arch->associate_instruction_ops = csky__associate_ins_ops;
> > -
> > +     arch->e_machine = EM_CSKY;
> > +#if defined(__CSKYABIV2__)
> > +     arch->e_flags = EF_CSKY_ABIV2;
> > +#else
> > +     arch->e_flags = EF_CSKY_ABIV1;
> > +#endif
>
> By moving this into the general code, it should take care of old systems
> that doesn't have the macro.
>
>   In file included from util/disasm.c:109:
>   /linux/tools/perf/arch/csky/annotate/instructions.c: In function 'csky__annotate_init':
>   /linux/tools/perf/arch/csky/annotate/instructions.c:50:25: error: 'EF_CSKY_ABIV1' undeclared (first use in this function)
>      50 |         arch->e_flags = EF_CSKY_ABIV1;
>         |                         ^~~~~~~~~~~~~
>   /linux/tools/perf/arch/csky/annotate/instructions.c:50:25: note: each undeclared identifier is reported only once for each function it appears in

EF_CSKY_ABIV1 is defined in elf.h and has been there at least 5 years in libelf:
https://sourceware.org/git/?p=elfutils.git;a=commit;f=libelf/elf.h;h=9c82942ae7355a3226c53a92c2c73b33193c5e33
I suspected the issue here is missing elf.h include, but the .c file
is included in tools/perf/util/disasm.c and that must have a
transitive dependency given other things are building. Do you want me
to send a patch making this conditional with extra #ifdefs or re-send
the series?

> Also, I think __CSKYABIV2__ is defined only when the host is csky.  So
> it'll use ABI v1 on cross env.  I'm not sure if it's a problem.  We may
> need to save the ABI somewhere in the metadata later.

Agreed. In general we should read e_machine and e_flags from the ELF
file, so I'm not sure new metadata is needed. This patch is trying to
lay groundwork for that.

Thanks,
Ian


From namhyung at kernel.org  Fri Nov  8 10:33:41 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 8 Nov 2024 10:33:41 -0800
Subject: [PATCH v3 00/20] Remove PERF_HAVE_DWARF_REGS
In-Reply-To: <20241108090040.463cb3f0820e7ac22d1bb6c2@kernel.org>
References: <20241017002520.59124-1-irogers@google.com>
 <Zy0VHro3wE-ZTKsq@google.com>
 <20241108090040.463cb3f0820e7ac22d1bb6c2@kernel.org>
Message-ID: <Zy5ZhX-ZWRCQRHVs@google.com>

On Fri, Nov 08, 2024 at 09:00:40AM +0900, Masami Hiramatsu wrote:
> Hi,
> 
> On Thu, 7 Nov 2024 11:29:34 -0800
> Namhyung Kim <namhyung at kernel.org> wrote:
> 
> > Hi all,
> > 
> > On Wed, Oct 16, 2024 at 05:25:00PM -0700, Ian Rogers wrote:
> > > These changes are on top of:
> > > https://lore.kernel.org/lkml/20241017001354.56973-1-irogers at google.com/
> > > 
> > > Prior to these patches PERF_HAVE_DWARF_REGS indicated the presence of
> > > dwarf-regs.c in the arch directory. dwarf-regs.c provided upto 4
> > > functions:
> > > 
> > > 1) regs_query_register_offset would translate a register name into a
> > > pt_regs offset and was used by BPF prologues. BPF prologues existed
> > > for BPF events and support for these was removed many releases ago.
> > > This code was dead and could be removed.
> > > 
> > > 2) get_arch_regstr duplicated get_dwarf_regstr and so it could be
> > > removed.  The case for csky was a little more complicated as the ABI
> > > controlled the string. The callers of get_dwarf_regstr were updated to
> > > also pass the ELF flags so that on csky the ABI appropriate table
> > > could be used. As the argument is only used on csky this a no-op for
> > > everything else.
> > > 
> > > 3) get_arch_regnum translated a register name back to a dwarf number
> > > and only existed on x86 where "al", "ax", "eax" and "rax" could all
> > > mean register 0. This code was moved to util with similar
> > > machine/flags logic to get_arch_regstr and for consistency with it.
> > > 
> > > 4) get_powerpc_regs a PowerPC specific function used by annotate that
> > > should really be in util.
> > > 
> > > 2 and 3 required the wiring through of the ELF machine and flags in
> > > callers to get_dwarf_regstr and get_dwarf_regnum. When these values
> > > weren't dependent on an ELF file a new EM_HOST and EF_HOST were added
> > > to give the host ELF machine and flags. These 2 #defines got rid of
> > > the existing separate arch files and #ifdefs.
> > > 
> > > v3: These files were separated from the rest of the v2 libdw clean up
> > >     in:
> > > https://lore.kernel.org/lkml/CAP-5=fVZH3L-6y_sxLwSmT8WyMXDMFnuqUksNULdQYJCPNBFYw at mail.gmail.com/
> > > 
> > > Ian Rogers (20):
> > >   perf bpf-prologue: Remove unused file
> > >   perf dwarf-regs: Remove PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
> > >   perf dwarf-regs: Add EM_HOST and EF_HOST defines
> > >   perf disasm: Add e_machine/e_flags to struct arch
> > >   perf dwarf-regs: Pass accurate disassembly machine to get_dwarf_regnum
> > >   perf dwarf-regs: Pass ELF flags to get_dwarf_regstr
> > >   perf dwarf-regs: Move x86 dwarf-regs out of arch
> > >   perf arm64: Remove dwarf-regs.c
> > >   perf arm: Remove dwarf-regs.c
> > >   perf dwarf-regs: Move csky dwarf-regs out of arch
> > >   perf loongarch: Remove dwarf-regs.c
> > >   perf mips: Remove dwarf-regs.c
> > >   perf dwarf-regs: Move powerpc dwarf-regs out of arch
> > >   perf riscv: Remove dwarf-regs.c and add dwarf-regs-table.h
> > >   perf s390: Remove dwarf-regs.c
> > >   perf sh: Remove dwarf-regs.c
> > >   perf sparc: Remove dwarf-regs.c
> > >   perf xtensa: Remove dwarf-regs.c
> > >   perf dwarf-regs: Remove get_arch_regstr code
> > >   perf build: Remove PERF_HAVE_DWARF_REGS
> > 
> > These look all good and I'm about to apply the series.
> > 
> > Masami, do you have any remaining concerns?  It'd be nice if you can
> > give your Reviewed-by.
> 
> I think it looks good to me.
> 
> Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>

Thanks for your review!
Namhyung



From atishp at rivosinc.com  Fri Nov  8 10:37:54 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Fri, 8 Nov 2024 10:37:54 -0800
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is provided
In-Reply-To: <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org>
References: <20241026121758.143259-1-irogers@google.com> <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
 <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org>
Message-ID: <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>

On Fri, Nov 8, 2024 at 4:16?AM James Clark <james.clark at linaro.org> wrote:
>
>
>
> On 07/11/2024 18:51, Ian Rogers wrote:
> > On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
> >>
> >> At the RISC-V summit the topic of avoiding event data being in the
> >> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
> >> events being the priority when no PMU is provided so that legacy
> >> events maybe supported via json. Originally Mark Rutland also
> >> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
> >> M? processors, but James Clark more recently tested this and believes
> >> the driver issues there may not have existed or have been resolved. In
> >> any case, it is inconsistent that with a PMU event names avoid legacy
> >> encodings, but when wildcarding PMUs (ie without a PMU with the event
> >> name) the legacy encodings have priority.
> >>
> >> The patch doing this work was reverted in a v6.10 release candidate
> >> as, even though the patch was posted for weeks and had been on
> >> linux-next for weeks without issue, Linus was in the habit of using
> >> explicit legacy events with unsupported precision options on his
> >> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
> >> where ARM decided to call the events bus_cycles and cycles, the latter
> >> being also a legacy event name. ARM haven't renamed the cycles event
> >> to a more consistent cpu_cycles and avoided the problem. With these
> >> changes the problematic event will now be skipped, a large warning
> >> produced, and perf record will continue for the other PMU events. This
> >> solution was proposed by Arnaldo.
> >>
> >> Two minor changes have been added to help with the error message and
> >> to work around issues occurring with "perf stat metrics (shadow stat)
> >> test".
> >>
> >> The patches have only been tested on my x86 non-hybrid laptop.
> >
> > Hi Atish and James,
> >
> > Could I get your tags for this series?
> >

Hi Ian,
Thanks for your patches. It definitely helps to have a clean slate
implementation
for the perf tool. However, I have some open questions about other use cases
that we discussed during the RVI Summit.

> > The patches were originally motivated by wanting to make the behavior
> > of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
> > wildcarded to "cpu" in the first case. This was divergent because of
> > ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
> > config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
> > type>, config=<encoding from event>) when a PMU name was given. This
> > aligns with RISC-V wanting to use json encodings to avoid complexity
> > in the PMU driver.
> >
>
> I couldn't find the thread, but I remember fairly recently it was
> mentioned that RISC-V would be supporting the legacy events after all,
> maybe it was a comment from Atish? I'm not sure if that changes the
> requirements for this or not?
>
> I still can't really imagine how tooling would work if every tool has to
> maintain the mappings of basic events like instructions and branches.
> For example all the perf_event_open tests in ltp use the legacy events.
>

No it has not changed. While this series helps to avoid clunky vendor
specific encodings
in the driver for perf tool, I am still unsure how we will manage
other applications
(directly passing legacy events through perf_event_open or
perf_evlist__open) will work.

I have only anecdotal data about folks relying perf legacy events
directly to profile
their application. All of them use mostly cycle/instruction events though.
Are there any users who use other legacy events directly without perf tool ?

If not, we may have only cycle/instruction mapping in the driver and
rely on json for everything else.
The other use case is virtualization. I have been playing with these
patches to find a clean solution to
enable all the use cases. If you have any other ideas, please let me know.

> And wouldn't porting existing software to RISC-V would be an issue if it
> doesn't behave in a similar way to what's there already?
>
> > James, could you show the neoverse with the cmn PMU behavior for perf
> > record of "cycles:pp" due to sensitivities there.
> >
>
> Yep I can check this on Monday.
>
> > Thanks,
> > Ian
> >
>
>
> >
> >
> >
> >> Ian Rogers (4):
> >>    perf evsel: Add pmu_name helper
> >>    perf stat: Fix find_stat for mixed legacy/non-legacy events
> >>    perf record: Skip don't fail for events that don't open
> >>    perf parse-events: Reapply "Prefer sysfs/JSON hardware events over
> >>      legacy"
> >>
> >>   tools/perf/builtin-record.c    | 22 +++++++---
> >>   tools/perf/util/evsel.c        | 10 +++++
> >>   tools/perf/util/evsel.h        |  1 +
> >>   tools/perf/util/parse-events.c | 26 +++++++++---
> >>   tools/perf/util/parse-events.l | 76 +++++++++++++++++-----------------
> >>   tools/perf/util/parse-events.y | 60 ++++++++++++++++++---------
> >>   tools/perf/util/pmus.c         | 20 +++++++--
> >>   tools/perf/util/stat-shadow.c  |  3 +-
> >>   8 files changed, 145 insertions(+), 73 deletions(-)
> >>
> >> --
> >> 2.47.0.163.g1226f6d8fa-goog
> >>


From namhyung at kernel.org  Fri Nov  8 10:38:24 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 8 Nov 2024 10:38:24 -0800
Subject: [PATCH v3 04/20] perf disasm: Add e_machine/e_flags to struct
 arch
In-Reply-To: <CAP-5=fXe-gJ6pXwdTgGqScCR+mKS2FBfVDsbih7vL-1kPKAvaA@mail.gmail.com>
References: <20241017002520.59124-1-irogers@google.com>
 <20241017002520.59124-5-irogers@google.com>
 <Zy5Le-xn4gzQ2WLo@google.com>
 <CAP-5=fXe-gJ6pXwdTgGqScCR+mKS2FBfVDsbih7vL-1kPKAvaA@mail.gmail.com>
Message-ID: <Zy5aoMnY2nupb7SX@google.com>

On Fri, Nov 08, 2024 at 10:19:52AM -0800, Ian Rogers wrote:
> On Fri, Nov 8, 2024 at 9:33?AM Namhyung Kim <namhyung at kernel.org> wrote:
> >
> > On Wed, Oct 16, 2024 at 05:25:04PM -0700, Ian Rogers wrote:
> > > Currently functions like get_dwarf_regnum only work with the host
> > > architecture. Carry the elf machine and flags in struct arch so that
> > > in disassembly these can be used to allow cross platform disassembly.
> > >
> > > Signed-off-by: Ian Rogers <irogers at google.com>
> > > ---
> > >  tools/perf/arch/arc/annotate/instructions.c       | 2 ++
> > >  tools/perf/arch/arm/annotate/instructions.c       | 2 ++
> > >  tools/perf/arch/arm64/annotate/instructions.c     | 2 ++
> > >  tools/perf/arch/csky/annotate/instructions.c      | 7 ++++++-
> > >  tools/perf/arch/loongarch/annotate/instructions.c | 2 ++
> > >  tools/perf/arch/mips/annotate/instructions.c      | 2 ++
> > >  tools/perf/arch/powerpc/annotate/instructions.c   | 2 ++
> > >  tools/perf/arch/riscv64/annotate/instructions.c   | 2 ++
> > >  tools/perf/arch/s390/annotate/instructions.c      | 2 ++
> > >  tools/perf/arch/sparc/annotate/instructions.c     | 2 ++
> > >  tools/perf/arch/x86/annotate/instructions.c       | 3 ++-
> > >  tools/perf/util/disasm.h                          | 4 ++++
> > >  12 files changed, 30 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/tools/perf/arch/arc/annotate/instructions.c b/tools/perf/arch/arc/annotate/instructions.c
> > > index 2f00e995c7e3..e5619770a1af 100644
> > > --- a/tools/perf/arch/arc/annotate/instructions.c
> > > +++ b/tools/perf/arch/arc/annotate/instructions.c
> > > @@ -5,5 +5,7 @@ static int arc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> > >  {
> > >       arch->initialized = true;
> > >       arch->objdump.comment_char = ';';
> > > +     arch->e_machine = EM_ARC;
> > > +     arch->e_flags = 0;
> > >       return 0;
> > >  }
> > > diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c
> > > index 2ff6cedeb9c5..cf91a43362b0 100644
> > > --- a/tools/perf/arch/arm/annotate/instructions.c
> > > +++ b/tools/perf/arch/arm/annotate/instructions.c
> > > @@ -53,6 +53,8 @@ static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> > >       arch->associate_instruction_ops   = arm__associate_instruction_ops;
> > >       arch->objdump.comment_char        = ';';
> > >       arch->objdump.skip_functions_char = '+';
> > > +     arch->e_machine = EM_ARM;
> > > +     arch->e_flags = 0;
> > >       return 0;
> > >
> > >  out_free_call:
> > > diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c
> > > index f86d9f4798bd..d465d093e7eb 100644
> > > --- a/tools/perf/arch/arm64/annotate/instructions.c
> > > +++ b/tools/perf/arch/arm64/annotate/instructions.c
> > > @@ -113,6 +113,8 @@ static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> > >       arch->associate_instruction_ops   = arm64__associate_instruction_ops;
> > >       arch->objdump.comment_char        = '/';
> > >       arch->objdump.skip_functions_char = '+';
> > > +     arch->e_machine = EM_AARCH64;
> > > +     arch->e_flags = 0;
> > >       return 0;
> > >
> > >  out_free_call:
> > > diff --git a/tools/perf/arch/csky/annotate/instructions.c b/tools/perf/arch/csky/annotate/instructions.c
> > > index 5337bfb7d5fc..14270311d215 100644
> > > --- a/tools/perf/arch/csky/annotate/instructions.c
> > > +++ b/tools/perf/arch/csky/annotate/instructions.c
> > > @@ -43,6 +43,11 @@ static int csky__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> > >       arch->initialized = true;
> > >       arch->objdump.comment_char = '/';
> > >       arch->associate_instruction_ops = csky__associate_ins_ops;
> > > -
> > > +     arch->e_machine = EM_CSKY;
> > > +#if defined(__CSKYABIV2__)
> > > +     arch->e_flags = EF_CSKY_ABIV2;
> > > +#else
> > > +     arch->e_flags = EF_CSKY_ABIV1;
> > > +#endif
> >
> > By moving this into the general code, it should take care of old systems
> > that doesn't have the macro.
> >
> >   In file included from util/disasm.c:109:
> >   /linux/tools/perf/arch/csky/annotate/instructions.c: In function 'csky__annotate_init':
> >   /linux/tools/perf/arch/csky/annotate/instructions.c:50:25: error: 'EF_CSKY_ABIV1' undeclared (first use in this function)
> >      50 |         arch->e_flags = EF_CSKY_ABIV1;
> >         |                         ^~~~~~~~~~~~~
> >   /linux/tools/perf/arch/csky/annotate/instructions.c:50:25: note: each undeclared identifier is reported only once for each function it appears in
> 
> EF_CSKY_ABIV1 is defined in elf.h and has been there at least 5 years in libelf:
> https://sourceware.org/git/?p=elfutils.git;a=commit;f=libelf/elf.h;h=9c82942ae7355a3226c53a92c2c73b33193c5e33
> I suspected the issue here is missing elf.h include, but the .c file
> is included in tools/perf/util/disasm.c and that must have a
> transitive dependency given other things are building. Do you want me
> to send a patch making this conditional with extra #ifdefs or re-send
> the series?

Yeah, it's unfortunate but I think we can have a small incremental diff
here to define them if it's not there.  Then I'll squash it to the
patch.

> 
> > Also, I think __CSKYABIV2__ is defined only when the host is csky.  So
> > it'll use ABI v1 on cross env.  I'm not sure if it's a problem.  We may
> > need to save the ABI somewhere in the metadata later.
> 
> Agreed. In general we should read e_machine and e_flags from the ELF
> file, so I'm not sure new metadata is needed. This patch is trying to
> lay groundwork for that.

I understand that.  Yeah it should come from the binary.

Thanks,
Namhyung



From irogers at google.com  Fri Nov  8 10:45:54 2024
From: irogers at google.com (Ian Rogers)
Date: Fri, 8 Nov 2024 10:45:54 -0800
Subject: [PATCH v3 04/20] perf disasm: Add e_machine/e_flags to struct arch
In-Reply-To: <Zy5aoMnY2nupb7SX@google.com>
References: <20241017002520.59124-1-irogers@google.com> <20241017002520.59124-5-irogers@google.com>
 <Zy5Le-xn4gzQ2WLo@google.com> <CAP-5=fXe-gJ6pXwdTgGqScCR+mKS2FBfVDsbih7vL-1kPKAvaA@mail.gmail.com>
 <Zy5aoMnY2nupb7SX@google.com>
Message-ID: <CAP-5=fW7m0AVVn42XK9s=RFmAs63mh4Mk5QehpLKLFMAGje+9A@mail.gmail.com>

On Fri, Nov 8, 2024 at 10:38?AM Namhyung Kim <namhyung at kernel.org> wrote:
>
> On Fri, Nov 08, 2024 at 10:19:52AM -0800, Ian Rogers wrote:
> > On Fri, Nov 8, 2024 at 9:33?AM Namhyung Kim <namhyung at kernel.org> wrote:
> > >
> > > On Wed, Oct 16, 2024 at 05:25:04PM -0700, Ian Rogers wrote:
> > > > Currently functions like get_dwarf_regnum only work with the host
> > > > architecture. Carry the elf machine and flags in struct arch so that
> > > > in disassembly these can be used to allow cross platform disassembly.
> > > >
> > > > Signed-off-by: Ian Rogers <irogers at google.com>
> > > > ---
> > > >  tools/perf/arch/arc/annotate/instructions.c       | 2 ++
> > > >  tools/perf/arch/arm/annotate/instructions.c       | 2 ++
> > > >  tools/perf/arch/arm64/annotate/instructions.c     | 2 ++
> > > >  tools/perf/arch/csky/annotate/instructions.c      | 7 ++++++-
> > > >  tools/perf/arch/loongarch/annotate/instructions.c | 2 ++
> > > >  tools/perf/arch/mips/annotate/instructions.c      | 2 ++
> > > >  tools/perf/arch/powerpc/annotate/instructions.c   | 2 ++
> > > >  tools/perf/arch/riscv64/annotate/instructions.c   | 2 ++
> > > >  tools/perf/arch/s390/annotate/instructions.c      | 2 ++
> > > >  tools/perf/arch/sparc/annotate/instructions.c     | 2 ++
> > > >  tools/perf/arch/x86/annotate/instructions.c       | 3 ++-
> > > >  tools/perf/util/disasm.h                          | 4 ++++
> > > >  12 files changed, 30 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/tools/perf/arch/arc/annotate/instructions.c b/tools/perf/arch/arc/annotate/instructions.c
> > > > index 2f00e995c7e3..e5619770a1af 100644
> > > > --- a/tools/perf/arch/arc/annotate/instructions.c
> > > > +++ b/tools/perf/arch/arc/annotate/instructions.c
> > > > @@ -5,5 +5,7 @@ static int arc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> > > >  {
> > > >       arch->initialized = true;
> > > >       arch->objdump.comment_char = ';';
> > > > +     arch->e_machine = EM_ARC;
> > > > +     arch->e_flags = 0;
> > > >       return 0;
> > > >  }
> > > > diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c
> > > > index 2ff6cedeb9c5..cf91a43362b0 100644
> > > > --- a/tools/perf/arch/arm/annotate/instructions.c
> > > > +++ b/tools/perf/arch/arm/annotate/instructions.c
> > > > @@ -53,6 +53,8 @@ static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> > > >       arch->associate_instruction_ops   = arm__associate_instruction_ops;
> > > >       arch->objdump.comment_char        = ';';
> > > >       arch->objdump.skip_functions_char = '+';
> > > > +     arch->e_machine = EM_ARM;
> > > > +     arch->e_flags = 0;
> > > >       return 0;
> > > >
> > > >  out_free_call:
> > > > diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c
> > > > index f86d9f4798bd..d465d093e7eb 100644
> > > > --- a/tools/perf/arch/arm64/annotate/instructions.c
> > > > +++ b/tools/perf/arch/arm64/annotate/instructions.c
> > > > @@ -113,6 +113,8 @@ static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> > > >       arch->associate_instruction_ops   = arm64__associate_instruction_ops;
> > > >       arch->objdump.comment_char        = '/';
> > > >       arch->objdump.skip_functions_char = '+';
> > > > +     arch->e_machine = EM_AARCH64;
> > > > +     arch->e_flags = 0;
> > > >       return 0;
> > > >
> > > >  out_free_call:
> > > > diff --git a/tools/perf/arch/csky/annotate/instructions.c b/tools/perf/arch/csky/annotate/instructions.c
> > > > index 5337bfb7d5fc..14270311d215 100644
> > > > --- a/tools/perf/arch/csky/annotate/instructions.c
> > > > +++ b/tools/perf/arch/csky/annotate/instructions.c
> > > > @@ -43,6 +43,11 @@ static int csky__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> > > >       arch->initialized = true;
> > > >       arch->objdump.comment_char = '/';
> > > >       arch->associate_instruction_ops = csky__associate_ins_ops;
> > > > -
> > > > +     arch->e_machine = EM_CSKY;
> > > > +#if defined(__CSKYABIV2__)
> > > > +     arch->e_flags = EF_CSKY_ABIV2;
> > > > +#else
> > > > +     arch->e_flags = EF_CSKY_ABIV1;
> > > > +#endif
> > >
> > > By moving this into the general code, it should take care of old systems
> > > that doesn't have the macro.
> > >
> > >   In file included from util/disasm.c:109:
> > >   /linux/tools/perf/arch/csky/annotate/instructions.c: In function 'csky__annotate_init':
> > >   /linux/tools/perf/arch/csky/annotate/instructions.c:50:25: error: 'EF_CSKY_ABIV1' undeclared (first use in this function)
> > >      50 |         arch->e_flags = EF_CSKY_ABIV1;
> > >         |                         ^~~~~~~~~~~~~
> > >   /linux/tools/perf/arch/csky/annotate/instructions.c:50:25: note: each undeclared identifier is reported only once for each function it appears in
> >
> > EF_CSKY_ABIV1 is defined in elf.h and has been there at least 5 years in libelf:
> > https://sourceware.org/git/?p=elfutils.git;a=commit;f=libelf/elf.h;h=9c82942ae7355a3226c53a92c2c73b33193c5e33
> > I suspected the issue here is missing elf.h include, but the .c file
> > is included in tools/perf/util/disasm.c and that must have a
> > transitive dependency given other things are building. Do you want me
> > to send a patch making this conditional with extra #ifdefs or re-send
> > the series?
>
> Yeah, it's unfortunate but I think we can have a small incremental diff
> here to define them if it's not there.  Then I'll squash it to the
> patch.

Thanks, sgtm. Could you also explicitly include elf.h into disasm.c
rather than depending on the transitive #include? There's obviously
tech debt to not have .c files including each other to work around the
build system.

Ian

> >
> > > Also, I think __CSKYABIV2__ is defined only when the host is csky.  So
> > > it'll use ABI v1 on cross env.  I'm not sure if it's a problem.  We may
> > > need to save the ABI somewhere in the metadata later.
> >
> > Agreed. In general we should read e_machine and e_flags from the ELF
> > file, so I'm not sure new metadata is needed. This patch is trying to
> > lay groundwork for that.
>
> I understand that.  Yeah it should come from the binary.
>
> Thanks,
> Namhyung
>


From irogers at google.com  Fri Nov  8 10:59:59 2024
From: irogers at google.com (Ian Rogers)
Date: Fri, 8 Nov 2024 10:59:59 -0800
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is provided
In-Reply-To: <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
References: <20241026121758.143259-1-irogers@google.com> <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
 <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org> <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
Message-ID: <CAP-5=fV23r-_yVvGP3n5gjH8uZ2rEXmbZEwxr2wF+bpg=m745A@mail.gmail.com>

On Fri, Nov 8, 2024 at 10:38?AM Atish Kumar Patra <atishp at rivosinc.com> wrote:
>
> On Fri, Nov 8, 2024 at 4:16?AM James Clark <james.clark at linaro.org> wrote:
> >
> >
> >
> > On 07/11/2024 18:51, Ian Rogers wrote:
> > > On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
> > >>
> > >> At the RISC-V summit the topic of avoiding event data being in the
> > >> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
> > >> events being the priority when no PMU is provided so that legacy
> > >> events maybe supported via json. Originally Mark Rutland also
> > >> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
> > >> M? processors, but James Clark more recently tested this and believes
> > >> the driver issues there may not have existed or have been resolved. In
> > >> any case, it is inconsistent that with a PMU event names avoid legacy
> > >> encodings, but when wildcarding PMUs (ie without a PMU with the event
> > >> name) the legacy encodings have priority.
> > >>
> > >> The patch doing this work was reverted in a v6.10 release candidate
> > >> as, even though the patch was posted for weeks and had been on
> > >> linux-next for weeks without issue, Linus was in the habit of using
> > >> explicit legacy events with unsupported precision options on his
> > >> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
> > >> where ARM decided to call the events bus_cycles and cycles, the latter
> > >> being also a legacy event name. ARM haven't renamed the cycles event
> > >> to a more consistent cpu_cycles and avoided the problem. With these
> > >> changes the problematic event will now be skipped, a large warning
> > >> produced, and perf record will continue for the other PMU events. This
> > >> solution was proposed by Arnaldo.
> > >>
> > >> Two minor changes have been added to help with the error message and
> > >> to work around issues occurring with "perf stat metrics (shadow stat)
> > >> test".
> > >>
> > >> The patches have only been tested on my x86 non-hybrid laptop.
> > >
> > > Hi Atish and James,
> > >
> > > Could I get your tags for this series?
> > >
>
> Hi Ian,
> Thanks for your patches. It definitely helps to have a clean slate
> implementation
> for the perf tool. However, I have some open questions about other use cases
> that we discussed during the RVI Summit.

Thanks Atish, could I get your acked/reviewed/tested tags?

Ian

> > > The patches were originally motivated by wanting to make the behavior
> > > of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
> > > wildcarded to "cpu" in the first case. This was divergent because of
> > > ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
> > > config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
> > > type>, config=<encoding from event>) when a PMU name was given. This
> > > aligns with RISC-V wanting to use json encodings to avoid complexity
> > > in the PMU driver.
> > >
> >
> > I couldn't find the thread, but I remember fairly recently it was
> > mentioned that RISC-V would be supporting the legacy events after all,
> > maybe it was a comment from Atish? I'm not sure if that changes the
> > requirements for this or not?
> >
> > I still can't really imagine how tooling would work if every tool has to
> > maintain the mappings of basic events like instructions and branches.
> > For example all the perf_event_open tests in ltp use the legacy events.
> >
>
> No it has not changed. While this series helps to avoid clunky vendor
> specific encodings
> in the driver for perf tool, I am still unsure how we will manage
> other applications
> (directly passing legacy events through perf_event_open or
> perf_evlist__open) will work.
>
> I have only anecdotal data about folks relying perf legacy events
> directly to profile
> their application. All of them use mostly cycle/instruction events though.
> Are there any users who use other legacy events directly without perf tool ?
>
> If not, we may have only cycle/instruction mapping in the driver and
> rely on json for everything else.
> The other use case is virtualization. I have been playing with these
> patches to find a clean solution to
> enable all the use cases. If you have any other ideas, please let me know.
>
> > And wouldn't porting existing software to RISC-V would be an issue if it
> > doesn't behave in a similar way to what's there already?
> >
> > > James, could you show the neoverse with the cmn PMU behavior for perf
> > > record of "cycles:pp" due to sensitivities there.
> > >
> >
> > Yep I can check this on Monday.
> >
> > > Thanks,
> > > Ian
> > >
> >
> >
> > >
> > >
> > >
> > >> Ian Rogers (4):
> > >>    perf evsel: Add pmu_name helper
> > >>    perf stat: Fix find_stat for mixed legacy/non-legacy events
> > >>    perf record: Skip don't fail for events that don't open
> > >>    perf parse-events: Reapply "Prefer sysfs/JSON hardware events over
> > >>      legacy"
> > >>
> > >>   tools/perf/builtin-record.c    | 22 +++++++---
> > >>   tools/perf/util/evsel.c        | 10 +++++
> > >>   tools/perf/util/evsel.h        |  1 +
> > >>   tools/perf/util/parse-events.c | 26 +++++++++---
> > >>   tools/perf/util/parse-events.l | 76 +++++++++++++++++-----------------
> > >>   tools/perf/util/parse-events.y | 60 ++++++++++++++++++---------
> > >>   tools/perf/util/pmus.c         | 20 +++++++--
> > >>   tools/perf/util/stat-shadow.c  |  3 +-
> > >>   8 files changed, 145 insertions(+), 73 deletions(-)
> > >>
> > >> --
> > >> 2.47.0.163.g1226f6d8fa-goog
> > >>


From namhyung at kernel.org  Fri Nov  8 12:03:02 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Fri, 8 Nov 2024 12:03:02 -0800
Subject: [PATCH v3 10/20] perf dwarf-regs: Move csky dwarf-regs out of
 arch
In-Reply-To: <20241017002520.59124-11-irogers@google.com>
References: <20241017002520.59124-1-irogers@google.com>
 <20241017002520.59124-11-irogers@google.com>
Message-ID: <Zy5udmX6gZAg0wkS@google.com>

On Wed, Oct 16, 2024 at 05:25:10PM -0700, Ian Rogers wrote:
> Move arch/csky/util/dwarf-regs.c to util/dwarf-regs-csky.c and compile
> in unconditionally. To avoid get_arch_regstr being duplicated, rename
> to get_csky_regstr and add to get_dwarf_regstr switch.
> 
> Update #ifdefs to allow ABI V1 and V2 tables at the same
> time. Determine the table from the ELF flags.
> 
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/arch/csky/util/Build               |  1 -
>  tools/perf/util/Build                         |  1 +
>  .../dwarf-regs.c => util/dwarf-regs-csky.c}   | 19 ++++++++++---------
>  tools/perf/util/dwarf-regs.c                  | 11 +++++++----
>  tools/perf/util/include/dwarf-regs.h          |  2 ++
>  5 files changed, 20 insertions(+), 14 deletions(-)
>  rename tools/perf/{arch/csky/util/dwarf-regs.c => util/dwarf-regs-csky.c} (74%)
> 
> diff --git a/tools/perf/arch/csky/util/Build b/tools/perf/arch/csky/util/Build
> index 1325310cab6a..5e6ea82c4202 100644
> --- a/tools/perf/arch/csky/util/Build
> +++ b/tools/perf/arch/csky/util/Build
> @@ -1,4 +1,3 @@
>  perf-util-y += perf_regs.o
>  
> -perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
>  perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index 4c615611b9d7..99ae4e2802b8 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -203,6 +203,7 @@ endif
>  perf-util-$(CONFIG_LIBDW) += probe-finder.o
>  perf-util-$(CONFIG_LIBDW) += dwarf-aux.o
>  perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
> +perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o
>  perf-util-$(CONFIG_LIBDW) += dwarf-regs-x86.o
>  perf-util-$(CONFIG_LIBDW) += debuginfo.o
>  perf-util-$(CONFIG_LIBDW) += annotate-data.o
> diff --git a/tools/perf/arch/csky/util/dwarf-regs.c b/tools/perf/util/dwarf-regs-csky.c
> similarity index 74%
> rename from tools/perf/arch/csky/util/dwarf-regs.c
> rename to tools/perf/util/dwarf-regs-csky.c
> index ca86ecaeacbb..d38ef1f07f3e 100644
> --- a/tools/perf/arch/csky/util/dwarf-regs.c
> +++ b/tools/perf/util/dwarf-regs-csky.c
> @@ -5,9 +5,8 @@
>  #include <stddef.h>
>  #include <dwarf-regs.h>
>  
> -#if defined(__CSKYABIV2__)
> -#define CSKY_MAX_REGS 73
> -const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
> +#define CSKY_ABIV2_MAX_REGS 73
> +const char *csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = {
>  	/* r0 ~ r8 */
>  	"%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", "%regs2", "%regs3",
>  	/* r9 ~ r15 */
> @@ -26,9 +25,9 @@ const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
>  	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
>  	"%epc",
>  };
> -#else
> -#define CSKY_MAX_REGS 57
> -const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
> +
> +#define CSKY_ABIV1_MAX_REGS 57
> +const char *csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = {
>  	/* r0 ~ r8 */
>  	"%sp", "%regs9", "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1",
>  	/* r9 ~ r15 */
> @@ -41,9 +40,11 @@ const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
>  	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
>  	"%epc",
>  };
> -#endif
>  
> -const char *get_arch_regstr(unsigned int n)
> +const char *get_csky_regstr(unsigned int n, unsigned int flags)
>  {
> -	return (n < CSKY_MAX_REGS) ? csky_dwarf_regs_table[n] : NULL;
> +	if (flags & EF_CSKY_ABIV2)

Hmm.. you need it here as well.


> +		return (n < CSKY_ABIV2_MAX_REGS) ? csky_dwarf_regs_table_abiv2[n] : NULL;
> +
> +	return (n < CSKY_ABIV1_MAX_REGS) ? csky_dwarf_regs_table_abiv1[n] : NULL;
>  }
> diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> index fd21f9e90e40..9a76f83af62c 100644
> --- a/tools/perf/util/dwarf-regs.c
> +++ b/tools/perf/util/dwarf-regs.c
> @@ -29,17 +29,18 @@
>  #define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
>  
>  /* Return architecture dependent register string (for kprobe-tracer) */
> -const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
> -			     unsigned int flags __maybe_unused)
> +const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags)
>  {
> -#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM
> +#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
> +    || EM_HOST == EM_CSKY

And here too.  It seems you also need a rebase.

At this point, I'm giving up.  Can you please refresh the series with
a fix?

Thanks,
Namhyung


>  	if (machine == EM_NONE) {
>  		/* Generic arch - use host arch */
>  		machine = EM_HOST;
>  	}
>  #endif
>  	switch (machine) {
> -#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM
> +#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
> +    && EM_HOST != EM_CSKY
>  	case EM_NONE:	/* Generic arch - use host arch */
>  		return get_arch_regstr(n);
>  #endif
> @@ -51,6 +52,8 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
>  		return __get_dwarf_regstr(arm_regstr_tbl, n);
>  	case EM_AARCH64:
>  		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
> +	case EM_CSKY:
> +		return get_csky_regstr(n, flags);
>  	case EM_SH:
>  		return __get_dwarf_regstr(sh_regstr_tbl, n);
>  	case EM_S390:
> diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
> index 0b533409d82a..b72d9d308ce4 100644
> --- a/tools/perf/util/include/dwarf-regs.h
> +++ b/tools/perf/util/include/dwarf-regs.h
> @@ -83,6 +83,8 @@
>  const char *get_arch_regstr(unsigned int n);
>  #endif
>  
> +const char *get_csky_regstr(unsigned int n, unsigned int flags);
> +
>  /**
>   * get_dwarf_regstr() - Returns ftrace register string from DWARF regnum.
>   * @n: DWARF register number.
> -- 
> 2.47.0.105.g07ac214952-goog
> 


From atishp at rivosinc.com  Fri Nov  8 14:06:22 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Fri, 8 Nov 2024 14:06:22 -0800
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is provided
In-Reply-To: <CAP-5=fV23r-_yVvGP3n5gjH8uZ2rEXmbZEwxr2wF+bpg=m745A@mail.gmail.com>
References: <20241026121758.143259-1-irogers@google.com> <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
 <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org> <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
 <CAP-5=fV23r-_yVvGP3n5gjH8uZ2rEXmbZEwxr2wF+bpg=m745A@mail.gmail.com>
Message-ID: <CAHBxVyF77Ndio+a9OfbLTfMDVZvuXCVPrbeNvLYH06MbKXz4-A@mail.gmail.com>

On Fri, Nov 8, 2024 at 11:00?AM Ian Rogers <irogers at google.com> wrote:
>
> On Fri, Nov 8, 2024 at 10:38?AM Atish Kumar Patra <atishp at rivosinc.com> wrote:
> >
> > On Fri, Nov 8, 2024 at 4:16?AM James Clark <james.clark at linaro.org> wrote:
> > >
> > >
> > >
> > > On 07/11/2024 18:51, Ian Rogers wrote:
> > > > On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
> > > >>
> > > >> At the RISC-V summit the topic of avoiding event data being in the
> > > >> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
> > > >> events being the priority when no PMU is provided so that legacy
> > > >> events maybe supported via json. Originally Mark Rutland also
> > > >> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
> > > >> M? processors, but James Clark more recently tested this and believes
> > > >> the driver issues there may not have existed or have been resolved. In
> > > >> any case, it is inconsistent that with a PMU event names avoid legacy
> > > >> encodings, but when wildcarding PMUs (ie without a PMU with the event
> > > >> name) the legacy encodings have priority.
> > > >>
> > > >> The patch doing this work was reverted in a v6.10 release candidate
> > > >> as, even though the patch was posted for weeks and had been on
> > > >> linux-next for weeks without issue, Linus was in the habit of using
> > > >> explicit legacy events with unsupported precision options on his
> > > >> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
> > > >> where ARM decided to call the events bus_cycles and cycles, the latter
> > > >> being also a legacy event name. ARM haven't renamed the cycles event
> > > >> to a more consistent cpu_cycles and avoided the problem. With these
> > > >> changes the problematic event will now be skipped, a large warning
> > > >> produced, and perf record will continue for the other PMU events. This
> > > >> solution was proposed by Arnaldo.
> > > >>
> > > >> Two minor changes have been added to help with the error message and
> > > >> to work around issues occurring with "perf stat metrics (shadow stat)
> > > >> test".
> > > >>
> > > >> The patches have only been tested on my x86 non-hybrid laptop.
> > > >
> > > > Hi Atish and James,
> > > >
> > > > Could I get your tags for this series?
> > > >
> >
> > Hi Ian,
> > Thanks for your patches. It definitely helps to have a clean slate
> > implementation
> > for the perf tool. However, I have some open questions about other use cases
> > that we discussed during the RVI Summit.
>
> Thanks Atish, could I get your acked/reviewed/tested tags?
>

Sure. I will finish the testing and send those.

> Ian
>
> > > > The patches were originally motivated by wanting to make the behavior
> > > > of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
> > > > wildcarded to "cpu" in the first case. This was divergent because of
> > > > ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
> > > > config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
> > > > type>, config=<encoding from event>) when a PMU name was given. This
> > > > aligns with RISC-V wanting to use json encodings to avoid complexity
> > > > in the PMU driver.
> > > >
> > >
> > > I couldn't find the thread, but I remember fairly recently it was
> > > mentioned that RISC-V would be supporting the legacy events after all,
> > > maybe it was a comment from Atish? I'm not sure if that changes the
> > > requirements for this or not?
> > >
> > > I still can't really imagine how tooling would work if every tool has to
> > > maintain the mappings of basic events like instructions and branches.
> > > For example all the perf_event_open tests in ltp use the legacy events.
> > >
> >
> > No it has not changed. While this series helps to avoid clunky vendor
> > specific encodings
> > in the driver for perf tool, I am still unsure how we will manage
> > other applications
> > (directly passing legacy events through perf_event_open or
> > perf_evlist__open) will work.
> >
> > I have only anecdotal data about folks relying perf legacy events
> > directly to profile
> > their application. All of them use mostly cycle/instruction events though.
> > Are there any users who use other legacy events directly without perf tool ?
> >

+ Michale from tensorrent who was suggesting that they use the direct perf calls
in their profiling application.

@Michale : Do you have more details of direct usage of perf legacy
events to profile your application ?

> > If not, we may have only cycle/instruction mapping in the driver and
> > rely on json for everything else.
> > The other use case is virtualization. I have been playing with these
> > patches to find a clean solution to
> > enable all the use cases. If you have any other ideas, please let me know.
> >

@Ian

Any thoughts on this ? Let me explain the hypervisor use case a little bit more.
RISC-V KVM relies on SBI PMU[1] (equivalent to hypercall in x86 or HVC in ARM).
As the RISC-V ISA doesn't have any event encodings, the SBI PMU
defines a standard set corresponding to
each perf legacy event. When a guest tries to allocate a counter for
an event, it makes an SBI call (CFG_MATCH)
with SBI event encodings (matching perf legacy) or a raw event
encoding. The host kernel allocates a virtual counter
and programs the corresponding event CSRs and enables the counter.

There are two possible approaches to support it.

1. The guest OS has the correct version of the perf tool with the json
file that provides the encoding of the events supported by
the running host. The guest OS passes the exact encoding of the event
during the CFG_MATCH SBI call as a raw event and the host programs
the event CSR.  It is a much simpler scheme and less management on the
host side. But the perf tool on guests has to pass any perf legacy
events
as raw events to the driver instead of PERF_HARDWARE/CACHE or indicate
event encoding is coming from json in some other way.

The other issue is that VMM can not modify the vendorid,implid,archid
shown to the guest (the default is the same as the host).
Migration across CPU generation or vendors won't be possible if perf
in use. This may not be an issue as VM migration across CPU
Generations are not a common thing.

2. The guest OS driver always relies on the SBI PMU event encoding
(i.e perf legacy event) which the host can translate to the event
encoding the hardware
supports if it is baked into the driver. The obvious downside is the
vendor specific encodings in the driver which we are trying to avoid.

[1] https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-pmu.adoc
> > > And wouldn't porting existing software to RISC-V would be an issue if it
> > > doesn't behave in a similar way to what's there already?
> > >
> > > > James, could you show the neoverse with the cmn PMU behavior for perf
> > > > record of "cycles:pp" due to sensitivities there.
> > > >
> > >
> > > Yep I can check this on Monday.
> > >
> > > > Thanks,
> > > > Ian
> > > >
> > >
> > >
> > > >
> > > >
> > > >
> > > >> Ian Rogers (4):
> > > >>    perf evsel: Add pmu_name helper
> > > >>    perf stat: Fix find_stat for mixed legacy/non-legacy events
> > > >>    perf record: Skip don't fail for events that don't open
> > > >>    perf parse-events: Reapply "Prefer sysfs/JSON hardware events over
> > > >>      legacy"
> > > >>
> > > >>   tools/perf/builtin-record.c    | 22 +++++++---
> > > >>   tools/perf/util/evsel.c        | 10 +++++
> > > >>   tools/perf/util/evsel.h        |  1 +
> > > >>   tools/perf/util/parse-events.c | 26 +++++++++---
> > > >>   tools/perf/util/parse-events.l | 76 +++++++++++++++++-----------------
> > > >>   tools/perf/util/parse-events.y | 60 ++++++++++++++++++---------
> > > >>   tools/perf/util/pmus.c         | 20 +++++++--
> > > >>   tools/perf/util/stat-shadow.c  |  3 +-
> > > >>   8 files changed, 145 insertions(+), 73 deletions(-)
> > > >>
> > > >> --
> > > >> 2.47.0.163.g1226f6d8fa-goog
> > > >>


From mr.bossman075 at gmail.com  Fri Nov  8 14:09:16 2024
From: mr.bossman075 at gmail.com (Jesse T)
Date: Fri, 8 Nov 2024 17:09:16 -0500
Subject: [PATCH for-next] riscv: Fix default misaligned access trap
In-Reply-To: <20241107-fix_handle_misaligned_load-v1-1-07d7852c9991@rivosinc.com>
References: <20241107-fix_handle_misaligned_load-v1-1-07d7852c9991@rivosinc.com>
Message-ID: <CAJFTR8RBcoqYmWNmNe_ZixO3bv2aP-wGCbX7ieorXYxxMAa7BA@mail.gmail.com>

On Thu, Nov 7, 2024 at 5:38?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
>
> Commit d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses
> supported") removed the default handlers for handle_misaligned_load()
> and handle_misaligned_store(). When the kernel is compiled without
> RISCV_SCALAR_MISALIGNED
Technically CONFIG_RISCV_MISALIGNED.
I apparently changed `+obj-y += traps_misaligned.o` to
`+obj-$(CONFIG_RISCV_MISALIGNED) += traps_misaligned.o`
in V2 and didn't change that check back oops sorry.

> , these handlers are never defined, causing
> compilation errors.
>
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Signed-off-by: Jesse Taube <mr.bossman075 at gmail.com>

> Fixes: d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses supported")
> ---
>  arch/riscv/include/asm/entry-common.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/arch/riscv/include/asm/entry-common.h b/arch/riscv/include/asm/entry-common.h
> index 7b32d2b08bb6..c2808561df81 100644
> --- a/arch/riscv/include/asm/entry-common.h
> +++ b/arch/riscv/include/asm/entry-common.h
> @@ -25,7 +25,19 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
>  void handle_page_fault(struct pt_regs *regs);
>  void handle_break(struct pt_regs *regs);
>
> +#ifdef CONFIG_RISCV_SCALAR_MISALIGNED
>  int handle_misaligned_load(struct pt_regs *regs);
>  int handle_misaligned_store(struct pt_regs *regs);
> +#else
> +static inline int handle_misaligned_load(struct pt_regs *regs)
> +{
> +       return -1;
> +}
> +
> +static inline int handle_misaligned_store(struct pt_regs *regs)
> +{
> +       return -1;
> +}
> +#endif
>
>  #endif /* _ASM_RISCV_ENTRY_COMMON_H */
>
> ---
> base-commit: 74741a050b79d31d8d2eeee12c77736596d0a6b2
> change-id: 20241107-fix_handle_misaligned_load-8be86cb0806e
> --
> - Charlie
>


From mr.bossman075 at gmail.com  Fri Nov  8 14:12:04 2024
From: mr.bossman075 at gmail.com (Jesse T)
Date: Fri, 8 Nov 2024 17:12:04 -0500
Subject: [PATCH for-next] riscv: Fix default misaligned access trap
In-Reply-To: <CAJFTR8RBcoqYmWNmNe_ZixO3bv2aP-wGCbX7ieorXYxxMAa7BA@mail.gmail.com>
References: <20241107-fix_handle_misaligned_load-v1-1-07d7852c9991@rivosinc.com>
 <CAJFTR8RBcoqYmWNmNe_ZixO3bv2aP-wGCbX7ieorXYxxMAa7BA@mail.gmail.com>
Message-ID: <CAJFTR8Sas83NkRPSuSdbb3qtDNra=cbinPoBmpyt4_ic8R5LQg@mail.gmail.com>

On Fri, Nov 8, 2024 at 5:09?PM Jesse T <mr.bossman075 at gmail.com> wrote:
>
> On Thu, Nov 7, 2024 at 5:38?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
> >
> > Commit d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses
> > supported") removed the default handlers for handle_misaligned_load()
> > and handle_misaligned_store(). When the kernel is compiled without
> > RISCV_SCALAR_MISALIGNED
> Technically CONFIG_RISCV_MISALIGNED.
> I apparently changed `+obj-y += traps_misaligned.o` to
> `+obj-$(CONFIG_RISCV_MISALIGNED) += traps_misaligned.o`
> in V2 and didn't change that check back oops sorry.
>
> > , these handlers are never defined, causing
> > compilation errors.
> >
> > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> Signed-off-by: Jesse Taube <mr.bossman075 at gmail.com>
>
> > Fixes: d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses supported")
> > ---
> >  arch/riscv/include/asm/entry-common.h | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/arch/riscv/include/asm/entry-common.h b/arch/riscv/include/asm/entry-common.h
> > index 7b32d2b08bb6..c2808561df81 100644
> > --- a/arch/riscv/include/asm/entry-common.h
> > +++ b/arch/riscv/include/asm/entry-common.h
> > @@ -25,7 +25,19 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
> >  void handle_page_fault(struct pt_regs *regs);
> >  void handle_break(struct pt_regs *regs);
> >
> > +#ifdef CONFIG_RISCV_SCALAR_MISALIGNED

Meant to say to change this to CONFIG_RISCV_MISALIGNED.
As they are defined when CONFIG_RISCV_SCALAR_MISALIGNED is false
and CONFIG_RISCV_VECTOE_MISALIGNED is true. they are only not defined when
CONFIG_RISCV_SCALAR_MISALIGNED is false.

> >  int handle_misaligned_load(struct pt_regs *regs);
> >  int handle_misaligned_store(struct pt_regs *regs);
> > +#else
> > +static inline int handle_misaligned_load(struct pt_regs *regs)
> > +{
> > +       return -1;
> > +}
> > +
> > +static inline int handle_misaligned_store(struct pt_regs *regs)
> > +{
> > +       return -1;
> > +}
> > +#endif
> >
> >  #endif /* _ASM_RISCV_ENTRY_COMMON_H */
> >
> > ---
> > base-commit: 74741a050b79d31d8d2eeee12c77736596d0a6b2
> > change-id: 20241107-fix_handle_misaligned_load-8be86cb0806e
> > --
> > - Charlie
> >


From mr.bossman075 at gmail.com  Fri Nov  8 14:16:04 2024
From: mr.bossman075 at gmail.com (Jesse T)
Date: Fri, 8 Nov 2024 17:16:04 -0500
Subject: [PATCH v10 00/14] riscv: Add support for xtheadvector
In-Reply-To: <d9eaaf71-dfe7-4bf8-8aee-538ee8ad9f24@outlook.com>
References: <20240911-xtheadvector-v10-0-8d3930091246@rivosinc.com>
 <a1f41f92-6bd0-48b6-a931-e7ad7aba18cc@outlook.com> <20240930-reenact-stratus-9d42d7439df4@spud>
 <d9eaaf71-dfe7-4bf8-8aee-538ee8ad9f24@outlook.com>
Message-ID: <CAJFTR8REgZkOVGP+Y3skYPYbdV6x3E2iMfWjg0SoSkaSxQtGig@mail.gmail.com>

Hey Palmer there are a bunch of merge artifacts in for-next from this
set. Just letting you know.
https://git.kernel.org/pub/scm/linux/kernel/git/palmer/linux.git/commit/?h=for-next&id=95437f8c02b5907b5f2d7dc6c03e3c73523c5cd6

On Mon, Sep 30, 2024 at 11:52?AM Aoba K <nExp_0x17 at outlook.com> wrote:
>
> The devicetree name shown in OpenSBI is
> the one packed with U-Boot SPL.
> As the image builder didn't put the kernel
> devicetree with the image under boot partition,
> The whole boot process only uses the U-Boot device tree.
>
> The reason why the log shows "Nezha"
> but not "Lichee RV" is that this log is produced
> which U-Boot revision is d1-2022-10-31 from samuel's repo.
> Build from d1-wip can show "Lichee RV" correctly
> (manually edit config to specify LicheeRV dtb should have same effect though),
> while the issue persists when kernel load to
> the procedure same as the dmesg mentioned above.
>
>
> Cheers,
> Aoba K
>
> 2024?9?30? ??10:53:40 Conor Dooley <conor at kernel.org>:
>
> > On Sun, Sep 29, 2024 at 12:44:07PM +0000, Aoba K wrote:
> >> Hello Charlie,
> >>
> >> I've been working on bringing up the Sipeed Lichee RV Dock
> >> (which also uses the D1 SoC) with the kernel patches you provided.
> >> The patches applied cleanly to Palmer's for-next branch,
> >> but I've encountered a couple of issues:
> >>
> >> 1. Skiffos Compilation Error during the compilation process of `cgo`:
> >> `unknown relocation type 17; compiled without -fpic?`
> >> Unfortunately, I closed the terminal before saving the full log,
> >> so I don't have the complete details, but the result should be reproducible.
> >> While this should be a SkiffOS issue, mention it in case SkiffOS is the method
> >> that you mentioned for bringing up the device.
> >>
> >> 2. Image Building with sehraf/riscv-arch-image-builder:
> >> After building the image, the device failed to start at an early stage.
> >> I suspect this may be related to incorrect RAM size detection,
> >> as the board only has 512MB of RAM.
> >> Interestingly, the vendor image reports 1GB, and the Sipeed website also states
> >> that the Dock has 1GB, despite there being no extra memory bank present.
> >>
> >> You can find the boot log here: https://fars.ee/bdYk.log
> >>
> >> Any help would be appreciated, and big thanks to your work
> >> to make the efficient part of this board to work (again)!
> >
> > The log you posted at https://fars.ee/XFzR appears to be using the
> > devicetree of a Nezha not the Lichee RV Dock. Why are you doing that,
> > when the Lichee RV Dock is supported in the kernel already?
> >
> > Cheers,
> > Conor.
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From irogers at google.com  Fri Nov  8 15:08:07 2024
From: irogers at google.com (Ian Rogers)
Date: Fri, 8 Nov 2024 15:08:07 -0800
Subject: [PATCH v3 10/20] perf dwarf-regs: Move csky dwarf-regs out of arch
In-Reply-To: <Zy5udmX6gZAg0wkS@google.com>
References: <20241017002520.59124-1-irogers@google.com> <20241017002520.59124-11-irogers@google.com>
 <Zy5udmX6gZAg0wkS@google.com>
Message-ID: <CAP-5=fWhiLJ97smNySGk+TmmQ=ELOdztqdb7h3hrxT+18wG_HA@mail.gmail.com>

On Fri, Nov 8, 2024 at 12:03?PM Namhyung Kim <namhyung at kernel.org> wrote:
>
> On Wed, Oct 16, 2024 at 05:25:10PM -0700, Ian Rogers wrote:
> > Move arch/csky/util/dwarf-regs.c to util/dwarf-regs-csky.c and compile
> > in unconditionally. To avoid get_arch_regstr being duplicated, rename
> > to get_csky_regstr and add to get_dwarf_regstr switch.
> >
> > Update #ifdefs to allow ABI V1 and V2 tables at the same
> > time. Determine the table from the ELF flags.
> >
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >  tools/perf/arch/csky/util/Build               |  1 -
> >  tools/perf/util/Build                         |  1 +
> >  .../dwarf-regs.c => util/dwarf-regs-csky.c}   | 19 ++++++++++---------
> >  tools/perf/util/dwarf-regs.c                  | 11 +++++++----
> >  tools/perf/util/include/dwarf-regs.h          |  2 ++
> >  5 files changed, 20 insertions(+), 14 deletions(-)
> >  rename tools/perf/{arch/csky/util/dwarf-regs.c => util/dwarf-regs-csky.c} (74%)
> >
> > diff --git a/tools/perf/arch/csky/util/Build b/tools/perf/arch/csky/util/Build
> > index 1325310cab6a..5e6ea82c4202 100644
> > --- a/tools/perf/arch/csky/util/Build
> > +++ b/tools/perf/arch/csky/util/Build
> > @@ -1,4 +1,3 @@
> >  perf-util-y += perf_regs.o
> >
> > -perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
> >  perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> > diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> > index 4c615611b9d7..99ae4e2802b8 100644
> > --- a/tools/perf/util/Build
> > +++ b/tools/perf/util/Build
> > @@ -203,6 +203,7 @@ endif
> >  perf-util-$(CONFIG_LIBDW) += probe-finder.o
> >  perf-util-$(CONFIG_LIBDW) += dwarf-aux.o
> >  perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
> > +perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o
> >  perf-util-$(CONFIG_LIBDW) += dwarf-regs-x86.o
> >  perf-util-$(CONFIG_LIBDW) += debuginfo.o
> >  perf-util-$(CONFIG_LIBDW) += annotate-data.o
> > diff --git a/tools/perf/arch/csky/util/dwarf-regs.c b/tools/perf/util/dwarf-regs-csky.c
> > similarity index 74%
> > rename from tools/perf/arch/csky/util/dwarf-regs.c
> > rename to tools/perf/util/dwarf-regs-csky.c
> > index ca86ecaeacbb..d38ef1f07f3e 100644
> > --- a/tools/perf/arch/csky/util/dwarf-regs.c
> > +++ b/tools/perf/util/dwarf-regs-csky.c
> > @@ -5,9 +5,8 @@
> >  #include <stddef.h>
> >  #include <dwarf-regs.h>
> >
> > -#if defined(__CSKYABIV2__)
> > -#define CSKY_MAX_REGS 73
> > -const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
> > +#define CSKY_ABIV2_MAX_REGS 73
> > +const char *csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = {
> >       /* r0 ~ r8 */
> >       "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", "%regs2", "%regs3",
> >       /* r9 ~ r15 */
> > @@ -26,9 +25,9 @@ const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
> >       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> >       "%epc",
> >  };
> > -#else
> > -#define CSKY_MAX_REGS 57
> > -const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
> > +
> > +#define CSKY_ABIV1_MAX_REGS 57

Definition of CSKY_ABIV1_MAX_REGS.

> > +const char *csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = {
> >       /* r0 ~ r8 */
> >       "%sp", "%regs9", "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1",
> >       /* r9 ~ r15 */
> > @@ -41,9 +40,11 @@ const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
> >       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> >       "%epc",
> >  };
> > -#endif
> >
> > -const char *get_arch_regstr(unsigned int n)
> > +const char *get_csky_regstr(unsigned int n, unsigned int flags)
> >  {
> > -     return (n < CSKY_MAX_REGS) ? csky_dwarf_regs_table[n] : NULL;
> > +     if (flags & EF_CSKY_ABIV2)
>
> Hmm.. you need it here as well.

These constants are part of the dwarf-regs-csky.c file and not elf.h.

> > +             return (n < CSKY_ABIV2_MAX_REGS) ? csky_dwarf_regs_table_abiv2[n] : NULL;
> > +
> > +     return (n < CSKY_ABIV1_MAX_REGS) ? csky_dwarf_regs_table_abiv1[n] : NULL;
> >  }
> > diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
> > index fd21f9e90e40..9a76f83af62c 100644
> > --- a/tools/perf/util/dwarf-regs.c
> > +++ b/tools/perf/util/dwarf-regs.c
> > @@ -29,17 +29,18 @@
> >  #define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
> >
> >  /* Return architecture dependent register string (for kprobe-tracer) */
> > -const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
> > -                          unsigned int flags __maybe_unused)
> > +const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags)
> >  {
> > -#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM
> > +#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
> > +    || EM_HOST == EM_CSKY
>
> And here too.  It seems you also need a rebase.
>
> At this point, I'm giving up.  Can you please refresh the series with
> a fix?

Sure I'll rebase and add ifndef+defines to dwarf-regs.h, I see we have
these currently for EM_AARCH64 and EM_LOONGARCH there.

Thanks,
Ian


From charlie at rivosinc.com  Fri Nov  8 15:16:19 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Fri, 8 Nov 2024 15:16:19 -0800
Subject: [PATCH for-next] riscv: Fix default misaligned access trap
In-Reply-To: <CAJFTR8Sas83NkRPSuSdbb3qtDNra=cbinPoBmpyt4_ic8R5LQg@mail.gmail.com>
References: <20241107-fix_handle_misaligned_load-v1-1-07d7852c9991@rivosinc.com>
 <CAJFTR8RBcoqYmWNmNe_ZixO3bv2aP-wGCbX7ieorXYxxMAa7BA@mail.gmail.com>
 <CAJFTR8Sas83NkRPSuSdbb3qtDNra=cbinPoBmpyt4_ic8R5LQg@mail.gmail.com>
Message-ID: <Zy6bw8Fnkxl2Q78K@ghost>

On Fri, Nov 08, 2024 at 05:12:04PM -0500, Jesse T wrote:
> On Fri, Nov 8, 2024 at 5:09?PM Jesse T <mr.bossman075 at gmail.com> wrote:
> >
> > On Thu, Nov 7, 2024 at 5:38?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
> > >
> > > Commit d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses
> > > supported") removed the default handlers for handle_misaligned_load()
> > > and handle_misaligned_store(). When the kernel is compiled without
> > > RISCV_SCALAR_MISALIGNED
> > Technically CONFIG_RISCV_MISALIGNED.
> > I apparently changed `+obj-y += traps_misaligned.o` to
> > `+obj-$(CONFIG_RISCV_MISALIGNED) += traps_misaligned.o`
> > in V2 and didn't change that check back oops sorry.
> >
> > > , these handlers are never defined, causing
> > > compilation errors.
> > >
> > > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > Signed-off-by: Jesse Taube <mr.bossman075 at gmail.com>
> >
> > > Fixes: d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses supported")
> > > ---
> > >  arch/riscv/include/asm/entry-common.h | 12 ++++++++++++
> > >  1 file changed, 12 insertions(+)
> > >
> > > diff --git a/arch/riscv/include/asm/entry-common.h b/arch/riscv/include/asm/entry-common.h
> > > index 7b32d2b08bb6..c2808561df81 100644
> > > --- a/arch/riscv/include/asm/entry-common.h
> > > +++ b/arch/riscv/include/asm/entry-common.h
> > > @@ -25,7 +25,19 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
> > >  void handle_page_fault(struct pt_regs *regs);
> > >  void handle_break(struct pt_regs *regs);
> > >
> > > +#ifdef CONFIG_RISCV_SCALAR_MISALIGNED
> 
> Meant to say to change this to CONFIG_RISCV_MISALIGNED.
> As they are defined when CONFIG_RISCV_SCALAR_MISALIGNED is false
> and CONFIG_RISCV_VECTOE_MISALIGNED is true. they are only not defined when
> CONFIG_RISCV_SCALAR_MISALIGNED is false.

Oh yes, thank you!

- Charlie

> 
> > >  int handle_misaligned_load(struct pt_regs *regs);
> > >  int handle_misaligned_store(struct pt_regs *regs);
> > > +#else
> > > +static inline int handle_misaligned_load(struct pt_regs *regs)
> > > +{
> > > +       return -1;
> > > +}
> > > +
> > > +static inline int handle_misaligned_store(struct pt_regs *regs)
> > > +{
> > > +       return -1;
> > > +}
> > > +#endif
> > >
> > >  #endif /* _ASM_RISCV_ENTRY_COMMON_H */
> > >
> > > ---
> > > base-commit: 74741a050b79d31d8d2eeee12c77736596d0a6b2
> > > change-id: 20241107-fix_handle_misaligned_load-8be86cb0806e
> > > --
> > > - Charlie
> > >


From irogers at google.com  Fri Nov  8 15:45:45 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:45 -0800
Subject: [PATCH v4 00/20] Remove PERF_HAVE_DWARF_REGS
Message-ID: <20241108234606.429459-1-irogers@google.com>

These changes were originally on top of:
https://lore.kernel.org/lkml/20241017001354.56973-1-irogers at google.com/

Prior to these patches PERF_HAVE_DWARF_REGS indicated the presence of
dwarf-regs.c in the arch directory. dwarf-regs.c provided upto 4
functions:

1) regs_query_register_offset would translate a register name into a
pt_regs offset and was used by BPF prologues. BPF prologues existed
for BPF events and support for these was removed many releases ago.
This code was dead and could be removed.

2) get_arch_regstr duplicated get_dwarf_regstr and so it could be
removed.  The case for csky was a little more complicated as the ABI
controlled the string. The callers of get_dwarf_regstr were updated to
also pass the ELF flags so that on csky the ABI appropriate table
could be used. As the argument is only used on csky this a no-op for
everything else.

3) get_arch_regnum translated a register name back to a dwarf number
and only existed on x86 where "al", "ax", "eax" and "rax" could all
mean register 0. This code was moved to util with similar
machine/flags logic to get_arch_regstr and for consistency with it.

4) get_powerpc_regs a PowerPC specific function used by annotate that
should really be in util.

2 and 3 required the wiring through of the ELF machine and flags in
callers to get_dwarf_regstr and get_dwarf_regnum. When these values
weren't dependent on an ELF file a new EM_HOST and EF_HOST were added
to give the host ELF machine and flags. These 2 #defines got rid of
the existing separate arch files and #ifdefs.

v4: Add CSky defines to dwarf-regs.h Add reviewed-by tags from Masami.
v3: These files were separated from the rest of the v2 libdw clean up
    in:
https://lore.kernel.org/lkml/CAP-5=fVZH3L-6y_sxLwSmT8WyMXDMFnuqUksNULdQYJCPNBFYw at mail.gmail.com/

Ian Rogers (20):
  perf bpf-prologue: Remove unused file
  perf dwarf-regs: Remove PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
  perf dwarf-regs: Add EM_HOST and EF_HOST defines
  perf disasm: Add e_machine/e_flags to struct arch
  perf dwarf-regs: Pass accurate disassembly machine to get_dwarf_regnum
  perf dwarf-regs: Pass ELF flags to get_dwarf_regstr
  perf dwarf-regs: Move x86 dwarf-regs out of arch
  perf arm64: Remove dwarf-regs.c
  perf arm: Remove dwarf-regs.c
  perf dwarf-regs: Move csky dwarf-regs out of arch
  perf loongarch: Remove dwarf-regs.c
  perf mips: Remove dwarf-regs.c
  perf dwarf-regs: Move powerpc dwarf-regs out of arch
  perf riscv: Remove dwarf-regs.c and add dwarf-regs-table.h
  perf s390: Remove dwarf-regs.c
  perf sh: Remove dwarf-regs.c
  perf sparc: Remove dwarf-regs.c
  perf xtensa: Remove dwarf-regs.c
  perf dwarf-regs: Remove get_arch_regstr code
  perf build: Remove PERF_HAVE_DWARF_REGS

 tools/perf/Makefile.config                    |  17 +-
 tools/perf/arch/arc/annotate/instructions.c   |   2 +
 tools/perf/arch/arm/Makefile                  |   3 -
 tools/perf/arch/arm/annotate/instructions.c   |   2 +
 tools/perf/arch/arm/util/Build                |   2 -
 tools/perf/arch/arm/util/dwarf-regs.c         |  61 -------
 tools/perf/arch/arm64/Makefile                |   4 -
 tools/perf/arch/arm64/annotate/instructions.c |   2 +
 tools/perf/arch/arm64/util/Build              |   1 -
 tools/perf/arch/arm64/util/dwarf-regs.c       |  92 -----------
 tools/perf/arch/csky/Makefile                 |   4 -
 tools/perf/arch/csky/annotate/instructions.c  |   7 +-
 tools/perf/arch/csky/util/Build               |   1 -
 tools/perf/arch/loongarch/Makefile            |   4 -
 .../arch/loongarch/annotate/instructions.c    |   2 +
 tools/perf/arch/loongarch/util/Build          |   1 -
 tools/perf/arch/loongarch/util/dwarf-regs.c   |  44 -----
 tools/perf/arch/mips/Makefile                 |   4 -
 tools/perf/arch/mips/annotate/instructions.c  |   2 +
 tools/perf/arch/mips/util/Build               |   1 -
 tools/perf/arch/mips/util/dwarf-regs.c        |  38 -----
 tools/perf/arch/powerpc/Makefile              |   5 -
 .../perf/arch/powerpc/annotate/instructions.c |   2 +
 tools/perf/arch/powerpc/util/Build            |   1 -
 tools/perf/arch/powerpc/util/dwarf-regs.c     | 153 ------------------
 tools/perf/arch/riscv/Makefile                |   5 +-
 .../arch/riscv/include/dwarf-regs-table.h     |  42 +++++
 tools/perf/arch/riscv/util/Build              |   1 -
 tools/perf/arch/riscv/util/dwarf-regs.c       |  72 ---------
 .../perf/arch/riscv64/annotate/instructions.c |   2 +
 tools/perf/arch/s390/Makefile                 |   4 -
 tools/perf/arch/s390/annotate/instructions.c  |   2 +
 tools/perf/arch/s390/util/Build               |   1 -
 tools/perf/arch/s390/util/dwarf-regs.c        |  43 -----
 tools/perf/arch/sh/Build                      |   1 -
 tools/perf/arch/sh/Makefile                   |   4 -
 tools/perf/arch/sh/util/Build                 |   1 -
 tools/perf/arch/sh/util/dwarf-regs.c          |  41 -----
 tools/perf/arch/sparc/Build                   |   1 -
 tools/perf/arch/sparc/Makefile                |   4 -
 tools/perf/arch/sparc/annotate/instructions.c |   2 +
 tools/perf/arch/sparc/util/Build              |   1 -
 tools/perf/arch/sparc/util/dwarf-regs.c       |  39 -----
 tools/perf/arch/x86/Makefile                  |   4 -
 tools/perf/arch/x86/annotate/instructions.c   |   3 +-
 tools/perf/arch/x86/util/Build                |   3 -
 tools/perf/arch/x86/util/dwarf-regs.c         | 153 ------------------
 tools/perf/arch/xtensa/Build                  |   1 -
 tools/perf/arch/xtensa/Makefile               |   4 -
 tools/perf/arch/xtensa/util/Build             |   1 -
 tools/perf/arch/xtensa/util/dwarf-regs.c      |  21 ---
 tools/perf/util/Build                         |   3 +
 tools/perf/util/annotate.c                    |   6 +-
 tools/perf/util/bpf-prologue.h                |  37 -----
 tools/perf/util/disasm.c                      |   1 +
 tools/perf/util/disasm.h                      |   4 +
 .../dwarf-regs.c => util/dwarf-regs-csky.c}   |  19 +--
 tools/perf/util/dwarf-regs-powerpc.c          |  61 +++++++
 tools/perf/util/dwarf-regs-x86.c              |  50 ++++++
 tools/perf/util/dwarf-regs.c                  |  38 +++--
 tools/perf/util/include/dwarf-regs.h          | 120 +++++++++++---
 tools/perf/util/probe-finder.c                |  13 +-
 tools/perf/util/probe-finder.h                |   3 +-
 63 files changed, 339 insertions(+), 927 deletions(-)
 delete mode 100644 tools/perf/arch/arm/util/dwarf-regs.c
 delete mode 100644 tools/perf/arch/arm64/util/dwarf-regs.c
 delete mode 100644 tools/perf/arch/csky/Makefile
 delete mode 100644 tools/perf/arch/loongarch/util/dwarf-regs.c
 delete mode 100644 tools/perf/arch/mips/util/dwarf-regs.c
 delete mode 100644 tools/perf/arch/powerpc/util/dwarf-regs.c
 create mode 100644 tools/perf/arch/riscv/include/dwarf-regs-table.h
 delete mode 100644 tools/perf/arch/riscv/util/dwarf-regs.c
 delete mode 100644 tools/perf/arch/s390/util/dwarf-regs.c
 delete mode 100644 tools/perf/arch/sh/Build
 delete mode 100644 tools/perf/arch/sh/Makefile
 delete mode 100644 tools/perf/arch/sh/util/Build
 delete mode 100644 tools/perf/arch/sh/util/dwarf-regs.c
 delete mode 100644 tools/perf/arch/sparc/Build
 delete mode 100644 tools/perf/arch/sparc/util/Build
 delete mode 100644 tools/perf/arch/sparc/util/dwarf-regs.c
 delete mode 100644 tools/perf/arch/x86/util/dwarf-regs.c
 delete mode 100644 tools/perf/arch/xtensa/Build
 delete mode 100644 tools/perf/arch/xtensa/Makefile
 delete mode 100644 tools/perf/arch/xtensa/util/Build
 delete mode 100644 tools/perf/arch/xtensa/util/dwarf-regs.c
 delete mode 100644 tools/perf/util/bpf-prologue.h
 rename tools/perf/{arch/csky/util/dwarf-regs.c => util/dwarf-regs-csky.c} (74%)
 create mode 100644 tools/perf/util/dwarf-regs-powerpc.c
 create mode 100644 tools/perf/util/dwarf-regs-x86.c

-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:46 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:46 -0800
Subject: [PATCH v4 01/20] perf bpf-prologue: Remove unused file
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-2-irogers@google.com>

Commit 4a73fca22692 ("perf bpf-prologue: Remove unused file") missed
cleaning up the header file. The code was unnecessary as Commit
3d6dfae88917 ("perf parse-events: Remove BPF event support") removed
building bpf-prologue.c.

Fixes: 4a73fca22692 ("perf bpf-prologue: Remove unused file")
Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/bpf-prologue.h | 37 ----------------------------------
 1 file changed, 37 deletions(-)
 delete mode 100644 tools/perf/util/bpf-prologue.h

diff --git a/tools/perf/util/bpf-prologue.h b/tools/perf/util/bpf-prologue.h
deleted file mode 100644
index 66dcf751ef65..000000000000
--- a/tools/perf/util/bpf-prologue.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2015, He Kuang <hekuang at huawei.com>
- * Copyright (C) 2015, Huawei Inc.
- */
-#ifndef __BPF_PROLOGUE_H
-#define __BPF_PROLOGUE_H
-
-struct probe_trace_arg;
-struct bpf_insn;
-
-#define BPF_PROLOGUE_MAX_ARGS 3
-#define BPF_PROLOGUE_START_ARG_REG BPF_REG_3
-#define BPF_PROLOGUE_FETCH_RESULT_REG BPF_REG_2
-
-#ifdef HAVE_BPF_PROLOGUE
-int bpf__gen_prologue(struct probe_trace_arg *args, int nargs,
-		      struct bpf_insn *new_prog, size_t *new_cnt,
-		      size_t cnt_space);
-#else
-#include <linux/compiler.h>
-#include <errno.h>
-
-static inline int
-bpf__gen_prologue(struct probe_trace_arg *args __maybe_unused,
-		  int nargs __maybe_unused,
-		  struct bpf_insn *new_prog __maybe_unused,
-		  size_t *new_cnt,
-		  size_t cnt_space __maybe_unused)
-{
-	if (!new_cnt)
-		return -EINVAL;
-	*new_cnt = 0;
-	return -ENOTSUP;
-}
-#endif
-#endif /* __BPF_PROLOGUE_H */
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:47 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:47 -0800
Subject: [PATCH v4 02/20] perf dwarf-regs: Remove PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-3-irogers@google.com>

PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET was used for BPF prologue
support which was removed in Commit 3d6dfae88917 ("perf parse-events:
Remove BPF event support"). The code is no longer used so remove.

Remove the offset from various dwarf-regs.c tables and the dependence
on ptrace.h. Rename structs starting pt_ as the ptrace derived offset is
now removed.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/Makefile.config                  |   4 -
 tools/perf/arch/arm64/Makefile              |   1 -
 tools/perf/arch/arm64/util/dwarf-regs.c     |  20 +---
 tools/perf/arch/loongarch/Makefile          |   1 -
 tools/perf/arch/loongarch/util/dwarf-regs.c |  10 --
 tools/perf/arch/powerpc/Makefile            |   1 -
 tools/perf/arch/powerpc/util/dwarf-regs.c   |  26 ++---
 tools/perf/arch/riscv/Makefile              |   1 -
 tools/perf/arch/riscv/util/dwarf-regs.c     |  14 +--
 tools/perf/arch/s390/Makefile               |   1 -
 tools/perf/arch/s390/util/dwarf-regs.c      |  27 -----
 tools/perf/arch/x86/Makefile                |   1 -
 tools/perf/arch/x86/util/dwarf-regs.c       | 109 +++-----------------
 tools/perf/util/include/dwarf-regs.h        |   8 --
 14 files changed, 27 insertions(+), 197 deletions(-)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 80bf06e828f0..52a216df9e2a 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -211,10 +211,6 @@ FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arc
 # include ARCH specific config
 -include $(src-perf)/arch/$(SRCARCH)/Makefile
 
-ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
-  CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
-endif
-
 include $(srctree)/tools/scripts/utilities.mak
 
 ifeq ($(call get-executable,$(FLEX)),)
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
index 8a5ffbfe809f..ca2e35961287 100644
--- a/tools/perf/arch/arm64/Makefile
+++ b/tools/perf/arch/arm64/Makefile
@@ -3,7 +3,6 @@ ifndef NO_LIBDW
 PERF_HAVE_DWARF_REGS := 1
 endif
 PERF_HAVE_JITDUMP := 1
-PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 HAVE_KVM_STAT_SUPPORT := 1
 
 #
diff --git a/tools/perf/arch/arm64/util/dwarf-regs.c b/tools/perf/arch/arm64/util/dwarf-regs.c
index 917b97d7c5d3..343a62fa4199 100644
--- a/tools/perf/arch/arm64/util/dwarf-regs.c
+++ b/tools/perf/arch/arm64/util/dwarf-regs.c
@@ -9,10 +9,9 @@
 #include <stddef.h>
 #include <string.h>
 #include <dwarf-regs.h>
-#include <linux/ptrace.h> /* for struct user_pt_regs */
 #include <linux/stringify.h>
 
-struct pt_regs_dwarfnum {
+struct regs_dwarfnum {
 	const char *name;
 	unsigned int dwarfnum;
 };
@@ -21,14 +20,12 @@ struct pt_regs_dwarfnum {
 #define GPR_DWARFNUM_NAME(num) \
 	{.name = __stringify(%x##num), .dwarfnum = num}
 #define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
-#define DWARFNUM2OFFSET(index) \
-	(index * sizeof((struct user_pt_regs *)0)->regs[0])
 
 /*
  * Reference:
  * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0057b/IHI0057B_aadwarf64.pdf
  */
-static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
+static const struct regs_dwarfnum regdwarfnum_table[] = {
 	GPR_DWARFNUM_NAME(0),
 	GPR_DWARFNUM_NAME(1),
 	GPR_DWARFNUM_NAME(2),
@@ -74,19 +71,10 @@ static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
  */
 const char *get_arch_regstr(unsigned int n)
 {
-	const struct pt_regs_dwarfnum *roff;
+	const struct regs_dwarfnum *roff;
+
 	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
 		if (roff->dwarfnum == n)
 			return roff->name;
 	return NULL;
 }
-
-int regs_query_register_offset(const char *name)
-{
-	const struct pt_regs_dwarfnum *roff;
-
-	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
-		if (!strcmp(roff->name, name))
-			return DWARFNUM2OFFSET(roff->dwarfnum);
-	return -EINVAL;
-}
diff --git a/tools/perf/arch/loongarch/Makefile b/tools/perf/arch/loongarch/Makefile
index 1cc5eb01f32b..79b432744296 100644
--- a/tools/perf/arch/loongarch/Makefile
+++ b/tools/perf/arch/loongarch/Makefile
@@ -2,7 +2,6 @@
 ifndef NO_LIBDW
 PERF_HAVE_DWARF_REGS := 1
 endif
-PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
 
diff --git a/tools/perf/arch/loongarch/util/dwarf-regs.c b/tools/perf/arch/loongarch/util/dwarf-regs.c
index 0f6ebc387463..bee08fdcf2fd 100644
--- a/tools/perf/arch/loongarch/util/dwarf-regs.c
+++ b/tools/perf/arch/loongarch/util/dwarf-regs.c
@@ -32,13 +32,3 @@ const char *get_arch_regstr(unsigned int n)
 	n %= 32;
 	return loongarch_gpr_table[n].name;
 }
-
-int regs_query_register_offset(const char *name)
-{
-	const struct pt_regs_dwarfnum *roff;
-
-	for (roff = loongarch_gpr_table; roff->name != NULL; roff++)
-		if (!strcmp(roff->name, name))
-			return roff->dwarfnum;
-	return -EINVAL;
-}
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index 7672d555f6cd..ae05727835d8 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -4,7 +4,6 @@ PERF_HAVE_DWARF_REGS := 1
 endif
 
 HAVE_KVM_STAT_SUPPORT := 1
-PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 PERF_HAVE_JITDUMP := 1
 
 #
diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c
index 104c7ae5c433..23846c59a522 100644
--- a/tools/perf/arch/powerpc/util/dwarf-regs.c
+++ b/tools/perf/arch/powerpc/util/dwarf-regs.c
@@ -9,29 +9,25 @@
 #include <errno.h>
 #include <string.h>
 #include <dwarf-regs.h>
-#include <linux/ptrace.h>
 #include <linux/kernel.h>
 #include <linux/stringify.h>
 
-struct pt_regs_dwarfnum {
+struct regs_dwarfnum {
 	const char *name;
 	unsigned int dwarfnum;
-	unsigned int ptregs_offset;
 };
 
 #define REG_DWARFNUM_NAME(r, num)					\
-		{.name = __stringify(%)__stringify(r), .dwarfnum = num,			\
-		.ptregs_offset = offsetof(struct pt_regs, r)}
+	{.name = __stringify(%)__stringify(r), .dwarfnum = num}
 #define GPR_DWARFNUM_NAME(num)						\
-		{.name = __stringify(%gpr##num), .dwarfnum = num,		\
-		.ptregs_offset = offsetof(struct pt_regs, gpr[num])}
-#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0, .ptregs_offset = 0}
+	{.name = __stringify(%gpr##num), .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
 
 /*
  * Reference:
  * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
  */
-static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
+static const struct regs_dwarfnum regdwarfnum_table[] = {
 	GPR_DWARFNUM_NAME(0),
 	GPR_DWARFNUM_NAME(1),
 	GPR_DWARFNUM_NAME(2),
@@ -83,22 +79,14 @@ static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
  */
 const char *get_arch_regstr(unsigned int n)
 {
-	const struct pt_regs_dwarfnum *roff;
+	const struct regs_dwarfnum *roff;
+
 	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
 		if (roff->dwarfnum == n)
 			return roff->name;
 	return NULL;
 }
 
-int regs_query_register_offset(const char *name)
-{
-	const struct pt_regs_dwarfnum *roff;
-	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
-		if (!strcmp(roff->name, name))
-			return roff->ptregs_offset;
-	return -EINVAL;
-}
-
 #define PPC_OP(op)	(((op) >> 26) & 0x3F)
 #define PPC_RA(a)	(((a) >> 16) & 0x1f)
 #define PPC_RT(t)	(((t) >> 21) & 0x1f)
diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
index 00573af87a68..d83e0f32f3a8 100644
--- a/tools/perf/arch/riscv/Makefile
+++ b/tools/perf/arch/riscv/Makefile
@@ -1,7 +1,6 @@
 ifndef NO_LIBDW
 PERF_HAVE_DWARF_REGS := 1
 endif
-PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
 
diff --git a/tools/perf/arch/riscv/util/dwarf-regs.c b/tools/perf/arch/riscv/util/dwarf-regs.c
index cd0504c02e2e..a9c4402ae57e 100644
--- a/tools/perf/arch/riscv/util/dwarf-regs.c
+++ b/tools/perf/arch/riscv/util/dwarf-regs.c
@@ -9,7 +9,7 @@
 #include <string.h> /* for strcmp */
 #include <dwarf-regs.h>
 
-struct pt_regs_dwarfnum {
+struct regs_dwarfnum {
 	const char *name;
 	unsigned int dwarfnum;
 };
@@ -17,7 +17,7 @@ struct pt_regs_dwarfnum {
 #define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
 #define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
 
-struct pt_regs_dwarfnum riscv_dwarf_regs_table[] = {
+struct regs_dwarfnum riscv_dwarf_regs_table[] = {
 	REG_DWARFNUM_NAME("%zero", 0),
 	REG_DWARFNUM_NAME("%ra", 1),
 	REG_DWARFNUM_NAME("%sp", 2),
@@ -60,13 +60,3 @@ const char *get_arch_regstr(unsigned int n)
 {
 	return (n < RISCV_MAX_REGS) ? riscv_dwarf_regs_table[n].name : NULL;
 }
-
-int regs_query_register_offset(const char *name)
-{
-	const struct pt_regs_dwarfnum *roff;
-
-	for (roff = riscv_dwarf_regs_table; roff->name; roff++)
-		if (!strcmp(roff->name, name))
-			return roff->dwarfnum;
-	return -EINVAL;
-}
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
index 3f66e2ede3f7..58e79f5b67a4 100644
--- a/tools/perf/arch/s390/Makefile
+++ b/tools/perf/arch/s390/Makefile
@@ -3,7 +3,6 @@ ifndef NO_LIBDW
 PERF_HAVE_DWARF_REGS := 1
 endif
 HAVE_KVM_STAT_SUPPORT := 1
-PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 PERF_HAVE_JITDUMP := 1
 
 #
diff --git a/tools/perf/arch/s390/util/dwarf-regs.c b/tools/perf/arch/s390/util/dwarf-regs.c
index dfddb3099bfa..5bcf3192623a 100644
--- a/tools/perf/arch/s390/util/dwarf-regs.c
+++ b/tools/perf/arch/s390/util/dwarf-regs.c
@@ -7,37 +7,10 @@
  *
  */
 
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
 #include <linux/kernel.h>
-#include <asm/ptrace.h>
-#include <string.h>
-#include <dwarf-regs.h>
 #include "dwarf-regs-table.h"
 
 const char *get_arch_regstr(unsigned int n)
 {
 	return (n >= ARRAY_SIZE(s390_dwarf_regs)) ? NULL : s390_dwarf_regs[n];
 }
-
-/*
- * Convert the register name into an offset to struct pt_regs (kernel).
- * This is required by the BPF prologue generator.  The BPF
- * program is called in the BPF overflow handler in the perf
- * core.
- */
-int regs_query_register_offset(const char *name)
-{
-	unsigned long gpr;
-
-	if (!name || strncmp(name, "%r", 2))
-		return -EINVAL;
-
-	errno = 0;
-	gpr = strtoul(name + 2, NULL, 10);
-	if (errno || gpr >= 16)
-		return -EINVAL;
-
-	return offsetof(user_pt_regs, gprs) + 8 * gpr;
-}
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index 9aa58acb5564..51cf267f4d85 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -3,7 +3,6 @@ ifndef NO_LIBDW
 PERF_HAVE_DWARF_REGS := 1
 endif
 HAVE_KVM_STAT_SUPPORT := 1
-PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 PERF_HAVE_JITDUMP := 1
 
 ###
diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
index 399c4a0a29d8..530905118cd4 100644
--- a/tools/perf/arch/x86/util/dwarf-regs.c
+++ b/tools/perf/arch/x86/util/dwarf-regs.c
@@ -6,112 +6,31 @@
  * Written by Masami Hiramatsu <mhiramat at redhat.com>
  */
 
-#include <stddef.h>
 #include <errno.h> /* for EINVAL */
 #include <string.h> /* for strcmp */
-#include <linux/ptrace.h> /* for struct pt_regs */
-#include <linux/kernel.h> /* for offsetof */
+#include <linux/kernel.h> /* for ARRAY_SIZE */
 #include <dwarf-regs.h>
 
-/*
- * See arch/x86/kernel/ptrace.c.
- * Different from it:
- *
- *  - Since struct pt_regs is defined differently for user and kernel,
- *    but we want to use 'ax, bx' instead of 'rax, rbx' (which is struct
- *    field name of user's pt_regs), we make REG_OFFSET_NAME to accept
- *    both string name and reg field name.
- *
- *  - Since accessing x86_32's pt_regs from x86_64 building is difficult
- *    and vise versa, we simply fill offset with -1, so
- *    get_arch_regstr() still works but regs_query_register_offset()
- *    returns error.
- *    The only inconvenience caused by it now is that we are not allowed
- *    to generate BPF prologue for a x86_64 kernel if perf is built for
- *    x86_32. This is really a rare usecase.
- *
- *  - Order is different from kernel's ptrace.c for get_arch_regstr(). Use
- *    the order defined by dwarf.
- */
+#define DEFINE_DWARF_REGSTR_TABLE 1
+#include "dwarf-regs-table.h"
 
-struct pt_regs_offset {
-	const char *name;
-	int offset;
-};
-
-#define REG_OFFSET_END {.name = NULL, .offset = 0}
-
-#ifdef __x86_64__
-# define REG_OFFSET_NAME_64(n, r) {.name = n, .offset = offsetof(struct pt_regs, r)}
-# define REG_OFFSET_NAME_32(n, r) {.name = n, .offset = -1}
+/* Return architecture dependent register string (for kprobe-tracer) */
+const char *get_arch_regstr(unsigned int n)
+{
+#if defined(__i386__)
+	size_t len = ARRAY_SIZE(x86_32_regstr_tbl);
 #else
-# define REG_OFFSET_NAME_64(n, r) {.name = n, .offset = -1}
-# define REG_OFFSET_NAME_32(n, r) {.name = n, .offset = offsetof(struct pt_regs, r)}
+	size_t len = ARRAY_SIZE(x86_64_regstr_tbl);
 #endif
 
-/* TODO: switching by dwarf address size */
-#ifndef __x86_64__
-static const struct pt_regs_offset x86_32_regoffset_table[] = {
-	REG_OFFSET_NAME_32("%ax",	eax),
-	REG_OFFSET_NAME_32("%cx",	ecx),
-	REG_OFFSET_NAME_32("%dx",	edx),
-	REG_OFFSET_NAME_32("%bx",	ebx),
-	REG_OFFSET_NAME_32("$stack",	esp),	/* Stack address instead of %sp */
-	REG_OFFSET_NAME_32("%bp",	ebp),
-	REG_OFFSET_NAME_32("%si",	esi),
-	REG_OFFSET_NAME_32("%di",	edi),
-	REG_OFFSET_END,
-};
+	if (n >= len)
+		return NULL;
 
-#define regoffset_table x86_32_regoffset_table
+#if defined(__i386__)
+	return x86_32_regstr_tbl[n];
 #else
-static const struct pt_regs_offset x86_64_regoffset_table[] = {
-	REG_OFFSET_NAME_64("%ax",	rax),
-	REG_OFFSET_NAME_64("%dx",	rdx),
-	REG_OFFSET_NAME_64("%cx",	rcx),
-	REG_OFFSET_NAME_64("%bx",	rbx),
-	REG_OFFSET_NAME_64("%si",	rsi),
-	REG_OFFSET_NAME_64("%di",	rdi),
-	REG_OFFSET_NAME_64("%bp",	rbp),
-	REG_OFFSET_NAME_64("%sp",	rsp),
-	REG_OFFSET_NAME_64("%r8",	r8),
-	REG_OFFSET_NAME_64("%r9",	r9),
-	REG_OFFSET_NAME_64("%r10",	r10),
-	REG_OFFSET_NAME_64("%r11",	r11),
-	REG_OFFSET_NAME_64("%r12",	r12),
-	REG_OFFSET_NAME_64("%r13",	r13),
-	REG_OFFSET_NAME_64("%r14",	r14),
-	REG_OFFSET_NAME_64("%r15",	r15),
-	REG_OFFSET_END,
-};
-
-#define regoffset_table x86_64_regoffset_table
+	return x86_64_regstr_tbl[n];
 #endif
-
-/* Minus 1 for the ending REG_OFFSET_END */
-#define ARCH_MAX_REGS ((sizeof(regoffset_table) / sizeof(regoffset_table[0])) - 1)
-
-/* Return architecture dependent register string (for kprobe-tracer) */
-const char *get_arch_regstr(unsigned int n)
-{
-	return (n < ARCH_MAX_REGS) ? regoffset_table[n].name : NULL;
-}
-
-/* Reuse code from arch/x86/kernel/ptrace.c */
-/**
- * regs_query_register_offset() - query register offset from its name
- * @name:	the name of a register
- *
- * regs_query_register_offset() returns the offset of a register in struct
- * pt_regs from its name. If the name is invalid, this returns -EINVAL;
- */
-int regs_query_register_offset(const char *name)
-{
-	const struct pt_regs_offset *roff;
-	for (roff = regoffset_table; roff->name != NULL; roff++)
-		if (!strcmp(roff->name, name))
-			return roff->offset;
-	return -EINVAL;
 }
 
 struct dwarf_regs_idx {
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 29a7d0546b82..fbdd7307e0c2 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -42,12 +42,4 @@ static inline void get_powerpc_regs(u32 raw_insn __maybe_unused, int is_source _
 void get_powerpc_regs(u32 raw_insn, int is_source, struct annotated_op_loc *op_loc);
 #endif
 
-#ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
-/*
- * Arch should support fetching the offset of a register in pt_regs
- * by its name. See kernel's regs_query_register_offset in
- * arch/xxx/kernel/ptrace.c.
- */
-int regs_query_register_offset(const char *name);
-#endif
 #endif
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:48 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:48 -0800
Subject: [PATCH v4 03/20] perf dwarf-regs: Add EM_HOST and EF_HOST defines
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-4-irogers@google.com>

Computed from the build architecture defines, EM_HOST and EF_HOST give
values that can be used in dwarf register lookup. Place in
dwarf-regs.h so the value can be shared. Move some dwarf-regs.c
constants used for EM_HOST to dwarf-regs.h. Add CSky constants that
may be missing.

In disasm.c add an include of dwarf-regs.h as the included
arch/*/annotate/instructions.c files make use of the constants and we
want the elf.h/dwarf-regs.h dependency to be explicit.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/disasm.c             |  1 +
 tools/perf/util/dwarf-regs.c         |  8 ---
 tools/perf/util/include/dwarf-regs.h | 82 ++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c
index bd98fec903f7..a525b80b934f 100644
--- a/tools/perf/util/disasm.c
+++ b/tools/perf/util/disasm.c
@@ -18,6 +18,7 @@
 #include "disasm.h"
 #include "disasm_bpf.h"
 #include "dso.h"
+#include "dwarf-regs.h"
 #include "env.h"
 #include "evsel.h"
 #include "map.h"
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 5b7f86c0063f..7c01bc4d7e5b 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -13,14 +13,6 @@
 #include <errno.h>
 #include <linux/kernel.h>
 
-#ifndef EM_AARCH64
-#define EM_AARCH64	183  /* ARM 64 bit */
-#endif
-
-#ifndef EM_LOONGARCH
-#define EM_LOONGARCH	258 /* LoongArch */
-#endif
-
 /* Define const char * {arch}_register_tbl[] */
 #define DEFINE_DWARF_REGSTR_TABLE
 #include "../arch/x86/include/dwarf-regs-table.h"
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index fbdd7307e0c2..ce9f10b3282d 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -2,6 +2,88 @@
 #ifndef _PERF_DWARF_REGS_H_
 #define _PERF_DWARF_REGS_H_
 #include "annotate.h"
+#include <elf.h>
+
+#ifndef EM_AARCH64
+#define EM_AARCH64	183  /* ARM 64 bit */
+#endif
+
+#ifndef EM_CSKY
+#define EM_CSKY		252  /* C-SKY */
+#endif
+#ifndef EF_CSKY_ABIV1
+#define EF_CSKY_ABIV1	0X10000000
+#endif
+#ifndef EF_CSKY_ABIV2
+#define EF_CSKY_ABIV2	0X20000000
+#endif
+
+#ifndef EM_LOONGARCH
+#define EM_LOONGARCH	258 /* LoongArch */
+#endif
+
+/* EM_HOST gives the ELF machine for host, EF_HOST gives additional flags. */
+#if defined(__x86_64__)
+  #define EM_HOST EM_X86_64
+#elif defined(__i386__)
+  #define EM_HOST EM_386
+#elif defined(__aarch64__)
+  #define EM_HOST EM_AARCH64
+#elif defined(__arm__)
+  #define EM_HOST EM_ARM
+#elif defined(__alpha__)
+  #define EM_HOST EM_ALPHA
+#elif defined(__arc__)
+  #define EM_HOST EM_ARC
+#elif defined(__AVR__)
+  #define EM_HOST EM_AVR
+#elif defined(__AVR32__)
+  #define EM_HOST EM_AVR32
+#elif defined(__bfin__)
+  #define EM_HOST EM_BLACKFIN
+#elif defined(__csky__)
+  #define EM_HOST EM_CSKY
+  #if defined(__CSKYABIV2__)
+    #define EF_HOST EF_CSKY_ABIV2
+  #else
+    #define EF_HOST EF_CSKY_ABIV1
+  #endif
+#elif defined(__cris__)
+  #define EM_HOST EM_CRIS
+#elif defined(__hppa__) // HP PA-RISC
+  #define EM_HOST EM_PARISC
+#elif defined(__loongarch__)
+  #define EM_HOST EM_LOONGARCH
+#elif defined(__mips__)
+  #define EM_HOST EM_MIPS
+#elif defined(__m32r__)
+  #define EM_HOST EM_M32R
+#elif defined(__microblaze__)
+  #define EM_HOST EM_MICROBLAZE
+#elif defined(__MSP430__)
+  #define EM_HOST EM_MSP430
+#elif defined(__powerpc64__)
+  #define EM_HOST EM_PPC64
+#elif defined(__powerpc__)
+  #define EM_HOST EM_PPC
+#elif defined(__riscv)
+  #define EM_HOST EM_RISCV
+#elif defined(__s390x__)
+  #define EM_HOST EM_S390
+#elif defined(__sh__)
+  #define EM_HOST EM_SH
+#elif defined(__sparc64__) || defined(__sparc__)
+  #define EM_HOST EM_SPARC
+#elif defined(__xtensa__)
+  #define EM_HOST EM_XTENSA
+#else
+  /* Unknown host ELF machine type. */
+  #define EM_HOST EM_NONE
+#endif
+
+#if !defined(EF_HOST)
+  #define EF_HOST 0
+#endif
 
 #define DWARF_REG_PC  0xd3af9c /* random number */
 #define DWARF_REG_FB  0xd3affb /* random number */
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:49 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:49 -0800
Subject: [PATCH v4 04/20] perf disasm: Add e_machine/e_flags to struct arch
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-5-irogers@google.com>

Currently functions like get_dwarf_regnum only work with the host
architecture. Carry the elf machine and flags in struct arch so that
in disassembly these can be used to allow cross platform disassembly.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arc/annotate/instructions.c       | 2 ++
 tools/perf/arch/arm/annotate/instructions.c       | 2 ++
 tools/perf/arch/arm64/annotate/instructions.c     | 2 ++
 tools/perf/arch/csky/annotate/instructions.c      | 7 ++++++-
 tools/perf/arch/loongarch/annotate/instructions.c | 2 ++
 tools/perf/arch/mips/annotate/instructions.c      | 2 ++
 tools/perf/arch/powerpc/annotate/instructions.c   | 2 ++
 tools/perf/arch/riscv64/annotate/instructions.c   | 2 ++
 tools/perf/arch/s390/annotate/instructions.c      | 2 ++
 tools/perf/arch/sparc/annotate/instructions.c     | 2 ++
 tools/perf/arch/x86/annotate/instructions.c       | 3 ++-
 tools/perf/util/disasm.h                          | 4 ++++
 12 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/tools/perf/arch/arc/annotate/instructions.c b/tools/perf/arch/arc/annotate/instructions.c
index 2f00e995c7e3..e5619770a1af 100644
--- a/tools/perf/arch/arc/annotate/instructions.c
+++ b/tools/perf/arch/arc/annotate/instructions.c
@@ -5,5 +5,7 @@ static int arc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
 	arch->initialized = true;
 	arch->objdump.comment_char = ';';
+	arch->e_machine = EM_ARC;
+	arch->e_flags = 0;
 	return 0;
 }
diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c
index 2ff6cedeb9c5..cf91a43362b0 100644
--- a/tools/perf/arch/arm/annotate/instructions.c
+++ b/tools/perf/arch/arm/annotate/instructions.c
@@ -53,6 +53,8 @@ static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 	arch->associate_instruction_ops   = arm__associate_instruction_ops;
 	arch->objdump.comment_char	  = ';';
 	arch->objdump.skip_functions_char = '+';
+	arch->e_machine = EM_ARM;
+	arch->e_flags = 0;
 	return 0;
 
 out_free_call:
diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c
index f86d9f4798bd..d465d093e7eb 100644
--- a/tools/perf/arch/arm64/annotate/instructions.c
+++ b/tools/perf/arch/arm64/annotate/instructions.c
@@ -113,6 +113,8 @@ static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 	arch->associate_instruction_ops   = arm64__associate_instruction_ops;
 	arch->objdump.comment_char	  = '/';
 	arch->objdump.skip_functions_char = '+';
+	arch->e_machine = EM_AARCH64;
+	arch->e_flags = 0;
 	return 0;
 
 out_free_call:
diff --git a/tools/perf/arch/csky/annotate/instructions.c b/tools/perf/arch/csky/annotate/instructions.c
index 5337bfb7d5fc..14270311d215 100644
--- a/tools/perf/arch/csky/annotate/instructions.c
+++ b/tools/perf/arch/csky/annotate/instructions.c
@@ -43,6 +43,11 @@ static int csky__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 	arch->initialized = true;
 	arch->objdump.comment_char = '/';
 	arch->associate_instruction_ops = csky__associate_ins_ops;
-
+	arch->e_machine = EM_CSKY;
+#if defined(__CSKYABIV2__)
+	arch->e_flags = EF_CSKY_ABIV2;
+#else
+	arch->e_flags = EF_CSKY_ABIV1;
+#endif
 	return 0;
 }
diff --git a/tools/perf/arch/loongarch/annotate/instructions.c b/tools/perf/arch/loongarch/annotate/instructions.c
index ab43b1ab51e3..70262d5f1444 100644
--- a/tools/perf/arch/loongarch/annotate/instructions.c
+++ b/tools/perf/arch/loongarch/annotate/instructions.c
@@ -131,6 +131,8 @@ int loongarch__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 		arch->associate_instruction_ops = loongarch__associate_ins_ops;
 		arch->initialized = true;
 		arch->objdump.comment_char = '#';
+		arch->e_machine = EM_LOONGARCH;
+		arch->e_flags = 0;
 	}
 
 	return 0;
diff --git a/tools/perf/arch/mips/annotate/instructions.c b/tools/perf/arch/mips/annotate/instructions.c
index 340993f2a897..b50b46c613d6 100644
--- a/tools/perf/arch/mips/annotate/instructions.c
+++ b/tools/perf/arch/mips/annotate/instructions.c
@@ -40,6 +40,8 @@ int mips__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 		arch->associate_instruction_ops = mips__associate_ins_ops;
 		arch->initialized = true;
 		arch->objdump.comment_char = '#';
+		arch->e_machine = EM_MIPS;
+		arch->e_flags = 0;
 	}
 
 	return 0;
diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/arch/powerpc/annotate/instructions.c
index 54478cf5cccc..ca567cfdcbdb 100644
--- a/tools/perf/arch/powerpc/annotate/instructions.c
+++ b/tools/perf/arch/powerpc/annotate/instructions.c
@@ -309,6 +309,8 @@ static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 		arch->associate_instruction_ops = powerpc__associate_instruction_ops;
 		arch->objdump.comment_char      = '#';
 		annotate_opts.show_asm_raw = true;
+		arch->e_machine = EM_PPC;
+		arch->e_flags = 0;
 	}
 
 	return 0;
diff --git a/tools/perf/arch/riscv64/annotate/instructions.c b/tools/perf/arch/riscv64/annotate/instructions.c
index 869a0eb28953..55cf911633f8 100644
--- a/tools/perf/arch/riscv64/annotate/instructions.c
+++ b/tools/perf/arch/riscv64/annotate/instructions.c
@@ -28,6 +28,8 @@ int riscv64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 		arch->associate_instruction_ops = riscv64__associate_ins_ops;
 		arch->initialized = true;
 		arch->objdump.comment_char = '#';
+		arch->e_machine = EM_RISCV;
+		arch->e_flags = 0;
 	}
 
 	return 0;
diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c
index eeac25cca699..c61193f1e096 100644
--- a/tools/perf/arch/s390/annotate/instructions.c
+++ b/tools/perf/arch/s390/annotate/instructions.c
@@ -166,6 +166,8 @@ static int s390__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 			if (s390__cpuid_parse(arch, cpuid))
 				err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING;
 		}
+		arch->e_machine = EM_S390;
+		arch->e_flags = 0;
 	}
 
 	return err;
diff --git a/tools/perf/arch/sparc/annotate/instructions.c b/tools/perf/arch/sparc/annotate/instructions.c
index 2614c010c235..68c31580ccfc 100644
--- a/tools/perf/arch/sparc/annotate/instructions.c
+++ b/tools/perf/arch/sparc/annotate/instructions.c
@@ -163,6 +163,8 @@ static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 		arch->initialized = true;
 		arch->associate_instruction_ops = sparc__associate_instruction_ops;
 		arch->objdump.comment_char = '#';
+		arch->e_machine = EM_SPARC;
+		arch->e_flags = 0;
 	}
 
 	return 0;
diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/x86/annotate/instructions.c
index c869abe3c31d..ae94b1f0b9cc 100644
--- a/tools/perf/arch/x86/annotate/instructions.c
+++ b/tools/perf/arch/x86/annotate/instructions.c
@@ -202,7 +202,8 @@ static int x86__annotate_init(struct arch *arch, char *cpuid)
 		if (x86__cpuid_parse(arch, cpuid))
 			err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING;
 	}
-
+	arch->e_machine = EM_X86_64;
+	arch->e_flags = 0;
 	arch->initialized = true;
 	return err;
 }
diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h
index 486c269b29ba..c135db2416b5 100644
--- a/tools/perf/util/disasm.h
+++ b/tools/perf/util/disasm.h
@@ -44,6 +44,10 @@ struct arch {
 				struct data_loc_info *dloc, Dwarf_Die *cu_die,
 				struct disasm_line *dl);
 #endif
+	/** @e_machine: ELF machine associated with arch. */
+	unsigned int e_machine;
+	/** @e_flags: Optional ELF flags associated with arch. */
+	unsigned int e_flags;
 };
 
 struct ins {
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:50 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:50 -0800
Subject: [PATCH v4 05/20] perf dwarf-regs: Pass accurate disassembly machine
 to get_dwarf_regnum
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-6-irogers@google.com>

Rather than pass 0/EM_NONE, use the value computed in the disasm
struct arch. Switch the EM_NONE case to EM_HOST, rewriting EM_NONE if
it were passed to get_dwarf_regnum. Pass a flags value as
architectures like csky need the flags to determine the ABI variant.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/annotate.c           | 6 +++---
 tools/perf/util/dwarf-regs.c         | 8 ++++++--
 tools/perf/util/include/dwarf-regs.h | 5 +++--
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 37ce43c4eb8f..b1d98da79be8 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -2292,7 +2292,7 @@ static int extract_reg_offset(struct arch *arch, const char *str,
 	if (regname == NULL)
 		return -1;
 
-	op_loc->reg1 = get_dwarf_regnum(regname, 0);
+	op_loc->reg1 = get_dwarf_regnum(regname, arch->e_machine, arch->e_flags);
 	free(regname);
 
 	/* Get the second register */
@@ -2305,7 +2305,7 @@ static int extract_reg_offset(struct arch *arch, const char *str,
 		if (regname == NULL)
 			return -1;
 
-		op_loc->reg2 = get_dwarf_regnum(regname, 0);
+		op_loc->reg2 = get_dwarf_regnum(regname, arch->e_machine, arch->e_flags);
 		free(regname);
 	}
 	return 0;
@@ -2405,7 +2405,7 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl,
 				return -1;
 
 			if (*s == arch->objdump.register_char)
-				op_loc->reg1 = get_dwarf_regnum(s, 0);
+				op_loc->reg1 = get_dwarf_regnum(s, arch->e_machine, arch->e_flags);
 			else if (*s == arch->objdump.imm_char) {
 				op_loc->offset = strtol(s + 1, &p, 0);
 				if (p && p != s + 1)
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 7c01bc4d7e5b..1321387f6948 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -70,7 +70,7 @@ __weak int get_arch_regnum(const char *name __maybe_unused)
 }
 
 /* Return DWARF register number from architecture register name */
-int get_dwarf_regnum(const char *name, unsigned int machine)
+int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags __maybe_unused)
 {
 	char *regname = strdup(name);
 	int reg = -1;
@@ -84,8 +84,12 @@ int get_dwarf_regnum(const char *name, unsigned int machine)
 	if (p)
 		*p = '\0';
 
+	if (machine == EM_NONE) {
+		/* Generic arch - use host arch */
+		machine = EM_HOST;
+	}
 	switch (machine) {
-	case EM_NONE:	/* Generic arch - use host arch */
+	case EM_HOST:
 		reg = get_arch_regnum(regname);
 		break;
 	default:
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index ce9f10b3282d..3c3a908b9f36 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -103,12 +103,13 @@ int get_arch_regnum(const char *name);
  * name: architecture register name
  * machine: ELF machine signature (EM_*)
  */
-int get_dwarf_regnum(const char *name, unsigned int machine);
+int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags);
 
 #else /* HAVE_LIBDW_SUPPORT */
 
 static inline int get_dwarf_regnum(const char *name __maybe_unused,
-				   unsigned int machine __maybe_unused)
+				   unsigned int machine __maybe_unused,
+				   unsigned int flags __maybe_unused)
 {
 	return -1;
 }
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:51 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:51 -0800
Subject: [PATCH v4 06/20] perf dwarf-regs: Pass ELF flags to get_dwarf_regstr
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-7-irogers@google.com>

Pass a flags value as architectures like csky need the flags to
determine the ABI variant.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/dwarf-regs.c         |  3 ++-
 tools/perf/util/include/dwarf-regs.h | 11 ++++++-----
 tools/perf/util/probe-finder.c       | 13 +++++++------
 tools/perf/util/probe-finder.h       |  3 ++-
 4 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 1321387f6948..86b3ef638fbb 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -29,7 +29,8 @@
 #define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
 
 /* Return architecture dependent register string (for kprobe-tracer) */
-const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
+const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
+			     unsigned int flags __maybe_unused)
 {
 	switch (machine) {
 	case EM_NONE:	/* Generic arch - use host arch */
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 3c3a908b9f36..0ef428d07bcc 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -90,12 +90,13 @@
 
 #ifdef HAVE_LIBDW_SUPPORT
 const char *get_arch_regstr(unsigned int n);
-/*
- * get_dwarf_regstr - Returns ftrace register string from DWARF regnum
- * n: DWARF register number
- * machine: ELF machine signature (EM_*)
+/**
+ * get_dwarf_regstr() - Returns ftrace register string from DWARF regnum.
+ * @n: DWARF register number.
+ * @machine: ELF machine signature (EM_*).
+ * @flags: ELF flags for things like ABI differences.
  */
-const char *get_dwarf_regstr(unsigned int n, unsigned int machine);
+const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags);
 
 int get_arch_regnum(const char *name);
 /*
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index c2ca94e29aca..7f2ee0cb43ca 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -56,7 +56,7 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
  */
 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
 				     Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
-				     unsigned int machine,
+				     const struct probe_finder *pf,
 				     struct probe_trace_arg *tvar)
 {
 	Dwarf_Attribute attr;
@@ -166,7 +166,7 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
 	if (!tvar)
 		return ret2;
 
-	regs = get_dwarf_regstr(regn, machine);
+	regs = get_dwarf_regstr(regn, pf->e_machine, pf->e_flags);
 	if (!regs) {
 		/* This should be a bug in DWARF or this tool */
 		pr_warning("Mapping for the register number %u "
@@ -451,7 +451,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
 		 dwarf_diename(vr_die));
 
 	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
-					&pf->sp_die, pf->machine, pf->tvar);
+					&pf->sp_die, pf, pf->tvar);
 	if (ret == -ENOENT && pf->skip_empty_arg)
 		/* This can be found in other place. skip it */
 		return 0;
@@ -1134,7 +1134,8 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
 	if (gelf_getehdr(elf, &ehdr) == NULL)
 		return -EINVAL;
 
-	pf->machine = ehdr.e_machine;
+	pf->e_machine = ehdr.e_machine;
+	pf->e_flags = ehdr.e_flags;
 
 	do {
 		GElf_Shdr shdr;
@@ -1171,7 +1172,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
 	    (tag == DW_TAG_variable && vf->vars)) {
 		if (convert_variable_location(die_mem, vf->pf->addr,
 					      vf->pf->fb_ops, &pf->sp_die,
-					      pf->machine, NULL) == 0) {
+					      pf, /*tvar=*/NULL) == 0) {
 			vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
 			if (vf->args[vf->nargs].var == NULL) {
 				vf->ret = -ENOMEM;
@@ -1402,7 +1403,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
 	    tag == DW_TAG_variable) {
 		ret = convert_variable_location(die_mem, af->pf.addr,
 						af->pf.fb_ops, &af->pf.sp_die,
-						af->pf.machine, NULL);
+						&af->pf, /*tvar=*/NULL);
 		if (ret == 0 || ret == -ERANGE) {
 			int ret2;
 			bool externs = !af->child;
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index dfcf8cdd9e8d..be7b46ea2460 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -68,7 +68,8 @@ struct probe_finder {
 	/* Call Frame Information from .debug_frame. Not owned. */
 	Dwarf_CFI		*cfi_dbg;
 	Dwarf_Op		*fb_ops;	/* Frame base attribute */
-	unsigned int		machine;	/* Target machine arch */
+	unsigned int		e_machine;	/* ELF target machine arch */
+	unsigned int		e_flags;	/* ELF target machine flags */
 	struct perf_probe_arg	*pvar;		/* Current target variable */
 	struct probe_trace_arg	*tvar;		/* Current result variable */
 	bool			skip_empty_arg;	/* Skip non-exist args */
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:52 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:52 -0800
Subject: [PATCH v4 07/20] perf dwarf-regs: Move x86 dwarf-regs out of arch
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-8-irogers@google.com>

Move arch/x86/util/dwarf-regs.c to util/dwarf-regs-x86.c and compile
in unconditionally. To avoid get_arch_regnum being duplicated, rename
to get_x86_regnum and add to get_dwarf_regnum switch.

For get_arch_regstr, this was unused on x86 unless the machine type
was EM_NONE. Map that case to EM_HOST and remove get_arch_regstr from
dwarf-regs-x86.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/x86/util/Build                |  3 ---
 tools/perf/util/Build                         |  1 +
 .../dwarf-regs.c => util/dwarf-regs-x86.c}    | 24 +------------------
 tools/perf/util/dwarf-regs.c                  | 17 +++++++++++++
 tools/perf/util/include/dwarf-regs.h          |  8 +++++++
 5 files changed, 27 insertions(+), 26 deletions(-)
 rename tools/perf/{arch/x86/util/dwarf-regs.c => util/dwarf-regs-x86.c} (77%)

diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
index bc56a8e70f34..848327378694 100644
--- a/tools/perf/arch/x86/util/Build
+++ b/tools/perf/arch/x86/util/Build
@@ -11,9 +11,6 @@ perf-util-y += mem-events.o
 perf-util-y += evsel.o
 perf-util-y += iostat.o
 
-perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
-perf-util-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
-
 perf-util-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 1eedead5f2f2..4c615611b9d7 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -203,6 +203,7 @@ endif
 perf-util-$(CONFIG_LIBDW) += probe-finder.o
 perf-util-$(CONFIG_LIBDW) += dwarf-aux.o
 perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
+perf-util-$(CONFIG_LIBDW) += dwarf-regs-x86.o
 perf-util-$(CONFIG_LIBDW) += debuginfo.o
 perf-util-$(CONFIG_LIBDW) += annotate-data.o
 
diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/util/dwarf-regs-x86.c
similarity index 77%
rename from tools/perf/arch/x86/util/dwarf-regs.c
rename to tools/perf/util/dwarf-regs-x86.c
index 530905118cd4..7a55c65e8da6 100644
--- a/tools/perf/arch/x86/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs-x86.c
@@ -11,28 +11,6 @@
 #include <linux/kernel.h> /* for ARRAY_SIZE */
 #include <dwarf-regs.h>
 
-#define DEFINE_DWARF_REGSTR_TABLE 1
-#include "dwarf-regs-table.h"
-
-/* Return architecture dependent register string (for kprobe-tracer) */
-const char *get_arch_regstr(unsigned int n)
-{
-#if defined(__i386__)
-	size_t len = ARRAY_SIZE(x86_32_regstr_tbl);
-#else
-	size_t len = ARRAY_SIZE(x86_64_regstr_tbl);
-#endif
-
-	if (n >= len)
-		return NULL;
-
-#if defined(__i386__)
-	return x86_32_regstr_tbl[n];
-#else
-	return x86_64_regstr_tbl[n];
-#endif
-}
-
 struct dwarf_regs_idx {
 	const char *name;
 	int idx;
@@ -58,7 +36,7 @@ static const struct dwarf_regs_idx x86_regidx_table[] = {
 	{ "rip", DWARF_REG_PC },
 };
 
-int get_arch_regnum(const char *name)
+int get_x86_regnum(const char *name)
 {
 	unsigned int i;
 
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 86b3ef638fbb..eac99a246737 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -32,9 +32,17 @@
 const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
 			     unsigned int flags __maybe_unused)
 {
+#if EM_HOST == EM_X86_64 || EM_HOST == EM_386
+	if (machine == EM_NONE) {
+		/* Generic arch - use host arch */
+		machine = EM_HOST;
+	}
+#endif
 	switch (machine) {
+#if EM_HOST != EM_X86_64 && EM_HOST != EM_386
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
+#endif
 	case EM_386:
 		return __get_dwarf_regstr(x86_32_regstr_tbl, n);
 	case EM_X86_64:
@@ -65,10 +73,12 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
 	return NULL;
 }
 
+#if EM_HOST != EM_X86_64 && EM_HOST != EM_386
 __weak int get_arch_regnum(const char *name __maybe_unused)
 {
 	return -ENOTSUP;
 }
+#endif
 
 /* Return DWARF register number from architecture register name */
 int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags __maybe_unused)
@@ -90,9 +100,16 @@ int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags
 		machine = EM_HOST;
 	}
 	switch (machine) {
+#if EM_HOST != EM_X86_64 && EM_HOST != EM_386
 	case EM_HOST:
 		reg = get_arch_regnum(regname);
 		break;
+#endif
+	case EM_X86_64:
+		fallthrough;
+	case EM_386:
+		reg = get_x86_regnum(regname);
+		break;
 	default:
 		pr_err("ELF MACHINE %x is not supported.\n", machine);
 	}
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 0ef428d07bcc..6aa66c375942 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -89,7 +89,10 @@
 #define DWARF_REG_FB  0xd3affb /* random number */
 
 #ifdef HAVE_LIBDW_SUPPORT
+#if !defined(__x86_64__) && !defined(__i386__)
 const char *get_arch_regstr(unsigned int n);
+#endif
+
 /**
  * get_dwarf_regstr() - Returns ftrace register string from DWARF regnum.
  * @n: DWARF register number.
@@ -98,7 +101,12 @@ const char *get_arch_regstr(unsigned int n);
  */
 const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags);
 
+int get_x86_regnum(const char *name);
+
+#if !defined(__x86_64__) && !defined(__i386__)
 int get_arch_regnum(const char *name);
+#endif
+
 /*
  * get_dwarf_regnum - Returns DWARF regnum from register name
  * name: architecture register name
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:53 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:53 -0800
Subject: [PATCH v4 08/20] perf arm64: Remove dwarf-regs.c
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-9-irogers@google.com>

The file just provides the function get_arch_regstr, however, if in
the only caller get_dwarf_regstr EM_HOST is used for the EM_NONE case
the function can never be called. So remove as dead code. Tidy up the
EM_NONE cases for arm64 in dwarf-regs.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm64/util/Build        |  1 -
 tools/perf/arch/arm64/util/dwarf-regs.c | 80 -------------------------
 tools/perf/util/dwarf-regs.c            |  4 +-
 tools/perf/util/include/dwarf-regs.h    |  2 +-
 4 files changed, 3 insertions(+), 84 deletions(-)
 delete mode 100644 tools/perf/arch/arm64/util/dwarf-regs.c

diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
index 4387a6d6a6c3..a74521b79eaa 100644
--- a/tools/perf/arch/arm64/util/Build
+++ b/tools/perf/arch/arm64/util/Build
@@ -4,7 +4,6 @@ perf-util-y += perf_regs.o
 perf-util-y += tsc.o
 perf-util-y += pmu.o
 perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
-perf-util-$(CONFIG_LIBDW)     += dwarf-regs.o
 perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 
diff --git a/tools/perf/arch/arm64/util/dwarf-regs.c b/tools/perf/arch/arm64/util/dwarf-regs.c
deleted file mode 100644
index 343a62fa4199..000000000000
--- a/tools/perf/arch/arm64/util/dwarf-regs.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Mapping of DWARF debug register numbers into register names.
- *
- * Copyright (C) 2010 Will Deacon, ARM Ltd.
- */
-
-#include <errno.h>
-#include <stddef.h>
-#include <string.h>
-#include <dwarf-regs.h>
-#include <linux/stringify.h>
-
-struct regs_dwarfnum {
-	const char *name;
-	unsigned int dwarfnum;
-};
-
-#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
-#define GPR_DWARFNUM_NAME(num) \
-	{.name = __stringify(%x##num), .dwarfnum = num}
-#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
-
-/*
- * Reference:
- * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0057b/IHI0057B_aadwarf64.pdf
- */
-static const struct regs_dwarfnum regdwarfnum_table[] = {
-	GPR_DWARFNUM_NAME(0),
-	GPR_DWARFNUM_NAME(1),
-	GPR_DWARFNUM_NAME(2),
-	GPR_DWARFNUM_NAME(3),
-	GPR_DWARFNUM_NAME(4),
-	GPR_DWARFNUM_NAME(5),
-	GPR_DWARFNUM_NAME(6),
-	GPR_DWARFNUM_NAME(7),
-	GPR_DWARFNUM_NAME(8),
-	GPR_DWARFNUM_NAME(9),
-	GPR_DWARFNUM_NAME(10),
-	GPR_DWARFNUM_NAME(11),
-	GPR_DWARFNUM_NAME(12),
-	GPR_DWARFNUM_NAME(13),
-	GPR_DWARFNUM_NAME(14),
-	GPR_DWARFNUM_NAME(15),
-	GPR_DWARFNUM_NAME(16),
-	GPR_DWARFNUM_NAME(17),
-	GPR_DWARFNUM_NAME(18),
-	GPR_DWARFNUM_NAME(19),
-	GPR_DWARFNUM_NAME(20),
-	GPR_DWARFNUM_NAME(21),
-	GPR_DWARFNUM_NAME(22),
-	GPR_DWARFNUM_NAME(23),
-	GPR_DWARFNUM_NAME(24),
-	GPR_DWARFNUM_NAME(25),
-	GPR_DWARFNUM_NAME(26),
-	GPR_DWARFNUM_NAME(27),
-	GPR_DWARFNUM_NAME(28),
-	GPR_DWARFNUM_NAME(29),
-	REG_DWARFNUM_NAME("%lr", 30),
-	REG_DWARFNUM_NAME("%sp", 31),
-	REG_DWARFNUM_END,
-};
-
-/**
- * get_arch_regstr() - lookup register name from it's DWARF register number
- * @n:	the DWARF register number
- *
- * get_arch_regstr() returns the name of the register in struct
- * regdwarfnum_table from it's DWARF register number. If the register is not
- * found in the table, this returns NULL;
- */
-const char *get_arch_regstr(unsigned int n)
-{
-	const struct regs_dwarfnum *roff;
-
-	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
-		if (roff->dwarfnum == n)
-			return roff->name;
-	return NULL;
-}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index eac99a246737..18e916c8e993 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -32,14 +32,14 @@
 const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
 			     unsigned int flags __maybe_unused)
 {
-#if EM_HOST == EM_X86_64 || EM_HOST == EM_386
+#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
 	}
 #endif
 	switch (machine) {
-#if EM_HOST != EM_X86_64 && EM_HOST != EM_386
+#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 6aa66c375942..f976528fdfd6 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -89,7 +89,7 @@
 #define DWARF_REG_FB  0xd3affb /* random number */
 
 #ifdef HAVE_LIBDW_SUPPORT
-#if !defined(__x86_64__) && !defined(__i386__)
+#if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:54 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:54 -0800
Subject: [PATCH v4 09/20] perf arm: Remove dwarf-regs.c
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-10-irogers@google.com>

The file just provides the function get_arch_regstr, however, if in
the only caller get_dwarf_regstr EM_HOST is used for the EM_NONE case
the function can never be called. So remove as dead code. Tidy up the
EM_NONE cases for arm in dwarf-regs.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/arm/util/Build        |  2 -
 tools/perf/arch/arm/util/dwarf-regs.c | 61 ---------------------------
 tools/perf/util/dwarf-regs.c          |  4 +-
 tools/perf/util/include/dwarf-regs.h  |  2 +-
 4 files changed, 3 insertions(+), 66 deletions(-)
 delete mode 100644 tools/perf/arch/arm/util/dwarf-regs.c

diff --git a/tools/perf/arch/arm/util/Build b/tools/perf/arch/arm/util/Build
index e06fea1ea8ff..f7a8b37d1c68 100644
--- a/tools/perf/arch/arm/util/Build
+++ b/tools/perf/arch/arm/util/Build
@@ -1,7 +1,5 @@
 perf-util-y += perf_regs.o
 
-perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
-
 perf-util-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 
diff --git a/tools/perf/arch/arm/util/dwarf-regs.c b/tools/perf/arch/arm/util/dwarf-regs.c
deleted file mode 100644
index fc5f71c91802..000000000000
--- a/tools/perf/arch/arm/util/dwarf-regs.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Mapping of DWARF debug register numbers into register names.
- *
- * Copyright (C) 2010 Will Deacon, ARM Ltd.
- */
-
-#include <stddef.h>
-#include <linux/stringify.h>
-#include <dwarf-regs.h>
-
-struct pt_regs_dwarfnum {
-	const char *name;
-	unsigned int dwarfnum;
-};
-
-#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
-#define GPR_DWARFNUM_NAME(num) \
-	{.name = __stringify(%r##num), .dwarfnum = num}
-#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
-
-/*
- * Reference:
- * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040a/IHI0040A_aadwarf.pdf
- */
-static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
-	GPR_DWARFNUM_NAME(0),
-	GPR_DWARFNUM_NAME(1),
-	GPR_DWARFNUM_NAME(2),
-	GPR_DWARFNUM_NAME(3),
-	GPR_DWARFNUM_NAME(4),
-	GPR_DWARFNUM_NAME(5),
-	GPR_DWARFNUM_NAME(6),
-	GPR_DWARFNUM_NAME(7),
-	GPR_DWARFNUM_NAME(8),
-	GPR_DWARFNUM_NAME(9),
-	GPR_DWARFNUM_NAME(10),
-	REG_DWARFNUM_NAME("%fp", 11),
-	REG_DWARFNUM_NAME("%ip", 12),
-	REG_DWARFNUM_NAME("%sp", 13),
-	REG_DWARFNUM_NAME("%lr", 14),
-	REG_DWARFNUM_NAME("%pc", 15),
-	REG_DWARFNUM_END,
-};
-
-/**
- * get_arch_regstr() - lookup register name from it's DWARF register number
- * @n:	the DWARF register number
- *
- * get_arch_regstr() returns the name of the register in struct
- * regdwarfnum_table from it's DWARF register number. If the register is not
- * found in the table, this returns NULL;
- */
-const char *get_arch_regstr(unsigned int n)
-{
-	const struct pt_regs_dwarfnum *roff;
-	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
-		if (roff->dwarfnum == n)
-			return roff->name;
-	return NULL;
-}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 18e916c8e993..fd21f9e90e40 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -32,14 +32,14 @@
 const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
 			     unsigned int flags __maybe_unused)
 {
-#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64
+#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
 	}
 #endif
 	switch (machine) {
-#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64
+#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index f976528fdfd6..3652f9d98fe4 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -89,7 +89,7 @@
 #define DWARF_REG_FB  0xd3affb /* random number */
 
 #ifdef HAVE_LIBDW_SUPPORT
-#if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__)
+#if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:55 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:55 -0800
Subject: [PATCH v4 10/20] perf dwarf-regs: Move csky dwarf-regs out of arch
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-11-irogers@google.com>

Move arch/csky/util/dwarf-regs.c to util/dwarf-regs-csky.c and compile
in unconditionally. To avoid get_arch_regstr being duplicated, rename
to get_csky_regstr and add to get_dwarf_regstr switch.

Update #ifdefs to allow ABI V1 and V2 tables at the same
time. Determine the table from the ELF flags.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/csky/util/Build               |  1 -
 tools/perf/util/Build                         |  1 +
 .../dwarf-regs.c => util/dwarf-regs-csky.c}   | 19 ++++++++++---------
 tools/perf/util/dwarf-regs.c                  | 11 +++++++----
 tools/perf/util/include/dwarf-regs.h          |  2 ++
 5 files changed, 20 insertions(+), 14 deletions(-)
 rename tools/perf/{arch/csky/util/dwarf-regs.c => util/dwarf-regs-csky.c} (74%)

diff --git a/tools/perf/arch/csky/util/Build b/tools/perf/arch/csky/util/Build
index 1325310cab6a..5e6ea82c4202 100644
--- a/tools/perf/arch/csky/util/Build
+++ b/tools/perf/arch/csky/util/Build
@@ -1,4 +1,3 @@
 perf-util-y += perf_regs.o
 
-perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 4c615611b9d7..99ae4e2802b8 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -203,6 +203,7 @@ endif
 perf-util-$(CONFIG_LIBDW) += probe-finder.o
 perf-util-$(CONFIG_LIBDW) += dwarf-aux.o
 perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
+perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o
 perf-util-$(CONFIG_LIBDW) += dwarf-regs-x86.o
 perf-util-$(CONFIG_LIBDW) += debuginfo.o
 perf-util-$(CONFIG_LIBDW) += annotate-data.o
diff --git a/tools/perf/arch/csky/util/dwarf-regs.c b/tools/perf/util/dwarf-regs-csky.c
similarity index 74%
rename from tools/perf/arch/csky/util/dwarf-regs.c
rename to tools/perf/util/dwarf-regs-csky.c
index ca86ecaeacbb..d38ef1f07f3e 100644
--- a/tools/perf/arch/csky/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs-csky.c
@@ -5,9 +5,8 @@
 #include <stddef.h>
 #include <dwarf-regs.h>
 
-#if defined(__CSKYABIV2__)
-#define CSKY_MAX_REGS 73
-const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
+#define CSKY_ABIV2_MAX_REGS 73
+const char *csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = {
 	/* r0 ~ r8 */
 	"%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", "%regs2", "%regs3",
 	/* r9 ~ r15 */
@@ -26,9 +25,9 @@ const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	"%epc",
 };
-#else
-#define CSKY_MAX_REGS 57
-const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
+
+#define CSKY_ABIV1_MAX_REGS 57
+const char *csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = {
 	/* r0 ~ r8 */
 	"%sp", "%regs9", "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1",
 	/* r9 ~ r15 */
@@ -41,9 +40,11 @@ const char *csky_dwarf_regs_table[CSKY_MAX_REGS] = {
 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	"%epc",
 };
-#endif
 
-const char *get_arch_regstr(unsigned int n)
+const char *get_csky_regstr(unsigned int n, unsigned int flags)
 {
-	return (n < CSKY_MAX_REGS) ? csky_dwarf_regs_table[n] : NULL;
+	if (flags & EF_CSKY_ABIV2)
+		return (n < CSKY_ABIV2_MAX_REGS) ? csky_dwarf_regs_table_abiv2[n] : NULL;
+
+	return (n < CSKY_ABIV1_MAX_REGS) ? csky_dwarf_regs_table_abiv1[n] : NULL;
 }
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index fd21f9e90e40..9a76f83af62c 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -29,17 +29,18 @@
 #define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
 
 /* Return architecture dependent register string (for kprobe-tracer) */
-const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
-			     unsigned int flags __maybe_unused)
+const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags)
 {
-#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM
+#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
+    || EM_HOST == EM_CSKY
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
 	}
 #endif
 	switch (machine) {
-#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM
+#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
+    && EM_HOST != EM_CSKY
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
@@ -51,6 +52,8 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine,
 		return __get_dwarf_regstr(arm_regstr_tbl, n);
 	case EM_AARCH64:
 		return __get_dwarf_regstr(aarch64_regstr_tbl, n);
+	case EM_CSKY:
+		return get_csky_regstr(n, flags);
 	case EM_SH:
 		return __get_dwarf_regstr(sh_regstr_tbl, n);
 	case EM_S390:
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 3652f9d98fe4..0641c2942b01 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -93,6 +93,8 @@
 const char *get_arch_regstr(unsigned int n);
 #endif
 
+const char *get_csky_regstr(unsigned int n, unsigned int flags);
+
 /**
  * get_dwarf_regstr() - Returns ftrace register string from DWARF regnum.
  * @n: DWARF register number.
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:56 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:56 -0800
Subject: [PATCH v4 11/20] perf loongarch: Remove dwarf-regs.c
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-12-irogers@google.com>

The file just provides the function get_arch_regstr, however, if in
the only caller get_dwarf_regstr EM_HOST is used for the EM_NONE case
the function can never be called. So remove as dead code. Tidy up the
EM_NONE cases for loongarch in dwarf-regs.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/loongarch/util/Build        |  1 -
 tools/perf/arch/loongarch/util/dwarf-regs.c | 34 ---------------------
 tools/perf/util/dwarf-regs.c                |  4 +--
 tools/perf/util/include/dwarf-regs.h        |  3 +-
 4 files changed, 4 insertions(+), 38 deletions(-)
 delete mode 100644 tools/perf/arch/loongarch/util/dwarf-regs.c

diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongarch/util/Build
index 06ff95394921..0aa31986ecb5 100644
--- a/tools/perf/arch/loongarch/util/Build
+++ b/tools/perf/arch/loongarch/util/Build
@@ -1,7 +1,6 @@
 perf-util-y += header.o
 perf-util-y += perf_regs.o
 
-perf-util-$(CONFIG_LIBDW)     += dwarf-regs.o
 perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
diff --git a/tools/perf/arch/loongarch/util/dwarf-regs.c b/tools/perf/arch/loongarch/util/dwarf-regs.c
deleted file mode 100644
index bee08fdcf2fd..000000000000
--- a/tools/perf/arch/loongarch/util/dwarf-regs.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
- *
- * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
- */
-
-#include <stdio.h>
-#include <errno.h> /* for EINVAL */
-#include <string.h> /* for strcmp */
-#include <dwarf-regs.h>
-
-struct pt_regs_dwarfnum {
-	const char *name;
-	unsigned int dwarfnum;
-};
-
-static struct pt_regs_dwarfnum loongarch_gpr_table[] = {
-	{"%r0", 0}, {"%r1", 1}, {"%r2", 2}, {"%r3", 3},
-	{"%r4", 4}, {"%r5", 5}, {"%r6", 6}, {"%r7", 7},
-	{"%r8", 8}, {"%r9", 9}, {"%r10", 10}, {"%r11", 11},
-	{"%r12", 12}, {"%r13", 13}, {"%r14", 14}, {"%r15", 15},
-	{"%r16", 16}, {"%r17", 17}, {"%r18", 18}, {"%r19", 19},
-	{"%r20", 20}, {"%r21", 21}, {"%r22", 22}, {"%r23", 23},
-	{"%r24", 24}, {"%r25", 25}, {"%r26", 26}, {"%r27", 27},
-	{"%r28", 28}, {"%r29", 29}, {"%r30", 30}, {"%r31", 31},
-	{NULL, 0}
-};
-
-const char *get_arch_regstr(unsigned int n)
-{
-	n %= 32;
-	return loongarch_gpr_table[n].name;
-}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 9a76f83af62c..efc41d0fbee9 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -32,7 +32,7 @@
 const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags)
 {
 #if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
-    || EM_HOST == EM_CSKY
+    || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
@@ -40,7 +40,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 #endif
 	switch (machine) {
 #if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
-    && EM_HOST != EM_CSKY
+    && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 0641c2942b01..4e591379f367 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -89,7 +89,8 @@
 #define DWARF_REG_FB  0xd3affb /* random number */
 
 #ifdef HAVE_LIBDW_SUPPORT
-#if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__)
+#if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__) \
+    && !defined(__loongarch__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:57 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:57 -0800
Subject: [PATCH v4 12/20] perf mips: Remove dwarf-regs.c
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-13-irogers@google.com>

The file just provides the function get_arch_regstr, however, if in
the only caller get_dwarf_regstr EM_HOST is used for the EM_NONE case
the function can never be called. So remove as dead code. Tidy up the
EM_NONE cases for mips in dwarf-regs.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/mips/util/Build        |  1 -
 tools/perf/arch/mips/util/dwarf-regs.c | 38 --------------------------
 tools/perf/util/dwarf-regs.c           |  4 +--
 tools/perf/util/include/dwarf-regs.h   |  2 +-
 4 files changed, 3 insertions(+), 42 deletions(-)
 delete mode 100644 tools/perf/arch/mips/util/dwarf-regs.c

diff --git a/tools/perf/arch/mips/util/Build b/tools/perf/arch/mips/util/Build
index b328109fc16c..691fa2051958 100644
--- a/tools/perf/arch/mips/util/Build
+++ b/tools/perf/arch/mips/util/Build
@@ -1,3 +1,2 @@
 perf-util-y += perf_regs.o
-perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
 perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
diff --git a/tools/perf/arch/mips/util/dwarf-regs.c b/tools/perf/arch/mips/util/dwarf-regs.c
deleted file mode 100644
index 25c13a91c2a7..000000000000
--- a/tools/perf/arch/mips/util/dwarf-regs.c
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
- *
- * Copyright (C) 2013 Cavium, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <stdio.h>
-#include <dwarf-regs.h>
-
-static const char *mips_gpr_names[32] = {
-	"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
-	"$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19",
-	"$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29",
-	"$30", "$31"
-};
-
-const char *get_arch_regstr(unsigned int n)
-{
-	if (n < 32)
-		return mips_gpr_names[n];
-	if (n == 64)
-		return "hi";
-	if (n == 65)
-		return "lo";
-	return NULL;
-}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index efc41d0fbee9..d536964df43c 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -32,7 +32,7 @@
 const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags)
 {
 #if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
-    || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH
+    || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH || EM_HOST == EM_MIPS
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
@@ -40,7 +40,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 #endif
 	switch (machine) {
 #if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
-    && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH
+    && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH && EM_HOST != EM_MIPS
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 4e591379f367..55f21d8082a2 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -90,7 +90,7 @@
 
 #ifdef HAVE_LIBDW_SUPPORT
 #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__) \
-    && !defined(__loongarch__)
+    && !defined(__loongarch__) && !defined(__mips__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:58 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:58 -0800
Subject: [PATCH v4 13/20] perf dwarf-regs: Move powerpc dwarf-regs out of arch
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-14-irogers@google.com>

Move arch/powerpc/util/dwarf-regs.c to util/dwarf-regs-powerpc.c and
compile in unconditionally. get_arch_regstr is redundant when EM_NONE
is treated as EM_HOST so remove and update dwarf-regs.c conditions.
Make get_powerpc_regs unconditionally available whwn libdw is.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/powerpc/util/Build        |   1 -
 tools/perf/arch/powerpc/util/dwarf-regs.c | 141 ----------------------
 tools/perf/util/Build                     |   1 +
 tools/perf/util/dwarf-regs-powerpc.c      |  61 ++++++++++
 tools/perf/util/dwarf-regs.c              |   6 +-
 tools/perf/util/include/dwarf-regs.h      |   9 +-
 6 files changed, 70 insertions(+), 149 deletions(-)
 delete mode 100644 tools/perf/arch/powerpc/util/dwarf-regs.c
 create mode 100644 tools/perf/util/dwarf-regs-powerpc.c

diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build
index 3d979480a188..ed82715080f9 100644
--- a/tools/perf/arch/powerpc/util/Build
+++ b/tools/perf/arch/powerpc/util/Build
@@ -7,7 +7,6 @@ perf-util-y += sym-handling.o
 perf-util-y += evsel.o
 perf-util-y += event.o
 
-perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
 perf-util-$(CONFIG_LIBDW) += skip-callchain-idx.o
 
 perf-util-$(CONFIG_LIBUNWIND) += unwind-libunwind.o
diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c
deleted file mode 100644
index 23846c59a522..000000000000
--- a/tools/perf/arch/powerpc/util/dwarf-regs.c
+++ /dev/null
@@ -1,141 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Mapping of DWARF debug register numbers into register names.
- *
- * Copyright (C) 2010 Ian Munsie, IBM Corporation.
- */
-
-#include <stddef.h>
-#include <errno.h>
-#include <string.h>
-#include <dwarf-regs.h>
-#include <linux/kernel.h>
-#include <linux/stringify.h>
-
-struct regs_dwarfnum {
-	const char *name;
-	unsigned int dwarfnum;
-};
-
-#define REG_DWARFNUM_NAME(r, num)					\
-	{.name = __stringify(%)__stringify(r), .dwarfnum = num}
-#define GPR_DWARFNUM_NAME(num)						\
-	{.name = __stringify(%gpr##num), .dwarfnum = num}
-#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
-
-/*
- * Reference:
- * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
- */
-static const struct regs_dwarfnum regdwarfnum_table[] = {
-	GPR_DWARFNUM_NAME(0),
-	GPR_DWARFNUM_NAME(1),
-	GPR_DWARFNUM_NAME(2),
-	GPR_DWARFNUM_NAME(3),
-	GPR_DWARFNUM_NAME(4),
-	GPR_DWARFNUM_NAME(5),
-	GPR_DWARFNUM_NAME(6),
-	GPR_DWARFNUM_NAME(7),
-	GPR_DWARFNUM_NAME(8),
-	GPR_DWARFNUM_NAME(9),
-	GPR_DWARFNUM_NAME(10),
-	GPR_DWARFNUM_NAME(11),
-	GPR_DWARFNUM_NAME(12),
-	GPR_DWARFNUM_NAME(13),
-	GPR_DWARFNUM_NAME(14),
-	GPR_DWARFNUM_NAME(15),
-	GPR_DWARFNUM_NAME(16),
-	GPR_DWARFNUM_NAME(17),
-	GPR_DWARFNUM_NAME(18),
-	GPR_DWARFNUM_NAME(19),
-	GPR_DWARFNUM_NAME(20),
-	GPR_DWARFNUM_NAME(21),
-	GPR_DWARFNUM_NAME(22),
-	GPR_DWARFNUM_NAME(23),
-	GPR_DWARFNUM_NAME(24),
-	GPR_DWARFNUM_NAME(25),
-	GPR_DWARFNUM_NAME(26),
-	GPR_DWARFNUM_NAME(27),
-	GPR_DWARFNUM_NAME(28),
-	GPR_DWARFNUM_NAME(29),
-	GPR_DWARFNUM_NAME(30),
-	GPR_DWARFNUM_NAME(31),
-	REG_DWARFNUM_NAME(msr,   66),
-	REG_DWARFNUM_NAME(ctr,   109),
-	REG_DWARFNUM_NAME(link,  108),
-	REG_DWARFNUM_NAME(xer,   101),
-	REG_DWARFNUM_NAME(dar,   119),
-	REG_DWARFNUM_NAME(dsisr, 118),
-	REG_DWARFNUM_END,
-};
-
-/**
- * get_arch_regstr() - lookup register name from it's DWARF register number
- * @n:	the DWARF register number
- *
- * get_arch_regstr() returns the name of the register in struct
- * regdwarfnum_table from it's DWARF register number. If the register is not
- * found in the table, this returns NULL;
- */
-const char *get_arch_regstr(unsigned int n)
-{
-	const struct regs_dwarfnum *roff;
-
-	for (roff = regdwarfnum_table; roff->name != NULL; roff++)
-		if (roff->dwarfnum == n)
-			return roff->name;
-	return NULL;
-}
-
-#define PPC_OP(op)	(((op) >> 26) & 0x3F)
-#define PPC_RA(a)	(((a) >> 16) & 0x1f)
-#define PPC_RT(t)	(((t) >> 21) & 0x1f)
-#define PPC_RB(b)	(((b) >> 11) & 0x1f)
-#define PPC_D(D)	((D) & 0xfffe)
-#define PPC_DS(DS)	((DS) & 0xfffc)
-#define OP_LD	58
-#define OP_STD	62
-
-static int get_source_reg(u32 raw_insn)
-{
-	return PPC_RA(raw_insn);
-}
-
-static int get_target_reg(u32 raw_insn)
-{
-	return PPC_RT(raw_insn);
-}
-
-static int get_offset_opcode(u32 raw_insn)
-{
-	int opcode = PPC_OP(raw_insn);
-
-	/* DS- form */
-	if ((opcode == OP_LD) || (opcode == OP_STD))
-		return PPC_DS(raw_insn);
-	else
-		return PPC_D(raw_insn);
-}
-
-/*
- * Fills the required fields for op_loc depending on if it
- * is a source or target.
- * D form: ins RT,D(RA) -> src_reg1 = RA, offset = D, dst_reg1 = RT
- * DS form: ins RT,DS(RA) -> src_reg1 = RA, offset = DS, dst_reg1 = RT
- * X form: ins RT,RA,RB -> src_reg1 = RA, src_reg2 = RB, dst_reg1 = RT
- */
-void get_powerpc_regs(u32 raw_insn, int is_source,
-		struct annotated_op_loc *op_loc)
-{
-	if (is_source)
-		op_loc->reg1 = get_source_reg(raw_insn);
-	else
-		op_loc->reg1 = get_target_reg(raw_insn);
-
-	if (op_loc->multi_regs)
-		op_loc->reg2 = PPC_RB(raw_insn);
-
-	/* TODO: Implement offset handling for X Form */
-	if ((op_loc->mem_ref) && (PPC_OP(raw_insn) != 31))
-		op_loc->offset = get_offset_opcode(raw_insn);
-}
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 99ae4e2802b8..eeab8684ddcc 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -204,6 +204,7 @@ perf-util-$(CONFIG_LIBDW) += probe-finder.o
 perf-util-$(CONFIG_LIBDW) += dwarf-aux.o
 perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
 perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o
+perf-util-$(CONFIG_LIBDW) += dwarf-regs-powerpc.o
 perf-util-$(CONFIG_LIBDW) += dwarf-regs-x86.o
 perf-util-$(CONFIG_LIBDW) += debuginfo.o
 perf-util-$(CONFIG_LIBDW) += annotate-data.o
diff --git a/tools/perf/util/dwarf-regs-powerpc.c b/tools/perf/util/dwarf-regs-powerpc.c
new file mode 100644
index 000000000000..caf77a234c78
--- /dev/null
+++ b/tools/perf/util/dwarf-regs-powerpc.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2010 Ian Munsie, IBM Corporation.
+ */
+
+#include <dwarf-regs.h>
+
+#define PPC_OP(op)	(((op) >> 26) & 0x3F)
+#define PPC_RA(a)	(((a) >> 16) & 0x1f)
+#define PPC_RT(t)	(((t) >> 21) & 0x1f)
+#define PPC_RB(b)	(((b) >> 11) & 0x1f)
+#define PPC_D(D)	((D) & 0xfffe)
+#define PPC_DS(DS)	((DS) & 0xfffc)
+#define OP_LD	58
+#define OP_STD	62
+
+static int get_source_reg(u32 raw_insn)
+{
+	return PPC_RA(raw_insn);
+}
+
+static int get_target_reg(u32 raw_insn)
+{
+	return PPC_RT(raw_insn);
+}
+
+static int get_offset_opcode(u32 raw_insn)
+{
+	int opcode = PPC_OP(raw_insn);
+
+	/* DS- form */
+	if ((opcode == OP_LD) || (opcode == OP_STD))
+		return PPC_DS(raw_insn);
+	else
+		return PPC_D(raw_insn);
+}
+
+/*
+ * Fills the required fields for op_loc depending on if it
+ * is a source or target.
+ * D form: ins RT,D(RA) -> src_reg1 = RA, offset = D, dst_reg1 = RT
+ * DS form: ins RT,DS(RA) -> src_reg1 = RA, offset = DS, dst_reg1 = RT
+ * X form: ins RT,RA,RB -> src_reg1 = RA, src_reg2 = RB, dst_reg1 = RT
+ */
+void get_powerpc_regs(u32 raw_insn, int is_source,
+		struct annotated_op_loc *op_loc)
+{
+	if (is_source)
+		op_loc->reg1 = get_source_reg(raw_insn);
+	else
+		op_loc->reg1 = get_target_reg(raw_insn);
+
+	if (op_loc->multi_regs)
+		op_loc->reg2 = PPC_RB(raw_insn);
+
+	/* TODO: Implement offset handling for X Form */
+	if ((op_loc->mem_ref) && (PPC_OP(raw_insn) != 31))
+		op_loc->offset = get_offset_opcode(raw_insn);
+}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index d536964df43c..3d98c2bf6035 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -32,7 +32,8 @@
 const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags)
 {
 #if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
-    || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH || EM_HOST == EM_MIPS
+    || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH || EM_HOST == EM_MIPS || EM_HOST == EM_PPC \
+    || EM_HOST == EM_PPC64
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
@@ -40,7 +41,8 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 #endif
 	switch (machine) {
 #if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
-    && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH && EM_HOST != EM_MIPS
+    && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH && EM_HOST != EM_MIPS && EM_HOST != EM_PPC \
+    && EM_HOST != EM_PPC64
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 55f21d8082a2..e47c4697da36 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -90,7 +90,8 @@
 
 #ifdef HAVE_LIBDW_SUPPORT
 #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__) \
-    && !defined(__loongarch__) && !defined(__mips__)
+    && !defined(__loongarch__) && !defined(__mips__) && !defined(__powerpc__) \
+    && !defined(__powerpc64__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
@@ -117,6 +118,8 @@ int get_arch_regnum(const char *name);
  */
 int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags);
 
+void get_powerpc_regs(u32 raw_insn, int is_source, struct annotated_op_loc *op_loc);
+
 #else /* HAVE_LIBDW_SUPPORT */
 
 static inline int get_dwarf_regnum(const char *name __maybe_unused,
@@ -125,16 +128,12 @@ static inline int get_dwarf_regnum(const char *name __maybe_unused,
 {
 	return -1;
 }
-#endif
 
-#if !defined(__powerpc__) || !defined(HAVE_LIBDW_SUPPORT)
 static inline void get_powerpc_regs(u32 raw_insn __maybe_unused, int is_source __maybe_unused,
 		struct annotated_op_loc *op_loc __maybe_unused)
 {
 	return;
 }
-#else
-void get_powerpc_regs(u32 raw_insn, int is_source, struct annotated_op_loc *op_loc);
 #endif
 
 #endif
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:45:59 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:45:59 -0800
Subject: [PATCH v4 14/20] perf riscv: Remove dwarf-regs.c and add dwarf-regs-table.h
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-15-irogers@google.com>

The file just provides the function get_arch_regstr, however, if in
the only caller get_dwarf_regstr EM_HOST is used for the EM_NONE case,
and the register table is provided in a header file, the function can
never be called. So remove as dead code. Tidy up the EM_NONE cases for
riscv in dwarf-regs.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 .../dwarf-regs-table.h}                       | 32 ++++---------------
 tools/perf/arch/riscv/util/Build              |  1 -
 tools/perf/util/dwarf-regs.c                  |  7 ++--
 tools/perf/util/include/dwarf-regs.h          |  2 +-
 4 files changed, 12 insertions(+), 30 deletions(-)
 rename tools/perf/arch/riscv/{util/dwarf-regs.c => include/dwarf-regs-table.h} (56%)

diff --git a/tools/perf/arch/riscv/util/dwarf-regs.c b/tools/perf/arch/riscv/include/dwarf-regs-table.h
similarity index 56%
rename from tools/perf/arch/riscv/util/dwarf-regs.c
rename to tools/perf/arch/riscv/include/dwarf-regs-table.h
index a9c4402ae57e..a45b63a6d5a8 100644
--- a/tools/perf/arch/riscv/util/dwarf-regs.c
+++ b/tools/perf/arch/riscv/include/dwarf-regs-table.h
@@ -1,23 +1,10 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd.
- * Mapping of DWARF debug register numbers into register names.
- */
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+/* This is included in perf/util/dwarf-regs.c */
 
-#include <stddef.h>
-#include <errno.h> /* for EINVAL */
-#include <string.h> /* for strcmp */
-#include <dwarf-regs.h>
+#define REG_DWARFNUM_NAME(reg, idx)	[idx] = "%" #reg
 
-struct regs_dwarfnum {
-	const char *name;
-	unsigned int dwarfnum;
-};
-
-#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
-#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
-
-struct regs_dwarfnum riscv_dwarf_regs_table[] = {
+static const char * const riscv_regstr_tbl[] = {
 	REG_DWARFNUM_NAME("%zero", 0),
 	REG_DWARFNUM_NAME("%ra", 1),
 	REG_DWARFNUM_NAME("%sp", 2),
@@ -50,13 +37,6 @@ struct regs_dwarfnum riscv_dwarf_regs_table[] = {
 	REG_DWARFNUM_NAME("%t4", 29),
 	REG_DWARFNUM_NAME("%t5", 30),
 	REG_DWARFNUM_NAME("%t6", 31),
-	REG_DWARFNUM_END,
 };
 
-#define RISCV_MAX_REGS ((sizeof(riscv_dwarf_regs_table) / \
-		 sizeof(riscv_dwarf_regs_table[0])) - 1)
-
-const char *get_arch_regstr(unsigned int n)
-{
-	return (n < RISCV_MAX_REGS) ? riscv_dwarf_regs_table[n].name : NULL;
-}
+#endif
diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
index 8f93091b8345..58a672246024 100644
--- a/tools/perf/arch/riscv/util/Build
+++ b/tools/perf/arch/riscv/util/Build
@@ -2,5 +2,4 @@ perf-util-y += perf_regs.o
 perf-util-y += header.o
 
 perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
-perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 3d98c2bf6035..2c6b197556dd 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -20,6 +20,7 @@
 #include "../arch/arm64/include/dwarf-regs-table.h"
 #include "../arch/sh/include/dwarf-regs-table.h"
 #include "../arch/powerpc/include/dwarf-regs-table.h"
+#include "../arch/riscv/include/dwarf-regs-table.h"
 #include "../arch/s390/include/dwarf-regs-table.h"
 #include "../arch/sparc/include/dwarf-regs-table.h"
 #include "../arch/xtensa/include/dwarf-regs-table.h"
@@ -33,7 +34,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 {
 #if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
     || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH || EM_HOST == EM_MIPS || EM_HOST == EM_PPC \
-    || EM_HOST == EM_PPC64
+    || EM_HOST == EM_PPC64 || EM_HOST == EM_RISCV
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
@@ -42,7 +43,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 	switch (machine) {
 #if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
     && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH && EM_HOST != EM_MIPS && EM_HOST != EM_PPC \
-    && EM_HOST != EM_PPC64
+    && EM_HOST != EM_PPC64 && EM_HOST != EM_RISCV
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
@@ -63,6 +64,8 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 	case EM_PPC:
 	case EM_PPC64:
 		return __get_dwarf_regstr(powerpc_regstr_tbl, n);
+	case EM_RISCV:
+		return __get_dwarf_regstr(riscv_regstr_tbl, n);
 	case EM_SPARC:
 	case EM_SPARCV9:
 		return __get_dwarf_regstr(sparc_regstr_tbl, n);
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index e47c4697da36..28075de8bcf4 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -91,7 +91,7 @@
 #ifdef HAVE_LIBDW_SUPPORT
 #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__) \
     && !defined(__loongarch__) && !defined(__mips__) && !defined(__powerpc__) \
-    && !defined(__powerpc64__)
+    && !defined(__powerpc64__) && !defined(__riscv__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:46:00 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:46:00 -0800
Subject: [PATCH v4 15/20] perf s390: Remove dwarf-regs.c
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-16-irogers@google.com>

The file just provides the function get_arch_regstr, however, if in
the only caller get_dwarf_regstr EM_HOST is used for the EM_NONE case
the function can never be called. So remove as dead code. Tidy up the
EM_NONE cases for s390 in dwarf-regs.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/s390/util/Build        |  1 -
 tools/perf/arch/s390/util/dwarf-regs.c | 16 ----------------
 tools/perf/util/dwarf-regs.c           |  4 ++--
 tools/perf/util/include/dwarf-regs.h   |  2 +-
 4 files changed, 3 insertions(+), 20 deletions(-)
 delete mode 100644 tools/perf/arch/s390/util/dwarf-regs.c

diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build
index 787410f99bb3..736c0ad09194 100644
--- a/tools/perf/arch/s390/util/Build
+++ b/tools/perf/arch/s390/util/Build
@@ -2,7 +2,6 @@ perf-util-y += header.o
 perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
 perf-util-y += perf_regs.o
 
-perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 
 perf-util-y += machine.o
diff --git a/tools/perf/arch/s390/util/dwarf-regs.c b/tools/perf/arch/s390/util/dwarf-regs.c
deleted file mode 100644
index 5bcf3192623a..000000000000
--- a/tools/perf/arch/s390/util/dwarf-regs.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Mapping of DWARF debug register numbers into register names.
- *
- * Copyright IBM Corp. 2010, 2017
- * Author(s): Hendrik Brueckner <brueckner at linux.vnet.ibm.com>
- *
- */
-
-#include <linux/kernel.h>
-#include "dwarf-regs-table.h"
-
-const char *get_arch_regstr(unsigned int n)
-{
-	return (n >= ARRAY_SIZE(s390_dwarf_regs)) ? NULL : s390_dwarf_regs[n];
-}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 2c6b197556dd..1649fc07f4f5 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -34,7 +34,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 {
 #if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
     || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH || EM_HOST == EM_MIPS || EM_HOST == EM_PPC \
-    || EM_HOST == EM_PPC64 || EM_HOST == EM_RISCV
+    || EM_HOST == EM_PPC64 || EM_HOST == EM_RISCV || EM_HOST == EM_S390
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
@@ -43,7 +43,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 	switch (machine) {
 #if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
     && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH && EM_HOST != EM_MIPS && EM_HOST != EM_PPC \
-    && EM_HOST != EM_PPC64 && EM_HOST != EM_RISCV
+    && EM_HOST != EM_PPC64 && EM_HOST != EM_RISCV && EM_HOST != EM_S390
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 28075de8bcf4..086b537690d7 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -91,7 +91,7 @@
 #ifdef HAVE_LIBDW_SUPPORT
 #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__) \
     && !defined(__loongarch__) && !defined(__mips__) && !defined(__powerpc__) \
-    && !defined(__powerpc64__) && !defined(__riscv__)
+    && !defined(__powerpc64__) && !defined(__riscv__) && !defined(__s390x__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:46:01 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:46:01 -0800
Subject: [PATCH v4 16/20] perf sh: Remove dwarf-regs.c
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-17-irogers@google.com>

The file just provides the function get_arch_regstr, however, if in
the only caller get_dwarf_regstr EM_HOST is used for the EM_NONE case
the function can never be called. So remove as dead code. As this is
the only file in the arch/sh/util clean up Build files. Tidy up the
EM_NONE cases for sh in dwarf-regs.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/sh/Build             |  1 -
 tools/perf/arch/sh/util/Build        |  1 -
 tools/perf/arch/sh/util/dwarf-regs.c | 41 ----------------------------
 tools/perf/util/dwarf-regs.c         |  4 +--
 tools/perf/util/include/dwarf-regs.h |  2 +-
 5 files changed, 3 insertions(+), 46 deletions(-)
 delete mode 100644 tools/perf/arch/sh/Build
 delete mode 100644 tools/perf/arch/sh/util/Build
 delete mode 100644 tools/perf/arch/sh/util/dwarf-regs.c

diff --git a/tools/perf/arch/sh/Build b/tools/perf/arch/sh/Build
deleted file mode 100644
index e63eabc2c8f4..000000000000
--- a/tools/perf/arch/sh/Build
+++ /dev/null
@@ -1 +0,0 @@
-perf-util-y += util/
diff --git a/tools/perf/arch/sh/util/Build b/tools/perf/arch/sh/util/Build
deleted file mode 100644
index 2337a0b710a2..000000000000
--- a/tools/perf/arch/sh/util/Build
+++ /dev/null
@@ -1 +0,0 @@
-perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
diff --git a/tools/perf/arch/sh/util/dwarf-regs.c b/tools/perf/arch/sh/util/dwarf-regs.c
deleted file mode 100644
index 4b17fc86c73b..000000000000
--- a/tools/perf/arch/sh/util/dwarf-regs.c
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Mapping of DWARF debug register numbers into register names.
- *
- * Copyright (C) 2010 Matt Fleming <matt at console-pimps.org>
- */
-
-#include <stddef.h>
-#include <dwarf-regs.h>
-
-/*
- * Generic dwarf analysis helpers
- */
-
-#define SH_MAX_REGS 18
-const char *sh_regs_table[SH_MAX_REGS] = {
-	"r0",
-	"r1",
-	"r2",
-	"r3",
-	"r4",
-	"r5",
-	"r6",
-	"r7",
-	"r8",
-	"r9",
-	"r10",
-	"r11",
-	"r12",
-	"r13",
-	"r14",
-	"r15",
-	"pc",
-	"pr",
-};
-
-/* Return architecture dependent register string (for kprobe-tracer) */
-const char *get_arch_regstr(unsigned int n)
-{
-	return (n < SH_MAX_REGS) ? sh_regs_table[n] : NULL;
-}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 1649fc07f4f5..944ff4ef0290 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -34,7 +34,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 {
 #if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
     || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH || EM_HOST == EM_MIPS || EM_HOST == EM_PPC \
-    || EM_HOST == EM_PPC64 || EM_HOST == EM_RISCV || EM_HOST == EM_S390
+    || EM_HOST == EM_PPC64 || EM_HOST == EM_RISCV || EM_HOST == EM_S390 || EM_HOST == EM_SH
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
@@ -43,7 +43,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 	switch (machine) {
 #if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
     && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH && EM_HOST != EM_MIPS && EM_HOST != EM_PPC \
-    && EM_HOST != EM_PPC64 && EM_HOST != EM_RISCV && EM_HOST != EM_S390
+    && EM_HOST != EM_PPC64 && EM_HOST != EM_RISCV && EM_HOST != EM_S390 && EM_HOST != EM_SH
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 086b537690d7..7026a3d2aaa7 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -91,7 +91,7 @@
 #ifdef HAVE_LIBDW_SUPPORT
 #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__) \
     && !defined(__loongarch__) && !defined(__mips__) && !defined(__powerpc__) \
-    && !defined(__powerpc64__) && !defined(__riscv__) && !defined(__s390x__)
+    && !defined(__powerpc64__) && !defined(__riscv__) && !defined(__s390x__) && !defined(__sh__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:46:02 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:46:02 -0800
Subject: [PATCH v4 17/20] perf sparc: Remove dwarf-regs.c
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-18-irogers@google.com>

The file just provides the function get_arch_regstr, however, if in
the only caller get_dwarf_regstr EM_HOST is used for the EM_NONE case
the function can never be called. So remove as dead code. As this is
the only file in the arch/sparc/util clean up Build files. Tidy up the
EM_NONE cases for sparc in dwarf-regs.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/sparc/Build             |  1 -
 tools/perf/arch/sparc/util/Build        |  1 -
 tools/perf/arch/sparc/util/dwarf-regs.c | 39 -------------------------
 tools/perf/util/dwarf-regs.c            |  6 ++--
 tools/perf/util/include/dwarf-regs.h    |  3 +-
 5 files changed, 6 insertions(+), 44 deletions(-)
 delete mode 100644 tools/perf/arch/sparc/Build
 delete mode 100644 tools/perf/arch/sparc/util/Build
 delete mode 100644 tools/perf/arch/sparc/util/dwarf-regs.c

diff --git a/tools/perf/arch/sparc/Build b/tools/perf/arch/sparc/Build
deleted file mode 100644
index e63eabc2c8f4..000000000000
--- a/tools/perf/arch/sparc/Build
+++ /dev/null
@@ -1 +0,0 @@
-perf-util-y += util/
diff --git a/tools/perf/arch/sparc/util/Build b/tools/perf/arch/sparc/util/Build
deleted file mode 100644
index 2337a0b710a2..000000000000
--- a/tools/perf/arch/sparc/util/Build
+++ /dev/null
@@ -1 +0,0 @@
-perf-util-$(CONFIG_LIBDW) += dwarf-regs.o
diff --git a/tools/perf/arch/sparc/util/dwarf-regs.c b/tools/perf/arch/sparc/util/dwarf-regs.c
deleted file mode 100644
index 1282cb2dc7bd..000000000000
--- a/tools/perf/arch/sparc/util/dwarf-regs.c
+++ /dev/null
@@ -1,39 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Mapping of DWARF debug register numbers into register names.
- *
- * Copyright (C) 2010 David S. Miller <davem at davemloft.net>
- */
-
-#include <stddef.h>
-#include <dwarf-regs.h>
-
-#define SPARC_MAX_REGS	96
-
-const char *sparc_regs_table[SPARC_MAX_REGS] = {
-	"%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
-	"%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
-	"%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
-	"%i0", "%i1", "%i2", "%i3", "%i4", "%i5", "%fp", "%i7",
-	"%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
-	"%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
-	"%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
-	"%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
-	"%f32", "%f33", "%f34", "%f35", "%f36", "%f37", "%f38", "%f39",
-	"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",
-	"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",
-	"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",
-};
-
-/**
- * get_arch_regstr() - lookup register name from it's DWARF register number
- * @n:	the DWARF register number
- *
- * get_arch_regstr() returns the name of the register in struct
- * regdwarfnum_table from it's DWARF register number. If the register is not
- * found in the table, this returns NULL;
- */
-const char *get_arch_regstr(unsigned int n)
-{
-	return (n < SPARC_MAX_REGS) ? sparc_regs_table[n] : NULL;
-}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 944ff4ef0290..a0bcc2529cb0 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -34,7 +34,8 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 {
 #if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
     || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH || EM_HOST == EM_MIPS || EM_HOST == EM_PPC \
-    || EM_HOST == EM_PPC64 || EM_HOST == EM_RISCV || EM_HOST == EM_S390 || EM_HOST == EM_SH
+    || EM_HOST == EM_PPC64 || EM_HOST == EM_RISCV || EM_HOST == EM_S390 || EM_HOST == EM_SH \
+    || EM_HOST == EM_SPARC || EM_HOST == EM_SPARCV9
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
@@ -43,7 +44,8 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 	switch (machine) {
 #if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
     && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH && EM_HOST != EM_MIPS && EM_HOST != EM_PPC \
-    && EM_HOST != EM_PPC64 && EM_HOST != EM_RISCV && EM_HOST != EM_S390 && EM_HOST != EM_SH
+    && EM_HOST != EM_PPC64 && EM_HOST != EM_RISCV && EM_HOST != EM_S390 && EM_HOST != EM_SH \
+    && EM_HOST != EM_SPARC && EM_HOST != EM_SPARCV9
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 7026a3d2aaa7..cb632d1f46f3 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -91,7 +91,8 @@
 #ifdef HAVE_LIBDW_SUPPORT
 #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__) \
     && !defined(__loongarch__) && !defined(__mips__) && !defined(__powerpc__) \
-    && !defined(__powerpc64__) && !defined(__riscv__) && !defined(__s390x__) && !defined(__sh__)
+    && !defined(__powerpc64__) && !defined(__riscv__) && !defined(__s390x__) && !defined(__sh__) \
+    && !defined(__sparc64__) && !defined(__sparc__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:46:03 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:46:03 -0800
Subject: [PATCH v4 18/20] perf xtensa: Remove dwarf-regs.c
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-19-irogers@google.com>

The file just provides the function get_arch_regstr, however, if in
the only caller get_dwarf_regstr EM_HOST is used for the EM_NONE case
the function can never be called. So remove as dead code. As this is
the only file in the arch/xtensa/util clean up Build files. Tidy up the
EM_NONE cases for xtensa in dwarf-regs.c.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/arch/xtensa/Build             |  1 -
 tools/perf/arch/xtensa/util/Build        |  1 -
 tools/perf/arch/xtensa/util/dwarf-regs.c | 21 ---------------------
 tools/perf/util/dwarf-regs.c             |  4 ++--
 tools/perf/util/include/dwarf-regs.h     |  2 +-
 5 files changed, 3 insertions(+), 26 deletions(-)
 delete mode 100644 tools/perf/arch/xtensa/Build
 delete mode 100644 tools/perf/arch/xtensa/util/Build
 delete mode 100644 tools/perf/arch/xtensa/util/dwarf-regs.c

diff --git a/tools/perf/arch/xtensa/Build b/tools/perf/arch/xtensa/Build
deleted file mode 100644
index e63eabc2c8f4..000000000000
--- a/tools/perf/arch/xtensa/Build
+++ /dev/null
@@ -1 +0,0 @@
-perf-util-y += util/
diff --git a/tools/perf/arch/xtensa/util/Build b/tools/perf/arch/xtensa/util/Build
deleted file mode 100644
index 2d1a48696ad9..000000000000
--- a/tools/perf/arch/xtensa/util/Build
+++ /dev/null
@@ -1 +0,0 @@
-perf-$(CONFIG_LIBDW) += dwarf-regs.o
diff --git a/tools/perf/arch/xtensa/util/dwarf-regs.c b/tools/perf/arch/xtensa/util/dwarf-regs.c
deleted file mode 100644
index 12f5457300f5..000000000000
--- a/tools/perf/arch/xtensa/util/dwarf-regs.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Mapping of DWARF debug register numbers into register names.
- *
- * Copyright (c) 2015 Cadence Design Systems Inc.
- */
-
-#include <stddef.h>
-#include <dwarf-regs.h>
-
-#define XTENSA_MAX_REGS 16
-
-const char *xtensa_regs_table[XTENSA_MAX_REGS] = {
-	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
-	"a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15",
-};
-
-const char *get_arch_regstr(unsigned int n)
-{
-	return n < XTENSA_MAX_REGS ? xtensa_regs_table[n] : NULL;
-}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index a0bcc2529cb0..05fff75a8f59 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -35,7 +35,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 #if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
     || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH || EM_HOST == EM_MIPS || EM_HOST == EM_PPC \
     || EM_HOST == EM_PPC64 || EM_HOST == EM_RISCV || EM_HOST == EM_S390 || EM_HOST == EM_SH \
-    || EM_HOST == EM_SPARC || EM_HOST == EM_SPARCV9
+    || EM_HOST == EM_SPARC || EM_HOST == EM_SPARCV9 || EM_HOST == EM_XTENSA
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
@@ -45,7 +45,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int
 #if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
     && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH && EM_HOST != EM_MIPS && EM_HOST != EM_PPC \
     && EM_HOST != EM_PPC64 && EM_HOST != EM_RISCV && EM_HOST != EM_S390 && EM_HOST != EM_SH \
-    && EM_HOST != EM_SPARC && EM_HOST != EM_SPARCV9
+    && EM_HOST != EM_SPARC && EM_HOST != EM_SPARCV9 && EM_HOST != EM_XTENSA
 	case EM_NONE:	/* Generic arch - use host arch */
 		return get_arch_regstr(n);
 #endif
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index cb632d1f46f3..e0f1d65895f5 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -92,7 +92,7 @@
 #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__) \
     && !defined(__loongarch__) && !defined(__mips__) && !defined(__powerpc__) \
     && !defined(__powerpc64__) && !defined(__riscv__) && !defined(__s390x__) && !defined(__sh__) \
-    && !defined(__sparc64__) && !defined(__sparc__)
+    && !defined(__sparc64__) && !defined(__sparc__) && !defined(__xtensa__)
 const char *get_arch_regstr(unsigned int n);
 #endif
 
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:46:04 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:46:04 -0800
Subject: [PATCH v4 19/20] perf dwarf-regs: Remove get_arch_regstr code
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-20-irogers@google.com>

get_arch_regstr no longer exists so remove declaration. Associated ifs
and switches are made unconditional.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/dwarf-regs.c         | 12 ------------
 tools/perf/util/include/dwarf-regs.h |  7 -------
 2 files changed, 19 deletions(-)

diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 05fff75a8f59..28a1cfdf26d4 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -32,23 +32,11 @@
 /* Return architecture dependent register string (for kprobe-tracer) */
 const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags)
 {
-#if EM_HOST == EM_X86_64 || EM_HOST == EM_386 || EM_HOST == EM_AARCH64 || EM_HOST == EM_ARM \
-    || EM_HOST == EM_CSKY || EM_HOST == EM_LOONGARCH || EM_HOST == EM_MIPS || EM_HOST == EM_PPC \
-    || EM_HOST == EM_PPC64 || EM_HOST == EM_RISCV || EM_HOST == EM_S390 || EM_HOST == EM_SH \
-    || EM_HOST == EM_SPARC || EM_HOST == EM_SPARCV9 || EM_HOST == EM_XTENSA
 	if (machine == EM_NONE) {
 		/* Generic arch - use host arch */
 		machine = EM_HOST;
 	}
-#endif
 	switch (machine) {
-#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 && EM_HOST != EM_AARCH64 && EM_HOST != EM_ARM \
-    && EM_HOST != EM_CSKY && EM_HOST != EM_LOONGARCH && EM_HOST != EM_MIPS && EM_HOST != EM_PPC \
-    && EM_HOST != EM_PPC64 && EM_HOST != EM_RISCV && EM_HOST != EM_S390 && EM_HOST != EM_SH \
-    && EM_HOST != EM_SPARC && EM_HOST != EM_SPARCV9 && EM_HOST != EM_XTENSA
-	case EM_NONE:	/* Generic arch - use host arch */
-		return get_arch_regstr(n);
-#endif
 	case EM_386:
 		return __get_dwarf_regstr(x86_32_regstr_tbl, n);
 	case EM_X86_64:
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index e0f1d65895f5..6f1b9f6b2466 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -89,13 +89,6 @@
 #define DWARF_REG_FB  0xd3affb /* random number */
 
 #ifdef HAVE_LIBDW_SUPPORT
-#if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && !defined(__arm__) \
-    && !defined(__loongarch__) && !defined(__mips__) && !defined(__powerpc__) \
-    && !defined(__powerpc64__) && !defined(__riscv__) && !defined(__s390x__) && !defined(__sh__) \
-    && !defined(__sparc64__) && !defined(__sparc__) && !defined(__xtensa__)
-const char *get_arch_regstr(unsigned int n);
-#endif
-
 const char *get_csky_regstr(unsigned int n, unsigned int flags);
 
 /**
-- 
2.47.0.277.g8800431eea-goog



From irogers at google.com  Fri Nov  8 15:46:05 2024
From: irogers at google.com (Ian Rogers)
Date: Fri,  8 Nov 2024 15:46:05 -0800
Subject: [PATCH v4 20/20] perf build: Remove PERF_HAVE_DWARF_REGS
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <20241108234606.429459-21-irogers@google.com>

PERF_HAVE_DWARF_REGS was true when an architecture had a dwarf-regs.c
file. There are no more architecture dwarf-regs.c files, selection is
done using constants from the ELF file rather than conditional
compilation. When removing PERF_HAVE_DWARF_REGS was the only variable
in the Makefile, remove the Makefile.

Add missing SPDX for RISC-V Makefile.

Reviewed-by: Masami Hiramatsu (Google) <mhiramat at kernel.org>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/Makefile.config         | 13 ++++---------
 tools/perf/arch/arm/Makefile       |  3 ---
 tools/perf/arch/arm64/Makefile     |  3 ---
 tools/perf/arch/csky/Makefile      |  4 ----
 tools/perf/arch/loongarch/Makefile |  3 ---
 tools/perf/arch/mips/Makefile      |  4 ----
 tools/perf/arch/powerpc/Makefile   |  4 ----
 tools/perf/arch/riscv/Makefile     |  4 +---
 tools/perf/arch/s390/Makefile      |  3 ---
 tools/perf/arch/sh/Makefile        |  4 ----
 tools/perf/arch/sparc/Makefile     |  4 ----
 tools/perf/arch/x86/Makefile       |  3 ---
 tools/perf/arch/xtensa/Makefile    |  4 ----
 13 files changed, 5 insertions(+), 51 deletions(-)
 delete mode 100644 tools/perf/arch/csky/Makefile
 delete mode 100644 tools/perf/arch/sh/Makefile
 delete mode 100644 tools/perf/arch/xtensa/Makefile

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 52a216df9e2a..2916d59c88cd 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -559,15 +559,10 @@ ifndef NO_LIBELF
   endif
 
   ifndef NO_LIBDW
-    ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
-      $(warning DWARF register mappings have not been defined for architecture $(SRCARCH), DWARF support disabled)
-      NO_LIBDW := 1
-    else
-      CFLAGS += -DHAVE_LIBDW_SUPPORT $(LIBDW_CFLAGS)
-      LDFLAGS += $(LIBDW_LDFLAGS)
-      EXTLIBS += ${DWARFLIBS}
-      $(call detected,CONFIG_LIBDW)
-    endif # PERF_HAVE_DWARF_REGS
+    CFLAGS += -DHAVE_LIBDW_SUPPORT $(LIBDW_CFLAGS)
+    LDFLAGS += $(LIBDW_LDFLAGS)
+    EXTLIBS += ${DWARFLIBS}
+    $(call detected,CONFIG_LIBDW)
   endif # NO_LIBDW
 
   ifndef NO_LIBBPF
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 9b164d379548..8b59ce8efb89 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -1,5 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
 PERF_HAVE_JITDUMP := 1
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
index ca2e35961287..91570d5d428e 100644
--- a/tools/perf/arch/arm64/Makefile
+++ b/tools/perf/arch/arm64/Makefile
@@ -1,7 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
 
diff --git a/tools/perf/arch/csky/Makefile b/tools/perf/arch/csky/Makefile
deleted file mode 100644
index 119b06a64bed..000000000000
--- a/tools/perf/arch/csky/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
diff --git a/tools/perf/arch/loongarch/Makefile b/tools/perf/arch/loongarch/Makefile
index 79b432744296..52544d59245b 100644
--- a/tools/perf/arch/loongarch/Makefile
+++ b/tools/perf/arch/loongarch/Makefile
@@ -1,7 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
 
diff --git a/tools/perf/arch/mips/Makefile b/tools/perf/arch/mips/Makefile
index 733f7b76f52d..827168f1077a 100644
--- a/tools/perf/arch/mips/Makefile
+++ b/tools/perf/arch/mips/Makefile
@@ -1,8 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
-
 # Syscall table generation for perf
 out    := $(OUTPUT)arch/mips/include/generated/asm
 header := $(out)/syscalls_n64.c
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index ae05727835d8..dc8f4fb8e324 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -1,8 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
-
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
 
diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
index d83e0f32f3a8..18ad078000e2 100644
--- a/tools/perf/arch/riscv/Makefile
+++ b/tools/perf/arch/riscv/Makefile
@@ -1,6 +1,4 @@
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
+# SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
 HAVE_KVM_STAT_SUPPORT := 1
 
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
index 58e79f5b67a4..c431c21b11ef 100644
--- a/tools/perf/arch/s390/Makefile
+++ b/tools/perf/arch/s390/Makefile
@@ -1,7 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
 
diff --git a/tools/perf/arch/sh/Makefile b/tools/perf/arch/sh/Makefile
deleted file mode 100644
index 119b06a64bed..000000000000
--- a/tools/perf/arch/sh/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
diff --git a/tools/perf/arch/sparc/Makefile b/tools/perf/arch/sparc/Makefile
index 7741184894c8..8b59ce8efb89 100644
--- a/tools/perf/arch/sparc/Makefile
+++ b/tools/perf/arch/sparc/Makefile
@@ -1,6 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
-
 PERF_HAVE_JITDUMP := 1
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index 51cf267f4d85..a6b6e0a9308a 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -1,7 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
 HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
 
diff --git a/tools/perf/arch/xtensa/Makefile b/tools/perf/arch/xtensa/Makefile
deleted file mode 100644
index 119b06a64bed..000000000000
--- a/tools/perf/arch/xtensa/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-ifndef NO_LIBDW
-PERF_HAVE_DWARF_REGS := 1
-endif
-- 
2.47.0.277.g8800431eea-goog



From charlie at rivosinc.com  Fri Nov  8 15:47:36 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Fri, 08 Nov 2024 15:47:36 -0800
Subject: [PATCH for-next v2] riscv: Fix default misaligned access trap
Message-ID: <20241108-fix_handle_misaligned_load-v2-1-91d547ce64db@rivosinc.com>

Commit d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses
supported") removed the default handlers for handle_misaligned_load()
and handle_misaligned_store(). When the kernel is compiled without
RISCV_SCALAR_MISALIGNED, these handlers are never defined, causing
compilation errors.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Fixes: d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses supported")
---
Changes in v2:
- Change CONFIG_RISCV_SCALAR_MISALIGNED to CONFIG_RISCV_MISALIGNED
  (Jesse)
- Link to v1: https://lore.kernel.org/r/20241107-fix_handle_misaligned_load-v1-1-07d7852c9991 at rivosinc.com
---
 arch/riscv/include/asm/entry-common.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/riscv/include/asm/entry-common.h b/arch/riscv/include/asm/entry-common.h
index 7b32d2b08bb6..b28ccc6cdeea 100644
--- a/arch/riscv/include/asm/entry-common.h
+++ b/arch/riscv/include/asm/entry-common.h
@@ -25,7 +25,19 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
 void handle_page_fault(struct pt_regs *regs);
 void handle_break(struct pt_regs *regs);
 
+#ifdef CONFIG_RISCV_MISALIGNED
 int handle_misaligned_load(struct pt_regs *regs);
 int handle_misaligned_store(struct pt_regs *regs);
+#else
+static inline int handle_misaligned_load(struct pt_regs *regs)
+{
+	return -1;
+}
+
+static inline int handle_misaligned_store(struct pt_regs *regs)
+{
+	return -1;
+}
+#endif
 
 #endif /* _ASM_RISCV_ENTRY_COMMON_H */

---
base-commit: 74741a050b79d31d8d2eeee12c77736596d0a6b2
change-id: 20241107-fix_handle_misaligned_load-8be86cb0806e
-- 
- Charlie



From ruanjinjie at huawei.com  Fri Nov  8 17:46:05 2024
From: ruanjinjie at huawei.com (Jinjie Ruan)
Date: Sat, 9 Nov 2024 09:46:05 +0800
Subject: [PATCH] riscv: Remove unused TASK_TI_FLAGS
Message-ID: <20241109014605.2801492-1-ruanjinjie@huawei.com>

Since commit f0bddf50586d ("riscv: entry: Convert to generic
entry"), TASK_TI_FLAGS is not used any more, so remove it.

Fixes: f0bddf50586d ("riscv: entry: Convert to generic entry")
Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
---
 arch/riscv/kernel/asm-offsets.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index c2f3129a8e5c..d3ad87fcf1ef 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -36,7 +36,6 @@ void asm_offsets(void)
 	OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]);
 
 	OFFSET(TASK_TI_CPU, task_struct, thread_info.cpu);
-	OFFSET(TASK_TI_FLAGS, task_struct, thread_info.flags);
 	OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count);
 	OFFSET(TASK_TI_KERNEL_SP, task_struct, thread_info.kernel_sp);
 	OFFSET(TASK_TI_USER_SP, task_struct, thread_info.user_sp);
-- 
2.34.1



From drew at pdp7.com  Fri Nov  8 18:42:22 2024
From: drew at pdp7.com (Drew Fustini)
Date: Fri, 8 Nov 2024 18:42:22 -0800
Subject: RISC-V T-HEAD Devicetrees for v6.13, part 2
Message-ID: <Zy7MDgtCtPkxLbjm@x1>

Hi Arnd,

Please pull these thead dts changes. I've run W=1 dtbs_check and the
new ethernet support has been tested in linux-next.

Thanks,
Drew

The following changes since commit 2a3bf75a9408c40403aab39336274c8010b4c815:

  riscv: dts: thead: remove enabled property for spi0 (2024-10-15 10:01:18 -0700)

are available in the Git repository at:

  git at github.com:pdp7/linux.git tags/thead-dt-for-v6.13-p2

for you to fetch changes up to 7e756671a664b73b2a3c0cc37fd25abf6bcd851e:

  riscv: dts: thead: Add TH1520 ethernet nodes (2024-11-06 17:03:42 -0800)

----------------------------------------------------------------
T-HEAD Devicetrees for v6.13, part 2

Add gmac, mdio, and phy nodes to enable the gigabit Ethernet ports on
the TH1520 SoC-based BeagleV Ahead and Sipeed Lichee Pi 4a boards.

The dwmac-thead driver and dt binding have been accepted by netdev and
are in linux-next as well as the dts patch in this pull request. I have
tested next-20241108 on the Ahead and LPi4a boards, and Ethernet works
correctly.

Signed-off-by: Drew Fustini <drew at pdp7.com>

----------------------------------------------------------------
Emil Renner Berthing (1):
      riscv: dts: thead: Add TH1520 ethernet nodes

 arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts |  91 ++++++++++++++++
 .../boot/dts/thead/th1520-lichee-module-4a.dtsi    | 119 +++++++++++++++++++++
 arch/riscv/boot/dts/thead/th1520.dtsi              |  50 +++++++++
 3 files changed, 260 insertions(+)


From yangyicong at huawei.com  Sat Nov  9 02:54:26 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Sat, 9 Nov 2024 18:54:26 +0800
Subject: [PATCH v2 8/8] perf pmu: Move pmu_metrics_table__find and remove
 ARM override
In-Reply-To: <20241107162035.52206-9-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
 <20241107162035.52206-9-irogers@google.com>
Message-ID: <5a57de7c-924e-ccd6-8981-b9fddc647465@huawei.com>

Hi,

On 2024/11/8 0:20, Ian Rogers wrote:
> Move pmu_metrics_table__find to the jevents.py generated pmu-events.c
> and remove indirection override for ARM. The movement removes
> perf_pmu__find_metrics_table that exists to enable the ARM
> override. The ARM override isn't necessary as just the CPUID, not PMU,
> is used in the metric table lookup. On non-ARM the CPU argument is
> just ignored for the CPUID, for ARM -1 is passed so that the CPUID for
> the first logical CPU is read.

Since the logic here's already been touching, is it possible to step it further to just
ignore the CPUID matching when finding the system metrics/events tables? It's may not be
that reasonable for finding a system metrics/events from the CPUID, since one system PMU may
exists on different platforms with different CPU types.

FYI, there's a similiar problem when trying to count the system metrics but fails [1].
I've tested with this series but the problem still exists.

[1] https://lore.kernel.org/linux-perf-users/20241010074430.16685-1-hejunhao3 at huawei.com/

Thanks.

> 
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/arch/arm64/util/pmu.c         | 20 --------------------
>  tools/perf/pmu-events/empty-pmu-events.c | 10 ++++------
>  tools/perf/pmu-events/jevents.py         | 10 ++++------
>  tools/perf/pmu-events/pmu-events.h       |  2 +-
>  tools/perf/util/pmu.c                    |  5 -----
>  tools/perf/util/pmu.h                    |  1 -
>  6 files changed, 9 insertions(+), 39 deletions(-)
> 
> diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/pmu.c
> index a0964b191fcb..895fb0d0610c 100644
> --- a/tools/perf/arch/arm64/util/pmu.c
> +++ b/tools/perf/arch/arm64/util/pmu.c
> @@ -1,29 +1,9 @@
>  // SPDX-License-Identifier: GPL-2.0
>  
> -#include <internal/cpumap.h>
> -#include "../../../util/cpumap.h"
> -#include "../../../util/header.h"
>  #include "../../../util/pmu.h"
>  #include "../../../util/pmus.h"
>  #include "../../../util/tool_pmu.h"
>  #include <api/fs/fs.h>
> -#include <math.h>
> -
> -const struct pmu_metrics_table *pmu_metrics_table__find(void)
> -{
> -	struct perf_pmu *pmu;
> -
> -	/* Metrics aren't currently supported on heterogeneous Arm systems */
> -	if (perf_pmus__num_core_pmus() > 1)
> -		return NULL;
> -
> -	/* Doesn't matter which one here because they'll all be the same */
> -	pmu = perf_pmus__find_core_pmu();
> -	if (pmu)
> -		return perf_pmu__find_metrics_table(pmu);
> -
> -	return NULL;
> -}
>  
>  u64 tool_pmu__cpu_slots_per_cycle(void)
>  {
> diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
> index 17306e316a3c..1c7a2cfa321f 100644
> --- a/tools/perf/pmu-events/empty-pmu-events.c
> +++ b/tools/perf/pmu-events/empty-pmu-events.c
> @@ -587,14 +587,12 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
>          return NULL;
>  }
>  
> -const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
> +const struct pmu_metrics_table *pmu_metrics_table__find(void)
>  {
> -        const struct pmu_events_map *map = map_for_pmu(pmu);
> -
> -        if (!map)
> -                return NULL;
> +        struct perf_cpu cpu = {-1};
> +        const struct pmu_events_map *map = map_for_cpu(cpu);
>  
> -	return &map->metric_table;
> +        return map ? &map->metric_table : NULL;
>  }
>  
>  const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
> diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
> index e44b72e56ac3..d781a377757a 100755
> --- a/tools/perf/pmu-events/jevents.py
> +++ b/tools/perf/pmu-events/jevents.py
> @@ -1103,14 +1103,12 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
>          return NULL;
>  }
>  
> -const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
> +const struct pmu_metrics_table *pmu_metrics_table__find(void)
>  {
> -        const struct pmu_events_map *map = map_for_pmu(pmu);
> -
> -        if (!map)
> -                return NULL;
> +        struct perf_cpu cpu = {-1};
> +        const struct pmu_events_map *map = map_for_cpu(cpu);
>  
> -	return &map->metric_table;
> +        return map ? &map->metric_table : NULL;
>  }
>  
>  const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
> diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
> index 5435ad92180c..675562e6f770 100644
> --- a/tools/perf/pmu-events/pmu-events.h
> +++ b/tools/perf/pmu-events/pmu-events.h
> @@ -103,7 +103,7 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pm
>  				     void *data);
>  
>  const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu);
> -const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu);
> +const struct pmu_metrics_table *pmu_metrics_table__find(void);
>  const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid);
>  const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid);
>  int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data);
> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> index 514cb865f57b..45838651b361 100644
> --- a/tools/perf/util/pmu.c
> +++ b/tools/perf/util/pmu.c
> @@ -818,11 +818,6 @@ static int is_sysfs_pmu_core(const char *name)
>  	return file_available(path);
>  }
>  
> -__weak const struct pmu_metrics_table *pmu_metrics_table__find(void)
> -{
> -	return perf_pmu__find_metrics_table(NULL);
> -}
> -
>  /**
>   * Return the length of the PMU name not including the suffix for uncore PMUs.
>   *
> diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
> index fba3fc608b64..7b3e71194e49 100644
> --- a/tools/perf/util/pmu.h
> +++ b/tools/perf/util/pmu.h
> @@ -260,7 +260,6 @@ void perf_pmu__arch_init(struct perf_pmu *pmu);
>  void pmu_add_cpu_aliases_table(struct perf_pmu *pmu,
>  			       const struct pmu_events_table *table);
>  
> -const struct pmu_metrics_table *pmu_metrics_table__find(void);
>  bool pmu_uncore_identifier_match(const char *compat, const char *id);
>  
>  int perf_pmu__convert_scale(const char *scale, char **end, double *sval);
> 


From irogers at google.com  Sat Nov  9 08:10:22 2024
From: irogers at google.com (Ian Rogers)
Date: Sat, 9 Nov 2024 08:10:22 -0800
Subject: [PATCH v2 8/8] perf pmu: Move pmu_metrics_table__find and remove
 ARM override
In-Reply-To: <5a57de7c-924e-ccd6-8981-b9fddc647465@huawei.com>
References: <20241107162035.52206-1-irogers@google.com> <20241107162035.52206-9-irogers@google.com>
 <5a57de7c-924e-ccd6-8981-b9fddc647465@huawei.com>
Message-ID: <CAP-5=fWw04Qi+3=y7M4uMrhgrFWpnF7mZ09yb4v0P0qFT1Gfnw@mail.gmail.com>

On Sat, Nov 9, 2024 at 2:54?AM Yicong Yang <yangyicong at huawei.com> wrote:
>
> Hi,
>
> On 2024/11/8 0:20, Ian Rogers wrote:
> > Move pmu_metrics_table__find to the jevents.py generated pmu-events.c
> > and remove indirection override for ARM. The movement removes
> > perf_pmu__find_metrics_table that exists to enable the ARM
> > override. The ARM override isn't necessary as just the CPUID, not PMU,
> > is used in the metric table lookup. On non-ARM the CPU argument is
> > just ignored for the CPUID, for ARM -1 is passed so that the CPUID for
> > the first logical CPU is read.
>
> Since the logic here's already been touching, is it possible to step it further to just
> ignore the CPUID matching when finding the system metrics/events tables? It's may not be
> that reasonable for finding a system metrics/events from the CPUID, since one system PMU may
> exists on different platforms with different CPU types.

The issue is for conciseness reasons we let metrics and metric
thresholds refer to other metrics, for example:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/pmu-events/arch/x86/icelakex/icx-metrics.json#n78
```
    {
        "BriefDescription": "This category represents fraction of
slots where no uops are being delivered due to a lack of required
resources for accepting new uops in the Backend",
        "MetricExpr": "topdown\\-be\\-bound / (topdown\\-fe\\-bound +
topdown\\-bad\\-spec + topdown\\-retiring + topdown\\-be\\-bound) + 5
* cpu at INT_MISC.RECOVERY_CYCLES\\,cmask\\=1\\,edge@ / tma_info_slots",
        "MetricGroup": "TmaL1;TopdownL1;tma_L1_group",
        "MetricName": "tma_backend_bound",
        "MetricThreshold": "tma_backend_bound > 0.2",
        "MetricgroupNoGroup": "TopdownL1",
        "PublicDescription": "This category represents fraction of
slots where no uops are being delivered due to a lack of required
resources for accepting new uops in the Backend. Backend is the
portion of the processor core where the out-of-order scheduler
dispatches ready uops into their respective execution units; and once
completed these uops get retired according to program order. For
example; stalls due to data-cache misses or stalls due to the divider
unit being overloaded are both categorized under Backend Bound.
Backend Bound is further divided into two main categories: Memory
Bound and Core Bound. Sample with: TOPDOWN.BACKEND_BOUND_SLOTS",
        "ScaleUnit": "100%"
    },
```

The system metrics were added on top of this and we never rethought
the design. For a metric to refer to another metric there needs to be
some kind of place we look up from and for that we use the CPUID
associated table. Perhaps the easiest thing is that if no CPUID table
is matched we have an empty table.

> FYI, there's a similiar problem when trying to count the system metrics but fails [1].
> I've tested with this series but the problem still exists.

Not sure what you are asking me for here.

Thanks,
Ian

> [1] https://lore.kernel.org/linux-perf-users/20241010074430.16685-1-hejunhao3 at huawei.com/
>
> Thanks.
>
> >
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >  tools/perf/arch/arm64/util/pmu.c         | 20 --------------------
> >  tools/perf/pmu-events/empty-pmu-events.c | 10 ++++------
> >  tools/perf/pmu-events/jevents.py         | 10 ++++------
> >  tools/perf/pmu-events/pmu-events.h       |  2 +-
> >  tools/perf/util/pmu.c                    |  5 -----
> >  tools/perf/util/pmu.h                    |  1 -
> >  6 files changed, 9 insertions(+), 39 deletions(-)
> >
> > diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/pmu.c
> > index a0964b191fcb..895fb0d0610c 100644
> > --- a/tools/perf/arch/arm64/util/pmu.c
> > +++ b/tools/perf/arch/arm64/util/pmu.c
> > @@ -1,29 +1,9 @@
> >  // SPDX-License-Identifier: GPL-2.0
> >
> > -#include <internal/cpumap.h>
> > -#include "../../../util/cpumap.h"
> > -#include "../../../util/header.h"
> >  #include "../../../util/pmu.h"
> >  #include "../../../util/pmus.h"
> >  #include "../../../util/tool_pmu.h"
> >  #include <api/fs/fs.h>
> > -#include <math.h>
> > -
> > -const struct pmu_metrics_table *pmu_metrics_table__find(void)
> > -{
> > -     struct perf_pmu *pmu;
> > -
> > -     /* Metrics aren't currently supported on heterogeneous Arm systems */
> > -     if (perf_pmus__num_core_pmus() > 1)
> > -             return NULL;
> > -
> > -     /* Doesn't matter which one here because they'll all be the same */
> > -     pmu = perf_pmus__find_core_pmu();
> > -     if (pmu)
> > -             return perf_pmu__find_metrics_table(pmu);
> > -
> > -     return NULL;
> > -}
> >
> >  u64 tool_pmu__cpu_slots_per_cycle(void)
> >  {
> > diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-events/empty-pmu-events.c
> > index 17306e316a3c..1c7a2cfa321f 100644
> > --- a/tools/perf/pmu-events/empty-pmu-events.c
> > +++ b/tools/perf/pmu-events/empty-pmu-events.c
> > @@ -587,14 +587,12 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
> >          return NULL;
> >  }
> >
> > -const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
> > +const struct pmu_metrics_table *pmu_metrics_table__find(void)
> >  {
> > -        const struct pmu_events_map *map = map_for_pmu(pmu);
> > -
> > -        if (!map)
> > -                return NULL;
> > +        struct perf_cpu cpu = {-1};
> > +        const struct pmu_events_map *map = map_for_cpu(cpu);
> >
> > -     return &map->metric_table;
> > +        return map ? &map->metric_table : NULL;
> >  }
> >
> >  const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
> > diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
> > index e44b72e56ac3..d781a377757a 100755
> > --- a/tools/perf/pmu-events/jevents.py
> > +++ b/tools/perf/pmu-events/jevents.py
> > @@ -1103,14 +1103,12 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
> >          return NULL;
> >  }
> >
> > -const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
> > +const struct pmu_metrics_table *pmu_metrics_table__find(void)
> >  {
> > -        const struct pmu_events_map *map = map_for_pmu(pmu);
> > -
> > -        if (!map)
> > -                return NULL;
> > +        struct perf_cpu cpu = {-1};
> > +        const struct pmu_events_map *map = map_for_cpu(cpu);
> >
> > -     return &map->metric_table;
> > +        return map ? &map->metric_table : NULL;
> >  }
> >
> >  const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
> > diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
> > index 5435ad92180c..675562e6f770 100644
> > --- a/tools/perf/pmu-events/pmu-events.h
> > +++ b/tools/perf/pmu-events/pmu-events.h
> > @@ -103,7 +103,7 @@ int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table, pm
> >                                    void *data);
> >
> >  const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu);
> > -const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu);
> > +const struct pmu_metrics_table *pmu_metrics_table__find(void);
> >  const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid);
> >  const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid);
> >  int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data);
> > diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> > index 514cb865f57b..45838651b361 100644
> > --- a/tools/perf/util/pmu.c
> > +++ b/tools/perf/util/pmu.c
> > @@ -818,11 +818,6 @@ static int is_sysfs_pmu_core(const char *name)
> >       return file_available(path);
> >  }
> >
> > -__weak const struct pmu_metrics_table *pmu_metrics_table__find(void)
> > -{
> > -     return perf_pmu__find_metrics_table(NULL);
> > -}
> > -
> >  /**
> >   * Return the length of the PMU name not including the suffix for uncore PMUs.
> >   *
> > diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
> > index fba3fc608b64..7b3e71194e49 100644
> > --- a/tools/perf/util/pmu.h
> > +++ b/tools/perf/util/pmu.h
> > @@ -260,7 +260,6 @@ void perf_pmu__arch_init(struct perf_pmu *pmu);
> >  void pmu_add_cpu_aliases_table(struct perf_pmu *pmu,
> >                              const struct pmu_events_table *table);
> >
> > -const struct pmu_metrics_table *pmu_metrics_table__find(void);
> >  bool pmu_uncore_identifier_match(const char *compat, const char *id);
> >
> >  int perf_pmu__convert_scale(const char *scale, char **end, double *sval);
> >


From cyy at cyyself.name  Sat Nov  9 09:09:09 2024
From: cyy at cyyself.name (Yangyu Chen)
Date: Sun, 10 Nov 2024 01:09:09 +0800
Subject: [PATCH v10 00/14] riscv: Add support for xtheadvector
In-Reply-To: <CAJFTR8REgZkOVGP+Y3skYPYbdV6x3E2iMfWjg0SoSkaSxQtGig@mail.gmail.com>
References: <20240911-xtheadvector-v10-0-8d3930091246@rivosinc.com>
 <a1f41f92-6bd0-48b6-a931-e7ad7aba18cc@outlook.com>
 <20240930-reenact-stratus-9d42d7439df4@spud>
 <d9eaaf71-dfe7-4bf8-8aee-538ee8ad9f24@outlook.com>
 <CAJFTR8REgZkOVGP+Y3skYPYbdV6x3E2iMfWjg0SoSkaSxQtGig@mail.gmail.com>
Message-ID: <tencent_EA66C5C485CC35BAF2250AD26A5F39EAE10A@qq.com>



On 11/9/24 06:16, Jesse T wrote:
> Hey Palmer there are a bunch of merge artifacts in for-next from this
> set. Just letting you know.
> https://git.kernel.org/pub/scm/linux/kernel/git/palmer/linux.git/commit/?h=for-next&id=95437f8c02b5907b5f2d7dc6c03e3c73523c5cd6
> 

I think these can be merged with keep both merge option except for the 
line "#define RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0	9". The 9 here should 
be changed to 11.

> On Mon, Sep 30, 2024 at 11:52?AM Aoba K <nExp_0x17 at outlook.com> wrote:
>>
>> The devicetree name shown in OpenSBI is
>> the one packed with U-Boot SPL.
>> As the image builder didn't put the kernel
>> devicetree with the image under boot partition,
>> The whole boot process only uses the U-Boot device tree.
>>
>> The reason why the log shows "Nezha"
>> but not "Lichee RV" is that this log is produced
>> which U-Boot revision is d1-2022-10-31 from samuel's repo.
>> Build from d1-wip can show "Lichee RV" correctly
>> (manually edit config to specify LicheeRV dtb should have same effect though),
>> while the issue persists when kernel load to
>> the procedure same as the dmesg mentioned above.
>>
>>
>> Cheers,
>> Aoba K
>>
>> 2024?9?30? ??10:53:40 Conor Dooley <conor at kernel.org>:
>>
>>> On Sun, Sep 29, 2024 at 12:44:07PM +0000, Aoba K wrote:
>>>> Hello Charlie,
>>>>
>>>> I've been working on bringing up the Sipeed Lichee RV Dock
>>>> (which also uses the D1 SoC) with the kernel patches you provided.
>>>> The patches applied cleanly to Palmer's for-next branch,
>>>> but I've encountered a couple of issues:
>>>>
>>>> 1. Skiffos Compilation Error during the compilation process of `cgo`:
>>>> `unknown relocation type 17; compiled without -fpic?`
>>>> Unfortunately, I closed the terminal before saving the full log,
>>>> so I don't have the complete details, but the result should be reproducible.
>>>> While this should be a SkiffOS issue, mention it in case SkiffOS is the method
>>>> that you mentioned for bringing up the device.
>>>>
>>>> 2. Image Building with sehraf/riscv-arch-image-builder:
>>>> After building the image, the device failed to start at an early stage.
>>>> I suspect this may be related to incorrect RAM size detection,
>>>> as the board only has 512MB of RAM.
>>>> Interestingly, the vendor image reports 1GB, and the Sipeed website also states
>>>> that the Dock has 1GB, despite there being no extra memory bank present.
>>>>
>>>> You can find the boot log here: https://fars.ee/bdYk.log
>>>>
>>>> Any help would be appreciated, and big thanks to your work
>>>> to make the efficient part of this board to work (again)!
>>>
>>> The log you posted at https://fars.ee/XFzR appears to be using the
>>> devicetree of a Nezha not the Lichee RV Dock. Why are you doing that,
>>> when the Lichee RV Dock is supported in the kernel already?
>>>
>>> Cheers,
>>> Conor.
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv




From cyy at cyyself.name  Sat Nov  9 11:34:54 2024
From: cyy at cyyself.name (Yangyu Chen)
Date: Sun, 10 Nov 2024 03:34:54 +0800
Subject: [PATCH v10 05/14] riscv: vector: Use vlenb from DT for thead
In-Reply-To: <20240911-xtheadvector-v10-5-8d3930091246@rivosinc.com>
References: <20240911-xtheadvector-v10-0-8d3930091246@rivosinc.com>
 <20240911-xtheadvector-v10-5-8d3930091246@rivosinc.com>
Message-ID: <tencent_2EF88DF37C4B82B2DA0B8E49B85C312E2108@qq.com>

Hi Charlie,

I have tested this patchset with ghostwrite rebased to linux commit da4373fbcf ("Merge tag 'thermal-6.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm") [1] on my D1 Nezha board, with defconfig + CONFIG_ERRATA_THEAD_GHOSTWRITE=n, I got this message during boot:

[    0.027584] Kernel panic - not syncing: __kmem_cache_create_args: Failed to create slab 'riscv_vector_ctx'. Error -22
[    0.038057] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.0-rc6-00310-gb276cf69df24-dirty #11
[    0.047240] Hardware name: Allwinner D1 Nezha (DT)
[    0.052007] Call Trace:
[    0.054434] [<ffffffff80007172>] dump_backtrace+0x1c/0x24
[    0.059806] [<ffffffff809f6834>] show_stack+0x2c/0x38
[    0.064833] [<ffffffff80a040f0>] dump_stack_lvl+0x52/0x74
[    0.070206] [<ffffffff80a04126>] dump_stack+0x14/0x1c
[    0.075233] [<ffffffff809f6db6>] panic+0x10c/0x300
[    0.080000] [<ffffffff8017b5a0>] __kmem_cache_create_args+0x24a/0x2b6
[    0.086413] [<ffffffff80c04c68>] riscv_v_setup_ctx_cache+0x56/0x84
[    0.092566] [<ffffffff80c04288>] arch_task_cache_init+0x10/0x1c
[    0.098460] [<ffffffff80c07d02>] fork_init+0x68/0x1a8
[    0.103486] [<ffffffff80c00ed2>] start_kernel+0x77e/0x822
[    0.108870] ---[ end Kernel panic - not syncing: __kmem_cache_create_args: Failed to create slab 'riscv_vector_ctx'. Error -22 ]---

[1] https://github.com/cyyself/linux/tree/xtheadvector_20241110

On 9/12/24 13:55, Charlie Jenkins wrote:
>  diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
> index 682b3feee451..9775d6a9c8ee 100644
> --- a/arch/riscv/kernel/vector.c
> +++ b/arch/riscv/kernel/vector.c
> @@ -33,7 +33,17 @@ int riscv_v_setup_vsize(void)
>  {
>  	unsigned long this_vsize;
>  -	/* There are 32 vector registers with vlenb length. */
> +	/*
> +	 * There are 32 vector registers with vlenb length.
> +	 *
> +	 * If the thead,vlenb property was provided by the firmware, use that
> +	 * instead of probing the CSRs.
> +	 */
> +	if (thead_vlenb_of) {
> +		this_vsize = thead_vlenb_of * 32;

Then, I patched here which replaces "this_vsize" with "riscv_v_vsize". The kernel boots normally and I can see ?xtheadvector" in /proc/cpuinfo.

However, when I try to run the "v_exec_initval_nolibc" test, the kernel panics with these outputs:

[  978.788878] Oops - illegal instruction [#1]
[  978.788897] Modules linked in:
[  978.788908] CPU: 0 UID: 1000 PID: 461 Comm: v_exec_initval_ Not tainted 6.12.0-rc6-00310-gb276cf69df24-dirty #12
[  978.788924] Hardware name: Allwinner D1 Nezha (DT)
[  978.788929] epc : do_trap_ecall_u+0x56/0x20a
[  978.788956]  ra : _new_vmalloc_restore_context_a0+0xc2/0xce
[  978.788974] epc : ffffffff80a04afe ra : ffffffff80a0e742 sp : ffffffc6003fbeb0
[  978.788983]  gp : ffffffff81717080 tp : ffffffd60723b300 t0 : ffffffff81001268
[  978.788991]  t1 : ffffffff80a04aa8 t2 : ffffffff810012a8 s0 : ffffffc6003fbee0
[  978.789000]  s1 : ffffffc6003fbee0 a0 : ffffffc6003fbee0 a1 : 000000000000005d
[  978.789007]  a2 : 0000000000000000 a3 : ffffffffffffffda a4 : 0000000000000003
[  978.789015]  a5 : 0000000000000000 a6 : 0000000002adb5fe a7 : 000000000000005d
[  978.789022]  s2 : 00000000000108a8 s3 : 0000000000000000 s4 : 0000000000000008
[  978.789030]  s5 : 0000003fb42ab780 s6 : 0000002adb5fe420 s7 : 0000002adb5fb9e0
[  978.789038]  s8 : 0000002adb5fe440 s9 : 0000002adb5fe420 s10: 0000002adb572ad4
[  978.789046]  s11: 0000002adb572ad0 t3 : 0000003fb43c5e3c t4 : 622f7273752f3d5f
[  978.789053]  t5 : 0000002adb5fd5a1 t6 : 0000000002adb5ff
[  978.789060] status: 8000000201800100 badaddr: 000000005e0fb057 cause: 0000000000000002
[  978.789069] [<ffffffff80a04afe>] do_trap_ecall_u+0x56/0x20a
[  978.789086] [<ffffffff80a0e742>] _new_vmalloc_restore_context_a0+0xc2/0xce
[  978.789113] Code: a073 1007 006f 1a60 7057 0c30 57fd 17fe 77d7 0c30 (b057) 5e0f
[  978.789123] ---[ end trace 0000000000000000 ]---
[  978.789131] Kernel panic - not syncing: Fatal exception in interrupt
[  978.937158] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---

Is something wrong with my setup?

Thanks,
Yangyu Chen

> +		return 0;
> +	}
> +
>  	riscv_v_enable();
>  	this_vsize = csr_read(CSR_VLENB) * 32;
>  	riscv_v_disable();
> diff --git a/arch/riscv/kernel/vendor_extensions/thead.c b/arch/riscv/kernel/vendor_extensions/thead.c
> index 0f27baf8d245..519dbf70710a 100644
> --- a/arch/riscv/kernel/vendor_extensions/thead.c
> +++ b/arch/riscv/kernel/vendor_extensions/thead.c
> @@ -5,6 +5,7 @@
>  #include <asm/vendor_extensions/thead.h>
>    #include <linux/array_size.h>
> +#include <linux/cpumask.h>
>  #include <linux/types.h>
>    /* All T-Head vendor extensions supported in Linux */
> @@ -16,3 +17,13 @@ struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_thead = {
>  	.ext_data_count = ARRAY_SIZE(riscv_isa_vendor_ext_thead),
>  	.ext_data = riscv_isa_vendor_ext_thead,
>  };
> +
> +void disable_xtheadvector(void)
> +{
> +	int cpu;
> +
> +	for_each_possible_cpu(cpu)
> +		clear_bit(RISCV_ISA_VENDOR_EXT_XTHEADVECTOR, riscv_isa_vendor_ext_list_thead.per_hart_isa_bitmap[cpu].isa);
> +
> +	clear_bit(RISCV_ISA_VENDOR_EXT_XTHEADVECTOR, riscv_isa_vendor_ext_list_thead.all_harts_isa_bitmap.isa);
> +}



From drew at pdp7.com  Sat Nov  9 21:44:11 2024
From: drew at pdp7.com (Drew Fustini)
Date: Sat,  9 Nov 2024 21:44:11 -0800
Subject: [PATCH] riscv: defconfig: enable pinctrl and dwmac support for TH1520
Message-ID: <20241110054405.667779-1-drew@pdp7.com>

Enable pinctrl and ethernet dwmac driver for the TH1520 SoC boards like
the BeagleV Ahead and the Sipeed LicheePi 4A.

Signed-off-by: Drew Fustini <drew at pdp7.com>
---
Note: the th1520 pinctrl driver and thead dwmac ethernet driver have
been applied by their respective subsystems and are in linux-next.
I've successfully tested next on both the ahead and lpi4a boards.
This patch is based on next-20241108.

 arch/riscv/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index b4a37345703e..99a11142c03c 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -167,6 +167,7 @@ CONFIG_PINCTRL_SOPHGO_CV1800B=y
 CONFIG_PINCTRL_SOPHGO_CV1812H=y
 CONFIG_PINCTRL_SOPHGO_SG2000=y
 CONFIG_PINCTRL_SOPHGO_SG2002=y
+CONFIG_PINCTRL_TH1520=y
 CONFIG_GPIO_DWAPB=y
 CONFIG_GPIO_SIFIVE=y
 CONFIG_POWER_RESET_GPIO_RESTART=y
@@ -242,6 +243,7 @@ CONFIG_RTC_DRV_SUN6I=y
 CONFIG_DMADEVICES=y
 CONFIG_DMA_SUN6I=m
 CONFIG_DW_AXI_DMAC=y
+CONFIG_DWMAC_THEAD=y
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_INPUT=y
-- 
2.34.1



From privatesub2 at gmail.com  Sun Nov 10 03:16:31 2024
From: privatesub2 at gmail.com (=?UTF-8?B?0JDQu9C10LrRgdCw0L3QtNGAINCo0YPQsdC40L0=?=)
Date: Sun, 10 Nov 2024 14:16:31 +0300
Subject: [PATCH v10 1/3] dt-bindings: pwm: Add binding for Allwinner
 D1/T113-S3/R329 PWM controller
In-Reply-To: <4ioz6f6efs2uhf5mitb4xhebqeryyz5ukple4fkn54wpqep3c4@4ktefld35c3s>
References: <20241011102751.153248-1-privatesub2@gmail.com>
 <20241011102751.153248-2-privatesub2@gmail.com> <4ioz6f6efs2uhf5mitb4xhebqeryyz5ukple4fkn54wpqep3c4@4ktefld35c3s>
Message-ID: <CAF4idNmDMQpFppUvCBbC1=SNMQBrTOqmFO60SMvKvaHvNJy=Bg@mail.gmail.com>

Hello Uwe,

I appreciate your suggestion to use a more standardized
property name like "pwm-number" instead of vendor-specific names.

Since the name "pwm-number" is present in two drivers,
we could consider using this name here as an option.
Or perhaps we should choose a new common name "npwms"
as you suggested?

Please let me know what you think about this.

Best regards,
Aleksandr.

??, 29 ???. 2024??. ? 11:56, Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>:
>
> Hello,
>
> On Fri, Oct 11, 2024 at 01:27:32PM +0300, Aleksandr Shubin wrote:
> > +  allwinner,pwm-channels:
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    description: The number of PWM channels configured for this instance
> > +    enum: [6, 9]
>
> I wonder if the number of channels is a property common enough that we
> can use "num-pwm-channels" here instead of a vendor specific property.
> Or would you suggest a different name? gpio-controller nodes have
> "ngpios", so maybe "npwms"?
>
> A quick grep suggests we already have:
>
>         fsl,pwm-number in mxs-pwm.yaml
>         st,pwm-num-chan in pwm-st.txt
>         snps,pwm-number in snps,dw-apb-timers-pwm2.yaml
>
> As a follow up this could then be used by pwmchip_alloc() to determine
> the number of channels if the passed npwm value is 0.
>
> Best regards
> Uwe


From namhyung at kernel.org  Sun Nov 10 08:08:19 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Sun, 10 Nov 2024 08:08:19 -0800
Subject: [PATCH v4 00/20] Remove PERF_HAVE_DWARF_REGS
In-Reply-To: <20241108234606.429459-1-irogers@google.com>
References: <20241108234606.429459-1-irogers@google.com>
Message-ID: <173125489927.241089.8450722244768775739.b4-ty@kernel.org>

On Fri, 08 Nov 2024 15:45:45 -0800, Ian Rogers wrote:

> These changes were originally on top of:
> https://lore.kernel.org/lkml/20241017001354.56973-1-irogers at google.com/
> 
> Prior to these patches PERF_HAVE_DWARF_REGS indicated the presence of
> dwarf-regs.c in the arch directory. dwarf-regs.c provided upto 4
> functions:
> 
> [...]

Applied to perf-tools-next, thanks!

Best regards,
Namhyung



From mr.bossman075 at gmail.com  Sun Nov 10 13:15:53 2024
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Sun, 10 Nov 2024 16:15:53 -0500
Subject: [PATCH for-next v2] riscv: Fix default misaligned access trap
In-Reply-To: <20241108-fix_handle_misaligned_load-v2-1-91d547ce64db@rivosinc.com>
References: <20241108-fix_handle_misaligned_load-v2-1-91d547ce64db@rivosinc.com>
Message-ID: <208f8a06-c176-4377-8255-7800ecd2cf6c@gmail.com>



On 11/8/24 18:47, Charlie Jenkins wrote:
> Commit d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses
> supported") removed the default handlers for handle_misaligned_load()
> and handle_misaligned_store(). When the kernel is compiled without
> RISCV_SCALAR_MISALIGNED, these handlers are never defined, causing
> compilation errors.
> 
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Reviewed-by: Jesse Taube <mr.bossman075 at gmail.com>

Thanks,
Jesse
> Fixes: d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses supported")
> ---
> Changes in v2:
> - Change CONFIG_RISCV_SCALAR_MISALIGNED to CONFIG_RISCV_MISALIGNED
>    (Jesse)
> - Link to v1: https://lore.kernel.org/r/20241107-fix_handle_misaligned_load-v1-1-07d7852c9991 at rivosinc.com
> ---
>   arch/riscv/include/asm/entry-common.h | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/entry-common.h b/arch/riscv/include/asm/entry-common.h
> index 7b32d2b08bb6..b28ccc6cdeea 100644
> --- a/arch/riscv/include/asm/entry-common.h
> +++ b/arch/riscv/include/asm/entry-common.h
> @@ -25,7 +25,19 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
>   void handle_page_fault(struct pt_regs *regs);
>   void handle_break(struct pt_regs *regs);
>   
> +#ifdef CONFIG_RISCV_MISALIGNED
>   int handle_misaligned_load(struct pt_regs *regs);
>   int handle_misaligned_store(struct pt_regs *regs);
> +#else
> +static inline int handle_misaligned_load(struct pt_regs *regs)
> +{
> +	return -1;
> +}
> +
> +static inline int handle_misaligned_store(struct pt_regs *regs)
> +{
> +	return -1;
> +}
> +#endif
>   
>   #endif /* _ASM_RISCV_ENTRY_COMMON_H */
> 
> ---
> base-commit: 74741a050b79d31d8d2eeee12c77736596d0a6b2
> change-id: 20241107-fix_handle_misaligned_load-8be86cb0806e



From unicornxw at gmail.com  Sun Nov 10 20:01:13 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 12:01:13 +0800
Subject: [PATCH 0/3] irqchip: Add Sophgo SG2042 MSI controller
Message-ID: <cover.1731296803.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

This controller is on the Sophgo SG2042 SoC to transform interrupts from
PCIe MSI to PLIC interrupts.

Chen Wang (3):
  dt-bindings: interrupt-controller: Add Sophgo SG2042 MSI
  irqchip: Add the Sophgo SG2042 MSI interrupt controller
  riscv: sophgo: dts: add msi controller for SG2042

 .../sophgo,sg2042-msi.yaml                    |  78 ++++++
 arch/riscv/boot/dts/sophgo/sg2042.dtsi        |  13 +
 drivers/irqchip/Kconfig                       |   8 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-sg2042-msi.c              | 255 ++++++++++++++++++
 5 files changed, 355 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml
 create mode 100644 drivers/irqchip/irq-sg2042-msi.c


base-commit: 2d5404caa8c7bb5c4e0435f94b28834ae5456623
-- 
2.34.1



From unicornxw at gmail.com  Sun Nov 10 20:01:36 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 12:01:36 +0800
Subject: [PATCH 1/3] dt-bindings: interrupt-controller: Add Sophgo SG2042 MSI
In-Reply-To: <cover.1731296803.git.unicorn_wang@outlook.com>
References: <cover.1731296803.git.unicorn_wang@outlook.com>
Message-ID: <5186bb9c7feebb87136eb5e5e117fb1142dba4c2.1731296803.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

Add binding for Sophgo SG2042 MSI controller.

Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
---
 .../sophgo,sg2042-msi.yaml                    | 78 +++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml b/Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml
new file mode 100644
index 000000000000..9fe99b74c211
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/sophgo,sg2042-msi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo SG2042 MSI Controller
+
+maintainers:
+  - Chen Wang <unicorn_wang at outlook.com>
+
+description:
+  This interrupt controller is in Sophgo SG2042 for transforming interrupts from
+  PCIe MSI to PLIC interrupts.
+
+allOf:
+  - $ref: /schemas/interrupts.yaml#
+  - $ref: /schemas/interrupt-controller/msi-controller.yaml#
+
+properties:
+  compatible:
+    const: sophgo,sg2042-msi
+
+  reg:
+    items:
+      - description: clear register
+
+  reg-names:
+    items:
+      - const: clr
+
+  sophgo,msi-doorbell-addr:
+    description:
+      u64 value of the MSI doorbell address
+    $ref: /schemas/types.yaml#/definitions/uint64
+
+  sophgo,msi-base-vec:
+    description:
+      u32 value of the base of parent PLIC vector allocated
+      to MSI.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 64
+    maximum: 95
+
+  sophgo,msi-num-vecs:
+    description:
+      u32 value of the number of parent PLIC vectors allocated
+      to MSI.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 32
+
+  msi-controller: true
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - msi-controller
+  - sophgo,msi-doorbell-addr
+  - sophgo,msi-base-vec
+  - sophgo,msi-num-vecs
+
+additionalProperties: true
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    msi: msi-controller at 30000000 {
+      compatible = "sophgo,sg2042-msi";
+      reg = <0x30000000 0x4>;
+      reg-names = "clr";
+      msi-controller;
+      sophgo,msi-doorbell-addr = <0x00000070 0x30010300>;
+      sophgo,msi-base-vec = <64>;
+      sophgo,msi-num-vecs = <32>;
+      interrupt-parent = <&plic>;
+    };
-- 
2.34.1



From unicornxw at gmail.com  Sun Nov 10 20:01:55 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 12:01:55 +0800
Subject: [PATCH 2/3] irqchip: Add the Sophgo SG2042 MSI interrupt controller
In-Reply-To: <cover.1731296803.git.unicorn_wang@outlook.com>
References: <cover.1731296803.git.unicorn_wang@outlook.com>
Message-ID: <8076fe2af9f2b007a42c986ed193ba50ff674bfa.1731296803.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

Add driver for Sophgo SG2042 MSI interrupt controller.

Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
---
 drivers/irqchip/Kconfig          |   8 +
 drivers/irqchip/Makefile         |   1 +
 drivers/irqchip/irq-sg2042-msi.c | 255 +++++++++++++++++++++++++++++++
 3 files changed, 264 insertions(+)
 create mode 100644 drivers/irqchip/irq-sg2042-msi.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index d82bcab233a1..76a38a4d62eb 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -729,6 +729,14 @@ config MCHP_EIC
 	help
 	  Support for Microchip External Interrupt Controller.
 
+config SOPHGO_SG2042_MSI
+	bool "Sophgo SG2042 MSI controller"
+	depends on ARCH_SOPHGO || COMPILE_TEST
+	help
+	  Support for the Sophgo SG2042 MSI Controller.
+	  This on-chip interrupt controller enables MSI sources to be
+	  routed to the primary PLIC controller on SoC.
+
 config SUNPLUS_SP7021_INTC
 	bool "Sunplus SP7021 interrupt controller" if COMPILE_TEST
 	default SOC_SP7021
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index e3679ec2b9f7..53617890268a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -125,4 +125,5 @@ obj-$(CONFIG_WPCM450_AIC)		+= irq-wpcm450-aic.o
 obj-$(CONFIG_IRQ_IDT3243X)		+= irq-idt3243x.o
 obj-$(CONFIG_APPLE_AIC)			+= irq-apple-aic.o
 obj-$(CONFIG_MCHP_EIC)			+= irq-mchp-eic.o
+obj-$(CONFIG_SOPHGO_SG2042_MSI)		+= irq-sg2042-msi.o
 obj-$(CONFIG_SUNPLUS_SP7021_INTC)	+= irq-sp7021-intc.o
diff --git a/drivers/irqchip/irq-sg2042-msi.c b/drivers/irqchip/irq-sg2042-msi.c
new file mode 100644
index 000000000000..79449f974ed5
--- /dev/null
+++ b/drivers/irqchip/irq-sg2042-msi.c
@@ -0,0 +1,255 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SG2042 MSI Controller
+ *
+ * Copyright (C) 2024 Sophgo Technology Inc.
+ * Copyright (C) 2024 Chen Wang <unicorn_wang at outlook.com>
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct sg2042_msi_data {
+	void __iomem	*reg_clr; /* clear reg, see TRM, 10.1.33, GP_INTR0_CLR */
+
+	u64		doorbell_addr; /* see TRM, 10.1.32, GP_INTR0_SET */
+
+	u32		irq_first; /* The vector number that MSIs starts */
+	u32		num_irqs;  /* The number of vectors for MSIs */
+
+	unsigned long	*msi_map;
+	struct mutex	msi_map_lock; /* lock for msi_map */
+};
+
+static int sg2042_msi_allocate_hwirq(struct sg2042_msi_data *priv, int num_req)
+{
+	int first;
+
+	mutex_lock(&priv->msi_map_lock);
+
+	first = bitmap_find_free_region(priv->msi_map, priv->num_irqs,
+					get_count_order(num_req));
+	if (first < 0) {
+		mutex_unlock(&priv->msi_map_lock);
+		return -ENOSPC;
+	}
+
+	mutex_unlock(&priv->msi_map_lock);
+
+	return priv->irq_first + first;
+}
+
+static void sg2042_msi_free_hwirq(struct sg2042_msi_data *priv,
+				  int hwirq, int num_req)
+{
+	int first = hwirq - priv->irq_first;
+
+	mutex_lock(&priv->msi_map_lock);
+	bitmap_release_region(priv->msi_map, first, get_count_order(num_req));
+	mutex_unlock(&priv->msi_map_lock);
+}
+
+static void sg2042_msi_irq_ack(struct irq_data *d)
+{
+	struct sg2042_msi_data *data  = irq_data_get_irq_chip_data(d);
+	int bit_off = d->hwirq - data->irq_first;
+
+	writel(1 << bit_off, (unsigned int *)data->reg_clr);
+
+	irq_chip_ack_parent(d);
+}
+
+static void sg2042_msi_irq_compose_msi_msg(struct irq_data *data,
+					   struct msi_msg *msg)
+{
+	struct sg2042_msi_data *priv = irq_data_get_irq_chip_data(data);
+
+	msg->address_hi = upper_32_bits(priv->doorbell_addr);
+	msg->address_lo = lower_32_bits(priv->doorbell_addr);
+	msg->data = 1 << (data->hwirq - priv->irq_first);
+
+	pr_debug("%s hwirq[%d]: address_hi[%#x], address_lo[%#x], data[%#x]\n",
+		 __func__,
+		 (int)data->hwirq, msg->address_hi, msg->address_lo, msg->data);
+}
+
+static struct irq_chip sg2042_msi_middle_irq_chip = {
+	.name			= "SG2042 MSI",
+	.irq_ack		= sg2042_msi_irq_ack,
+	.irq_mask		= irq_chip_mask_parent,
+	.irq_unmask		= irq_chip_unmask_parent,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= irq_chip_set_affinity_parent,
+#endif
+	.irq_compose_msi_msg	= sg2042_msi_irq_compose_msi_msg,
+};
+
+static int sg2042_msi_parent_domain_alloc(struct irq_domain *domain,
+					  unsigned int virq, int hwirq)
+{
+	struct irq_fwspec fwspec;
+	struct irq_data *d;
+	int ret;
+
+	fwspec.fwnode = domain->parent->fwnode;
+	fwspec.param_count = 2;
+	fwspec.param[0] = hwirq;
+	fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
+
+	ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
+	if (ret)
+		return ret;
+
+	d = irq_domain_get_irq_data(domain->parent, virq);
+	return d->chip->irq_set_type(d, IRQ_TYPE_EDGE_RISING);
+}
+
+static int sg2042_msi_middle_domain_alloc(struct irq_domain *domain,
+					  unsigned int virq,
+					  unsigned int nr_irqs, void *args)
+{
+	struct sg2042_msi_data *priv = domain->host_data;
+	int hwirq, err, i;
+
+	hwirq = sg2042_msi_allocate_hwirq(priv, nr_irqs);
+	if (hwirq < 0)
+		return hwirq;
+
+	for (i = 0; i < nr_irqs; i++) {
+		err = sg2042_msi_parent_domain_alloc(domain, virq + i, hwirq + i);
+		if (err)
+			goto err_hwirq;
+
+		pr_debug("%s: virq[%d], hwirq[%d]\n",
+			 __func__, virq + i, (int)hwirq + i);
+
+		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
+					      &sg2042_msi_middle_irq_chip, priv);
+	}
+
+	return 0;
+
+err_hwirq:
+	sg2042_msi_free_hwirq(priv, hwirq, nr_irqs);
+	irq_domain_free_irqs_parent(domain, virq, i);
+
+	return err;
+}
+
+static void sg2042_msi_middle_domain_free(struct irq_domain *domain,
+					  unsigned int virq,
+					  unsigned int nr_irqs)
+{
+	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+	struct sg2042_msi_data *priv = irq_data_get_irq_chip_data(d);
+
+	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+	sg2042_msi_free_hwirq(priv, d->hwirq, nr_irqs);
+}
+
+static const struct irq_domain_ops pch_msi_middle_domain_ops = {
+	.alloc	= sg2042_msi_middle_domain_alloc,
+	.free	= sg2042_msi_middle_domain_free,
+};
+
+static int sg2042_msi_init_domains(struct sg2042_msi_data *priv,
+				   struct device_node *node)
+{
+	struct irq_domain *plic_domain, *middle_domain;
+	struct device_node *plic_node;
+	struct fwnode_handle *fwnode = of_node_to_fwnode(node);
+
+	if (!of_find_property(node, "interrupt-parent", NULL)) {
+		pr_err("Can't find interrupt-parent!\n");
+		return -EINVAL;
+	}
+
+	plic_node = of_irq_find_parent(node);
+	if (!plic_node) {
+		pr_err("Failed to find the PLIC node!\n");
+		return -ENXIO;
+	}
+
+	plic_domain = irq_find_host(plic_node);
+	of_node_put(plic_node);
+	if (!plic_domain) {
+		pr_err("Failed to find the PLIC domain\n");
+		return -ENXIO;
+	}
+
+	middle_domain = irq_domain_create_hierarchy(plic_domain, 0, priv->num_irqs,
+						    fwnode,
+						    &pch_msi_middle_domain_ops,
+						    priv);
+	if (!middle_domain) {
+		pr_err("Failed to create the MSI middle domain\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int sg2042_msi_probe(struct platform_device *pdev)
+{
+	struct sg2042_msi_data *data;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(struct sg2042_msi_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->reg_clr = devm_platform_ioremap_resource_byname(pdev, "clr");
+	if (IS_ERR(data->reg_clr)) {
+		dev_err(&pdev->dev, "Failed to map clear register\n");
+		return PTR_ERR(data->reg_clr);
+	}
+
+	if (of_property_read_u64(pdev->dev.of_node, "sophgo,msi-doorbell-addr",
+				 &data->doorbell_addr)) {
+		dev_err(&pdev->dev, "Unable to parse MSI doorbell addr\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(pdev->dev.of_node, "sophgo,msi-base-vec",
+				 &data->irq_first)) {
+		dev_err(&pdev->dev, "Unable to parse MSI vec base\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(pdev->dev.of_node, "sophgo,msi-num-vecs",
+				 &data->num_irqs)) {
+		dev_err(&pdev->dev, "Unable to parse MSI vec number\n");
+		return -EINVAL;
+	}
+
+	mutex_init(&data->msi_map_lock);
+
+	data->msi_map = bitmap_zalloc(data->num_irqs, GFP_KERNEL);
+	if (!data->msi_map)
+		return -ENOMEM;
+
+	return sg2042_msi_init_domains(data, pdev->dev.of_node);
+}
+
+static const struct of_device_id sg2042_msi_of_match[] = {
+	{ .compatible = "sophgo,sg2042-msi" },
+	{}
+};
+
+static struct platform_driver sg2042_msi_driver = {
+	.driver = {
+		.name = "sg2042-msi",
+		.of_match_table = of_match_ptr(sg2042_msi_of_match),
+	},
+	.probe = sg2042_msi_probe,
+};
+builtin_platform_driver(sg2042_msi_driver);
-- 
2.34.1



From unicornxw at gmail.com  Sun Nov 10 20:02:12 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 12:02:12 +0800
Subject: [PATCH 3/3] riscv: sophgo: dts: add msi controller for SG2042
In-Reply-To: <cover.1731296803.git.unicorn_wang@outlook.com>
References: <cover.1731296803.git.unicorn_wang@outlook.com>
Message-ID: <90bce35ca34b3c9f86f1af89d70ab34b2e497e0e.1731296803.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

Add msi-controller node to dts for SG2042.

Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
---
 arch/riscv/boot/dts/sophgo/sg2042.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
index e62ac51ac55a..35651cbac764 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042.dtsi
+++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
@@ -173,6 +173,19 @@ pllclk: clock-controller at 70300100c0 {
 			#clock-cells = <1>;
 		};
 
+		msi: msi-controller at 7030010304 {
+			compatible = "sophgo,sg2042-msi";
+			reg = <0x70 0x30010304 0x0 0x4>;
+			reg-names = "clr";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			msi-controller;
+			sophgo,msi-doorbell-addr = <0x00000070 0x30010300>;
+			sophgo,msi-base-vec = <64>;
+			sophgo,msi-num-vecs = <32>;
+			interrupt-parent = <&intc>;
+		};
+
 		rpgate: clock-controller at 7030010368 {
 			compatible = "sophgo,sg2042-rpgate";
 			reg = <0x70 0x30010368 0x0 0x98>;
-- 
2.34.1



From unicornxw at gmail.com  Sun Nov 10 21:59:17 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 13:59:17 +0800
Subject: [PATCH 0/5] Add PCIe support to Sophgo SG2042 SoC
Message-ID: <cover.1731303328.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

Sophgo's SG2042 SoC uses Cadence PCIe core to implement RC mode.

SG2042 PCIe controller supports two ways to report MSI:

Method A, the PICe controller implements an MSI interrupt controller
inside, and connect to PLIC upward through one interrupt line. Provides
memory-mapped msi address, and by programming the upper 32 bits of the
address to zero, it can be compatible with old pcie devices that only
support 32-bit msi address.

Method B, the PICe controller connects to PLIC upward through an
independent MSI controller "sophgo,sg2042-msi" on the SOC. The MSI
controller provides multiple(up to 32) interrupt sources to PLIC.
Compared with the first method, the advantage is that the interrupt
source is expanded, but because for SG2042, the msi address provided
by the MSI controller is fixed and only supports 64-bit address(> 2^32),
it is not compatible with old pcie devices that only support 32-bit
msi address.

This patchset depends on another patchset for the SG2042 MSI controller[msi].
If you need to test the DTS part, you need to apply the corresponding
patchset.

Link: https://lore.kernel.org/linux-riscv/cover.1731296803.git.unicorn_wang at outlook.com/ [msi]

Thanks,
Chen

Chen Wang (5):
  dt-bindings: pci: Add Sophgo SG2042 PCIe host
  PCI: sg2042: Add Sophgo SG2042 PCIe driver
  dt-bindings: mfd: syscon: Add sg2042 pcie ctrl compatible
  riscv: sophgo: dts: add pcie controllers for SG2042
  riscv: sophgo: dts: enable pcie for PioneerBox

 .../devicetree/bindings/mfd/syscon.yaml       |   2 +
 .../bindings/pci/sophgo,sg2042-pcie-host.yaml |  88 +++
 .../boot/dts/sophgo/sg2042-milkv-pioneer.dts  |  12 +
 arch/riscv/boot/dts/sophgo/sg2042.dtsi        |  82 +++
 drivers/pci/controller/cadence/Kconfig        |  11 +
 drivers/pci/controller/cadence/Makefile       |   1 +
 drivers/pci/controller/cadence/pcie-sg2042.c  | 611 ++++++++++++++++++
 7 files changed, 807 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
 create mode 100644 drivers/pci/controller/cadence/pcie-sg2042.c


base-commit: 2d5404caa8c7bb5c4e0435f94b28834ae5456623
-- 
2.34.1



From unicornxw at gmail.com  Sun Nov 10 21:59:37 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 13:59:37 +0800
Subject: [PATCH 1/5] dt-bindings: pci: Add Sophgo SG2042 PCIe host
In-Reply-To: <cover.1731303328.git.unicorn_wang@outlook.com>
References: <cover.1731303328.git.unicorn_wang@outlook.com>
Message-ID: <1edbed1276a459a144f0cb0815859a1eb40bfcbf.1731303328.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

Add binding for Sophgo SG2042 PCIe host controller.

Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
---
 .../bindings/pci/sophgo,sg2042-pcie-host.yaml | 88 +++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml

diff --git a/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml b/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
new file mode 100644
index 000000000000..d4d2232f354f
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/sophgo,sg2042-pcie-host.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sophgo SG2042 PCIe Host (Cadence PCIe Wrapper)
+
+description: |+
+  Sophgo SG2042 PCIe host controller is based on the Cadence PCIe core.
+  It shares common features with the PCIe core and inherits common properties
+  defined in Documentation/devicetree/bindings/pci/cdns-pcie-host.yaml.
+
+maintainers:
+  - Chen Wang <unicorn_wang at outlook.com>
+
+properties:
+  compatible:
+    const: sophgo,sg2042-pcie-host
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: reg
+      - const: cfg
+
+  sophgo,syscon-pcie-ctrl:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: Phandle to the SYSCON entry
+
+  sophgo,link-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: Cadence IP link ID.
+
+  sophgo,internal-msi:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: Identifies whether the PCIE node uses internal MSI controller.
+
+  vendor-id:
+    const: 0x1f1c
+
+  device-id:
+    const: 0x2042
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-names:
+    const: msi
+
+allOf:
+  - $ref: cdns-pcie-host.yaml#
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - sophgo,syscon-pcie-ctrl
+  - sophgo,link-id
+  - vendor-id
+  - device-id
+  - ranges
+
+additionalProperties: true
+
+examples:
+  - |
+    pcie at 62000000 {
+      compatible = "sophgo,sg2042-pcie-host";
+      device_type = "pci";
+      reg = <0x62000000  0x00800000>,
+            <0x48000000  0x00001000>;
+      reg-names = "reg", "cfg";
+      #address-cells = <3>;
+      #size-cells = <2>;
+      ranges = <0x81000000 0 0x00000000 0xde000000 0 0x00010000>,
+               <0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>;
+      bus-range = <0x80 0xbf>;
+      vendor-id = <0x1f1c>;
+      device-id = <0x2042>;
+      cdns,no-bar-match-nbits = <48>;
+      sophgo,link-id = <0>;
+      sophgo,syscon-pcie-ctrl = <&cdns_pcie1_ctrl>;
+      sophgo,internal-msi;
+      interrupt-parent = <&intc>;
+    };
-- 
2.34.1



From unicornxw at gmail.com  Sun Nov 10 21:59:56 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 13:59:56 +0800
Subject: [PATCH 2/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver
In-Reply-To: <cover.1731303328.git.unicorn_wang@outlook.com>
References: <cover.1731303328.git.unicorn_wang@outlook.com>
Message-ID: <5051f2375ff6218e7d44ce0c298efd5f9ee56964.1731303328.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

Add support for PCIe controller in SG2042 SoC. The controller
uses the Cadence PCIe core programmed by pcie-cadence*.c. The
PCIe controller will work in host mode only.

Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
---
 drivers/pci/controller/cadence/Kconfig       |  11 +
 drivers/pci/controller/cadence/Makefile      |   1 +
 drivers/pci/controller/cadence/pcie-sg2042.c | 611 +++++++++++++++++++
 3 files changed, 623 insertions(+)
 create mode 100644 drivers/pci/controller/cadence/pcie-sg2042.c

diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig
index 8a0044bb3989..45a16215ea94 100644
--- a/drivers/pci/controller/cadence/Kconfig
+++ b/drivers/pci/controller/cadence/Kconfig
@@ -67,4 +67,15 @@ config PCI_J721E_EP
 	  Say Y here if you want to support the TI J721E PCIe platform
 	  controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe
 	  core.
+
+config PCIE_SG2042
+	bool "Sophgo SG2042 PCIe controller (host mode)"
+	depends on ARCH_SOPHGO || COMPILE_TEST
+	depends on OF
+	select PCIE_CADENCE_HOST
+	help
+	  Say Y here if you want to support the Sophgo SG2042 PCIe platform
+	  controller in host mode. Sophgo SG2042 PCIe controller uses Cadence
+	  PCIe core.
+
 endmenu
diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
index 9bac5fb2f13d..89aa316f54ac 100644
--- a/drivers/pci/controller/cadence/Makefile
+++ b/drivers/pci/controller/cadence/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
 obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
 obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
 obj-$(CONFIG_PCI_J721E) += pci-j721e.o
+obj-$(CONFIG_PCIE_SG2042) += pcie-sg2042.o
\ No newline at end of file
diff --git a/drivers/pci/controller/cadence/pcie-sg2042.c b/drivers/pci/controller/cadence/pcie-sg2042.c
new file mode 100644
index 000000000000..809edb8e7259
--- /dev/null
+++ b/drivers/pci/controller/cadence/pcie-sg2042.c
@@ -0,0 +1,611 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pcie-sg2042 - PCIe controller driver for Sophgo SG2042 SoC
+ *
+ * Copyright (C) 2024 Sophgo Technology Inc.
+ * Copyright (C) 2024 Chen Wang <unicorn_wang at outlook.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/msi.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include "pcie-cadence.h"
+
+/*
+ * SG2042 PCIe controller supports two ways to report MSI:
+ * - Method A, the PICe controller implements an MSI interrupt controller inside,
+ *   and connect to PLIC upward through one interrupt line. Provides
+ *   memory-mapped msi address, and by programming the upper 32 bits of the
+ *   address to zero, it can be compatible with old pcie devices that only
+ *   support 32-bit msi address.
+ * - Method B, the PICe controller connects to PLIC upward through an
+ *   independent MSI controller "sophgo,sg2042-msi" on the SOC. The MSI
+ *   controller provides multiple(up to 32) interrupt sources to PLIC.
+ *   Compared with the first method, the advantage is that the interrupt source
+ *   is expanded, but because for SG2042, the msi address provided by the MSI
+ *   controller is fixed and only supports 64-bit address(> 2^32), it is not
+ *   compatible with old pcie devices that only support 32-bit msi address.
+ * Method A & B can be configured in DTS with property "sophgo,internal-msi",
+ * default is Method B.
+ */
+
+#define MAX_MSI_IRQS		8
+#define MAX_MSI_IRQS_PER_CTRL	1
+#define MAX_MSI_CTRLS		(MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL)
+#define MSI_DEF_NUM_VECTORS	MAX_MSI_IRQS
+#define BYTE_NUM_PER_MSI_VEC	4
+
+#define REG_CLEAR		0x0804
+#define REG_STATUS		0x0810
+#define REG_LINK0_MSI_ADDR_SIZE	0x085C
+#define REG_LINK1_MSI_ADDR_SIZE	0x080C
+#define REG_LINK0_MSI_ADDR_LOW	0x0860
+#define REG_LINK0_MSI_ADDR_HIGH	0x0864
+#define REG_LINK1_MSI_ADDR_LOW	0x0868
+#define REG_LINK1_MSI_ADDR_HIGH	0x086C
+
+#define REG_CLEAR_LINK0_BIT	2
+#define REG_CLEAR_LINK1_BIT	3
+#define REG_STATUS_LINK0_BIT	2
+#define REG_STATUS_LINK1_BIT	3
+
+#define REG_LINK0_MSI_ADDR_SIZE_MASK	GENMASK(15, 0)
+#define REG_LINK1_MSI_ADDR_SIZE_MASK	GENMASK(31, 16)
+
+#define SG2042_CDNS_PLAT_CPU_TO_BUS_ADDR	0xCFFFFFFFFF
+
+struct sg2042_pcie {
+	struct cdns_pcie *cdns_pcie;
+
+	struct regmap *syscon;
+
+	u32 link_id;
+	u32 internal_msi; /* Flag if use internal MSI controller, default external */
+
+	struct irq_domain *msi_domain;
+
+	int msi_irq;
+
+	dma_addr_t msi_phys;
+	void *msi_virt;
+
+	u32 num_applied_vecs; /* number of applied vectors, used to speed up ISR */
+
+	raw_spinlock_t lock;
+	DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
+};
+
+static void sg2042_pcie_msi_irq_mask_external(struct irq_data *d)
+{
+	pci_msi_mask_irq(d);
+	irq_chip_mask_parent(d);
+}
+
+static void sg2042_pcie_msi_irq_unmask_external(struct irq_data *d)
+{
+	pci_msi_unmask_irq(d);
+	irq_chip_unmask_parent(d);
+}
+
+static struct irq_chip sg2042_pcie_msi_chip_external = {
+	.name		= "SG2042 PCIe MSI External",
+	.irq_ack	= irq_chip_ack_parent,
+	.irq_mask	= sg2042_pcie_msi_irq_mask_external,
+	.irq_unmask	= sg2042_pcie_msi_irq_unmask_external,
+};
+
+static struct msi_domain_info sg2042_pcie_msi_domain_info_external = {
+	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+	.chip	= &sg2042_pcie_msi_chip_external,
+};
+
+static struct irq_chip sg2042_pcie_msi_chip = {
+	.name = "SG2042 PCIe MSI",
+	.irq_ack = irq_chip_ack_parent,
+};
+
+static struct msi_domain_info sg2042_pcie_msi_domain_info = {
+	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+	.chip	= &sg2042_pcie_msi_chip,
+};
+
+static void sg2042_pcie_msi_clear_status(struct sg2042_pcie *pcie)
+{
+	u32 status, clr_msi_in_bit;
+
+	if (pcie->link_id == 1)
+		clr_msi_in_bit = BIT(REG_CLEAR_LINK1_BIT);
+	else
+		clr_msi_in_bit = BIT(REG_CLEAR_LINK0_BIT);
+
+	regmap_read(pcie->syscon, REG_CLEAR, &status);
+	status |= clr_msi_in_bit;
+	regmap_write(pcie->syscon, REG_CLEAR, status);
+
+	/* need write 0 to reset, hardware can not reset automatically */
+	status &= ~clr_msi_in_bit;
+	regmap_write(pcie->syscon, REG_CLEAR, status);
+}
+
+static int sg2042_pcie_msi_irq_set_affinity(struct irq_data *d,
+					    const struct cpumask *mask,
+					    bool force)
+{
+	if (d->parent_data)
+		return irq_chip_set_affinity_parent(d, mask, force);
+
+	return -EINVAL;
+}
+
+static void sg2042_pcie_msi_irq_compose_msi_msg(struct irq_data *d,
+						struct msi_msg *msg)
+{
+	struct sg2042_pcie *pcie = irq_data_get_irq_chip_data(d);
+	struct device *dev = pcie->cdns_pcie->dev;
+
+	msg->address_lo = lower_32_bits(pcie->msi_phys) + BYTE_NUM_PER_MSI_VEC * d->hwirq;
+	msg->address_hi = upper_32_bits(pcie->msi_phys);
+	msg->data = 1;
+
+	pcie->num_applied_vecs = d->hwirq;
+
+	dev_info(dev, "compose msi msg hwirq[%d] address_hi[%#x] address_lo[%#x]\n",
+		 (int)d->hwirq, msg->address_hi, msg->address_lo);
+}
+
+static void sg2042_pcie_msi_irq_ack(struct irq_data *d)
+{
+	struct sg2042_pcie *pcie = irq_data_get_irq_chip_data(d);
+
+	sg2042_pcie_msi_clear_status(pcie);
+}
+
+static struct irq_chip sg2042_pcie_msi_bottom_chip = {
+	.name			= "SG2042 PCIe PLIC-MSI translator",
+	.irq_ack		= sg2042_pcie_msi_irq_ack,
+	.irq_compose_msi_msg	= sg2042_pcie_msi_irq_compose_msi_msg,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= sg2042_pcie_msi_irq_set_affinity,
+#endif
+};
+
+static int sg2042_pcie_irq_domain_alloc(struct irq_domain *domain,
+					unsigned int virq, unsigned int nr_irqs,
+					void *args)
+{
+	struct sg2042_pcie *pcie = domain->host_data;
+	unsigned long flags;
+	u32 i;
+	int bit;
+
+	raw_spin_lock_irqsave(&pcie->lock, flags);
+
+	bit = bitmap_find_free_region(pcie->msi_irq_in_use, MSI_DEF_NUM_VECTORS,
+				      order_base_2(nr_irqs));
+
+	raw_spin_unlock_irqrestore(&pcie->lock, flags);
+
+	if (bit < 0)
+		return -ENOSPC;
+
+	for (i = 0; i < nr_irqs; i++)
+		irq_domain_set_info(domain, virq + i, bit + i,
+				    &sg2042_pcie_msi_bottom_chip,
+				    pcie, handle_edge_irq,
+				    NULL, NULL);
+
+	return 0;
+}
+
+static void sg2042_pcie_irq_domain_free(struct irq_domain *domain,
+					unsigned int virq, unsigned int nr_irqs)
+{
+	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+	struct sg2042_pcie *pcie = irq_data_get_irq_chip_data(d);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&pcie->lock, flags);
+
+	bitmap_release_region(pcie->msi_irq_in_use, d->hwirq,
+			      order_base_2(nr_irqs));
+
+	raw_spin_unlock_irqrestore(&pcie->lock, flags);
+}
+
+static const struct irq_domain_ops sg2042_pcie_msi_domain_ops = {
+	.alloc	= sg2042_pcie_irq_domain_alloc,
+	.free	= sg2042_pcie_irq_domain_free,
+};
+
+/*
+ * We use the usual two domain structure, the top one being a generic PCI/MSI
+ * domain, the bottom one being SG2042-specific and handling the actual HW
+ * interrupt allocation.
+ * At the same time, for internal MSI controller(Method A), bottom chip uses a
+ * chained handler to handle the controller's MSI IRQ edge triggered.
+ */
+static int sg2042_pcie_create_msi_domain(struct sg2042_pcie *pcie,
+					 struct irq_domain *parent)
+{
+	struct device *dev = pcie->cdns_pcie->dev;
+	struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+
+	if (pcie->internal_msi)
+		pcie->msi_domain = pci_msi_create_irq_domain(fwnode,
+							     &sg2042_pcie_msi_domain_info,
+							     parent);
+
+	else
+		pcie->msi_domain = pci_msi_create_irq_domain(fwnode,
+							     &sg2042_pcie_msi_domain_info_external,
+							     parent);
+
+	if (!pcie->msi_domain) {
+		dev_err(dev, "Failed to create MSI domain\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int sg2042_pcie_setup_msi_external(struct sg2042_pcie *pcie)
+{
+	struct device *dev = pcie->cdns_pcie->dev;
+	struct device_node *np = dev->of_node;
+	struct irq_domain *parent_domain;
+	struct device_node *parent_np;
+
+	if (!of_find_property(np, "interrupt-parent", NULL)) {
+		dev_err(dev, "Can't find interrupt-parent!\n");
+		return -EINVAL;
+	}
+
+	parent_np = of_irq_find_parent(np);
+	if (!parent_np) {
+		dev_err(dev, "Can't find node of interrupt-parent!\n");
+		return -ENXIO;
+	}
+
+	parent_domain = irq_find_host(parent_np);
+	of_node_put(parent_np);
+	if (!parent_domain) {
+		dev_err(dev, "Can't find domain of interrupt-parent!\n");
+		return -ENXIO;
+	}
+
+	return sg2042_pcie_create_msi_domain(pcie, parent_domain);
+}
+
+static int sg2042_pcie_init_msi_data(struct sg2042_pcie *pcie)
+{
+	struct device *dev = pcie->cdns_pcie->dev;
+	u32 value;
+	int ret;
+
+	raw_spin_lock_init(&pcie->lock);
+
+	/*
+	 * Though the PCIe controller can address >32-bit address space, to
+	 * facilitate endpoints that support only 32-bit MSI target address,
+	 * the mask is set to 32-bit to make sure that MSI target address is
+	 * always a 32-bit address
+	 */
+	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+	if (ret < 0)
+		return ret;
+
+	pcie->msi_virt = dma_alloc_coherent(dev, BYTE_NUM_PER_MSI_VEC * MAX_MSI_IRQS,
+					    &pcie->msi_phys, GFP_KERNEL);
+	if (!pcie->msi_virt)
+		return -ENOMEM;
+
+	/* Program the msi address and size */
+	if (pcie->link_id == 1) {
+		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_LOW,
+			     lower_32_bits(pcie->msi_phys));
+		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_HIGH,
+			     upper_32_bits(pcie->msi_phys));
+
+		regmap_read(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, &value);
+		value = (value & REG_LINK1_MSI_ADDR_SIZE_MASK) | MAX_MSI_IRQS;
+		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, value);
+	} else {
+		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_LOW,
+			     lower_32_bits(pcie->msi_phys));
+		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_HIGH,
+			     upper_32_bits(pcie->msi_phys));
+
+		regmap_read(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, &value);
+		value = (value & REG_LINK0_MSI_ADDR_SIZE_MASK) | (MAX_MSI_IRQS << 16);
+		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, value);
+	}
+
+	return 0;
+}
+
+static irqreturn_t sg2042_pcie_msi_handle_irq(struct sg2042_pcie *pcie)
+{
+	u32 i, pos;
+	unsigned long val;
+	u32 status, num_vectors;
+	irqreturn_t ret = IRQ_NONE;
+
+	num_vectors = pcie->num_applied_vecs;
+	for (i = 0; i <= num_vectors; i++) {
+		status = readl((void *)(pcie->msi_virt + i * BYTE_NUM_PER_MSI_VEC));
+		if (!status)
+			continue;
+
+		ret = IRQ_HANDLED;
+		val = status;
+		pos = 0;
+		while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL,
+					    pos)) != MAX_MSI_IRQS_PER_CTRL) {
+			generic_handle_domain_irq(pcie->msi_domain->parent,
+						  (i * MAX_MSI_IRQS_PER_CTRL) +
+						  pos);
+			pos++;
+		}
+		writel(0, ((void *)(pcie->msi_virt) + i * BYTE_NUM_PER_MSI_VEC));
+	}
+	return ret;
+}
+
+static void sg2042_pcie_msi_chained_isr(struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	u32 status, st_msi_in_bit;
+	struct sg2042_pcie *pcie;
+
+	chained_irq_enter(chip, desc);
+
+	pcie = irq_desc_get_handler_data(desc);
+	if (pcie->link_id == 1)
+		st_msi_in_bit = REG_STATUS_LINK1_BIT;
+	else
+		st_msi_in_bit = REG_STATUS_LINK0_BIT;
+
+	regmap_read(pcie->syscon, REG_STATUS, &status);
+	if ((status >> st_msi_in_bit) & 0x1) {
+		sg2042_pcie_msi_clear_status(pcie);
+
+		sg2042_pcie_msi_handle_irq(pcie);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static int sg2042_pcie_setup_msi(struct sg2042_pcie *pcie, struct platform_device *pdev)
+{
+	struct device *dev = pcie->cdns_pcie->dev;
+	struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+	struct irq_domain *parent_domain;
+	int ret = 0;
+
+	parent_domain = irq_domain_create_linear(fwnode, MSI_DEF_NUM_VECTORS,
+						 &sg2042_pcie_msi_domain_ops, pcie);
+	if (!parent_domain) {
+		dev_err(dev, "Failed to create IRQ domain\n");
+		return -ENOMEM;
+	}
+	irq_domain_update_bus_token(parent_domain, DOMAIN_BUS_NEXUS);
+
+	ret = sg2042_pcie_create_msi_domain(pcie, parent_domain);
+	if (ret) {
+		irq_domain_remove(parent_domain);
+		return ret;
+	}
+
+	ret = sg2042_pcie_init_msi_data(pcie);
+	if (ret) {
+		dev_err(dev, "Failed to initialize msi data!\n");
+		return ret;
+	}
+
+	ret = platform_get_irq_byname(pdev, "msi");
+	if (ret <= 0) {
+		dev_err(dev, "failed to get MSI irq\n");
+		return ret;
+	}
+	pcie->msi_irq = ret;
+
+	irq_set_chained_handler_and_data(pcie->msi_irq,
+					 sg2042_pcie_msi_chained_isr, pcie);
+
+	return 0;
+}
+
+static void sg2042_pcie_free_msi(struct sg2042_pcie *pcie)
+{
+	struct device *dev = pcie->cdns_pcie->dev;
+
+	if (pcie->msi_irq)
+		irq_set_chained_handler_and_data(pcie->msi_irq, NULL, NULL);
+
+	if (pcie->msi_virt)
+		dma_free_coherent(dev, BYTE_NUM_PER_MSI_VEC * MAX_MSI_IRQS,
+				  pcie->msi_virt, pcie->msi_phys);
+}
+
+static u64 sg2042_cdns_pcie_cpu_addr_fixup(struct cdns_pcie *pcie, u64 cpu_addr)
+{
+	return cpu_addr & SG2042_CDNS_PLAT_CPU_TO_BUS_ADDR;
+}
+
+static const struct cdns_pcie_ops sg2042_cdns_pcie_ops = {
+	.cpu_addr_fixup = sg2042_cdns_pcie_cpu_addr_fixup,
+};
+
+/*
+ * SG2042 only support 4-byte aligned access, so for the rootbus (i.e. to read
+ * the PCIe controller itself, read32 is required. For non-rootbus (i.e. to read
+ * the PCIe peripheral registers, supports 1/2/4 byte aligned access, so
+ * directly use read should be fine.
+ * The same is true for write.
+ */
+static int sg2042_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
+				   int where, int size, u32 *value)
+{
+	if (pci_is_root_bus(bus))
+		return pci_generic_config_read32(bus, devfn, where, size,
+						 value);
+
+	return pci_generic_config_read(bus, devfn, where, size, value);
+}
+
+static int sg2042_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
+				    int where, int size, u32 value)
+{
+	if (pci_is_root_bus(bus))
+		return pci_generic_config_write32(bus, devfn, where, size,
+						  value);
+
+	return pci_generic_config_write(bus, devfn, where, size, value);
+}
+
+static struct pci_ops sg2042_pcie_host_ops = {
+	.map_bus	= cdns_pci_map_bus,
+	.read		= sg2042_pcie_config_read,
+	.write		= sg2042_pcie_config_write,
+};
+
+static int sg2042_pcie_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct pci_host_bridge *bridge;
+	struct device_node *np_syscon;
+	struct cdns_pcie *cdns_pcie;
+	struct sg2042_pcie *pcie;
+	struct cdns_pcie_rc *rc;
+	struct regmap *syscon;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_PCIE_CADENCE_HOST))
+		return -ENODEV;
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+	if (!bridge) {
+		dev_err(dev, "Failed to alloc host bridge!\n");
+		return -ENOMEM;
+	}
+	bridge->ops = &sg2042_pcie_host_ops;
+
+	rc = pci_host_bridge_priv(bridge);
+	cdns_pcie = &rc->pcie;
+	cdns_pcie->dev = dev;
+	cdns_pcie->ops = &sg2042_cdns_pcie_ops;
+	pcie->cdns_pcie = cdns_pcie;
+
+	np_syscon = of_parse_phandle(np, "sophgo,syscon-pcie-ctrl", 0);
+	if (!np_syscon) {
+		dev_err(dev, "Failed to get syscon node\n");
+		return -ENOMEM;
+	}
+	syscon = syscon_node_to_regmap(np_syscon);
+	if (IS_ERR(syscon)) {
+		dev_err(dev, "Failed to get regmap for syscon\n");
+		return -ENOMEM;
+	}
+	pcie->syscon = syscon;
+
+	if (of_property_read_u32(np, "sophgo,link-id", &pcie->link_id)) {
+		dev_err(dev, "Unable to parse link ID\n");
+		return -EINVAL;
+	}
+
+	pcie->internal_msi = 0;
+	if (of_property_read_bool(np, "sophgo,internal-msi"))
+		pcie->internal_msi = 1;
+
+	platform_set_drvdata(pdev, pcie);
+
+	pm_runtime_enable(dev);
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync failed\n");
+		goto err_get_sync;
+	}
+
+	if (pcie->internal_msi) {
+		ret = sg2042_pcie_setup_msi(pcie, pdev);
+		if (ret < 0)
+			goto err_setup_msi;
+	} else {
+		ret = sg2042_pcie_setup_msi_external(pcie);
+		if (ret < 0)
+			goto err_setup_msi;
+	}
+
+	ret = cdns_pcie_init_phy(dev, cdns_pcie);
+	if (ret) {
+		dev_err(dev, "Failed to init phy!\n");
+		goto err_setup_msi;
+	}
+
+	ret = cdns_pcie_host_setup(rc);
+	if (ret < 0) {
+		dev_err(dev, "Failed to setup host!\n");
+		goto err_host_setup;
+	}
+
+	return 0;
+
+err_host_setup:
+	cdns_pcie_disable_phy(cdns_pcie);
+
+err_setup_msi:
+	sg2042_pcie_free_msi(pcie);
+
+err_get_sync:
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static void sg2042_pcie_shutdown(struct platform_device *pdev)
+{
+	struct sg2042_pcie *pcie = platform_get_drvdata(pdev);
+	struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
+	struct device *dev = &pdev->dev;
+
+	sg2042_pcie_free_msi(pcie);
+
+	cdns_pcie_disable_phy(cdns_pcie);
+
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);
+}
+
+static const struct of_device_id sg2042_pcie_of_match[] = {
+	{ .compatible = "sophgo,sg2042-pcie-host" },
+	{},
+};
+
+static struct platform_driver sg2042_pcie_driver = {
+	.driver = {
+		.name		= "sg2042-pcie",
+		.of_match_table	= sg2042_pcie_of_match,
+		.pm		= &cdns_pcie_pm_ops,
+	},
+	.probe		= sg2042_pcie_probe,
+	.shutdown	= sg2042_pcie_shutdown,
+};
+builtin_platform_driver(sg2042_pcie_driver);
-- 
2.34.1



From unicornxw at gmail.com  Sun Nov 10 22:00:15 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 14:00:15 +0800
Subject: [PATCH 3/5] dt-bindings: mfd: syscon: Add sg2042 pcie ctrl compatible
In-Reply-To: <cover.1731303328.git.unicorn_wang@outlook.com>
References: <cover.1731303328.git.unicorn_wang@outlook.com>
Message-ID: <4f030066767c2a3b3acabe24e3dfbb8d87b42bfe.1731303328.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

Document SOPHGO SG2042 compatible for PCIe control registers.
These registers are shared by pcie controller nodes.

Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
---
 Documentation/devicetree/bindings/mfd/syscon.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index cc9b17ad69f2..55f919690001 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -106,6 +106,7 @@ select:
           - rockchip,rk3576-qos
           - rockchip,rk3588-qos
           - rockchip,rv1126-qos
+          - sophgo,sg2042-pcie-ctrl
           - st,spear1340-misc
           - stericsson,nomadik-pmu
           - starfive,jh7100-sysmain
@@ -203,6 +204,7 @@ properties:
           - rockchip,rk3576-qos
           - rockchip,rk3588-qos
           - rockchip,rv1126-qos
+          - sophgo,sg2042-pcie-ctrl
           - st,spear1340-misc
           - stericsson,nomadik-pmu
           - starfive,jh7100-sysmain
-- 
2.34.1



From unicornxw at gmail.com  Sun Nov 10 22:00:34 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 14:00:34 +0800
Subject: [PATCH 4/5] riscv: sophgo: dts: add pcie controllers for SG2042
In-Reply-To: <cover.1731303328.git.unicorn_wang@outlook.com>
References: <cover.1731303328.git.unicorn_wang@outlook.com>
Message-ID: <c8d05d3a4cf620ec4fcbf1050dea7c77f834c87a.1731303328.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

Add PCIe controller nodes in DTS for Sophgo SG2042.
Default they are disabled.

Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
---
 arch/riscv/boot/dts/sophgo/sg2042.dtsi | 82 ++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
index e62ac51ac55a..dca51fa9381b 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042.dtsi
+++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
@@ -195,6 +195,88 @@ clkgen: clock-controller at 7030012000 {
 			#clock-cells = <1>;
 		};
 
+		pcie_rc0: pcie at 7060000000 {
+			compatible = "sophgo,sg2042-pcie-host";
+			device_type = "pci";
+			reg = <0x70 0x60000000  0x0 0x02000000>,
+			      <0x40 0x00000000  0x0 0x00001000>;
+			reg-names = "reg", "cfg";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0  0xc0000000  0x40 0xc0000000  0x0 0x00400000>,
+				 <0x42000000 0x0  0xd0000000  0x40 0xd0000000  0x0 0x10000000>,
+				 <0x02000000 0x0  0xe0000000  0x40 0xe0000000  0x0 0x20000000>,
+				 <0x43000000 0x42 0x00000000  0x42 0x00000000  0x2 0x00000000>,
+				 <0x03000000 0x41 0x00000000  0x41 0x00000000  0x1 0x00000000>;
+			bus-range = <0x0 0x3f>;
+			vendor-id = <0x1f1c>;
+			device-id = <0x2042>;
+			cdns,no-bar-match-nbits = <48>;
+			sophgo,link-id = <0>;
+			sophgo,syscon-pcie-ctrl = <&cdns_pcie0_ctrl>;
+			interrupt-parent = <&msi>;
+			status = "disabled";
+		};
+
+		cdns_pcie0_ctrl: syscon at 7061800000 {
+			compatible = "sophgo,sg2042-pcie-ctrl", "syscon";
+			reg = <0x70 0x61800000 0x0 0x800000>;
+		};
+
+		pcie_rc1: pcie at 7062000000 {
+			compatible = "sophgo,sg2042-pcie-host";
+			device_type = "pci";
+			reg = <0x70 0x62000000  0x0 0x00800000>,
+			      <0x48 0x00000000  0x0 0x00001000>;
+			reg-names = "reg", "cfg";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0  0xc0800000  0x48 0xc0800000  0x0 0x00400000>,
+				 <0x42000000 0x0  0xd0000000  0x48 0xd0000000  0x0 0x10000000>,
+				 <0x02000000 0x0  0xe0000000  0x48 0xe0000000  0x0 0x20000000>,
+				 <0x03000000 0x49 0x00000000  0x49 0x00000000  0x1 0x00000000>,
+				 <0x43000000 0x4a 0x00000000  0x4a 0x00000000  0x2 0x00000000>;
+			bus-range = <0x80 0xbf>;
+			vendor-id = <0x1f1c>;
+			device-id = <0x2042>;
+			cdns,no-bar-match-nbits = <48>;
+			sophgo,link-id = <0>;
+			sophgo,syscon-pcie-ctrl = <&cdns_pcie1_ctrl>;
+			sophgo,internal-msi;
+			interrupt-parent = <&intc>;
+			interrupts = <123 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi";
+			status = "disabled";
+		};
+
+		pcie_rc2: pcie at 7062800000 {
+			compatible = "sophgo,sg2042-pcie-host";
+			device_type = "pci";
+			reg = <0x70 0x62800000  0x0 0x00800000>,
+			      <0x4c 0x00000000  0x0 0x00001000>;
+			reg-names = "reg", "cfg";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0  0xc0c00000  0x4c 0xc0c00000  0x0 0x00400000>,
+				 <0x42000000 0x0  0xf8000000  0x4c 0xf8000000  0x0 0x04000000>,
+				 <0x02000000 0x0  0xfc000000  0x4c 0xfc000000  0x0 0x04000000>,
+				 <0x43000000 0x4e 0x00000000  0x4e 0x00000000  0x2 0x00000000>,
+				 <0x03000000 0x4d 0x00000000  0x4d 0x00000000  0x1 0x00000000>;
+			bus-range = <0xc0 0xff>;
+			vendor-id = <0x1f1c>;
+			device-id = <0x2042>;
+			cdns,no-bar-match-nbits = <48>;
+			sophgo,link-id = <1>;
+			sophgo,syscon-pcie-ctrl = <&cdns_pcie1_ctrl>;
+			interrupt-parent = <&msi>;
+			status = "disabled";
+		};
+
+		cdns_pcie1_ctrl: syscon at 7063800000 {
+			compatible = "sophgo,sg2042-pcie-ctrl", "syscon";
+			reg = <0x70 0x63800000 0x0 0x800000>;
+		};
+
 		clint_mswi: interrupt-controller at 7094000000 {
 			compatible = "sophgo,sg2042-aclint-mswi", "thead,c900-aclint-mswi";
 			reg = <0x00000070 0x94000000 0x00000000 0x00004000>;
-- 
2.34.1



From unicornxw at gmail.com  Sun Nov 10 22:00:53 2024
From: unicornxw at gmail.com (Chen Wang)
Date: Mon, 11 Nov 2024 14:00:53 +0800
Subject: [PATCH 5/5] riscv: sophgo: dts: enable pcie for PioneerBox
In-Reply-To: <cover.1731303328.git.unicorn_wang@outlook.com>
References: <cover.1731303328.git.unicorn_wang@outlook.com>
Message-ID: <bbb573658f02c5a373eca1fe3f55ef40b09c7a57.1731303328.git.unicorn_wang@outlook.com>

From: Chen Wang <unicorn_wang at outlook.com>

Enable pcie controllers for PioneerBox, which uses SG2042 SoC.

Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
---
 arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
index a3f9d6f22566..746b9c3d254c 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
@@ -45,6 +45,18 @@ mcu: syscon at 17 {
 	};
 };
 
+&pcie_rc0 {
+	status = "okay";
+};
+
+&pcie_rc1 {
+	status = "okay";
+};
+
+&pcie_rc2 {
+	status = "okay";
+};
+
 &sd {
 	bus-width = <4>;
 	no-sdio;
-- 
2.34.1



From yangyicong at huawei.com  Mon Nov 11 00:39:09 2024
From: yangyicong at huawei.com (Yicong Yang)
Date: Mon, 11 Nov 2024 16:39:09 +0800
Subject: [PATCH v2 8/8] perf pmu: Move pmu_metrics_table__find and remove
 ARM override
In-Reply-To: <CAP-5=fWw04Qi+3=y7M4uMrhgrFWpnF7mZ09yb4v0P0qFT1Gfnw@mail.gmail.com>
References: <20241107162035.52206-1-irogers@google.com>
 <20241107162035.52206-9-irogers@google.com>
 <5a57de7c-924e-ccd6-8981-b9fddc647465@huawei.com>
 <CAP-5=fWw04Qi+3=y7M4uMrhgrFWpnF7mZ09yb4v0P0qFT1Gfnw@mail.gmail.com>
Message-ID: <e8603b0c-86db-c258-179a-f228c43ebf0b@huawei.com>

On 2024/11/10 0:10, Ian Rogers wrote:
> On Sat, Nov 9, 2024 at 2:54?AM Yicong Yang <yangyicong at huawei.com> wrote:
>>
>> Hi,
>>
>> On 2024/11/8 0:20, Ian Rogers wrote:
>>> Move pmu_metrics_table__find to the jevents.py generated pmu-events.c
>>> and remove indirection override for ARM. The movement removes
>>> perf_pmu__find_metrics_table that exists to enable the ARM
>>> override. The ARM override isn't necessary as just the CPUID, not PMU,
>>> is used in the metric table lookup. On non-ARM the CPU argument is
>>> just ignored for the CPUID, for ARM -1 is passed so that the CPUID for
>>> the first logical CPU is read.
>>
>> Since the logic here's already been touching, is it possible to step it further to just
>> ignore the CPUID matching when finding the system metrics/events tables? It's may not be
>> that reasonable for finding a system metrics/events from the CPUID, since one system PMU may
>> exists on different platforms with different CPU types.
> 
> The issue is for conciseness reasons we let metrics and metric
> thresholds refer to other metrics, for example:
> https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/pmu-events/arch/x86/icelakex/icx-metrics.json#n78
> ```
>     {
>         "BriefDescription": "This category represents fraction of
> slots where no uops are being delivered due to a lack of required
> resources for accepting new uops in the Backend",
>         "MetricExpr": "topdown\\-be\\-bound / (topdown\\-fe\\-bound +
> topdown\\-bad\\-spec + topdown\\-retiring + topdown\\-be\\-bound) + 5
> * cpu at INT_MISC.RECOVERY_CYCLES\\,cmask\\=1\\,edge@ / tma_info_slots",
>         "MetricGroup": "TmaL1;TopdownL1;tma_L1_group",
>         "MetricName": "tma_backend_bound",
>         "MetricThreshold": "tma_backend_bound > 0.2",
>         "MetricgroupNoGroup": "TopdownL1",
>         "PublicDescription": "This category represents fraction of
> slots where no uops are being delivered due to a lack of required
> resources for accepting new uops in the Backend. Backend is the
> portion of the processor core where the out-of-order scheduler
> dispatches ready uops into their respective execution units; and once
> completed these uops get retired according to program order. For
> example; stalls due to data-cache misses or stalls due to the divider
> unit being overloaded are both categorized under Backend Bound.
> Backend Bound is further divided into two main categories: Memory
> Bound and Core Bound. Sample with: TOPDOWN.BACKEND_BOUND_SLOTS",
>         "ScaleUnit": "100%"
>     },
> ```
> 
> The system metrics were added on top of this and we never rethought
> the design. For a metric to refer to another metric there needs to be
> some kind of place we look up from and for that we use the CPUID
> associated table. Perhaps the easiest thing is that if no CPUID table
> is matched we have an empty table.
> 

thanks for the clarificaiton. ok then it's different from my problem and I
shouldn't have mixed them up.

Thanks.


From schwab at suse.de  Mon Nov 11 01:41:52 2024
From: schwab at suse.de (Andreas Schwab)
Date: Mon, 11 Nov 2024 10:41:52 +0100
Subject: [PATCH] tools: add forwarding header for
 arch/riscv/include/asm/fence.h
In-Reply-To: <d380fd10-ebc4-4d66-becb-13995372d41a@ghiti.fr> (Alexandre
	Ghiti's message of "Mon, 4 Nov 2024 11:02:14 +0100")
References: <mvm5xq44bqh.fsf@suse.de>
	<d380fd10-ebc4-4d66-becb-13995372d41a@ghiti.fr>
Message-ID: <mvmfrnyxg2n.fsf@suse.de>

On Nov 04 2024, Alexandre Ghiti wrote:

> Unless you have any objection, we'll try to make Bjorn's patch into
> 6.12-rc7 instead of yours.

It still fails the same:

In file included from /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/tools/include/asm/barrier.h:12,
                 from /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/tools/include/linux/ring_buffer.h:4,
                 from libbpf.c:37:
/home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/tools/include/asm/../../arch/riscv/include/asm/barrier.h:13:10: fatal error: asm/fence.h: No such file or directory
   13 | #include <asm/fence.h>
      |          ^~~~~~~~~~~~~
compilation terminated.
make[5]: *** [/home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/tools/build/Makefile.build:106: /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/linux-obj/tools/bpf/resolve_btfids/libbpf/staticobjs/libbpf.o] Error 1
make[5]: *** Waiting for unfinished jobs....
make[4]: *** [Makefile:164: /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/linux-obj/tools/bpf/resolve_btfids/libbpf/staticobjs/libbpf-in.o] Error 2
make[3]: *** [Makefile:63: /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/linux-obj/tools/bpf/resolve_btfids//libbpf/libbpf.a] Error 2
make[2]: *** [Makefile:76: bpf/resolve_btfids] Error 2
make[1]: *** [/home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/Makefile:1393: tools/bpf/resolve_btfids] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [../Makefile:224: __sub-make] Error 2

-- 
Andreas Schwab, SUSE Labs, schwab at suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


From alex at ghiti.fr  Mon Nov 11 02:28:37 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Mon, 11 Nov 2024 11:28:37 +0100
Subject: [PATCH] tools: add forwarding header for
 arch/riscv/include/asm/fence.h
In-Reply-To: <mvmfrnyxg2n.fsf@suse.de>
References: <mvm5xq44bqh.fsf@suse.de>
 <d380fd10-ebc4-4d66-becb-13995372d41a@ghiti.fr> <mvmfrnyxg2n.fsf@suse.de>
Message-ID: <26452229-7461-48aa-987a-28444ace4f28@ghiti.fr>

Hi Andreas,

On 11/11/2024 10:41, Andreas Schwab wrote:
> On Nov 04 2024, Alexandre Ghiti wrote:
>
>> Unless you have any objection, we'll try to make Bjorn's patch into
>> 6.12-rc7 instead of yours.
> It still fails the same:
>
> In file included from /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/tools/include/asm/barrier.h:12,
>                   from /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/tools/include/linux/ring_buffer.h:4,
>                   from libbpf.c:37:
> /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/tools/include/asm/../../arch/riscv/include/asm/barrier.h:13:10: fatal error: asm/fence.h: No such file or directory
>     13 | #include <asm/fence.h>
>        |          ^~~~~~~~~~~~~
> compilation terminated.
> make[5]: *** [/home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/tools/build/Makefile.build:106: /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/linux-obj/tools/bpf/resolve_btfids/libbpf/staticobjs/libbpf.o] Error 1
> make[5]: *** Waiting for unfinished jobs....
> make[4]: *** [Makefile:164: /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/linux-obj/tools/bpf/resolve_btfids/libbpf/staticobjs/libbpf-in.o] Error 2
> make[3]: *** [Makefile:63: /home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/linux-obj/tools/bpf/resolve_btfids//libbpf/libbpf.a] Error 2
> make[2]: *** [Makefile:76: bpf/resolve_btfids] Error 2
> make[1]: *** [/home/abuild/rpmbuild/BUILD/kernel-default-6.12~rc7/linux-6.12-rc7/Makefile:1393: tools/bpf/resolve_btfids] Error 2
> make[1]: *** Waiting for unfinished jobs....
> make: *** [../Makefile:224: __sub-make] Error 2
>

Indeed, Bjorn's patches did not make it into rc7...



From schwab at suse.de  Mon Nov 11 02:31:15 2024
From: schwab at suse.de (Andreas Schwab)
Date: Mon, 11 Nov 2024 11:31:15 +0100
Subject: [PATCH] tools: add forwarding header for
 arch/riscv/include/asm/fence.h
In-Reply-To: <26452229-7461-48aa-987a-28444ace4f28@ghiti.fr> (Alexandre
	Ghiti's message of "Mon, 11 Nov 2024 11:28:37 +0100")
References: <mvm5xq44bqh.fsf@suse.de>
	<d380fd10-ebc4-4d66-becb-13995372d41a@ghiti.fr>
	<mvmfrnyxg2n.fsf@suse.de>
	<26452229-7461-48aa-987a-28444ace4f28@ghiti.fr>
Message-ID: <mvmbjymxdsc.fsf@suse.de>

On Nov 11 2024, Alexandre Ghiti wrote:

> Indeed, Bjorn's patches did not make it into rc7...

That needs to be fixed ASAP!

-- 
Andreas Schwab, SUSE Labs, schwab at suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


From james.clark at linaro.org  Mon Nov 11 02:45:14 2024
From: james.clark at linaro.org (James Clark)
Date: Mon, 11 Nov 2024 10:45:14 +0000
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is
 provided
In-Reply-To: <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
References: <20241026121758.143259-1-irogers@google.com>
 <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
 <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org>
 <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
Message-ID: <d9bfd75a-003a-4f65-abba-b8bcaad13682@linaro.org>



On 08/11/2024 6:37 pm, Atish Kumar Patra wrote:
> On Fri, Nov 8, 2024 at 4:16?AM James Clark <james.clark at linaro.org> wrote:
>>
>>
>>
>> On 07/11/2024 18:51, Ian Rogers wrote:
>>> On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
>>>>
>>>> At the RISC-V summit the topic of avoiding event data being in the
>>>> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
>>>> events being the priority when no PMU is provided so that legacy
>>>> events maybe supported via json. Originally Mark Rutland also
>>>> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
>>>> M? processors, but James Clark more recently tested this and believes
>>>> the driver issues there may not have existed or have been resolved. In
>>>> any case, it is inconsistent that with a PMU event names avoid legacy
>>>> encodings, but when wildcarding PMUs (ie without a PMU with the event
>>>> name) the legacy encodings have priority.
>>>>
>>>> The patch doing this work was reverted in a v6.10 release candidate
>>>> as, even though the patch was posted for weeks and had been on
>>>> linux-next for weeks without issue, Linus was in the habit of using
>>>> explicit legacy events with unsupported precision options on his
>>>> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
>>>> where ARM decided to call the events bus_cycles and cycles, the latter
>>>> being also a legacy event name. ARM haven't renamed the cycles event
>>>> to a more consistent cpu_cycles and avoided the problem. With these
>>>> changes the problematic event will now be skipped, a large warning
>>>> produced, and perf record will continue for the other PMU events. This
>>>> solution was proposed by Arnaldo.
>>>>
>>>> Two minor changes have been added to help with the error message and
>>>> to work around issues occurring with "perf stat metrics (shadow stat)
>>>> test".
>>>>
>>>> The patches have only been tested on my x86 non-hybrid laptop.
>>>
>>> Hi Atish and James,
>>>
>>> Could I get your tags for this series?
>>>
> 
> Hi Ian,
> Thanks for your patches. It definitely helps to have a clean slate
> implementation
> for the perf tool. However, I have some open questions about other use cases
> that we discussed during the RVI Summit.
> 
>>> The patches were originally motivated by wanting to make the behavior
>>> of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
>>> wildcarded to "cpu" in the first case. This was divergent because of
>>> ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
>>> config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
>>> type>, config=<encoding from event>) when a PMU name was given. This
>>> aligns with RISC-V wanting to use json encodings to avoid complexity
>>> in the PMU driver.
>>>
>>
>> I couldn't find the thread, but I remember fairly recently it was
>> mentioned that RISC-V would be supporting the legacy events after all,
>> maybe it was a comment from Atish? I'm not sure if that changes the
>> requirements for this or not?
>>
>> I still can't really imagine how tooling would work if every tool has to
>> maintain the mappings of basic events like instructions and branches.
>> For example all the perf_event_open tests in ltp use the legacy events.
>>
> 
> No it has not changed. While this series helps to avoid clunky vendor
> specific encodings
> in the driver for perf tool, I am still unsure how we will manage
> other applications
> (directly passing legacy events through perf_event_open or
> perf_evlist__open) will work.
> 
> I have only anecdotal data about folks relying perf legacy events
> directly to profile
> their application. All of them use mostly cycle/instruction events though.
> Are there any users who use other legacy events directly without perf tool ?
> 
> If not, we may have only cycle/instruction mapping in the driver and
> rely on json for everything else.
> The other use case is virtualization. I have been playing with these
> patches to find a clean solution to
> enable all the use cases. If you have any other ideas, please let me know.
> 

Yeah I would expect it's mostly cycles and instructions. I searched a 
bit for PERF_COUNT_HW_BRANCH_MISSES and only found tool/developer type 
usages, which I suppose we could expect to have to handle the mappings 
like perf. Although it's not the easiest thing to search for and 
obviously that only includes open source.

Usages do exist though, there are people posting on stack overflow using 
it, and other various bug tracker listings. So you would expect those 
same users to have to use raw event codes and some switch statement to 
pick the right one for their hardware, or use Perf.




From lkp at intel.com  Mon Nov 11 03:29:12 2024
From: lkp at intel.com (kernel test robot)
Date: Mon, 11 Nov 2024 19:29:12 +0800
Subject: [PATCH 2/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver
In-Reply-To: <5051f2375ff6218e7d44ce0c298efd5f9ee56964.1731303328.git.unicorn_wang@outlook.com>
References: <5051f2375ff6218e7d44ce0c298efd5f9ee56964.1731303328.git.unicorn_wang@outlook.com>
Message-ID: <202411111935.kqORCWuE-lkp@intel.com>

Hi Chen,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 2d5404caa8c7bb5c4e0435f94b28834ae5456623]

url:    https://github.com/intel-lab-lkp/linux/commits/Chen-Wang/dt-bindings-pci-Add-Sophgo-SG2042-PCIe-host/20241111-140237
base:   2d5404caa8c7bb5c4e0435f94b28834ae5456623
patch link:    https://lore.kernel.org/r/5051f2375ff6218e7d44ce0c298efd5f9ee56964.1731303328.git.unicorn_wang%40outlook.com
patch subject: [PATCH 2/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver
config: um-allyesconfig (https://download.01.org/0day-ci/archive/20241111/202411111935.kqORCWuE-lkp at intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241111/202411111935.kqORCWuE-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411111935.kqORCWuE-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> drivers/pci/controller/cadence/pcie-sg2042.c:141:12: warning: 'sg2042_pcie_msi_irq_set_affinity' defined but not used [-Wunused-function]
     141 | static int sg2042_pcie_msi_irq_set_affinity(struct irq_data *d,
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/sg2042_pcie_msi_irq_set_affinity +141 drivers/pci/controller/cadence/pcie-sg2042.c

   140	
 > 141	static int sg2042_pcie_msi_irq_set_affinity(struct irq_data *d,
   142						    const struct cpumask *mask,
   143						    bool force)
   144	{
   145		if (d->parent_data)
   146			return irq_chip_set_affinity_parent(d, mask, force);
   147	
   148		return -EINVAL;
   149	}
   150	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From vbabka at suse.cz  Mon Nov 11 04:12:27 2024
From: vbabka at suse.cz (Vlastimil Babka)
Date: Mon, 11 Nov 2024 13:12:27 +0100
Subject: [RFC PATCH v3 1/6] arch: introduce set_direct_map_valid_noflush()
In-Reply-To: <a774e13e-0616-4d96-bb51-bac0fcb2cb9b@redhat.com>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <20241030134912.515725-2-roypat@amazon.co.uk>
 <a774e13e-0616-4d96-bb51-bac0fcb2cb9b@redhat.com>
Message-ID: <440b2682-dbfb-4a5c-927c-2397413a7f9c@suse.cz>

On 10/31/24 10:57, David Hildenbrand wrote:
> On 30.10.24 14:49, Patrick Roy wrote:
>> From: "Mike Rapoport (Microsoft)" <rppt at kernel.org>
>> 
>> From: Mike Rapoport (Microsoft) <rppt at kernel.org>
>> 
>> Add an API that will allow updates of the direct/linear map for a set of
>> physically contiguous pages.
>> 
>> It will be used in the following patches.
>> 
>> Signed-off-by: Mike Rapoport (Microsoft) <rppt at kernel.org>
>> Signed-off-by: Patrick Roy <roypat at amazon.co.uk>
> 
> 
> [...]
> 
>>   #ifdef CONFIG_DEBUG_PAGEALLOC
>>   void __kernel_map_pages(struct page *page, int numpages, int enable)
>>   {
>> diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
>> index e7aec20fb44f1..3030d9245f5ac 100644
>> --- a/include/linux/set_memory.h
>> +++ b/include/linux/set_memory.h
>> @@ -34,6 +34,12 @@ static inline int set_direct_map_default_noflush(struct page *page)
>>   	return 0;
>>   }
>>   
>> +static inline int set_direct_map_valid_noflush(struct page *page,
>> +					       unsigned nr, bool valid)
> 
> I recall that "unsigned" is frowned upon; "unsigned int".
> 
>> +{
>> +	return 0;
>> +}
> 
> Can we add some kernel doc for this?
> 
> In particular
> 
> (a) What does it mean when we return 0? That it worked? Then, this

Seems so.

>      dummy function looks wrong. Or this it return the

That's !CONFIG_ARCH_HAS_SET_DIRECT_MAP and other functions around do it the
same way. Looks like the current callers can only exist with the CONFIG_
enabled in the first place.

>      number of processed entries? Then we'd have a possible "int" vs.
>      "unsigned int" inconsistency.
> 
> (b) What are the semantics when we fail halfway through the operation
>      when processing nr > 1? Is it "all or nothing"?

Looking at x86 implementation it seems like it can just bail out in the
middle, but then I'm not sure if it can really fail in the middle, hmm...




From n.proshkin at yadro.com  Mon Nov 11 07:25:58 2024
From: n.proshkin at yadro.com (Nikita Proshkin)
Date: Mon, 11 Nov 2024 18:25:58 +0300
Subject: [PATCH 0/2] dmaengine: sf-pdma: Fix dma transfers errors handling
Message-ID: <20241111152600.146912-1-n.proshkin@yadro.com>

Fix several problems in the sf-pdma driver related to handling situations
when the dma transfer fails (for example, due to IOMMU activities).

Nikita Proshkin (2):
  dmaengine: sf-pdma: Fix dma descriptor status reporting
  dmaengine: sf-pdma: Fix possible double-free for descriptors

 drivers/dma/sf-pdma/sf-pdma.c | 106 ++++++++++------------------------
 drivers/dma/sf-pdma/sf-pdma.h |   3 -
 2 files changed, 32 insertions(+), 77 deletions(-)

-- 
2.34.1



From n.proshkin at yadro.com  Mon Nov 11 07:25:59 2024
From: n.proshkin at yadro.com (Nikita Proshkin)
Date: Mon, 11 Nov 2024 18:25:59 +0300
Subject: [PATCH 1/2] dmaengine: sf-pdma: Fix dma descriptor status reporting
In-Reply-To: <20241111152600.146912-1-n.proshkin@yadro.com>
References: <20241111152600.146912-1-n.proshkin@yadro.com>
Message-ID: <20241111152600.146912-2-n.proshkin@yadro.com>

In the current implementation sf_pdma_tx_status() will never report about
descriptor error (it returns DMA_IN_PROGRESS even when currently processed
descriptor failed already).
In particular, this leads to polling until timeout in the dma_sync_wait()
from the dmaengine API.

* Make sf_pdma_tx_status() return DMA_ERROR for failed descriptors;
* Make sure that all accesses to the pdma channels state are protected by
  spinlock from struct virt_dma_chan;
* Remove the code related with retries from struct sf_pdma_chan because it
  is never used in the current driver implementation: chan->retries stays
  0 during the whole lifetime.

Signed-off-by: Nikita Proshkin <n.proshkin at yadro.com>
---
 drivers/dma/sf-pdma/sf-pdma.c | 95 ++++++++++-------------------------
 drivers/dma/sf-pdma/sf-pdma.h |  3 --
 2 files changed, 26 insertions(+), 72 deletions(-)

diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c
index 428473611115..55b7c57eeec9 100644
--- a/drivers/dma/sf-pdma/sf-pdma.c
+++ b/drivers/dma/sf-pdma/sf-pdma.c
@@ -153,44 +153,6 @@ static void sf_pdma_free_chan_resources(struct dma_chan *dchan)
 	vchan_dma_desc_free_list(&chan->vchan, &head);
 }
 
-static size_t sf_pdma_desc_residue(struct sf_pdma_chan *chan,
-				   dma_cookie_t cookie)
-{
-	struct virt_dma_desc *vd = NULL;
-	struct pdma_regs *regs = &chan->regs;
-	unsigned long flags;
-	u64 residue = 0;
-	struct sf_pdma_desc *desc;
-	struct dma_async_tx_descriptor *tx = NULL;
-
-	spin_lock_irqsave(&chan->vchan.lock, flags);
-
-	list_for_each_entry(vd, &chan->vchan.desc_submitted, node)
-		if (vd->tx.cookie == cookie)
-			tx = &vd->tx;
-
-	if (!tx)
-		goto out;
-
-	if (cookie == tx->chan->completed_cookie)
-		goto out;
-
-	if (cookie == tx->cookie) {
-		residue = readq(regs->residue);
-	} else {
-		vd = vchan_find_desc(&chan->vchan, cookie);
-		if (!vd)
-			goto out;
-
-		desc = to_sf_pdma_desc(vd);
-		residue = desc->xfer_size;
-	}
-
-out:
-	spin_unlock_irqrestore(&chan->vchan.lock, flags);
-	return residue;
-}
-
 static enum dma_status
 sf_pdma_tx_status(struct dma_chan *dchan,
 		  dma_cookie_t cookie,
@@ -198,12 +160,27 @@ sf_pdma_tx_status(struct dma_chan *dchan,
 {
 	struct sf_pdma_chan *chan = to_sf_pdma_chan(dchan);
 	enum dma_status status;
+	unsigned long flags;
+	struct virt_dma_desc *desc;
 
 	status = dma_cookie_status(dchan, cookie, txstate);
 
-	if (txstate && status != DMA_ERROR)
-		dma_set_residue(txstate, sf_pdma_desc_residue(chan, cookie));
+	if (status == DMA_COMPLETE) {
+		dma_set_residue(txstate, 0);
+		return status;
+	}
+
+	spin_lock_irqsave(&chan->vchan.lock, flags);
+
+	desc = vchan_find_desc(&chan->vchan, cookie);
+	if (chan->desc && cookie == chan->desc->async_tx->cookie) {
+		dma_set_residue(txstate, readq(chan->regs.residue));
+		status = chan->status;
+	} else if (desc) {
+		dma_set_residue(txstate, to_sf_pdma_desc(desc)->xfer_size);
+	}
 
+	spin_unlock_irqrestore(&chan->vchan.lock, flags);
 	return status;
 }
 
@@ -217,7 +194,6 @@ static int sf_pdma_terminate_all(struct dma_chan *dchan)
 	sf_pdma_disable_request(chan);
 	kfree(chan->desc);
 	chan->desc = NULL;
-	chan->xfer_err = false;
 	vchan_get_all_descriptors(&chan->vchan, &head);
 	spin_unlock_irqrestore(&chan->vchan.lock, flags);
 	vchan_dma_desc_free_list(&chan->vchan, &head);
@@ -278,7 +254,7 @@ static void sf_pdma_issue_pending(struct dma_chan *dchan)
 
 	spin_lock_irqsave(&chan->vchan.lock, flags);
 
-	if (!chan->desc && vchan_issue_pending(&chan->vchan)) {
+	if (vchan_issue_pending(&chan->vchan) && !chan->desc) {
 		/* vchan_issue_pending has made a check that desc in not NULL */
 		chan->desc = sf_pdma_get_first_pending_desc(chan);
 		sf_pdma_xfer_desc(chan);
@@ -300,15 +276,9 @@ static void sf_pdma_donebh_tasklet(struct tasklet_struct *t)
 	struct sf_pdma_chan *chan = from_tasklet(chan, t, done_tasklet);
 	unsigned long flags;
 
-	spin_lock_irqsave(&chan->lock, flags);
-	if (chan->xfer_err) {
-		chan->retries = MAX_RETRY;
-		chan->status = DMA_COMPLETE;
-		chan->xfer_err = false;
-	}
-	spin_unlock_irqrestore(&chan->lock, flags);
-
 	spin_lock_irqsave(&chan->vchan.lock, flags);
+	chan->status = DMA_COMPLETE;
+
 	list_del(&chan->desc->vdesc.node);
 	vchan_cookie_complete(&chan->desc->vdesc);
 
@@ -322,23 +292,12 @@ static void sf_pdma_donebh_tasklet(struct tasklet_struct *t)
 static void sf_pdma_errbh_tasklet(struct tasklet_struct *t)
 {
 	struct sf_pdma_chan *chan = from_tasklet(chan, t, err_tasklet);
-	struct sf_pdma_desc *desc = chan->desc;
 	unsigned long flags;
 
-	spin_lock_irqsave(&chan->lock, flags);
-	if (chan->retries <= 0) {
-		/* fail to recover */
-		spin_unlock_irqrestore(&chan->lock, flags);
-		dmaengine_desc_get_callback_invoke(desc->async_tx, NULL);
-	} else {
-		/* retry */
-		chan->retries--;
-		chan->xfer_err = true;
-		chan->status = DMA_ERROR;
-
-		sf_pdma_enable_request(chan);
-		spin_unlock_irqrestore(&chan->lock, flags);
-	}
+	spin_lock_irqsave(&chan->vchan.lock, flags);
+	dmaengine_desc_get_callback_invoke(chan->desc->async_tx, NULL);
+	chan->status = DMA_ERROR;
+	spin_unlock_irqrestore(&chan->vchan.lock, flags);
 }
 
 static irqreturn_t sf_pdma_done_isr(int irq, void *dev_id)
@@ -374,9 +333,9 @@ static irqreturn_t sf_pdma_err_isr(int irq, void *dev_id)
 	struct sf_pdma_chan *chan = dev_id;
 	struct pdma_regs *regs = &chan->regs;
 
-	spin_lock(&chan->lock);
+	spin_lock(&chan->vchan.lock);
 	writel((readl(regs->ctrl)) & ~PDMA_ERR_STATUS_MASK, regs->ctrl);
-	spin_unlock(&chan->lock);
+	spin_unlock(&chan->vchan.lock);
 
 	tasklet_schedule(&chan->err_tasklet);
 
@@ -480,8 +439,6 @@ static void sf_pdma_setup_chans(struct sf_pdma *pdma)
 		chan->pdma = pdma;
 		chan->pm_state = RUNNING;
 		chan->slave_id = i;
-		chan->xfer_err = false;
-		spin_lock_init(&chan->lock);
 
 		chan->vchan.desc_free = sf_pdma_free_desc;
 		vchan_init(&chan->vchan, &pdma->dma_dev);
diff --git a/drivers/dma/sf-pdma/sf-pdma.h b/drivers/dma/sf-pdma/sf-pdma.h
index 215e07183d7e..ea1a062adc18 100644
--- a/drivers/dma/sf-pdma/sf-pdma.h
+++ b/drivers/dma/sf-pdma/sf-pdma.h
@@ -102,11 +102,8 @@ struct sf_pdma_chan {
 	struct tasklet_struct		done_tasklet;
 	struct tasklet_struct		err_tasklet;
 	struct pdma_regs		regs;
-	spinlock_t			lock; /* protect chan data */
-	bool				xfer_err;
 	int				txirq;
 	int				errirq;
-	int				retries;
 };
 
 struct sf_pdma {
-- 
2.34.1



From n.proshkin at yadro.com  Mon Nov 11 07:26:00 2024
From: n.proshkin at yadro.com (Nikita Proshkin)
Date: Mon, 11 Nov 2024 18:26:00 +0300
Subject: [PATCH 2/2] dmaengine: sf-pdma: Fix possible double-free for descriptors
In-Reply-To: <20241111152600.146912-1-n.proshkin@yadro.com>
References: <20241111152600.146912-1-n.proshkin@yadro.com>
Message-ID: <20241111152600.146912-3-n.proshkin@yadro.com>

sf_pdma_issue_pending() sets pointer to the currently being processed
dma descriptor in struct sf_pdma_chan, but this descriptor remains a part
of the desc_issued list from the struct virt_dma_chan.

Descriptor is correctly deleted from the list and freed in done tasklet,
but stays in place in case of an error during dma processing, waiting for
sf_pdma_terminate_all() to be called.

If the pointer to the descriptor is valid in struct sf_pdma_chan,
sf_pdma_terminate_all() first frees this descriptor directly, but later
uses it again in the vchan_dma_desc_free_list(), leading to mem management
errors (double-free, use-after-free).

Signed-off-by: Nikita Proshkin <n.proshkin at yadro.com>
---
 drivers/dma/sf-pdma/sf-pdma.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c
index 55b7c57eeec9..8fec11ad4f0b 100644
--- a/drivers/dma/sf-pdma/sf-pdma.c
+++ b/drivers/dma/sf-pdma/sf-pdma.c
@@ -145,7 +145,6 @@ static void sf_pdma_free_chan_resources(struct dma_chan *dchan)
 
 	spin_lock_irqsave(&chan->vchan.lock, flags);
 	sf_pdma_disable_request(chan);
-	kfree(chan->desc);
 	chan->desc = NULL;
 	vchan_get_all_descriptors(&chan->vchan, &head);
 	sf_pdma_disclaim_chan(chan);
@@ -192,7 +191,6 @@ static int sf_pdma_terminate_all(struct dma_chan *dchan)
 
 	spin_lock_irqsave(&chan->vchan.lock, flags);
 	sf_pdma_disable_request(chan);
-	kfree(chan->desc);
 	chan->desc = NULL;
 	vchan_get_all_descriptors(&chan->vchan, &head);
 	spin_unlock_irqrestore(&chan->vchan.lock, flags);
@@ -279,8 +277,10 @@ static void sf_pdma_donebh_tasklet(struct tasklet_struct *t)
 	spin_lock_irqsave(&chan->vchan.lock, flags);
 	chan->status = DMA_COMPLETE;
 
-	list_del(&chan->desc->vdesc.node);
-	vchan_cookie_complete(&chan->desc->vdesc);
+	if (chan->desc) {
+		list_del(&chan->desc->vdesc.node);
+		vchan_cookie_complete(&chan->desc->vdesc);
+	}
 
 	chan->desc = sf_pdma_get_first_pending_desc(chan);
 	if (chan->desc)
@@ -295,7 +295,8 @@ static void sf_pdma_errbh_tasklet(struct tasklet_struct *t)
 	unsigned long flags;
 
 	spin_lock_irqsave(&chan->vchan.lock, flags);
-	dmaengine_desc_get_callback_invoke(chan->desc->async_tx, NULL);
+	if (chan->desc)
+		dmaengine_desc_get_callback_invoke(chan->desc->async_tx, NULL);
 	chan->status = DMA_ERROR;
 	spin_unlock_irqrestore(&chan->vchan.lock, flags);
 }
@@ -310,7 +311,7 @@ static irqreturn_t sf_pdma_done_isr(int irq, void *dev_id)
 	writel((readl(regs->ctrl)) & ~PDMA_DONE_STATUS_MASK, regs->ctrl);
 	residue = readq(regs->residue);
 
-	if (!residue) {
+	if (!residue || !chan->desc) {
 		tasklet_hi_schedule(&chan->done_tasklet);
 	} else {
 		/* submit next trascatioin if possible */
-- 
2.34.1



From james.clark at linaro.org  Mon Nov 11 07:49:47 2024
From: james.clark at linaro.org (James Clark)
Date: Mon, 11 Nov 2024 15:49:47 +0000
Subject: [PATCH v1 3/4] perf record: Skip don't fail for events that don't
 open
In-Reply-To: <20241026121758.143259-4-irogers@google.com>
References: <20241026121758.143259-1-irogers@google.com>
 <20241026121758.143259-4-irogers@google.com>
Message-ID: <7c1a0bbf-12fd-46ef-9db2-183dfa70a334@linaro.org>



On 26/10/2024 1:17 pm, Ian Rogers wrote:
> Whilst for many tools it is an expected behavior that failure to open
> a perf event is a failure, ARM decided to name PMU events the same as
> legacy events and then failed to rename such events on a server uncore
> SLC PMU. As perf's default behavior when no PMU is specified is to
> open the event on all PMUs that advertise/"have" the event, this
> yielded failures when trying to make the priority of legacy and
> sysfs/json events uniform - something requested by RISC-V and ARM. A
> legacy event user on ARM hardware may find their event opened on an
> uncore PMU which for perf record will fail. Arnaldo suggested skipping
> such events which this patch implements. Rather than have the skipping
> conditional on running on ARM, the skipping is done on all
> architectures as such a fundamental behavioral difference could lead
> to problems with tools built/depending on perf.
> 
> An example of perf record failing to open events on x86 is:
> ```
> $ perf record -e data_read,cycles,LLC-prefetch-read -a sleep 0.1
> Error:
> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0' which will be removed.
> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> "dmesg | grep -i perf" may provide additional information.
> 
> Error:
> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_1' which will be removed.
> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> "dmesg | grep -i perf" may provide additional information.
> 

This makes me wonder if this message was overly wordy to begin with. 
This line is fine:

  Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0'
  which will be removed.

The next bit about the syscall just repeats. The exit code could be 
included on the previous line. And the dmesg bit is general advice that 
could possibly be printed once at the end.

> Error:
> Failure to open event 'LLC-prefetch-read' on PMU 'cpu' which will be removed.
> The LLC-prefetch-read event is not supported.
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 2.188 MB perf.data (87 samples) ]
> 
> $ perf report --stats
> Aggregated stats:
>                 TOTAL events:      17255
>                  MMAP events:        284  ( 1.6%)
>                  COMM events:       1961  (11.4%)
>                  EXIT events:          1  ( 0.0%)
>                  FORK events:       1960  (11.4%)
>                SAMPLE events:         87  ( 0.5%)
>                 MMAP2 events:      12836  (74.4%)
>               KSYMBOL events:         83  ( 0.5%)
>             BPF_EVENT events:         36  ( 0.2%)
>        FINISHED_ROUND events:          2  ( 0.0%)
>              ID_INDEX events:          1  ( 0.0%)
>            THREAD_MAP events:          1  ( 0.0%)
>               CPU_MAP events:          1  ( 0.0%)
>             TIME_CONV events:          1  ( 0.0%)
>         FINISHED_INIT events:          1  ( 0.0%)
> cycles stats:
>                SAMPLE events:         87
> ```
> 
> Note, if all events fail to open then the data file will contain no
> samples. This is deliberate as at the point the events are opened
> there are other events, such as the dummy event for sideband data, and
> these events will succeed in opening even if the user specified ones

Is a file with only sideband events useful? Is it possible to fail the 
record command if the event doesn't open anywhere?

I noticed this leads to some different behavior and a libperf warning 
when you have paranoid=3:

   $ perf record -e cycles -C 0 -- true

   Error:
   Failure to open event 'cpu_atom/cycles/u' on PMU 'cpu_atom' which will
   be removed.
   ...
   Consider adjusting /proc/sys/kernel/perf_event_paranoid setting
   ...
   libperf: Miscounted nr_mmaps 0 vs 28
   WARNING: No sample_id_all support, falling back to unordered
   processing
   [ perf record: Woken up 1 times to write data ]
   [ perf record: Captured and wrote 0.021 MB perf.data ]


> don't. Having a mix of open and broken events leads to a problem of
> identifying different sources of events.
 >

In my basic test I saw that the opened event was identified correctly in 
perf report, unless you have an example that you encountered that we 
should fix?

One place I saw an issue was with auxtrace events. If there's an event 
name clash then you're likely to not be able to open the file afterwards 
because the auxtrace code can't handle an event that didn't open. But I 
don't know of any name clashes there (I just faked one for testing), and 
maybe that could be fixed up later in the auxtrace code if there is ever 
a real one.

Other than the above it does seem to work ok.

> The issue with legacy events is that on RISC-V they want the driver to
> not have mappings from legacy to non-legacy config encodings for each
> vendor/model due to size, complexity and difficulty to update. It was
> reported that on ARM Apple-M? CPUs the legacy mapping in the driver
> was broken and the sysfs/json events should always take precedent,
> however, it isn't clear this is still the case. It is the case that
> without working around this issue a legacy event like cycles without a
> PMU can encode differently than when specified with a PMU - the
> non-PMU version favoring legacy encodings, the PMU one avoiding legacy
> encodings.
> 
> The patch removes events and then adjusts the idx value for each
> evsel. This is done so that the dense xyarrays used for file
> descriptors, etc. don't contain broken entries. As event opening
> happens relatively late in the record process, use of the idx value
> before the open will have become corrupted, so it is expected there
> are latent bugs hidden behind this change - the change is best
> effort. As the only vendor that has broken event names is ARM, this
> will principally effect ARM users. They will also experience warning
> messages like those above because of the uncore PMU advertising legacy
> event names.



> 
> Suggested-by: Arnaldo Carvalho de Melo <acme at kernel.org>
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>   tools/perf/builtin-record.c | 22 +++++++++++++++++-----
>   1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index f83252472921..7e99743f7e42 100644
> --- a/tools/perf/builtin-record.c
> +++ b/tools/perf/builtin-record.c
> @@ -1364,6 +1364,7 @@ static int record__open(struct record *rec)
>   	struct perf_session *session = rec->session;
>   	struct record_opts *opts = &rec->opts;
>   	int rc = 0;
> +	bool skipped = false;
>   
>   	evlist__for_each_entry(evlist, pos) {
>   try_again:
> @@ -1379,15 +1380,26 @@ static int record__open(struct record *rec)
>   			        pos = evlist__reset_weak_group(evlist, pos, true);
>   				goto try_again;
>   			}
> -			rc = -errno;
>   			evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg));
> -			ui__error("%s\n", msg);
> -			goto out;
> +			ui__error("Failure to open event '%s' on PMU '%s' which will be removed.\n%s\n",
> +				  evsel__name(pos), evsel__pmu_name(pos), msg);
> +			pos->skippable = true;
> +			skipped = true;
> +		} else {
> +			pos->supported = true;
>   		}
> -
> -		pos->supported = true;
>   	}
>   
> +	if (skipped) {
> +		struct evsel *tmp;
> +		int idx = 0;
> +
> +		evlist__for_each_entry_safe(evlist, tmp, pos) {
> +			if (pos->skippable)
> +				evlist__remove(evlist, pos);
> +			pos->core.idx = idx++;
> +		}
> +	}
>   	if (symbol_conf.kptr_restrict && !evlist__exclude_kernel(evlist)) {
>   		pr_warning(
>   "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"



From will at kernel.org  Mon Nov 11 08:43:00 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 11 Nov 2024 16:43:00 +0000
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241103145153.105097-14-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com>
Message-ID: <20241111164259.GA20042@willie-the-truck>

On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> In order to produce a generic kernel, a user can select
> CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> spinlock implementation if Zabha or Ziccrse are not present.
> 
> Note that we can't use alternatives here because the discovery of
> extensions is done too late and we need to start with the qspinlock
> implementation because the ticket spinlock implementation would pollute
> the spinlock value, so let's use static keys.

I think the static key toggling takes a mutex (jump_label_lock()) which
can take a spinlock (lock->wait_lock) internally, so I don't grok how
this works:

> +static void __init riscv_spinlock_init(void)
> +{
> +	char *using_ext = NULL;
> +
> +	if (IS_ENABLED(CONFIG_RISCV_TICKET_SPINLOCKS)) {
> +		pr_info("Ticket spinlock: enabled\n");
> +		return;
> +	}
> +
> +	if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) &&
> +	    IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) &&
> +	    riscv_isa_extension_available(NULL, ZABHA) &&
> +	    riscv_isa_extension_available(NULL, ZACAS)) {
> +		using_ext = "using Zabha";
> +	} else if (riscv_isa_extension_available(NULL, ZICCRSE)) {
> +		using_ext = "using Ziccrse";
> +	}
> +#if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
> +	else {
> +		static_branch_disable(&qspinlock_key);
> +		pr_info("Ticket spinlock: enabled\n");
> +		return;
> +	}
> +#endif

i.e. we've potentially already used the qspinlock at this point.

Will


From irogers at google.com  Mon Nov 11 09:00:04 2024
From: irogers at google.com (Ian Rogers)
Date: Mon, 11 Nov 2024 09:00:04 -0800
Subject: [PATCH v1 3/4] perf record: Skip don't fail for events that don't open
In-Reply-To: <7c1a0bbf-12fd-46ef-9db2-183dfa70a334@linaro.org>
References: <20241026121758.143259-1-irogers@google.com> <20241026121758.143259-4-irogers@google.com>
 <7c1a0bbf-12fd-46ef-9db2-183dfa70a334@linaro.org>
Message-ID: <CAP-5=fVODgnWgfCpA7x3B8JFQhkt_unUeTjhWWdSDpKECdTSYg@mail.gmail.com>

On Mon, Nov 11, 2024 at 7:49?AM James Clark <james.clark at linaro.org> wrote:
>
>
>
> On 26/10/2024 1:17 pm, Ian Rogers wrote:
> > Whilst for many tools it is an expected behavior that failure to open
> > a perf event is a failure, ARM decided to name PMU events the same as
> > legacy events and then failed to rename such events on a server uncore
> > SLC PMU. As perf's default behavior when no PMU is specified is to
> > open the event on all PMUs that advertise/"have" the event, this
> > yielded failures when trying to make the priority of legacy and
> > sysfs/json events uniform - something requested by RISC-V and ARM. A
> > legacy event user on ARM hardware may find their event opened on an
> > uncore PMU which for perf record will fail. Arnaldo suggested skipping
> > such events which this patch implements. Rather than have the skipping
> > conditional on running on ARM, the skipping is done on all
> > architectures as such a fundamental behavioral difference could lead
> > to problems with tools built/depending on perf.
> >
> > An example of perf record failing to open events on x86 is:
> > ```
> > $ perf record -e data_read,cycles,LLC-prefetch-read -a sleep 0.1
> > Error:
> > Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0' which will be removed.
> > The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> > "dmesg | grep -i perf" may provide additional information.
> >
> > Error:
> > Failure to open event 'data_read' on PMU 'uncore_imc_free_running_1' which will be removed.
> > The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> > "dmesg | grep -i perf" may provide additional information.
> >
>
> This makes me wonder if this message was overly wordy to begin with.
> This line is fine:
>
>   Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0'
>   which will be removed.
>
> The next bit about the syscall just repeats. The exit code could be
> included on the previous line. And the dmesg bit is general advice that
> could possibly be printed once at the end.

Thanks for the time spent investigating this!

I agree on this. I wonder if we should have short and long messages,
or message+help like we do for parse events. One patch series like
this is improving EBUSY:
https://lore.kernel.org/lkml/20241106003007.2112584-1-ctshao at google.com/
The issue with printing at the end is knowing where/when the end is.
Printing once is easy enough.

> > Error:
> > Failure to open event 'LLC-prefetch-read' on PMU 'cpu' which will be removed.
> > The LLC-prefetch-read event is not supported.
> > [ perf record: Woken up 1 times to write data ]
> > [ perf record: Captured and wrote 2.188 MB perf.data (87 samples) ]
> >
> > $ perf report --stats
> > Aggregated stats:
> >                 TOTAL events:      17255
> >                  MMAP events:        284  ( 1.6%)
> >                  COMM events:       1961  (11.4%)
> >                  EXIT events:          1  ( 0.0%)
> >                  FORK events:       1960  (11.4%)
> >                SAMPLE events:         87  ( 0.5%)
> >                 MMAP2 events:      12836  (74.4%)
> >               KSYMBOL events:         83  ( 0.5%)
> >             BPF_EVENT events:         36  ( 0.2%)
> >        FINISHED_ROUND events:          2  ( 0.0%)
> >              ID_INDEX events:          1  ( 0.0%)
> >            THREAD_MAP events:          1  ( 0.0%)
> >               CPU_MAP events:          1  ( 0.0%)
> >             TIME_CONV events:          1  ( 0.0%)
> >         FINISHED_INIT events:          1  ( 0.0%)
> > cycles stats:
> >                SAMPLE events:         87
> > ```
> >
> > Note, if all events fail to open then the data file will contain no
> > samples. This is deliberate as at the point the events are opened
> > there are other events, such as the dummy event for sideband data, and
> > these events will succeed in opening even if the user specified ones
>
> Is a file with only sideband events useful? Is it possible to fail the
> record command if the event doesn't open anywhere?
>
> I noticed this leads to some different behavior and a libperf warning
> when you have paranoid=3:
>
>    $ perf record -e cycles -C 0 -- true
>
>    Error:
>    Failure to open event 'cpu_atom/cycles/u' on PMU 'cpu_atom' which will
>    be removed.
>    ...
>    Consider adjusting /proc/sys/kernel/perf_event_paranoid setting
>    ...
>    libperf: Miscounted nr_mmaps 0 vs 28
>    WARNING: No sample_id_all support, falling back to unordered
>    processing
>    [ perf record: Woken up 1 times to write data ]
>    [ perf record: Captured and wrote 0.021 MB perf.data ]

So paranoid=3 is a Debian extension that Peter Z doesn't agree with
and so isn't enabled in regular kernels. So we're dealing with cycles,
which we'd expect to open or fall-back to a software event like
task-clock. It feels like things could happen better here but that's
not necessarily the fault of this patch.

> > don't. Having a mix of open and broken events leads to a problem of
> > identifying different sources of events.
>  >
>
> In my basic test I saw that the opened event was identified correctly in
> perf report, unless you have an example that you encountered that we
> should fix?

I didn't find any but we also don't tend to test failing to open
events. I could imagine things failing in `perf test` on neoverse
testing given the l3 advertising the cycles event.

> One place I saw an issue was with auxtrace events. If there's an event
> name clash then you're likely to not be able to open the file afterwards
> because the auxtrace code can't handle an event that didn't open. But I
> don't know of any name clashes there (I just faked one for testing), and
> maybe that could be fixed up later in the auxtrace code if there is ever
> a real one.
>
> Other than the above it does seem to work ok.

Cool, can this be taken as a Tested-by?

Thanks,
Ian

> > The issue with legacy events is that on RISC-V they want the driver to
> > not have mappings from legacy to non-legacy config encodings for each
> > vendor/model due to size, complexity and difficulty to update. It was
> > reported that on ARM Apple-M? CPUs the legacy mapping in the driver
> > was broken and the sysfs/json events should always take precedent,
> > however, it isn't clear this is still the case. It is the case that
> > without working around this issue a legacy event like cycles without a
> > PMU can encode differently than when specified with a PMU - the
> > non-PMU version favoring legacy encodings, the PMU one avoiding legacy
> > encodings.
> >
> > The patch removes events and then adjusts the idx value for each
> > evsel. This is done so that the dense xyarrays used for file
> > descriptors, etc. don't contain broken entries. As event opening
> > happens relatively late in the record process, use of the idx value
> > before the open will have become corrupted, so it is expected there
> > are latent bugs hidden behind this change - the change is best
> > effort. As the only vendor that has broken event names is ARM, this
> > will principally effect ARM users. They will also experience warning
> > messages like those above because of the uncore PMU advertising legacy
> > event names.
>
>
>
> >
> > Suggested-by: Arnaldo Carvalho de Melo <acme at kernel.org>
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >   tools/perf/builtin-record.c | 22 +++++++++++++++++-----
> >   1 file changed, 17 insertions(+), 5 deletions(-)
> >
> > diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> > index f83252472921..7e99743f7e42 100644
> > --- a/tools/perf/builtin-record.c
> > +++ b/tools/perf/builtin-record.c
> > @@ -1364,6 +1364,7 @@ static int record__open(struct record *rec)
> >       struct perf_session *session = rec->session;
> >       struct record_opts *opts = &rec->opts;
> >       int rc = 0;
> > +     bool skipped = false;
> >
> >       evlist__for_each_entry(evlist, pos) {
> >   try_again:
> > @@ -1379,15 +1380,26 @@ static int record__open(struct record *rec)
> >                               pos = evlist__reset_weak_group(evlist, pos, true);
> >                               goto try_again;
> >                       }
> > -                     rc = -errno;
> >                       evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg));
> > -                     ui__error("%s\n", msg);
> > -                     goto out;
> > +                     ui__error("Failure to open event '%s' on PMU '%s' which will be removed.\n%s\n",
> > +                               evsel__name(pos), evsel__pmu_name(pos), msg);
> > +                     pos->skippable = true;
> > +                     skipped = true;
> > +             } else {
> > +                     pos->supported = true;
> >               }
> > -
> > -             pos->supported = true;
> >       }
> >
> > +     if (skipped) {
> > +             struct evsel *tmp;
> > +             int idx = 0;
> > +
> > +             evlist__for_each_entry_safe(evlist, tmp, pos) {
> > +                     if (pos->skippable)
> > +                             evlist__remove(evlist, pos);
> > +                     pos->core.idx = idx++;
> > +             }
> > +     }
> >       if (symbol_conf.kptr_restrict && !evlist__exclude_kernel(evlist)) {
> >               pr_warning(
> >   "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
>


From will at kernel.org  Mon Nov 11 09:10:53 2024
From: will at kernel.org (Will Deacon)
Date: Mon, 11 Nov 2024 17:10:53 +0000
Subject: [PATCH kvmtool] riscv: Pass correct size to snprintf()
In-Reply-To: <20241104192120.75841-1-bjorn@kernel.org>
References: <20241104192120.75841-1-bjorn@kernel.org>
Message-ID: <173134344938.1668143.13537130235205302790.b4-ty@kernel.org>

On Mon, 04 Nov 2024 20:21:19 +0100, Bj?rn T?pel wrote:
> The snprintf() function does not get the correct size argument passed,
> when the FDT ISA string is built. Instead of adjusting the size for
> each extension, the full size is passed for every iteration. Doing so
> will make __snprinf_chk() bail out on glibc.
> 
> Adjust size for each iteration.
> 
> [...]

Applied to kvmtool (master), thanks!

[1/1] riscv: Pass correct size to snprintf()
      https://git.kernel.org/will/kvmtool/c/574bd7b432ec

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From irogers at google.com  Mon Nov 11 09:19:26 2024
From: irogers at google.com (Ian Rogers)
Date: Mon, 11 Nov 2024 09:19:26 -0800
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is provided
In-Reply-To: <d9bfd75a-003a-4f65-abba-b8bcaad13682@linaro.org>
References: <20241026121758.143259-1-irogers@google.com> <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
 <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org> <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
 <d9bfd75a-003a-4f65-abba-b8bcaad13682@linaro.org>
Message-ID: <CAP-5=fUHjxL5QbsyQQU-3EYiVhiO6wt=F5MfSfDcAffKP7WWAg@mail.gmail.com>

On Mon, Nov 11, 2024 at 2:45?AM James Clark <james.clark at linaro.org> wrote:
>
>
>
> On 08/11/2024 6:37 pm, Atish Kumar Patra wrote:
> > On Fri, Nov 8, 2024 at 4:16?AM James Clark <james.clark at linaro.org> wrote:
> >>
> >>
> >>
> >> On 07/11/2024 18:51, Ian Rogers wrote:
> >>> On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
> >>>>
> >>>> At the RISC-V summit the topic of avoiding event data being in the
> >>>> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
> >>>> events being the priority when no PMU is provided so that legacy
> >>>> events maybe supported via json. Originally Mark Rutland also
> >>>> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
> >>>> M? processors, but James Clark more recently tested this and believes
> >>>> the driver issues there may not have existed or have been resolved. In
> >>>> any case, it is inconsistent that with a PMU event names avoid legacy
> >>>> encodings, but when wildcarding PMUs (ie without a PMU with the event
> >>>> name) the legacy encodings have priority.
> >>>>
> >>>> The patch doing this work was reverted in a v6.10 release candidate
> >>>> as, even though the patch was posted for weeks and had been on
> >>>> linux-next for weeks without issue, Linus was in the habit of using
> >>>> explicit legacy events with unsupported precision options on his
> >>>> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
> >>>> where ARM decided to call the events bus_cycles and cycles, the latter
> >>>> being also a legacy event name. ARM haven't renamed the cycles event
> >>>> to a more consistent cpu_cycles and avoided the problem. With these
> >>>> changes the problematic event will now be skipped, a large warning
> >>>> produced, and perf record will continue for the other PMU events. This
> >>>> solution was proposed by Arnaldo.
> >>>>
> >>>> Two minor changes have been added to help with the error message and
> >>>> to work around issues occurring with "perf stat metrics (shadow stat)
> >>>> test".
> >>>>
> >>>> The patches have only been tested on my x86 non-hybrid laptop.
> >>>
> >>> Hi Atish and James,
> >>>
> >>> Could I get your tags for this series?
> >>>
> >
> > Hi Ian,
> > Thanks for your patches. It definitely helps to have a clean slate
> > implementation
> > for the perf tool. However, I have some open questions about other use cases
> > that we discussed during the RVI Summit.
> >
> >>> The patches were originally motivated by wanting to make the behavior
> >>> of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
> >>> wildcarded to "cpu" in the first case. This was divergent because of
> >>> ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
> >>> config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
> >>> type>, config=<encoding from event>) when a PMU name was given. This
> >>> aligns with RISC-V wanting to use json encodings to avoid complexity
> >>> in the PMU driver.
> >>>
> >>
> >> I couldn't find the thread, but I remember fairly recently it was
> >> mentioned that RISC-V would be supporting the legacy events after all,
> >> maybe it was a comment from Atish? I'm not sure if that changes the
> >> requirements for this or not?
> >>
> >> I still can't really imagine how tooling would work if every tool has to
> >> maintain the mappings of basic events like instructions and branches.
> >> For example all the perf_event_open tests in ltp use the legacy events.
> >>
> >
> > No it has not changed. While this series helps to avoid clunky vendor
> > specific encodings
> > in the driver for perf tool, I am still unsure how we will manage
> > other applications
> > (directly passing legacy events through perf_event_open or
> > perf_evlist__open) will work.
> >
> > I have only anecdotal data about folks relying perf legacy events
> > directly to profile
> > their application. All of them use mostly cycle/instruction events though.
> > Are there any users who use other legacy events directly without perf tool ?
> >
> > If not, we may have only cycle/instruction mapping in the driver and
> > rely on json for everything else.
> > The other use case is virtualization. I have been playing with these
> > patches to find a clean solution to
> > enable all the use cases. If you have any other ideas, please let me know.
> >
>
> Yeah I would expect it's mostly cycles and instructions. I searched a
> bit for PERF_COUNT_HW_BRANCH_MISSES and only found tool/developer type
> usages, which I suppose we could expect to have to handle the mappings
> like perf. Although it's not the easiest thing to search for and
> obviously that only includes open source.
>
> Usages do exist though, there are people posting on stack overflow using
> it, and other various bug tracker listings. So you would expect those
> same users to have to use raw event codes and some switch statement to
> pick the right one for their hardware, or use Perf.

I don't have any magic to solve this. My thoughts:

1) I thought legacy events were just going to hang around forever,
although the name hinting they'd kind of been deprecated. At LPC '23
Atish and Mark Rutland originally asked for the sysfs/json to be the
preference. I thought Kan was going to push back given the upheaval,
especially updating every test expectation. It went through but we're
in this weird state where wildcard events are encoded using legacy and
PMU specifying events aren't. What this series hopes to solve.

2) I think it is important that perf tool be a reference
implementation where others can look (strace, etc.) to base their
implementation. Moving perf to sysfs/json is 1 step closer to legacy
event deprecation. Please yell if deprecation isn't what is wanted as
personally other than cleanliness I don't mind. If we do decide not to
have sysfs/json be the priority then I think it sensible to revert the
changes making it the priority for events that specify a PMU. I'd like
some level of consistency.

3) I'd like event parsing to be a library that is as easy to link
against as libbpf (i.e. not a viral license). Event parsing is really
just mapping an event name to 1 or more perf_event_attr. The PMU
abstraction is tied into the event parsing, but this has only been
more true recently. The evsel/evlist is tied into event parsing but
that feels separable. As most json isn't distributed under a viral
license this feels achievable, then I suspect most tools can use this
library rather than have to reinvent a wheel.

Still looking for tags :-)

Thanks,
Ian


From debug at rivosinc.com  Mon Nov 11 12:53:45 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:45 -0800
Subject: [PATCH v8 00/29] riscv control-flow integrity for usermode
Message-ID: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>

Basics and overview
===================

Software with larger attack surfaces (e.g. network facing apps like databases,
browsers or apps relying on browser runtimes) suffer from memory corruption
issues which can be utilized by attackers to bend control flow of the program
to eventually gain control (by making their payload executable). Attackers are
able to perform such attacks by leveraging call-sites which rely on indirect
calls or return sites which rely on obtaining return address from stack memory.

To mitigate such attacks, risc-v extension zicfilp enforces that all indirect
calls must land on a landing pad instruction `lpad` else cpu will raise software
check exception (a new cpu exception cause code on riscv).
Similarly for return flow, risc-v extension zicfiss extends architecture with

- `sspush` instruction to push return address on a shadow stack
- `sspopchk` instruction to pop return address from shadow stack
  and compare with input operand (i.e. return address on stack)
- `sspopchk` to raise software check exception if comparision above
  was a mismatch
- Protection mechanism using which shadow stack is not writeable via
  regular store instructions

More information an details can be found at extensions github repo [1].

Equivalent to landing pad (zicfilp) on x86 is `ENDBRANCH` instruction in Intel
CET [3] and branch target identification (BTI) [4] on arm.
Similarly x86's Intel CET has shadow stack [5] and arm64 has guarded control
stack (GCS) [6] which are very similar to risc-v's zicfiss shadow stack.

x86 already supports shadow stack for user mode and arm64 support for GCS in
usermode [7] is in -next.

Kernel awareness for user control flow integrity
================================================

This series picks up Samuel Holland's envcfg changes [2] as well. So if those are
being applied independently, they should be removed from this series.

Enabling:

In order to maintain compatibility and not break anything in user mode, kernel
doesn't enable control flow integrity cpu extensions on binary by default.
Instead exposes a prctl interface to enable, disable and lock the shadow stack
or landing pad feature for a task. This allows userspace (loader) to enumerate
if all objects in its address space are compiled with shadow stack and landing
pad support and accordingly enable the feature. Additionally if a subsequent
`dlopen` happens on a library, user mode can take a decision again to disable
the feature (if incoming library is not compiled with support) OR terminate the
task (if user mode policy is strict to have all objects in address space to be
compiled with control flow integirty cpu feature). prctl to enable shadow stack
results in allocating shadow stack from virtual memory and activating for user
address space. x86 and arm64 are also following same direction due to similar
reason(s).

clone/fork:

On clone and fork, cfi state for task is inherited by child. Shadow stack is
part of virtual memory and is a writeable memory from kernel perspective
(writeable via a restricted set of instructions aka shadow stack instructions)
Thus kernel changes ensure that this memory is converted into read-only when
fork/clone happens and COWed when fault is taken due to sspush, sspopchk or
ssamoswap. In case `CLONE_VM` is specified and shadow stack is to be enabled,
kernel will automatically allocate a shadow stack for that clone call.

map_shadow_stack:

x86 introduced `map_shadow_stack` system call to allow user space to explicitly
map shadow stack memory in its address space. It is useful to allocate shadow
for different contexts managed by a single thread (green threads or contexts)
risc-v implements this system call as well.

signal management:

If shadow stack is enabled for a task, kernel performs an asynchronous control
flow diversion to deliver the signal and eventually expects userspace to issue
sigreturn so that original execution can be resumed. Even though resume context
is prepared by kernel, it is in user space memory and is subject to memory
corruption and corruption bugs can be utilized by attacker in this race window
to perform arbitrary sigreturn and eventually bypass cfi mechanism.
Another issue is how to ensure that cfi related state on sigcontext area is not
trampled by legacy apps or apps compiled with old kernel headers.

In order to mitigate control-flow hijacting, kernel prepares a token and place
it on shadow stack before signal delivery and places address of token in
sigcontext structure. During sigreturn, kernel obtains address of token from
sigcontext struture, reads token from shadow stack and validates it and only
then allow sigreturn to succeed. Compatiblity issue is solved by adopting
dynamic sigcontext management introduced for vector extension. This series
re-factor the code little bit to allow future sigcontext management easy (as
proposed by Andy Chiu from SiFive)

config and compilation:

Introduce a new risc-v config option `CONFIG_RISCV_USER_CFI`. Selecting this
config option picks the kernel support for user control flow integrity. This
optin is presented only if toolchain has shadow stack and landing pad support.
And is on purpose guarded by toolchain support. Reason being that eventually
vDSO also needs to be compiled in with shadow stack and landing pad support.
vDSO compile patches are not included as of now because landing pad labeling
scheme is yet to settle for usermode runtime.

To get more information on kernel interactions with respect to
zicfilp and zicfiss, patch series adds documentation for
`zicfilp` and `zicfiss` in following:
Documentation/arch/riscv/zicfiss.rst
Documentation/arch/riscv/zicfilp.rst

How to test this series
=======================

Toolchain
---------
$ git clone git at github.com:sifive/riscv-gnu-toolchain.git -b cfi-dev
$ riscv-gnu-toolchain/configure --prefix=<path-to-where-to-build> --with-arch=rv64gc_zicfilp_zicfiss --enable-linux --disable-gdb  --with-extra-multilib-test="rv64gc_zicfilp_zicfiss-lp64d:-static"
$ make -j$(nproc)

Qemu
----
$ git clone git at github.com:deepak0414/qemu.git -b zicfilp_zicfiss_ratified_master_july11
$ cd qemu
$ mkdir build
$ cd build
$ ../configure --target-list=riscv64-softmmu
$ make -j$(nproc)

Opensbi
-------
$ git clone git at github.com:deepak0414/opensbi.git -b v6_cfi_spec_split_opensbi
$ make CROSS_COMPILE=<your riscv toolchain> -j$(nproc) PLATFORM=generic

Linux
-----
Running defconfig is fine. CFI is enabled by default if the toolchain
supports it.

$ make ARCH=riscv CROSS_COMPILE=<path-to-cfi-riscv-gnu-toolchain>/build/bin/riscv64-unknown-linux-gnu- -j$(nproc) defconfig
$ make ARCH=riscv CROSS_COMPILE=<path-to-cfi-riscv-gnu-toolchain>/build/bin/riscv64-unknown-linux-gnu- -j$(nproc)

Branch where user cfi enabling patches are maintained
https://github.com/deepak0414/linux-riscv-cfi/tree/vdso_user_cfi_v6.12-rc1

In case you're building your own rootfs using toolchain, please make sure you
pick following patch to ensure that vDSO compiled with lpad and shadow stack.

"arch/riscv: compile vdso with landing pad"

Running
-------

Modify your qemu command to have:
-bios <path-to-cfi-opensbi>/build/platform/generic/firmware/fw_dynamic.bin
-cpu rv64,zicfilp=true,zicfiss=true,zimop=true,zcmop=true

vDSO related Opens (in the flux)
=================================

I am listing these opens for laying out plan and what to expect in future
patch sets. And of course for the sake of discussion.

Shadow stack and landing pad enabling in vDSO
----------------------------------------------
vDSO must have shadow stack and landing pad support compiled in for task
to have shadow stack and landing pad support. This patch series doesn't
enable that (yet). Enabling shadow stack support in vDSO should be
straight forward (intend to do that in next versions of patch set). Enabling
landing pad support in vDSO requires some collaboration with toolchain folks
to follow a single label scheme for all object binaries. This is necessary to
ensure that all indirect call-sites are setting correct label and target landing
pads are decorated with same label scheme.

How many vDSOs
---------------
Shadow stack instructions are carved out of zimop (may be operations) and if CPU
doesn't implement zimop, they're illegal instructions. Kernel could be running on
a CPU which may or may not implement zimop. And thus kernel will have to carry 2
different vDSOs and expose the appropriate one depending on whether CPU implements
zimop or not.

References
==========
[1] - https://github.com/riscv/riscv-cfi
[2] - https://lore.kernel.org/all/20240814081126.956287-1-samuel.holland at sifive.com/
[3] - https://lwn.net/Articles/889475/
[4] - https://developer.arm.com/documentation/109576/0100/Branch-Target-Identification
[5] - https://www.intel.com/content/dam/develop/external/us/en/documents/catc17-introduction-intel-cet-844137.pdf
[6] - https://lwn.net/Articles/940403/
[7] - https://lore.kernel.org/all/20241001-arm64-gcs-v13-0-222b78d87eee at kernel.org/

---
changelog
---------

v8:
- rebased on palmer/for-next
- dropped samuel holland's `envcfg` context switch patches.
  they are in parlmer/for-next
  
v7:
- Removed "riscv/Kconfig: enable HAVE_EXIT_THREAD for riscv"
  Instead using `deactivate_mm` flow to clean up.
  see here for more context
  https://lore.kernel.org/all/20230908203655.543765-1-rick.p.edgecombe at intel.com/#t
- Changed the header include in `kselftest`. Hopefully this fixes compile
  issue faced by Zong Li at SiFive.
- Cleaned up an orphaned change to `mm/mmap.c` in below patch
  "riscv/mm : ensure PROT_WRITE leads to VM_READ | VM_WRITE"
- Lock interfaces for shadow stack and indirect branch tracking expect arg == 0
  Any future evolution of this interface should accordingly define how arg should
  be setup.
- `mm/map.c` has an instance of using `VM_SHADOW_STACK`. Fixed it to use helper
  `is_shadow_stack_vma`.
- Link to v6: https://lore.kernel.org/r/20241008-v5_user_cfi_series-v6-0-60d9fe073f37 at rivosinc.com

v6:
- Picked up Samuel Holland's changes as is with `envcfg` placed in
  `thread` instead of `thread_info`
- fixed unaligned newline escapes in kselftest
- cleaned up messages in kselftest and included test output in commit message
- fixed a bug in clone path reported by Zong Li
- fixed a build issue if CONFIG_RISCV_ISA_V is not selected
  (this was introduced due to re-factoring signal context
  management code)

v5:
- rebased on v6.12-rc1
- Fixed schema related issues in device tree file
- Fixed some of the documentation related issues in zicfilp/ss.rst
  (style issues and added index)
- added `SHADOW_STACK_SET_MARKER` so that implementation can define base
  of shadow stack.
- Fixed warnings on definitions added in usercfi.h when
  CONFIG_RISCV_USER_CFI is not selected.
- Adopted context header based signal handling as proposed by Andy Chiu
- Added support for enabling kernel mode access to shadow stack using
  FWFT
  (https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-firmware-features.adoc)
- Link to v5: https://lore.kernel.org/r/20241001-v5_user_cfi_series-v1-0-3ba65b6e550f at rivosinc.com
  (Note: I had an issue in my workflow due to which version number wasn't
  picked up correctly while sending out patches)

v4:
- rebased on 6.11-rc6
- envcfg: Converged with Samuel Holland's patches for envcfg management on per-
thread basis.
- vma_is_shadow_stack is renamed to is_vma_shadow_stack
- picked up Mark Brown's `ARCH_HAS_USER_SHADOW_STACK` patch
- signal context: using extended context management to maintain compatibility.
- fixed `-Wmissing-prototypes` compiler warnings for prctl functions
- Documentation fixes and amending typos.
- Link to v4: https://lore.kernel.org/all/20240912231650.3740732-1-debug at rivosinc.com/

v3:
- envcfg
  logic to pick up base envcfg had a bug where `ENVCFG_CBZE` could have been
  picked on per task basis, even though CPU didn't implement it. Fixed in
   this series.

- dt-bindings
  As suggested, split into separate commit. fixed the messaging that spec is
  in public review

- arch_is_shadow_stack change
  arch_is_shadow_stack changed to vma_is_shadow_stack

- hwprobe
  zicfiss / zicfilp if present will get enumerated in hwprobe

- selftests
  As suggested, added object and binary filenames to .gitignore
  Selftest binary anyways need to be compiled with cfi enabled compiler which
  will make sure that landing pad and shadow stack are enabled. Thus removed
  separate enable/disable tests. Cleaned up tests a bit.

- Link to v3: https://lore.kernel.org/lkml/20240403234054.2020347-1-debug at rivosinc.com/

v2:
- Using config `CONFIG_RISCV_USER_CFI`, kernel support for riscv control flow
  integrity for user mode programs can be compiled in the kernel.

- Enabling of control flow integrity for user programs is left to user runtime

- This patch series introduces arch agnostic `prctls` to enable shadow stack
  and indirect branch tracking. And implements them on riscv.

---
Changes in v8:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v7: https://lore.kernel.org/r/20241029-v5_user_cfi_series-v7-0-2727ce9936cb at rivosinc.com

---
Andy Chiu (1):
      riscv: signal: abstract header saving for setup_sigcontext

Cl?ment L?ger (1):
      riscv: Add Firmware Feature SBI extensions definitions

Deepak Gupta (25):
      mm: helper `is_shadow_stack_vma` to check shadow stack vma
      dt-bindings: riscv: zicfilp and zicfiss in dt-bindings (extensions.yaml)
      riscv: zicfiss / zicfilp enumeration
      riscv: zicfiss / zicfilp extension csr and bit definitions
      riscv: usercfi state for task and save/restore of CSR_SSP on trap entry/exit
      riscv/mm : ensure PROT_WRITE leads to VM_READ | VM_WRITE
      riscv mm: manufacture shadow stack pte
      riscv mmu: teach pte_mkwrite to manufacture shadow stack PTEs
      riscv mmu: write protect and shadow stack
      riscv/mm: Implement map_shadow_stack() syscall
      riscv/shstk: If needed allocate a new shadow stack on clone
      prctl: arch-agnostic prctl for indirect branch tracking
      riscv: Implements arch agnostic shadow stack prctls
      riscv: Implements arch agnostic indirect branch tracking prctls
      riscv/traps: Introduce software check exception
      riscv/signal: save and restore of shadow stack for signal
      riscv/kernel: update __show_regs to print shadow stack register
      riscv/ptrace: riscv cfi status and state via ptrace and in core files
      riscv/hwprobe: zicfilp / zicfiss enumeration in hwprobe
      riscv: enable kernel access to shadow stack memory via FWFT sbi call
      riscv: kernel command line option to opt out of user cfi
      riscv: create a config for shadow stack and landing pad instr support
      riscv: Documentation for landing pad / indirect branch tracking
      riscv: Documentation for shadow stack on riscv
      kselftest/riscv: kselftest for user mode cfi

Mark Brown (2):
      mm: Introduce ARCH_HAS_USER_SHADOW_STACK
      prctl: arch-agnostic prctl for shadow stack

 Documentation/arch/riscv/index.rst                 |   2 +
 Documentation/arch/riscv/zicfilp.rst               | 115 +++++
 Documentation/arch/riscv/zicfiss.rst               | 176 +++++++
 .../devicetree/bindings/riscv/extensions.yaml      |  14 +
 arch/riscv/Kconfig                                 |  20 +
 arch/riscv/include/asm/asm-prototypes.h            |   1 +
 arch/riscv/include/asm/cpufeature.h                |  13 +
 arch/riscv/include/asm/csr.h                       |  16 +
 arch/riscv/include/asm/entry-common.h              |   2 +
 arch/riscv/include/asm/hwcap.h                     |   2 +
 arch/riscv/include/asm/mman.h                      |  24 +
 arch/riscv/include/asm/mmu_context.h               |   7 +
 arch/riscv/include/asm/pgtable.h                   |  30 +-
 arch/riscv/include/asm/processor.h                 |   2 +
 arch/riscv/include/asm/sbi.h                       |  27 ++
 arch/riscv/include/asm/thread_info.h               |   3 +
 arch/riscv/include/asm/usercfi.h                   |  89 ++++
 arch/riscv/include/asm/vector.h                    |   3 +
 arch/riscv/include/uapi/asm/hwprobe.h              |   2 +
 arch/riscv/include/uapi/asm/ptrace.h               |  22 +
 arch/riscv/include/uapi/asm/sigcontext.h           |   1 +
 arch/riscv/kernel/Makefile                         |   2 +
 arch/riscv/kernel/asm-offsets.c                    |   8 +
 arch/riscv/kernel/cpufeature.c                     |   2 +
 arch/riscv/kernel/entry.S                          |  31 +-
 arch/riscv/kernel/head.S                           |  12 +
 arch/riscv/kernel/process.c                        |  26 +-
 arch/riscv/kernel/ptrace.c                         |  83 ++++
 arch/riscv/kernel/signal.c                         | 140 +++++-
 arch/riscv/kernel/sys_hwprobe.c                    |   2 +
 arch/riscv/kernel/sys_riscv.c                      |  10 +
 arch/riscv/kernel/traps.c                          |  42 ++
 arch/riscv/kernel/usercfi.c                        | 526 +++++++++++++++++++++
 arch/riscv/mm/init.c                               |   2 +-
 arch/riscv/mm/pgtable.c                            |  17 +
 arch/x86/Kconfig                                   |   1 +
 fs/proc/task_mmu.c                                 |   2 +-
 include/linux/cpu.h                                |   4 +
 include/linux/mm.h                                 |   5 +-
 include/uapi/asm-generic/mman.h                    |   4 +
 include/uapi/linux/elf.h                           |   1 +
 include/uapi/linux/prctl.h                         |  48 ++
 kernel/sys.c                                       |  60 +++
 mm/Kconfig                                         |   6 +
 mm/gup.c                                           |   2 +-
 mm/mmap.c                                          |   2 +-
 mm/vma.h                                           |  10 +-
 tools/testing/selftests/riscv/Makefile             |   2 +-
 tools/testing/selftests/riscv/cfi/.gitignore       |   3 +
 tools/testing/selftests/riscv/cfi/Makefile         |  10 +
 tools/testing/selftests/riscv/cfi/cfi_rv_test.h    |  84 ++++
 tools/testing/selftests/riscv/cfi/riscv_cfi_test.c |  78 +++
 tools/testing/selftests/riscv/cfi/shadowstack.c    | 373 +++++++++++++++
 tools/testing/selftests/riscv/cfi/shadowstack.h    |  37 ++
 54 files changed, 2171 insertions(+), 35 deletions(-)
---
base-commit: 64f7b77f0bd9271861ed9e410e9856b6b0b21c48
change-id: 20240930-v5_user_cfi_series-3dc332f8f5b2
--
- debug



From debug at rivosinc.com  Mon Nov 11 12:53:46 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:46 -0800
Subject: [PATCH v8 01/29] mm: Introduce ARCH_HAS_USER_SHADOW_STACK
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-1-dce14aa30207@rivosinc.com>

From: Mark Brown <broonie at kernel.org>

Since multiple architectures have support for shadow stacks and we need to
select support for this feature in several places in the generic code
provide a generic config option that the architectures can select.

Suggested-by: David Hildenbrand <david at redhat.com>
Acked-by: David Hildenbrand <david at redhat.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe at intel.com>
Reviewed-by: Deepak Gupta <debug at rivosinc.com>
Reviewed-by: Carlos Bilbao <carlos.bilbao.osdev at gmail.com>
---
 arch/x86/Kconfig   | 1 +
 fs/proc/task_mmu.c | 2 +-
 include/linux/mm.h | 2 +-
 mm/Kconfig         | 6 ++++++
 4 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 16354dfa6d96..fe6e9ece64b9 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1954,6 +1954,7 @@ config X86_USER_SHADOW_STACK
 	depends on AS_WRUSS
 	depends on X86_64
 	select ARCH_USES_HIGH_VMA_FLAGS
+	select ARCH_HAS_USER_SHADOW_STACK
 	select X86_CET
 	help
 	  Shadow stack protection is a hardware feature that detects function
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index e52bd96137a6..f57ea9b308bb 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -978,7 +978,7 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR
 		[ilog2(VM_UFFD_MINOR)]	= "ui",
 #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
-#ifdef CONFIG_X86_USER_SHADOW_STACK
+#ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK
 		[ilog2(VM_SHADOW_STACK)] = "ss",
 #endif
 #if defined(CONFIG_64BIT) || defined(CONFIG_PPC32)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 61fff5d34ed5..2291c02c74d2 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -354,7 +354,7 @@ extern unsigned int kobjsize(const void *objp);
 #endif
 #endif /* CONFIG_ARCH_HAS_PKEYS */
 
-#ifdef CONFIG_X86_USER_SHADOW_STACK
+#ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK
 /*
  * VM_SHADOW_STACK should not be set with VM_SHARED because of lack of
  * support core mm.
diff --git a/mm/Kconfig b/mm/Kconfig
index 4c9f5ea13271..4b2a1ef9a161 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1296,6 +1296,12 @@ config NUMA_EMU
 	  into virtual nodes when booted with "numa=fake=N", where N is the
 	  number of nodes. This is only useful for debugging.
 
+config ARCH_HAS_USER_SHADOW_STACK
+	bool
+	help
+	  The architecture has hardware support for userspace shadow call
+          stacks (eg, x86 CET, arm64 GCS or RISC-V Zicfiss).
+
 source "mm/damon/Kconfig"
 
 endmenu

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:47 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:47 -0800
Subject: [PATCH v8 02/29] mm: helper `is_shadow_stack_vma` to check shadow
 stack vma
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-2-dce14aa30207@rivosinc.com>

VM_SHADOW_STACK (alias to VM_HIGH_ARCH_5) is used to encode shadow stack
VMA on three architectures (x86 shadow stack, arm GCS and RISC-V shadow
stack). In case architecture doesn't implement shadow stack, it's VM_NONE
Introducing a helper `is_shadow_stack_vma` to determine shadow stack vma
or not.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 mm/gup.c  |  2 +-
 mm/mmap.c |  2 +-
 mm/vma.h  | 10 +++++++---
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index a82890b46a36..8e6e14179f6c 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1282,7 +1282,7 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags)
 		    !writable_file_mapping_allowed(vma, gup_flags))
 			return -EFAULT;
 
-		if (!(vm_flags & VM_WRITE) || (vm_flags & VM_SHADOW_STACK)) {
+		if (!(vm_flags & VM_WRITE) || is_shadow_stack_vma(vm_flags)) {
 			if (!(gup_flags & FOLL_FORCE))
 				return -EFAULT;
 			/* hugetlb does not support FOLL_FORCE|FOLL_WRITE. */
diff --git a/mm/mmap.c b/mm/mmap.c
index 9c0fb43064b5..f17573469c42 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -708,7 +708,7 @@ static unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info)
  */
 static inline unsigned long stack_guard_placement(vm_flags_t vm_flags)
 {
-	if (vm_flags & VM_SHADOW_STACK)
+	if (is_shadow_stack_vma(vm_flags))
 		return PAGE_SIZE;
 
 	return 0;
diff --git a/mm/vma.h b/mm/vma.h
index 819f994cf727..0f238dc37231 100644
--- a/mm/vma.h
+++ b/mm/vma.h
@@ -357,7 +357,7 @@ static inline struct vm_area_struct *vma_prev_limit(struct vma_iterator *vmi,
 }
 
 /*
- * These three helpers classifies VMAs for virtual memory accounting.
+ * These four helpers classifies VMAs for virtual memory accounting.
  */
 
 /*
@@ -368,6 +368,11 @@ static inline bool is_exec_mapping(vm_flags_t flags)
 	return (flags & (VM_EXEC | VM_WRITE | VM_STACK)) == VM_EXEC;
 }
 
+static inline bool is_shadow_stack_vma(vm_flags_t vm_flags)
+{
+	return !!(vm_flags & VM_SHADOW_STACK);
+}
+
 /*
  * Stack area (including shadow stacks)
  *
@@ -376,7 +381,7 @@ static inline bool is_exec_mapping(vm_flags_t flags)
  */
 static inline bool is_stack_mapping(vm_flags_t flags)
 {
-	return ((flags & VM_STACK) == VM_STACK) || (flags & VM_SHADOW_STACK);
+	return ((flags & VM_STACK) == VM_STACK) || is_shadow_stack_vma(flags);
 }
 
 /*
@@ -387,7 +392,6 @@ static inline bool is_data_mapping(vm_flags_t flags)
 	return (flags & (VM_WRITE | VM_SHARED | VM_STACK)) == VM_WRITE;
 }
 
-
 static inline void vma_iter_config(struct vma_iterator *vmi,
 		unsigned long index, unsigned long last)
 {

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:48 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:48 -0800
Subject: [PATCH v8 03/29] dt-bindings: riscv: zicfilp and zicfiss in
 dt-bindings (extensions.yaml)
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-3-dce14aa30207@rivosinc.com>

Make an entry for cfi extensions in extensions.yaml.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
Acked-by: Rob Herring (Arm) <robh at kernel.org>
---
 Documentation/devicetree/bindings/riscv/extensions.yaml | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
index af7e5237b2c0..5fb40665fbaf 100644
--- a/Documentation/devicetree/bindings/riscv/extensions.yaml
+++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
@@ -398,6 +398,20 @@ properties:
             The standard Zicboz extension for cache-block zeroing as ratified
             in commit 3dd606f ("Create cmobase-v1.0.pdf") of riscv-CMOs.
 
+        - const: zicfilp
+          description: |
+            The standard Zicfilp extension for enforcing forward edge
+            control-flow integrity as ratified in commit 3f8e450 ("merge
+            pull request #227 from ved-rivos/0709") of riscv-cfi
+            github repo.
+
+        - const: zicfiss
+          description: |
+            The standard Zicfiss extension for enforcing backward edge
+            control-flow integrity as ratified in commit 3f8e450 ("merge
+            pull request #227 from ved-rivos/0709") of riscv-cfi
+            github repo.
+
         - const: zicntr
           description:
             The standard Zicntr extension for base counters and timers, as

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:49 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:49 -0800
Subject: [PATCH v8 04/29] riscv: zicfiss / zicfilp enumeration
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-4-dce14aa30207@rivosinc.com>

This patch adds support for detecting zicfiss and zicfilp. zicfiss and
zicfilp stands for unprivleged integer spec extension for shadow stack
and branch tracking on indirect branches, respectively.

This patch looks for zicfiss and zicfilp in device tree and accordinlgy
lights up bit in cpu feature bitmap. Furthermore this patch adds detection
utility functions to return whether shadow stack or landing pads are
supported by cpu.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/include/asm/cpufeature.h | 13 +++++++++++++
 arch/riscv/include/asm/hwcap.h      |  2 ++
 arch/riscv/include/asm/processor.h  |  1 +
 arch/riscv/kernel/cpufeature.c      |  2 ++
 4 files changed, 18 insertions(+)

diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h
index 4bd054c54c21..8d12dc6c7d44 100644
--- a/arch/riscv/include/asm/cpufeature.h
+++ b/arch/riscv/include/asm/cpufeature.h
@@ -12,6 +12,7 @@
 #include <linux/kconfig.h>
 #include <linux/percpu-defs.h>
 #include <linux/threads.h>
+#include <linux/smp.h>
 #include <asm/hwcap.h>
 #include <asm/cpufeature-macros.h>
 
@@ -135,4 +136,16 @@ static __always_inline bool riscv_cpu_has_extension_unlikely(int cpu, const unsi
 	return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);
 }
 
+static inline bool cpu_supports_shadow_stack(void)
+{
+	return (IS_ENABLED(CONFIG_RISCV_USER_CFI) &&
+		    riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICFISS));
+}
+
+static inline bool cpu_supports_indirect_br_lp_instr(void)
+{
+	return (IS_ENABLED(CONFIG_RISCV_USER_CFI) &&
+		    riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICFILP));
+}
+
 #endif
diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index 08d2a5697466..f81f62b32f72 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -98,6 +98,8 @@
 #define RISCV_ISA_EXT_SSNPM		89
 #define RISCV_ISA_EXT_ZABHA		90
 #define RISCV_ISA_EXT_ZICCRSE		91
+#define RISCV_ISA_EXT_ZICFILP		92
+#define RISCV_ISA_EXT_ZICFISS		93
 
 #define RISCV_ISA_EXT_XLINUXENVCFG	127
 
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 5f56eb9d114a..e3aba3336e63 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -13,6 +13,7 @@
 #include <vdso/processor.h>
 
 #include <asm/ptrace.h>
+#include <asm/hwcap.h>
 
 #define arch_get_mmap_end(addr, len, flags)			\
 ({								\
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index eb904ca64ad0..0f2c466a51ee 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -318,6 +318,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 	__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts,
 					  riscv_ext_zicboz_validate),
 	__RISCV_ISA_EXT_DATA(ziccrse, RISCV_ISA_EXT_ZICCRSE),
+	__RISCV_ISA_EXT_SUPERSET(zicfilp, RISCV_ISA_EXT_ZICFILP, riscv_xlinuxenvcfg_exts),
+	__RISCV_ISA_EXT_SUPERSET(zicfiss, RISCV_ISA_EXT_ZICFISS, riscv_xlinuxenvcfg_exts),
 	__RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
 	__RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND),
 	__RISCV_ISA_EXT_DATA(zicsr, RISCV_ISA_EXT_ZICSR),

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:50 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:50 -0800
Subject: [PATCH v8 05/29] riscv: zicfiss / zicfilp extension csr and bit
 definitions
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-5-dce14aa30207@rivosinc.com>

zicfiss and zicfilp extension gets enabled via b3 and b2 in *envcfg CSR.
menvcfg controls enabling for S/HS mode. henvcfg control enabling for VS
while senvcfg controls enabling for U/VU mode.

zicfilp extension extends *status CSR to hold `expected landing pad` bit.
A trap or interrupt can occur between an indirect jmp/call and target
instr. `expected landing pad` bit from CPU is recorded into xstatus CSR so
that when supervisor performs xret, `expected landing pad` state of CPU can
be restored.

zicfiss adds one new CSR
- CSR_SSP: CSR_SSP contains current shadow stack pointer.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
Reviewed-by: Charlie Jenkins <charlie at rivosinc.com>
---
 arch/riscv/include/asm/csr.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index fe5d4eb9adea..e07b55028cc0 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -18,6 +18,15 @@
 #define SR_MPP		_AC(0x00001800, UL) /* Previously Machine */
 #define SR_SUM		_AC(0x00040000, UL) /* Supervisor User Memory Access */
 
+/* zicfilp landing pad status bit */
+#define SR_SPELP	_AC(0x00800000, UL)
+#define SR_MPELP	_AC(0x020000000000, UL)
+#ifdef CONFIG_RISCV_M_MODE
+#define SR_ELP		SR_MPELP
+#else
+#define SR_ELP		SR_SPELP
+#endif
+
 #define SR_FS		_AC(0x00006000, UL) /* Floating-point Status */
 #define SR_FS_OFF	_AC(0x00000000, UL)
 #define SR_FS_INITIAL	_AC(0x00002000, UL)
@@ -205,6 +214,8 @@
 #define ENVCFG_PMM_PMLEN_16		(_AC(0x3, ULL) << 32)
 #define ENVCFG_CBZE			(_AC(1, UL) << 7)
 #define ENVCFG_CBCFE			(_AC(1, UL) << 6)
+#define ENVCFG_LPE			(_AC(1, UL) << 2)
+#define ENVCFG_SSE			(_AC(1, UL) << 3)
 #define ENVCFG_CBIE_SHIFT		4
 #define ENVCFG_CBIE			(_AC(0x3, UL) << ENVCFG_CBIE_SHIFT)
 #define ENVCFG_CBIE_ILL			_AC(0x0, UL)
@@ -223,6 +234,11 @@
 #define SMSTATEEN0_HSENVCFG		(_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT)
 #define SMSTATEEN0_SSTATEEN0_SHIFT	63
 #define SMSTATEEN0_SSTATEEN0		(_ULL(1) << SMSTATEEN0_SSTATEEN0_SHIFT)
+/*
+ * zicfiss user mode csr
+ * CSR_SSP holds current shadow stack pointer.
+ */
+#define CSR_SSP                 0x011
 
 /* mseccfg bits */
 #define MSECCFG_PMM			ENVCFG_PMM

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:51 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:51 -0800
Subject: [PATCH v8 06/29] riscv: usercfi state for task and save/restore of
 CSR_SSP on trap entry/exit
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-6-dce14aa30207@rivosinc.com>

Carves out space in arch specific thread struct for cfi status and shadow
stack in usermode on riscv.

This patch does following
- defines a new structure cfi_status with status bit for cfi feature
- defines shadow stack pointer, base and size in cfi_status structure
- defines offsets to new member fields in thread in asm-offsets.c
- Saves and restore shadow stack pointer on trap entry (U --> S) and exit
  (S --> U)

Shadow stack save/restore is gated on feature availiblity and implemented
using alternative. CSR can be context switched in `switch_to` as well but
soon as kernel shadow stack support gets rolled in, shadow stack pointer
will need to be switched at trap entry/exit point (much like `sp`). It can
be argued that kernel using shadow stack deployment scenario may not be as
prevalant as user mode using this feature. But even if there is some
minimal deployment of kernel shadow stack, that means that it needs to be
supported. And thus save/restore of shadow stack pointer in entry.S instead
of in `switch_to.h`.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
Reviewed-by: Charlie Jenkins <charlie at rivosinc.com>
---
 arch/riscv/include/asm/processor.h   |  1 +
 arch/riscv/include/asm/thread_info.h |  3 +++
 arch/riscv/include/asm/usercfi.h     | 24 ++++++++++++++++++++++++
 arch/riscv/kernel/asm-offsets.c      |  4 ++++
 arch/riscv/kernel/entry.S            | 26 ++++++++++++++++++++++++++
 5 files changed, 58 insertions(+)

diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index e3aba3336e63..d851bb5c6da0 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -14,6 +14,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/hwcap.h>
+#include <asm/usercfi.h>
 
 #define arch_get_mmap_end(addr, len, flags)			\
 ({								\
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 9c10fb180f43..bb20bb7d17c3 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -62,6 +62,9 @@ struct thread_info {
 	long			user_sp;	/* User stack pointer */
 	int			cpu;
 	unsigned long		syscall_work;	/* SYSCALL_WORK_ flags */
+#ifdef CONFIG_RISCV_USER_CFI
+	struct cfi_status	user_cfi_state;
+#endif
 #ifdef CONFIG_SHADOW_CALL_STACK
 	void			*scs_base;
 	void			*scs_sp;
diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
new file mode 100644
index 000000000000..4fa201b4fc4e
--- /dev/null
+++ b/arch/riscv/include/asm/usercfi.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (C) 2024 Rivos, Inc.
+ * Deepak Gupta <debug at rivosinc.com>
+ */
+#ifndef _ASM_RISCV_USERCFI_H
+#define _ASM_RISCV_USERCFI_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+#ifdef CONFIG_RISCV_USER_CFI
+struct cfi_status {
+	unsigned long ubcfi_en : 1; /* Enable for backward cfi. */
+	unsigned long rsvd : ((sizeof(unsigned long)*8) - 1);
+	unsigned long user_shdw_stk; /* Current user shadow stack pointer */
+	unsigned long shdw_stk_base; /* Base address of shadow stack */
+	unsigned long shdw_stk_size; /* size of shadow stack */
+};
+
+#endif /* CONFIG_RISCV_USER_CFI */
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_USERCFI_H */
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index e94180ba432f..766bd33f10cb 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -52,6 +52,10 @@ void asm_offsets(void)
 #endif
 
 	OFFSET(TASK_TI_CPU_NUM, task_struct, thread_info.cpu);
+#ifdef CONFIG_RISCV_USER_CFI
+	OFFSET(TASK_TI_CFI_STATUS, task_struct, thread_info.user_cfi_state);
+	OFFSET(TASK_TI_USER_SSP, task_struct, thread_info.user_cfi_state.user_shdw_stk);
+#endif
 	OFFSET(TASK_THREAD_F0,  task_struct, thread.fstate.f[0]);
 	OFFSET(TASK_THREAD_F1,  task_struct, thread.fstate.f[1]);
 	OFFSET(TASK_THREAD_F2,  task_struct, thread.fstate.f[2]);
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index c200d329d4bd..8f7f477517e3 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -147,6 +147,20 @@ SYM_CODE_START(handle_exception)
 
 	REG_L s0, TASK_TI_USER_SP(tp)
 	csrrc s1, CSR_STATUS, t0
+	/*
+	 * If previous mode was U, capture shadow stack pointer and save it away
+	 * Zero CSR_SSP at the same time for sanitization.
+	 */
+	ALTERNATIVE("nop; nop; nop; nop",
+				__stringify(			\
+				andi s2, s1, SR_SPP;	\
+				bnez s2, skip_ssp_save;	\
+				csrrw s2, CSR_SSP, x0;	\
+				REG_S s2, TASK_TI_USER_SSP(tp); \
+				skip_ssp_save:),
+				0,
+				RISCV_ISA_EXT_ZICFISS,
+				CONFIG_RISCV_USER_CFI)
 	csrr s2, CSR_EPC
 	csrr s3, CSR_TVAL
 	csrr s4, CSR_CAUSE
@@ -236,6 +250,18 @@ SYM_CODE_START_NOALIGN(ret_from_exception)
 	 * structures again.
 	 */
 	csrw CSR_SCRATCH, tp
+
+	/*
+	 * Going back to U mode, restore shadow stack pointer
+	 */
+	ALTERNATIVE("nop; nop",
+				__stringify(					\
+				REG_L s3, TASK_TI_USER_SSP(tp); \
+				csrw CSR_SSP, s3),
+				0,
+				RISCV_ISA_EXT_ZICFISS,
+				CONFIG_RISCV_USER_CFI)
+
 1:
 #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
 	move a0, sp

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:52 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:52 -0800
Subject: [PATCH v8 07/29] riscv/mm : ensure PROT_WRITE leads to VM_READ |
 VM_WRITE
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-7-dce14aa30207@rivosinc.com>

`arch_calc_vm_prot_bits` is implemented on risc-v to return VM_READ |
VM_WRITE if PROT_WRITE is specified. Similarly `riscv_sys_mmap` is
updated to convert all incoming PROT_WRITE to (PROT_WRITE | PROT_READ).
This is to make sure that any existing apps using PROT_WRITE still work.

Earlier `protection_map[VM_WRITE]` used to pick read-write PTE encodings.
Now `protection_map[VM_WRITE]` will always pick PAGE_SHADOWSTACK PTE
encodings for shadow stack. Above changes ensure that existing apps
continue to work because underneath kernel will be picking
`protection_map[VM_WRITE|VM_READ]` PTE encodings.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/include/asm/mman.h    | 24 ++++++++++++++++++++++++
 arch/riscv/include/asm/pgtable.h |  1 +
 arch/riscv/kernel/sys_riscv.c    | 10 ++++++++++
 arch/riscv/mm/init.c             |  2 +-
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/mman.h b/arch/riscv/include/asm/mman.h
new file mode 100644
index 000000000000..ef9fedf32546
--- /dev/null
+++ b/arch/riscv/include/asm/mman.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <uapi/asm/mman.h>
+
+static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
+	unsigned long pkey __always_unused)
+{
+	unsigned long ret = 0;
+
+	/*
+	 * If PROT_WRITE was specified, force it to VM_READ | VM_WRITE.
+	 * Only VM_WRITE means shadow stack.
+	 */
+	if (prot & PROT_WRITE)
+		ret = (VM_READ | VM_WRITE);
+	return ret;
+}
+#define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey)
+
+#endif /* ! __ASM_MMAN_H__ */
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index e79f15293492..4948a1f18ae8 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -177,6 +177,7 @@ extern struct pt_alloc_ops pt_ops __meminitdata;
 #define PAGE_READ_EXEC		__pgprot(_PAGE_BASE | _PAGE_READ | _PAGE_EXEC)
 #define PAGE_WRITE_EXEC		__pgprot(_PAGE_BASE | _PAGE_READ |	\
 					 _PAGE_EXEC | _PAGE_WRITE)
+#define PAGE_SHADOWSTACK       __pgprot(_PAGE_BASE | _PAGE_WRITE)
 
 #define PAGE_COPY		PAGE_READ
 #define PAGE_COPY_EXEC		PAGE_READ_EXEC
diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
index d77afe05578f..43a448bf254b 100644
--- a/arch/riscv/kernel/sys_riscv.c
+++ b/arch/riscv/kernel/sys_riscv.c
@@ -7,6 +7,7 @@
 
 #include <linux/syscalls.h>
 #include <asm/cacheflush.h>
+#include <asm-generic/mman-common.h>
 
 static long riscv_sys_mmap(unsigned long addr, unsigned long len,
 			   unsigned long prot, unsigned long flags,
@@ -16,6 +17,15 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len,
 	if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))
 		return -EINVAL;
 
+	/*
+	 * If PROT_WRITE is specified then extend that to PROT_READ
+	 * protection_map[VM_WRITE] is now going to select shadow stack encodings.
+	 * So specifying PROT_WRITE actually should select protection_map [VM_WRITE | VM_READ]
+	 * If user wants to create shadow stack then they should use `map_shadow_stack` syscall.
+	 */
+	if (unlikely((prot & PROT_WRITE) && !(prot & PROT_READ)))
+		prot |= PROT_READ;
+
 	return ksys_mmap_pgoff(addr, len, prot, flags, fd,
 			       offset >> (PAGE_SHIFT - page_shift_offset));
 }
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 0e8c20adcd98..964810aeb405 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -326,7 +326,7 @@ pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
 static const pgprot_t protection_map[16] = {
 	[VM_NONE]					= PAGE_NONE,
 	[VM_READ]					= PAGE_READ,
-	[VM_WRITE]					= PAGE_COPY,
+	[VM_WRITE]					= PAGE_SHADOWSTACK,
 	[VM_WRITE | VM_READ]				= PAGE_COPY,
 	[VM_EXEC]					= PAGE_EXEC,
 	[VM_EXEC | VM_READ]				= PAGE_READ_EXEC,

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:53 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:53 -0800
Subject: [PATCH v8 08/29] riscv mm: manufacture shadow stack pte
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-8-dce14aa30207@rivosinc.com>

This patch implements creating shadow stack pte (on riscv). Creating
shadow stack PTE on riscv means that clearing RWX and then setting W=1.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
---
 arch/riscv/include/asm/pgtable.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 4948a1f18ae8..2c6edc8d04a3 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -421,6 +421,11 @@ static inline pte_t pte_mkwrite_novma(pte_t pte)
 	return __pte(pte_val(pte) | _PAGE_WRITE);
 }
 
+static inline pte_t pte_mkwrite_shstk(pte_t pte)
+{
+	return __pte((pte_val(pte) & ~(_PAGE_LEAF)) | _PAGE_WRITE);
+}
+
 /* static inline pte_t pte_mkexec(pte_t pte) */
 
 static inline pte_t pte_mkdirty(pte_t pte)
@@ -738,6 +743,11 @@ static inline pmd_t pmd_mkwrite_novma(pmd_t pmd)
 	return pte_pmd(pte_mkwrite_novma(pmd_pte(pmd)));
 }
 
+static inline pmd_t pmd_mkwrite_shstk(pmd_t pte)
+{
+	return __pmd((pmd_val(pte) & ~(_PAGE_LEAF)) | _PAGE_WRITE);
+}
+
 static inline pmd_t pmd_wrprotect(pmd_t pmd)
 {
 	return pte_pmd(pte_wrprotect(pmd_pte(pmd)));

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:54 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:54 -0800
Subject: [PATCH v8 09/29] riscv mmu: teach pte_mkwrite to manufacture
 shadow stack PTEs
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-9-dce14aa30207@rivosinc.com>

pte_mkwrite creates PTEs with WRITE encodings for underlying arch.
Underlying arch can have two types of writeable mappings. One that can be
written using regular store instructions. Another one that can only be
written using specialized store instructions (like shadow stack stores).
pte_mkwrite can select write PTE encoding based on VMA range (i.e.
VM_SHADOW_STACK)

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
---
 arch/riscv/include/asm/pgtable.h |  7 +++++++
 arch/riscv/mm/pgtable.c          | 17 +++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 2c6edc8d04a3..7963ab11d924 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -416,6 +416,10 @@ static inline pte_t pte_wrprotect(pte_t pte)
 
 /* static inline pte_t pte_mkread(pte_t pte) */
 
+struct vm_area_struct;
+pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma);
+#define pte_mkwrite pte_mkwrite
+
 static inline pte_t pte_mkwrite_novma(pte_t pte)
 {
 	return __pte(pte_val(pte) | _PAGE_WRITE);
@@ -738,6 +742,9 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd)
 	return pte_pmd(pte_mkyoung(pmd_pte(pmd)));
 }
 
+pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma);
+#define pmd_mkwrite pmd_mkwrite
+
 static inline pmd_t pmd_mkwrite_novma(pmd_t pmd)
 {
 	return pte_pmd(pte_mkwrite_novma(pmd_pte(pmd)));
diff --git a/arch/riscv/mm/pgtable.c b/arch/riscv/mm/pgtable.c
index 4ae67324f992..be5d38546bb3 100644
--- a/arch/riscv/mm/pgtable.c
+++ b/arch/riscv/mm/pgtable.c
@@ -155,3 +155,20 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
 	return pmd;
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma)
+{
+	if (vma->vm_flags & VM_SHADOW_STACK)
+		return pte_mkwrite_shstk(pte);
+
+	return pte_mkwrite_novma(pte);
+}
+
+pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma)
+{
+	if (vma->vm_flags & VM_SHADOW_STACK)
+		return pmd_mkwrite_shstk(pmd);
+
+	return pmd_mkwrite_novma(pmd);
+}
+

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:55 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:55 -0800
Subject: [PATCH v8 10/29] riscv mmu: write protect and shadow stack
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-10-dce14aa30207@rivosinc.com>

`fork` implements copy on write (COW) by making pages readonly in child
and parent both.

ptep_set_wrprotect and pte_wrprotect clears _PAGE_WRITE in PTE.
Assumption is that page is readable and on fault copy on write happens.

To implement COW on shadow stack pages, clearing up W bit makes them XWR =
000. This will result in wrong PTE setting which says no perms but V=1 and
PFN field pointing to final page. Instead desired behavior is to turn it
into a readable page, take an access (load/store) fault on sspush/sspop
(shadow stack) and then perform COW on such pages. This way regular reads
would still be allowed and not lead to COW maintaining current behavior
of COW on non-shadow stack but writeable memory.

On the other hand it doesn't interfere with existing COW for read-write
memory. Assumption is always that _PAGE_READ must have been set and thus
setting _PAGE_READ is harmless.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
Alexandre Ghiti <alexghiti at rivosinc.com>
---
 arch/riscv/include/asm/pgtable.h | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 7963ab11d924..fdab7d74437d 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -411,7 +411,7 @@ static inline int pte_devmap(pte_t pte)
 
 static inline pte_t pte_wrprotect(pte_t pte)
 {
-	return __pte(pte_val(pte) & ~(_PAGE_WRITE));
+	return __pte((pte_val(pte) & ~(_PAGE_WRITE)) | (_PAGE_READ));
 }
 
 /* static inline pte_t pte_mkread(pte_t pte) */
@@ -612,7 +612,15 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 static inline void ptep_set_wrprotect(struct mm_struct *mm,
 				      unsigned long address, pte_t *ptep)
 {
-	atomic_long_and(~(unsigned long)_PAGE_WRITE, (atomic_long_t *)ptep);
+	pte_t read_pte = READ_ONCE(*ptep);
+	/*
+	 * ptep_set_wrprotect can be called for shadow stack ranges too.
+	 * shadow stack memory is XWR = 010 and thus clearing _PAGE_WRITE will lead to
+	 * encoding 000b which is wrong encoding with V = 1. This should lead to page fault
+	 * but we dont want this wrong configuration to be set in page tables.
+	 */
+	atomic_long_set((atomic_long_t *)ptep,
+			((pte_val(read_pte) & ~(unsigned long)_PAGE_WRITE) | _PAGE_READ));
 }
 
 #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:56 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:56 -0800
Subject: [PATCH v8 11/29] riscv/mm: Implement map_shadow_stack() syscall
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-11-dce14aa30207@rivosinc.com>

As discussed extensively in the changelog for the addition of this
syscall on x86 ("x86/shstk: Introduce map_shadow_stack syscall") the
existing mmap() and madvise() syscalls do not map entirely well onto the
security requirements for shadow stack memory since they lead to windows
where memory is allocated but not yet protected or stacks which are not
properly and safely initialised. Instead a new syscall map_shadow_stack()
has been defined which allocates and initialises a shadow stack page.

This patch implements this syscall for riscv. riscv doesn't require token
to be setup by kernel because user mode can do that by itself. However to
provide compatibility and portability with other architectues, user mode
can specify token set flag.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/kernel/Makefile      |   2 +
 arch/riscv/kernel/usercfi.c     | 145 ++++++++++++++++++++++++++++++++++++++++
 include/uapi/asm-generic/mman.h |   4 ++
 3 files changed, 151 insertions(+)

diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 30db92672ada..3f5a8eafe578 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -118,3 +118,5 @@ obj-$(CONFIG_COMPAT)		+= compat_vdso/
 obj-$(CONFIG_64BIT)		+= pi/
 obj-$(CONFIG_ACPI)		+= acpi.o
 obj-$(CONFIG_ACPI_NUMA)	+= acpi_numa.o
+
+obj-$(CONFIG_RISCV_USER_CFI) += usercfi.o
diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
new file mode 100644
index 000000000000..96bb324abafb
--- /dev/null
+++ b/arch/riscv/kernel/usercfi.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 Rivos, Inc.
+ * Deepak Gupta <debug at rivosinc.com>
+ */
+
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/uaccess.h>
+#include <linux/sizes.h>
+#include <linux/user.h>
+#include <linux/syscalls.h>
+#include <linux/prctl.h>
+#include <asm/csr.h>
+#include <asm/usercfi.h>
+
+#define SHSTK_ENTRY_SIZE sizeof(void *)
+
+/*
+ * Writes on shadow stack can either be `sspush` or `ssamoswap`. `sspush` can happen
+ * implicitly on current shadow stack pointed to by CSR_SSP. `ssamoswap` takes pointer to
+ * shadow stack. To keep it simple, we plan to use `ssamoswap` to perform writes on shadow
+ * stack.
+ */
+static noinline unsigned long amo_user_shstk(unsigned long *addr, unsigned long val)
+{
+	/*
+	 * Never expect -1 on shadow stack. Expect return addresses and zero
+	 */
+	unsigned long swap = -1;
+
+	__enable_user_access();
+	asm goto(
+		".option push\n"
+		".option arch, +zicfiss\n"
+		"1: ssamoswap.d %[swap], %[val], %[addr]\n"
+		_ASM_EXTABLE(1b, %l[fault])
+		RISCV_ACQUIRE_BARRIER
+		".option pop\n"
+		: [swap] "=r" (swap), [addr] "+A" (*addr)
+		: [val] "r" (val)
+		: "memory"
+		: fault
+		);
+	__disable_user_access();
+	return swap;
+fault:
+	__disable_user_access();
+	return -1;
+}
+
+/*
+ * Create a restore token on the shadow stack.  A token is always XLEN wide
+ * and aligned to XLEN.
+ */
+static int create_rstor_token(unsigned long ssp, unsigned long *token_addr)
+{
+	unsigned long addr;
+
+	/* Token must be aligned */
+	if (!IS_ALIGNED(ssp, SHSTK_ENTRY_SIZE))
+		return -EINVAL;
+
+	/* On RISC-V we're constructing token to be function of address itself */
+	addr = ssp - SHSTK_ENTRY_SIZE;
+
+	if (amo_user_shstk((unsigned long __user *)addr, (unsigned long) ssp) == -1)
+		return -EFAULT;
+
+	if (token_addr)
+		*token_addr = addr;
+
+	return 0;
+}
+
+static unsigned long allocate_shadow_stack(unsigned long addr, unsigned long size,
+				unsigned long token_offset,
+				bool set_tok)
+{
+	int flags = MAP_ANONYMOUS | MAP_PRIVATE;
+	struct mm_struct *mm = current->mm;
+	unsigned long populate, tok_loc = 0;
+
+	if (addr)
+		flags |= MAP_FIXED_NOREPLACE;
+
+	mmap_write_lock(mm);
+	addr = do_mmap(NULL, addr, size, PROT_READ, flags,
+				VM_SHADOW_STACK | VM_WRITE, 0, &populate, NULL);
+	mmap_write_unlock(mm);
+
+	if (!set_tok || IS_ERR_VALUE(addr))
+		goto out;
+
+	if (create_rstor_token(addr + token_offset, &tok_loc)) {
+		vm_munmap(addr, size);
+		return -EINVAL;
+	}
+
+	addr = tok_loc;
+
+out:
+	return addr;
+}
+
+SYSCALL_DEFINE3(map_shadow_stack, unsigned long, addr, unsigned long, size, unsigned int, flags)
+{
+	bool set_tok = flags & SHADOW_STACK_SET_TOKEN;
+	unsigned long aligned_size = 0;
+
+	if (!cpu_supports_shadow_stack())
+		return -EOPNOTSUPP;
+
+	/* Anything other than set token should result in invalid param */
+	if (flags & ~SHADOW_STACK_SET_TOKEN)
+		return -EINVAL;
+
+	/*
+	 * Unlike other architectures, on RISC-V, SSP pointer is held in CSR_SSP and is available
+	 * CSR in all modes. CSR accesses are performed using 12bit index programmed in instruction
+	 * itself. This provides static property on register programming and writes to CSR can't
+	 * be unintentional from programmer's perspective. As long as programmer has guarded areas
+	 * which perform writes to CSR_SSP properly, shadow stack pivoting is not possible. Since
+	 * CSR_SSP is writeable by user mode, it itself can setup a shadow stack token subsequent
+	 * to allocation. Although in order to provide portablity with other architecture (because
+	 * `map_shadow_stack` is arch agnostic syscall), RISC-V will follow expectation of a token
+	 * flag in flags and if provided in flags, setup a token at the base.
+	 */
+
+	/* If there isn't space for a token */
+	if (set_tok && size < SHSTK_ENTRY_SIZE)
+		return -ENOSPC;
+
+	if (addr && (addr & (PAGE_SIZE - 1)))
+		return -EINVAL;
+
+	aligned_size = PAGE_ALIGN(size);
+	if (aligned_size < size)
+		return -EOVERFLOW;
+
+	return allocate_shadow_stack(addr, aligned_size, size, set_tok);
+}
diff --git a/include/uapi/asm-generic/mman.h b/include/uapi/asm-generic/mman.h
index 57e8195d0b53..9cfb3c1e337d 100644
--- a/include/uapi/asm-generic/mman.h
+++ b/include/uapi/asm-generic/mman.h
@@ -19,4 +19,8 @@
 #define MCL_FUTURE	2		/* lock all future mappings */
 #define MCL_ONFAULT	4		/* lock all pages that are faulted in */
 
+/* Set up a restore token in the shadow stack */
+#define SHADOW_STACK_SET_TOKEN (1ULL << 0)
+/* Set up a top of stack marker in the shadow stack */
+#define SHADOW_STACK_SET_MARKER (1ULL << 1)
 #endif /* __ASM_GENERIC_MMAN_H */

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:57 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:57 -0800
Subject: [PATCH v8 12/29] riscv/shstk: If needed allocate a new shadow
 stack on clone
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-12-dce14aa30207@rivosinc.com>

Userspace specifies CLONE_VM to share address space and spawn new thread.
`clone` allow userspace to specify a new stack for new thread. However
there is no way to specify new shadow stack base address without changing
API. This patch allocates a new shadow stack whenever CLONE_VM is given.

In case of CLONE_VFORK, parent is suspended until child finishes and thus
can child use parent shadow stack. In case of !CLONE_VM, COW kicks in
because entire address space is copied from parent to child.

`clone3` is extensible and can provide mechanisms using which shadow stack
as an input parameter can be provided. This is not settled yet and being
extensively discussed on mailing list. Once that's settled, this commit
will adapt to that.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/include/asm/mmu_context.h |   7 ++
 arch/riscv/include/asm/usercfi.h     |  25 ++++++++
 arch/riscv/kernel/process.c          |   9 +++
 arch/riscv/kernel/usercfi.c          | 121 +++++++++++++++++++++++++++++++++++
 4 files changed, 162 insertions(+)

diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h
index 8c4bc49a3a0f..44d3843e8c14 100644
--- a/arch/riscv/include/asm/mmu_context.h
+++ b/arch/riscv/include/asm/mmu_context.h
@@ -48,6 +48,13 @@ static inline unsigned long mm_untag_mask(struct mm_struct *mm)
 }
 #endif
 
+#define deactivate_mm deactivate_mm
+static inline void deactivate_mm(struct task_struct *tsk,
+			struct mm_struct *mm)
+{
+	shstk_release(tsk);
+}
+
 #include <asm-generic/mmu_context.h>
 
 #endif /* _ASM_RISCV_MMU_CONTEXT_H */
diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
index 4fa201b4fc4e..4da9cbc8f9b5 100644
--- a/arch/riscv/include/asm/usercfi.h
+++ b/arch/riscv/include/asm/usercfi.h
@@ -8,6 +8,9 @@
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 
+struct task_struct;
+struct kernel_clone_args;
+
 #ifdef CONFIG_RISCV_USER_CFI
 struct cfi_status {
 	unsigned long ubcfi_en : 1; /* Enable for backward cfi. */
@@ -17,6 +20,28 @@ struct cfi_status {
 	unsigned long shdw_stk_size; /* size of shadow stack */
 };
 
+unsigned long shstk_alloc_thread_stack(struct task_struct *tsk,
+							const struct kernel_clone_args *args);
+void shstk_release(struct task_struct *tsk);
+void set_shstk_base(struct task_struct *task, unsigned long shstk_addr, unsigned long size);
+unsigned long get_shstk_base(struct task_struct *task, unsigned long *size);
+void set_active_shstk(struct task_struct *task, unsigned long shstk_addr);
+bool is_shstk_enabled(struct task_struct *task);
+
+#else
+
+#define shstk_alloc_thread_stack(tsk, args) 0
+
+#define shstk_release(tsk)
+
+#define get_shstk_base(task, size) 0UL
+
+#define set_shstk_base(task, shstk_addr, size)
+
+#define set_active_shstk(task, shstk_addr)
+
+#define is_shstk_enabled(task) false
+
 #endif /* CONFIG_RISCV_USER_CFI */
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 58b6482c2bf6..2e8bd30a2b49 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -29,6 +29,7 @@
 #include <asm/vector.h>
 #include <asm/cpufeature.h>
 #include <asm/exec.h>
+#include <asm/usercfi.h>
 
 #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK)
 #include <linux/stackprotector.h>
@@ -211,6 +212,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 	unsigned long clone_flags = args->flags;
 	unsigned long usp = args->stack;
 	unsigned long tls = args->tls;
+	unsigned long ssp = 0;
 	struct pt_regs *childregs = task_pt_regs(p);
 
 	/* Ensure all threads in this mm have the same pointer masking mode. */
@@ -229,11 +231,18 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 		p->thread.s[0] = (unsigned long)args->fn;
 		p->thread.s[1] = (unsigned long)args->fn_arg;
 	} else {
+		/* allocate new shadow stack if needed. In case of CLONE_VM we have to */
+		ssp = shstk_alloc_thread_stack(p, args);
+		if (IS_ERR_VALUE(ssp))
+			return PTR_ERR((void *)ssp);
+
 		*childregs = *(current_pt_regs());
 		/* Turn off status.VS */
 		riscv_v_vstate_off(childregs);
 		if (usp) /* User fork */
 			childregs->sp = usp;
+		/* if needed, set new ssp */
+		ssp ? set_active_shstk(p, ssp) : 0;
 		if (clone_flags & CLONE_SETTLS)
 			childregs->tp = tls;
 		childregs->a0 = 0; /* Return value of fork() */
diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
index 96bb324abafb..6cd166b73316 100644
--- a/arch/riscv/kernel/usercfi.c
+++ b/arch/riscv/kernel/usercfi.c
@@ -19,6 +19,41 @@
 
 #define SHSTK_ENTRY_SIZE sizeof(void *)
 
+bool is_shstk_enabled(struct task_struct *task)
+{
+	return task->thread_info.user_cfi_state.ubcfi_en ? true : false;
+}
+
+void set_shstk_base(struct task_struct *task, unsigned long shstk_addr, unsigned long size)
+{
+	task->thread_info.user_cfi_state.shdw_stk_base = shstk_addr;
+	task->thread_info.user_cfi_state.shdw_stk_size = size;
+}
+
+unsigned long get_shstk_base(struct task_struct *task, unsigned long *size)
+{
+	if (size)
+		*size = task->thread_info.user_cfi_state.shdw_stk_size;
+	return task->thread_info.user_cfi_state.shdw_stk_base;
+}
+
+void set_active_shstk(struct task_struct *task, unsigned long shstk_addr)
+{
+	task->thread_info.user_cfi_state.user_shdw_stk = shstk_addr;
+}
+
+/*
+ * If size is 0, then to be compatible with regular stack we want it to be as big as
+ * regular stack. Else PAGE_ALIGN it and return back
+ */
+static unsigned long calc_shstk_size(unsigned long size)
+{
+	if (size)
+		return PAGE_ALIGN(size);
+
+	return PAGE_ALIGN(min_t(unsigned long long, rlimit(RLIMIT_STACK), SZ_4G));
+}
+
 /*
  * Writes on shadow stack can either be `sspush` or `ssamoswap`. `sspush` can happen
  * implicitly on current shadow stack pointed to by CSR_SSP. `ssamoswap` takes pointer to
@@ -143,3 +178,89 @@ SYSCALL_DEFINE3(map_shadow_stack, unsigned long, addr, unsigned long, size, unsi
 
 	return allocate_shadow_stack(addr, aligned_size, size, set_tok);
 }
+
+/*
+ * This gets called during clone/clone3/fork. And is needed to allocate a shadow stack for
+ * cases where CLONE_VM is specified and thus a different stack is specified by user. We
+ * thus need a separate shadow stack too. How does separate shadow stack is specified by
+ * user is still being debated. Once that's settled, remove this part of the comment.
+ * This function simply returns 0 if shadow stack are not supported or if separate shadow
+ * stack allocation is not needed (like in case of !CLONE_VM)
+ */
+unsigned long shstk_alloc_thread_stack(struct task_struct *tsk,
+					   const struct kernel_clone_args *args)
+{
+	unsigned long addr, size;
+
+	/* If shadow stack is not supported, return 0 */
+	if (!cpu_supports_shadow_stack())
+		return 0;
+
+	/*
+	 * If shadow stack is not enabled on the new thread, skip any
+	 * switch to a new shadow stack.
+	 */
+	if (!is_shstk_enabled(tsk))
+		return 0;
+
+	/*
+	 * For CLONE_VFORK the child will share the parents shadow stack.
+	 * Set base = 0 and size = 0, this is special means to track this state
+	 * so the freeing logic run for child knows to leave it alone.
+	 */
+	if (args->flags & CLONE_VFORK) {
+		set_shstk_base(tsk, 0, 0);
+		return 0;
+	}
+
+	/*
+	 * For !CLONE_VM the child will use a copy of the parents shadow
+	 * stack.
+	 */
+	if (!(args->flags & CLONE_VM))
+		return 0;
+
+	/*
+	 * reaching here means, CLONE_VM was specified and thus a separate shadow
+	 * stack is needed for new cloned thread. Note: below allocation is happening
+	 * using current mm.
+	 */
+	size = calc_shstk_size(args->stack_size);
+	addr = allocate_shadow_stack(0, size, 0, false);
+	if (IS_ERR_VALUE(addr))
+		return addr;
+
+	set_shstk_base(tsk, addr, size);
+
+	return addr + size;
+}
+
+void shstk_release(struct task_struct *tsk)
+{
+	unsigned long base = 0, size = 0;
+	/* If shadow stack is not supported or not enabled, nothing to release */
+	if (!cpu_supports_shadow_stack() ||
+		!is_shstk_enabled(tsk))
+		return;
+
+	/*
+	 * When fork() with CLONE_VM fails, the child (tsk) already has a
+	 * shadow stack allocated, and exit_thread() calls this function to
+	 * free it.  In this case the parent (current) and the child share
+	 * the same mm struct. Move forward only when they're same.
+	 */
+	if (!tsk->mm || tsk->mm != current->mm)
+		return;
+
+	/*
+	 * We know shadow stack is enabled but if base is NULL, then
+	 * this task is not managing its own shadow stack (CLONE_VFORK). So
+	 * skip freeing it.
+	 */
+	base = get_shstk_base(tsk, &size);
+	if (!base)
+		return;
+
+	vm_munmap(base, size);
+	set_shstk_base(tsk, 0, 0);
+}

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:58 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:58 -0800
Subject: [PATCH v8 13/29] prctl: arch-agnostic prctl for shadow stack
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-13-dce14aa30207@rivosinc.com>

From: Mark Brown <broonie at kernel.org>

Three architectures (x86, aarch64, riscv) have announced support for
shadow stacks with fairly similar functionality.  While x86 is using
arch_prctl() to control the functionality neither arm64 nor riscv uses
that interface so this patch adds arch-agnostic prctl() support to
get and set status of shadow stacks and lock the current configuration to
prevent further changes, with support for turning on and off individual
subfeatures so applications can limit their exposure to features that
they do not need.  The features are:

  - PR_SHADOW_STACK_ENABLE: Tracking and enforcement of shadow stacks,
    including allocation of a shadow stack if one is not already
    allocated.
  - PR_SHADOW_STACK_WRITE: Writes to specific addresses in the shadow
    stack.
  - PR_SHADOW_STACK_PUSH: Push additional values onto the shadow stack.
  - PR_SHADOW_STACK_DISABLE: Allow to disable shadow stack.
    Note once locked, disable must fail.

These features are expected to be inherited by new threads and cleared
on exec(), unknown features should be rejected for enable but accepted
for locking (in order to allow for future proofing).

This is based on a patch originally written by Deepak Gupta but later
modified by Mark Brown for arm's GCS patch series.

Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 include/linux/mm.h         |  3 +++
 include/uapi/linux/prctl.h | 21 +++++++++++++++++++++
 kernel/sys.c               | 30 ++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 2291c02c74d2..772516264a38 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -4147,6 +4147,9 @@ static inline bool pfn_is_unaccepted_memory(unsigned long pfn)
 {
 	return range_contains_unaccepted_memory(pfn << PAGE_SHIFT, PAGE_SIZE);
 }
+int arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *status);
+int arch_set_shadow_stack_status(struct task_struct *t, unsigned long status);
+int arch_lock_shadow_stack_status(struct task_struct *t, unsigned long status);
 
 void vma_pgtable_walk_begin(struct vm_area_struct *vma);
 void vma_pgtable_walk_end(struct vm_area_struct *vma);
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index cefd656ebf43..c42ed44e86bc 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -330,5 +330,26 @@ struct prctl_mm_map {
 # define PR_PPC_DEXCR_CTRL_SET_ONEXEC	 0x8 /* Set the aspect on exec */
 # define PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC	0x10 /* Clear the aspect on exec */
 # define PR_PPC_DEXCR_CTRL_MASK		0x1f
+/*
+ * Get the current shadow stack configuration for the current thread,
+ * this will be the value configured via PR_SET_SHADOW_STACK_STATUS.
+ */
+#define PR_GET_SHADOW_STACK_STATUS      74
+
+/*
+ * Set the current shadow stack configuration.  Enabling the shadow
+ * stack will cause a shadow stack to be allocated for the thread.
+ */
+#define PR_SET_SHADOW_STACK_STATUS      75
+# define PR_SHADOW_STACK_ENABLE         (1UL << 0)
+# define PR_SHADOW_STACK_WRITE		(1UL << 1)
+# define PR_SHADOW_STACK_PUSH		(1UL << 2)
+
+/*
+ * Prevent further changes to the specified shadow stack
+ * configuration.  All bits may be locked via this call, including
+ * undefined bits.
+ */
+#define PR_LOCK_SHADOW_STACK_STATUS      76
 
 #endif /* _LINUX_PRCTL_H */
diff --git a/kernel/sys.c b/kernel/sys.c
index 4da31f28fda8..3d38a9c7c5c9 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2324,6 +2324,21 @@ int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which,
 	return -EINVAL;
 }
 
+int __weak arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *status)
+{
+	return -EINVAL;
+}
+
+int __weak arch_set_shadow_stack_status(struct task_struct *t, unsigned long status)
+{
+	return -EINVAL;
+}
+
+int __weak arch_lock_shadow_stack_status(struct task_struct *t, unsigned long status)
+{
+	return -EINVAL;
+}
+
 #define PR_IO_FLUSHER (PF_MEMALLOC_NOIO | PF_LOCAL_THROTTLE)
 
 #ifdef CONFIG_ANON_VMA_NAME
@@ -2784,6 +2799,21 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 	case PR_RISCV_SET_ICACHE_FLUSH_CTX:
 		error = RISCV_SET_ICACHE_FLUSH_CTX(arg2, arg3);
 		break;
+	case PR_GET_SHADOW_STACK_STATUS:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_get_shadow_stack_status(me, (unsigned long __user *) arg2);
+		break;
+	case PR_SET_SHADOW_STACK_STATUS:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_set_shadow_stack_status(me, arg2);
+		break;
+	case PR_LOCK_SHADOW_STACK_STATUS:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_lock_shadow_stack_status(me, arg2);
+		break;
 	default:
 		error = -EINVAL;
 		break;

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:53:59 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:53:59 -0800
Subject: [PATCH v8 14/29] prctl: arch-agnostic prctl for indirect branch
 tracking
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-14-dce14aa30207@rivosinc.com>

Three architectures (x86, aarch64, riscv) have support for indirect branch
tracking feature in a very similar fashion. On a very high level, indirect
branch tracking is a CPU feature where CPU tracks branches which uses
memory operand to perform control transfer in program. As part of this
tracking on indirect branches, CPU goes in a state where it expects a
landing pad instr on target and if not found then CPU raises some fault
(architecture dependent)

x86 landing pad instr - `ENDBRANCH`
aarch64 landing pad instr - `BTI`
riscv landing instr - `lpad`

Given that three major arches have support for indirect branch tracking,
This patch makes `prctl` for indirect branch tracking arch agnostic.

To allow userspace to enable this feature for itself, following prtcls are
defined:
 - PR_GET_INDIR_BR_LP_STATUS: Gets current configured status for indirect
   branch tracking.
 - PR_SET_INDIR_BR_LP_STATUS: Sets a configuration for indirect branch
   tracking.
   Following status options are allowed
       - PR_INDIR_BR_LP_ENABLE: Enables indirect branch tracking on user
         thread.
       - PR_INDIR_BR_LP_DISABLE; Disables indirect branch tracking on user
         thread.
 - PR_LOCK_INDIR_BR_LP_STATUS: Locks configured status for indirect branch
   tracking for user thread.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 include/linux/cpu.h        |  4 ++++
 include/uapi/linux/prctl.h | 27 +++++++++++++++++++++++++++
 kernel/sys.c               | 30 ++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index bdcec1732445..eff56aae05d7 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -203,4 +203,8 @@ static inline bool cpu_mitigations_auto_nosmt(void)
 }
 #endif
 
+int arch_get_indir_br_lp_status(struct task_struct *t, unsigned long __user *status);
+int arch_set_indir_br_lp_status(struct task_struct *t, unsigned long status);
+int arch_lock_indir_br_lp_status(struct task_struct *t, unsigned long status);
+
 #endif /* _LINUX_CPU_H_ */
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index c42ed44e86bc..8afd5cb70237 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -352,4 +352,31 @@ struct prctl_mm_map {
  */
 #define PR_LOCK_SHADOW_STACK_STATUS      76
 
+/*
+ * Get the current indirect branch tracking configuration for the current
+ * thread, this will be the value configured via PR_SET_INDIR_BR_LP_STATUS.
+ */
+#define PR_GET_INDIR_BR_LP_STATUS      77
+
+/*
+ * Set the indirect branch tracking configuration. PR_INDIR_BR_LP_ENABLE will
+ * enable cpu feature for user thread, to track all indirect branches and ensure
+ * they land on arch defined landing pad instruction.
+ * x86 - If enabled, an indirect branch must land on `ENDBRANCH` instruction.
+ * arch64 - If enabled, an indirect branch must land on `BTI` instruction.
+ * riscv - If enabled, an indirect branch must land on `lpad` instruction.
+ * PR_INDIR_BR_LP_DISABLE will disable feature for user thread and indirect
+ * branches will no more be tracked by cpu to land on arch defined landing pad
+ * instruction.
+ */
+#define PR_SET_INDIR_BR_LP_STATUS      78
+# define PR_INDIR_BR_LP_ENABLE		   (1UL << 0)
+
+/*
+ * Prevent further changes to the specified indirect branch tracking
+ * configuration.  All bits may be locked via this call, including
+ * undefined bits.
+ */
+#define PR_LOCK_INDIR_BR_LP_STATUS      79
+
 #endif /* _LINUX_PRCTL_H */
diff --git a/kernel/sys.c b/kernel/sys.c
index 3d38a9c7c5c9..dafa31485584 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2339,6 +2339,21 @@ int __weak arch_lock_shadow_stack_status(struct task_struct *t, unsigned long st
 	return -EINVAL;
 }
 
+int __weak arch_get_indir_br_lp_status(struct task_struct *t, unsigned long __user *status)
+{
+	return -EINVAL;
+}
+
+int __weak arch_set_indir_br_lp_status(struct task_struct *t, unsigned long status)
+{
+	return -EINVAL;
+}
+
+int __weak arch_lock_indir_br_lp_status(struct task_struct *t, unsigned long status)
+{
+	return -EINVAL;
+}
+
 #define PR_IO_FLUSHER (PF_MEMALLOC_NOIO | PF_LOCAL_THROTTLE)
 
 #ifdef CONFIG_ANON_VMA_NAME
@@ -2814,6 +2829,21 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 			return -EINVAL;
 		error = arch_lock_shadow_stack_status(me, arg2);
 		break;
+	case PR_GET_INDIR_BR_LP_STATUS:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_get_indir_br_lp_status(me, (unsigned long __user *) arg2);
+		break;
+	case PR_SET_INDIR_BR_LP_STATUS:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_set_indir_br_lp_status(me, arg2);
+		break;
+	case PR_LOCK_INDIR_BR_LP_STATUS:
+		if (arg3 || arg4 || arg5)
+			return -EINVAL;
+		error = arch_lock_indir_br_lp_status(me, arg2);
+		break;
 	default:
 		error = -EINVAL;
 		break;

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:00 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:00 -0800
Subject: [PATCH v8 15/29] riscv: Implements arch agnostic shadow stack
 prctls
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-15-dce14aa30207@rivosinc.com>

Implement architecture agnostic prctls() interface for setting and getting
shadow stack status.

prctls implemented are PR_GET_SHADOW_STACK_STATUS,
PR_SET_SHADOW_STACK_STATUS and PR_LOCK_SHADOW_STACK_STATUS.

As part of PR_SET_SHADOW_STACK_STATUS/PR_GET_SHADOW_STACK_STATUS, only
PR_SHADOW_STACK_ENABLE is implemented because RISCV allows each mode to
write to their own shadow stack using `sspush` or `ssamoswap`.

PR_LOCK_SHADOW_STACK_STATUS locks current configuration of shadow stack
enabling.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/include/asm/usercfi.h |  18 ++++++-
 arch/riscv/kernel/process.c      |   8 +++
 arch/riscv/kernel/usercfi.c      | 107 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
index 4da9cbc8f9b5..0b3aff008c85 100644
--- a/arch/riscv/include/asm/usercfi.h
+++ b/arch/riscv/include/asm/usercfi.h
@@ -7,6 +7,7 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
+#include <linux/prctl.h>
 
 struct task_struct;
 struct kernel_clone_args;
@@ -14,7 +15,8 @@ struct kernel_clone_args;
 #ifdef CONFIG_RISCV_USER_CFI
 struct cfi_status {
 	unsigned long ubcfi_en : 1; /* Enable for backward cfi. */
-	unsigned long rsvd : ((sizeof(unsigned long)*8) - 1);
+	unsigned long ubcfi_locked : 1;
+	unsigned long rsvd : ((sizeof(unsigned long)*8) - 2);
 	unsigned long user_shdw_stk; /* Current user shadow stack pointer */
 	unsigned long shdw_stk_base; /* Base address of shadow stack */
 	unsigned long shdw_stk_size; /* size of shadow stack */
@@ -27,6 +29,12 @@ void set_shstk_base(struct task_struct *task, unsigned long shstk_addr, unsigned
 unsigned long get_shstk_base(struct task_struct *task, unsigned long *size);
 void set_active_shstk(struct task_struct *task, unsigned long shstk_addr);
 bool is_shstk_enabled(struct task_struct *task);
+bool is_shstk_locked(struct task_struct *task);
+bool is_shstk_allocated(struct task_struct *task);
+void set_shstk_lock(struct task_struct *task);
+void set_shstk_status(struct task_struct *task, bool enable);
+
+#define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK (PR_SHADOW_STACK_ENABLE)
 
 #else
 
@@ -42,6 +50,14 @@ bool is_shstk_enabled(struct task_struct *task);
 
 #define is_shstk_enabled(task) false
 
+#define is_shstk_locked(task) false
+
+#define is_shstk_allocated(task) false
+
+#define set_shstk_lock(task)
+
+#define set_shstk_status(task, enable)
+
 #endif /* CONFIG_RISCV_USER_CFI */
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 2e8bd30a2b49..d75721b243af 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -153,6 +153,14 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
 	regs->epc = pc;
 	regs->sp = sp;
 
+	/*
+	 * clear shadow stack state on exec.
+	 * libc will set it later via prctl.
+	 */
+	set_shstk_status(current, false);
+	set_shstk_base(current, 0, 0);
+	set_active_shstk(current, 0);
+
 #ifdef CONFIG_64BIT
 	regs->status &= ~SR_UXL;
 
diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
index 6cd166b73316..141ef70b08a3 100644
--- a/arch/riscv/kernel/usercfi.c
+++ b/arch/riscv/kernel/usercfi.c
@@ -24,6 +24,16 @@ bool is_shstk_enabled(struct task_struct *task)
 	return task->thread_info.user_cfi_state.ubcfi_en ? true : false;
 }
 
+bool is_shstk_allocated(struct task_struct *task)
+{
+	return task->thread_info.user_cfi_state.shdw_stk_base ? true : false;
+}
+
+bool is_shstk_locked(struct task_struct *task)
+{
+	return task->thread_info.user_cfi_state.ubcfi_locked ? true : false;
+}
+
 void set_shstk_base(struct task_struct *task, unsigned long shstk_addr, unsigned long size)
 {
 	task->thread_info.user_cfi_state.shdw_stk_base = shstk_addr;
@@ -42,6 +52,23 @@ void set_active_shstk(struct task_struct *task, unsigned long shstk_addr)
 	task->thread_info.user_cfi_state.user_shdw_stk = shstk_addr;
 }
 
+void set_shstk_status(struct task_struct *task, bool enable)
+{
+	task->thread_info.user_cfi_state.ubcfi_en = enable ? 1 : 0;
+
+	if (enable)
+		task->thread.envcfg |= ENVCFG_SSE;
+	else
+		task->thread.envcfg &= ~ENVCFG_SSE;
+
+	csr_write(CSR_ENVCFG, task->thread.envcfg);
+}
+
+void set_shstk_lock(struct task_struct *task)
+{
+	task->thread_info.user_cfi_state.ubcfi_locked = 1;
+}
+
 /*
  * If size is 0, then to be compatible with regular stack we want it to be as big as
  * regular stack. Else PAGE_ALIGN it and return back
@@ -264,3 +291,83 @@ void shstk_release(struct task_struct *tsk)
 	vm_munmap(base, size);
 	set_shstk_base(tsk, 0, 0);
 }
+
+int arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *status)
+{
+	unsigned long bcfi_status = 0;
+
+	if (!cpu_supports_shadow_stack())
+		return -EINVAL;
+
+	/* this means shadow stack is enabled on the task */
+	bcfi_status |= (is_shstk_enabled(t) ? PR_SHADOW_STACK_ENABLE : 0);
+
+	return copy_to_user(status, &bcfi_status, sizeof(bcfi_status)) ? -EFAULT : 0;
+}
+
+int arch_set_shadow_stack_status(struct task_struct *t, unsigned long status)
+{
+	unsigned long size = 0, addr = 0;
+	bool enable_shstk = false;
+
+	if (!cpu_supports_shadow_stack())
+		return -EINVAL;
+
+	/* Reject unknown flags */
+	if (status & ~PR_SHADOW_STACK_SUPPORTED_STATUS_MASK)
+		return -EINVAL;
+
+	/* bcfi status is locked and further can't be modified by user */
+	if (is_shstk_locked(t))
+		return -EINVAL;
+
+	enable_shstk = status & PR_SHADOW_STACK_ENABLE;
+	/* Request is to enable shadow stack and shadow stack is not enabled already */
+	if (enable_shstk && !is_shstk_enabled(t)) {
+		/* shadow stack was allocated and enable request again
+		 * no need to support such usecase and return EINVAL.
+		 */
+		if (is_shstk_allocated(t))
+			return -EINVAL;
+
+		size = calc_shstk_size(0);
+		addr = allocate_shadow_stack(0, size, 0, false);
+		if (IS_ERR_VALUE(addr))
+			return -ENOMEM;
+		set_shstk_base(t, addr, size);
+		set_active_shstk(t, addr + size);
+	}
+
+	/*
+	 * If a request to disable shadow stack happens, let's go ahead and release it
+	 * Although, if CLONE_VFORKed child did this, then in that case we will end up
+	 * not releasing the shadow stack (because it might be needed in parent). Although
+	 * we will disable it for VFORKed child. And if VFORKed child tries to enable again
+	 * then in that case, it'll get entirely new shadow stack because following condition
+	 * are true
+	 *  - shadow stack was not enabled for vforked child
+	 *  - shadow stack base was anyways pointing to 0
+	 * This shouldn't be a big issue because we want parent to have availability of shadow
+	 * stack whenever VFORKed child releases resources via exit or exec but at the same
+	 * time we want VFORKed child to break away and establish new shadow stack if it desires
+	 *
+	 */
+	if (!enable_shstk)
+		shstk_release(t);
+
+	set_shstk_status(t, enable_shstk);
+	return 0;
+}
+
+int arch_lock_shadow_stack_status(struct task_struct *task,
+				unsigned long arg)
+{
+	/* If shtstk not supported or not enabled on task, nothing to lock here */
+	if (!cpu_supports_shadow_stack() ||
+		!is_shstk_enabled(task) || (arg != 0))
+		return -EINVAL;
+
+	set_shstk_lock(task);
+
+	return 0;
+}

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:01 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:01 -0800
Subject: [PATCH v8 16/29] riscv: Implements arch agnostic indirect branch
 tracking prctls
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-16-dce14aa30207@rivosinc.com>

prctls implemented are:
PR_SET_INDIR_BR_LP_STATUS, PR_GET_INDIR_BR_LP_STATUS and
PR_LOCK_INDIR_BR_LP_STATUS.

On trap entry, ELP state is recorded in sstatus image on stack and SR_ELP
in CSR_STATUS is cleared.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/include/asm/usercfi.h | 16 ++++++++-
 arch/riscv/kernel/entry.S        |  2 +-
 arch/riscv/kernel/process.c      |  5 +++
 arch/riscv/kernel/usercfi.c      | 76 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
index 0b3aff008c85..19ee8e7e23ee 100644
--- a/arch/riscv/include/asm/usercfi.h
+++ b/arch/riscv/include/asm/usercfi.h
@@ -16,7 +16,9 @@ struct kernel_clone_args;
 struct cfi_status {
 	unsigned long ubcfi_en : 1; /* Enable for backward cfi. */
 	unsigned long ubcfi_locked : 1;
-	unsigned long rsvd : ((sizeof(unsigned long)*8) - 2);
+	unsigned long ufcfi_en : 1; /* Enable for forward cfi. Note that ELP goes in sstatus */
+	unsigned long ufcfi_locked : 1;
+	unsigned long rsvd : ((sizeof(unsigned long)*8) - 4);
 	unsigned long user_shdw_stk; /* Current user shadow stack pointer */
 	unsigned long shdw_stk_base; /* Base address of shadow stack */
 	unsigned long shdw_stk_size; /* size of shadow stack */
@@ -33,6 +35,10 @@ bool is_shstk_locked(struct task_struct *task);
 bool is_shstk_allocated(struct task_struct *task);
 void set_shstk_lock(struct task_struct *task);
 void set_shstk_status(struct task_struct *task, bool enable);
+bool is_indir_lp_enabled(struct task_struct *task);
+bool is_indir_lp_locked(struct task_struct *task);
+void set_indir_lp_status(struct task_struct *task, bool enable);
+void set_indir_lp_lock(struct task_struct *task);
 
 #define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK (PR_SHADOW_STACK_ENABLE)
 
@@ -58,6 +64,14 @@ void set_shstk_status(struct task_struct *task, bool enable);
 
 #define set_shstk_status(task, enable)
 
+#define is_indir_lp_enabled(task) false
+
+#define is_indir_lp_locked(task) false
+
+#define set_indir_lp_status(task, enable)
+
+#define set_indir_lp_lock(task)
+
 #endif /* CONFIG_RISCV_USER_CFI */
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 8f7f477517e3..a1f258fd7bbc 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -143,7 +143,7 @@ SYM_CODE_START(handle_exception)
 	 * Disable the FPU/Vector to detect illegal usage of floating point
 	 * or vector in kernel space.
 	 */
-	li t0, SR_SUM | SR_FS_VS
+	li t0, SR_SUM | SR_FS_VS | SR_ELP
 
 	REG_L s0, TASK_TI_USER_SP(tp)
 	csrrc s1, CSR_STATUS, t0
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index d75721b243af..226054db6c42 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -160,6 +160,11 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
 	set_shstk_status(current, false);
 	set_shstk_base(current, 0, 0);
 	set_active_shstk(current, 0);
+	/*
+	 * disable indirect branch tracking on exec.
+	 * libc will enable it later via prctl.
+	 */
+	set_indir_lp_status(current, false);
 
 #ifdef CONFIG_64BIT
 	regs->status &= ~SR_UXL;
diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
index 141ef70b08a3..c5fa90711089 100644
--- a/arch/riscv/kernel/usercfi.c
+++ b/arch/riscv/kernel/usercfi.c
@@ -69,6 +69,32 @@ void set_shstk_lock(struct task_struct *task)
 	task->thread_info.user_cfi_state.ubcfi_locked = 1;
 }
 
+bool is_indir_lp_enabled(struct task_struct *task)
+{
+	return task->thread_info.user_cfi_state.ufcfi_en ? true : false;
+}
+
+bool is_indir_lp_locked(struct task_struct *task)
+{
+	return task->thread_info.user_cfi_state.ufcfi_locked ? true : false;
+}
+
+void set_indir_lp_status(struct task_struct *task, bool enable)
+{
+	task->thread_info.user_cfi_state.ufcfi_en = enable ? 1 : 0;
+
+	if (enable)
+		task->thread.envcfg |= ENVCFG_LPE;
+	else
+		task->thread.envcfg &= ~ENVCFG_LPE;
+
+	csr_write(CSR_ENVCFG, task->thread.envcfg);
+}
+
+void set_indir_lp_lock(struct task_struct *task)
+{
+	task->thread_info.user_cfi_state.ufcfi_locked = 1;
+}
 /*
  * If size is 0, then to be compatible with regular stack we want it to be as big as
  * regular stack. Else PAGE_ALIGN it and return back
@@ -371,3 +397,53 @@ int arch_lock_shadow_stack_status(struct task_struct *task,
 
 	return 0;
 }
+
+int arch_get_indir_br_lp_status(struct task_struct *t, unsigned long __user *status)
+{
+	unsigned long fcfi_status = 0;
+
+	if (!cpu_supports_indirect_br_lp_instr())
+		return -EINVAL;
+
+	/* indirect branch tracking is enabled on the task or not */
+	fcfi_status |= (is_indir_lp_enabled(t) ? PR_INDIR_BR_LP_ENABLE : 0);
+
+	return copy_to_user(status, &fcfi_status, sizeof(fcfi_status)) ? -EFAULT : 0;
+}
+
+int arch_set_indir_br_lp_status(struct task_struct *t, unsigned long status)
+{
+	bool enable_indir_lp = false;
+
+	if (!cpu_supports_indirect_br_lp_instr())
+		return -EINVAL;
+
+	/* indirect branch tracking is locked and further can't be modified by user */
+	if (is_indir_lp_locked(t))
+		return -EINVAL;
+
+	/* Reject unknown flags */
+	if (status & ~PR_INDIR_BR_LP_ENABLE)
+		return -EINVAL;
+
+	enable_indir_lp = (status & PR_INDIR_BR_LP_ENABLE) ? true : false;
+	set_indir_lp_status(t, enable_indir_lp);
+
+	return 0;
+}
+
+int arch_lock_indir_br_lp_status(struct task_struct *task,
+				unsigned long arg)
+{
+	/*
+	 * If indirect branch tracking is not supported or not enabled on task,
+	 * nothing to lock here
+	 */
+	if (!cpu_supports_indirect_br_lp_instr() ||
+		!is_indir_lp_enabled(task) || (arg != 0))
+		return -EINVAL;
+
+	set_indir_lp_lock(task);
+
+	return 0;
+}

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:02 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:02 -0800
Subject: [PATCH v8 17/29] riscv/traps: Introduce software check exception
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-17-dce14aa30207@rivosinc.com>

zicfiss / zicfilp introduces a new exception to priv isa `software check
exception` with cause code = 18. This patch implements software check
exception.

Additionally it implements a cfi violation handler which checks for code
in xtval. If xtval=2, it means that sw check exception happened because of
an indirect branch not landing on 4 byte aligned PC or not landing on
`lpad` instruction or label value embedded in `lpad` not matching label
value setup in `x7`. If xtval=3, it means that sw check exception happened
because of mismatch between link register (x1 or x5) and top of shadow
stack (on execution of `sspopchk`).

In case of cfi violation, SIGSEGV is raised with code=SEGV_CPERR.
SEGV_CPERR was introduced by x86 shadow stack patches.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/include/asm/asm-prototypes.h |  1 +
 arch/riscv/include/asm/entry-common.h   |  2 ++
 arch/riscv/kernel/entry.S               |  3 +++
 arch/riscv/kernel/traps.c               | 42 +++++++++++++++++++++++++++++++++
 4 files changed, 48 insertions(+)

diff --git a/arch/riscv/include/asm/asm-prototypes.h b/arch/riscv/include/asm/asm-prototypes.h
index cd627ec289f1..5a27cefd7805 100644
--- a/arch/riscv/include/asm/asm-prototypes.h
+++ b/arch/riscv/include/asm/asm-prototypes.h
@@ -51,6 +51,7 @@ DECLARE_DO_ERROR_INFO(do_trap_ecall_u);
 DECLARE_DO_ERROR_INFO(do_trap_ecall_s);
 DECLARE_DO_ERROR_INFO(do_trap_ecall_m);
 DECLARE_DO_ERROR_INFO(do_trap_break);
+DECLARE_DO_ERROR_INFO(do_trap_software_check);
 
 asmlinkage void handle_bad_stack(struct pt_regs *regs);
 asmlinkage void do_page_fault(struct pt_regs *regs);
diff --git a/arch/riscv/include/asm/entry-common.h b/arch/riscv/include/asm/entry-common.h
index 7b32d2b08bb6..0f6448583a87 100644
--- a/arch/riscv/include/asm/entry-common.h
+++ b/arch/riscv/include/asm/entry-common.h
@@ -28,4 +28,6 @@ void handle_break(struct pt_regs *regs);
 int handle_misaligned_load(struct pt_regs *regs);
 int handle_misaligned_store(struct pt_regs *regs);
 
+bool handle_user_cfi_violation(struct pt_regs *regs);
+
 #endif /* _ASM_RISCV_ENTRY_COMMON_H */
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index a1f258fd7bbc..aaef4604d841 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -471,6 +471,9 @@ SYM_DATA_START_LOCAL(excp_vect_table)
 	RISCV_PTR do_page_fault   /* load page fault */
 	RISCV_PTR do_trap_unknown
 	RISCV_PTR do_page_fault   /* store page fault */
+	RISCV_PTR do_trap_unknown /* cause=16 */
+	RISCV_PTR do_trap_unknown /* cause=17 */
+	RISCV_PTR do_trap_software_check /* cause=18 is sw check exception */
 SYM_DATA_END_LABEL(excp_vect_table, SYM_L_LOCAL, excp_vect_table_end)
 
 #ifndef CONFIG_MMU
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 51ebfd23e007..225b1d198ab6 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -354,6 +354,48 @@ void do_trap_ecall_u(struct pt_regs *regs)
 
 }
 
+#define CFI_TVAL_FCFI_CODE	2
+#define CFI_TVAL_BCFI_CODE	3
+/* handle cfi violations */
+bool handle_user_cfi_violation(struct pt_regs *regs)
+{
+	bool ret = false;
+	unsigned long tval = csr_read(CSR_TVAL);
+
+	if (((tval == CFI_TVAL_FCFI_CODE) && cpu_supports_indirect_br_lp_instr()) ||
+		((tval == CFI_TVAL_BCFI_CODE) && cpu_supports_shadow_stack())) {
+		do_trap_error(regs, SIGSEGV, SEGV_CPERR, regs->epc,
+					  "Oops - control flow violation");
+		ret = true;
+	}
+
+	return ret;
+}
+/*
+ * software check exception is defined with risc-v cfi spec. Software check
+ * exception is raised when:-
+ * a) An indirect branch doesn't land on 4 byte aligned PC or `lpad`
+ *    instruction or `label` value programmed in `lpad` instr doesn't
+ *    match with value setup in `x7`. reported code in `xtval` is 2.
+ * b) `sspopchk` instruction finds a mismatch between top of shadow stack (ssp)
+ *    and x1/x5. reported code in `xtval` is 3.
+ */
+asmlinkage __visible __trap_section void do_trap_software_check(struct pt_regs *regs)
+{
+	if (user_mode(regs)) {
+		irqentry_enter_from_user_mode(regs);
+
+		/* not a cfi violation, then merge into flow of unknown trap handler */
+		if (!handle_user_cfi_violation(regs))
+			do_trap_unknown(regs);
+
+		irqentry_exit_to_user_mode(regs);
+	} else {
+		/* sw check exception coming from kernel is a bug in kernel */
+		die(regs, "Kernel BUG");
+	}
+}
+
 #ifdef CONFIG_MMU
 asmlinkage __visible noinstr void do_page_fault(struct pt_regs *regs)
 {

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:03 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:03 -0800
Subject: [PATCH v8 18/29] riscv: signal: abstract header saving for
 setup_sigcontext
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-18-dce14aa30207@rivosinc.com>

From: Andy Chiu <andybnac at gmail.com>

The function save_v_state() served two purposes. First, it saved
extension context into the signal stack. Then, it constructed the
extension header if there was no fault. The second part is independent
of the extension itself. As a result, we can pull that part out, so
future extensions may reuse it. This patch adds arch_ext_list and makes
setup_sigcontext() go through all possible extensions' save() callback.
The callback returns a positive value indicating the size of the
successfully saved extension. Then the kernel proceeds to construct the
header for that extension. The kernel skips an extension if it does
not exist, or if the saving fails for some reasons. The error code is
propagated out on the later case.

This patch does not introduce any functional changes.

Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
---
 arch/riscv/include/asm/vector.h |  3 +++
 arch/riscv/kernel/signal.c      | 60 ++++++++++++++++++++++++++---------------
 2 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index c7c023afbacd..921b0fdcc3fb 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -283,6 +283,9 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
 #define riscv_v_thread_free(tsk)		do {} while (0)
 #define  riscv_v_setup_ctx_cache()		do {} while (0)
 #define riscv_v_thread_alloc(tsk)		do {} while (0)
+#define get_cpu_vector_context()		do {} while (0)
+#define put_cpu_vector_context()		do {} while (0)
+#define riscv_v_vstate_set_restore(task, regs)	do {} while (0)
 
 #endif /* CONFIG_RISCV_ISA_V */
 
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index dcd282419456..014ac1024b85 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -68,18 +68,18 @@ static long save_fp_state(struct pt_regs *regs,
 #define restore_fp_state(task, regs) (0)
 #endif
 
-#ifdef CONFIG_RISCV_ISA_V
-
-static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
+static long save_v_state(struct pt_regs *regs, void __user *sc_vec)
 {
-	struct __riscv_ctx_hdr __user *hdr;
 	struct __sc_riscv_v_state __user *state;
 	void __user *datap;
 	long err;
 
-	hdr = *sc_vec;
-	/* Place state to the user's signal context space after the hdr */
-	state = (struct __sc_riscv_v_state __user *)(hdr + 1);
+	if (!IS_ENABLED(CONFIG_RISCV_ISA_V) ||
+		!(has_vector() && riscv_v_vstate_query(regs)))
+		return 0;
+
+	/* Place state to the user's signal context spac */
+	state = (struct __sc_riscv_v_state __user *)sc_vec;
 	/* Point datap right after the end of __sc_riscv_v_state */
 	datap = state + 1;
 
@@ -97,15 +97,11 @@ static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
 	err |= __put_user((__force void *)datap, &state->v_state.datap);
 	/* Copy the whole vector content to user space datap. */
 	err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize);
-	/* Copy magic to the user space after saving  all vector conetext */
-	err |= __put_user(RISCV_V_MAGIC, &hdr->magic);
-	err |= __put_user(riscv_v_sc_size, &hdr->size);
 	if (unlikely(err))
-		return err;
+		return -EFAULT;
 
-	/* Only progress the sv_vec if everything has done successfully  */
-	*sc_vec += riscv_v_sc_size;
-	return 0;
+	/* Only return the size if everything has done successfully  */
+	return riscv_v_sc_size;
 }
 
 /*
@@ -142,10 +138,19 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
 	 */
 	return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
 }
-#else
-#define save_v_state(task, regs) (0)
-#define __restore_v_state(task, regs) (0)
-#endif
+
+struct arch_ext_priv {
+	__u32 magic;
+	long (*save)(struct pt_regs *regs, void __user *sc_vec);
+};
+
+struct arch_ext_priv arch_ext_list[] = {
+	{
+		.magic = RISCV_V_MAGIC,
+		.save = &save_v_state,
+	},
+};
+const size_t nr_arch_exts = ARRAY_SIZE(arch_ext_list);
 
 static long restore_sigcontext(struct pt_regs *regs,
 	struct sigcontext __user *sc)
@@ -276,7 +281,8 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
 {
 	struct sigcontext __user *sc = &frame->uc.uc_mcontext;
 	struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
-	long err;
+	struct arch_ext_priv *arch_ext;
+	long err, i, ext_size;
 
 	/* sc_regs is structured the same as the start of pt_regs */
 	err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
@@ -284,8 +290,20 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
 	if (has_fpu())
 		err |= save_fp_state(regs, &sc->sc_fpregs);
 	/* Save the vector state. */
-	if (has_vector() && riscv_v_vstate_query(regs))
-		err |= save_v_state(regs, (void __user **)&sc_ext_ptr);
+	for (i = 0; i < nr_arch_exts; i++) {
+		arch_ext = &arch_ext_list[i];
+		if (!arch_ext->save)
+			continue;
+
+		ext_size = arch_ext->save(regs, sc_ext_ptr + 1);
+		if (ext_size <= 0) {
+			err |= ext_size;
+		} else {
+			err |= __put_user(arch_ext->magic, &sc_ext_ptr->magic);
+			err |= __put_user(ext_size, &sc_ext_ptr->size);
+			sc_ext_ptr = (void *)sc_ext_ptr + ext_size;
+		}
+	}
 	/* Write zero to fp-reserved space and check it on restore_sigcontext */
 	err |= __put_user(0, &sc->sc_extdesc.reserved);
 	/* And put END __riscv_ctx_hdr at the end. */

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:04 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:04 -0800
Subject: [PATCH v8 19/29] riscv/signal: save and restore of shadow stack
 for signal
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-19-dce14aa30207@rivosinc.com>

Save shadow stack pointer in sigcontext structure while delivering signal.
Restore shadow stack pointer from sigcontext on sigreturn.

As part of save operation, kernel uses `ssamoswap` to save snapshot of
current shadow stack on shadow stack itself (can be called as a save
token). During restore on sigreturn, kernel retrieves token from top of
shadow stack and validates it. This allows that user mode can't arbitrary
pivot to any shadow stack address without having a token and thus provide
strong security assurance between signaly delivery and sigreturn window.

Use ABI compatible way of saving/restoring shadow stack pointer into
signal stack. This follows what Vector extension, where extra registers
are placed in a form of extension header + extension body in the stack.
The extension header indicates the size of the extra architectural
states plus the size of header itself, and a magic identifier of the
extension. Then, the extensions body contains the new architectural
states in the form defined by uapi.

Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/include/asm/usercfi.h         | 10 ++++
 arch/riscv/include/uapi/asm/ptrace.h     |  4 ++
 arch/riscv/include/uapi/asm/sigcontext.h |  1 +
 arch/riscv/kernel/signal.c               | 80 ++++++++++++++++++++++++++++++++
 arch/riscv/kernel/usercfi.c              | 57 +++++++++++++++++++++++
 5 files changed, 152 insertions(+)

diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
index 19ee8e7e23ee..fe58b13b5fa6 100644
--- a/arch/riscv/include/asm/usercfi.h
+++ b/arch/riscv/include/asm/usercfi.h
@@ -8,6 +8,7 @@
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 #include <linux/prctl.h>
+#include <linux/errno.h>
 
 struct task_struct;
 struct kernel_clone_args;
@@ -35,6 +36,9 @@ bool is_shstk_locked(struct task_struct *task);
 bool is_shstk_allocated(struct task_struct *task);
 void set_shstk_lock(struct task_struct *task);
 void set_shstk_status(struct task_struct *task, bool enable);
+unsigned long get_active_shstk(struct task_struct *task);
+int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr);
+int save_user_shstk(struct task_struct *tsk, unsigned long *saved_shstk_ptr);
 bool is_indir_lp_enabled(struct task_struct *task);
 bool is_indir_lp_locked(struct task_struct *task);
 void set_indir_lp_status(struct task_struct *task, bool enable);
@@ -72,6 +76,12 @@ void set_indir_lp_lock(struct task_struct *task);
 
 #define set_indir_lp_lock(task)
 
+#define restore_user_shstk(tsk, shstk_ptr) -EINVAL
+
+#define save_user_shstk(tsk, saved_shstk_ptr) -EINVAL
+
+#define get_active_shstk(task) 0UL
+
 #endif /* CONFIG_RISCV_USER_CFI */
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/riscv/include/uapi/asm/ptrace.h b/arch/riscv/include/uapi/asm/ptrace.h
index a38268b19c3d..659ea3af5680 100644
--- a/arch/riscv/include/uapi/asm/ptrace.h
+++ b/arch/riscv/include/uapi/asm/ptrace.h
@@ -127,6 +127,10 @@ struct __riscv_v_regset_state {
  */
 #define RISCV_MAX_VLENB (8192)
 
+struct __sc_riscv_cfi_state {
+	unsigned long ss_ptr;   /* shadow stack pointer */
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI_ASM_RISCV_PTRACE_H */
diff --git a/arch/riscv/include/uapi/asm/sigcontext.h b/arch/riscv/include/uapi/asm/sigcontext.h
index cd4f175dc837..f37e4beffe03 100644
--- a/arch/riscv/include/uapi/asm/sigcontext.h
+++ b/arch/riscv/include/uapi/asm/sigcontext.h
@@ -10,6 +10,7 @@
 
 /* The Magic number for signal context frame header. */
 #define RISCV_V_MAGIC	0x53465457
+#define RISCV_ZICFISS_MAGIC		0x9487
 #define END_MAGIC	0x0
 
 /* The size of END signal context header. */
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 014ac1024b85..77cbc4a01e49 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -22,11 +22,13 @@
 #include <asm/vector.h>
 #include <asm/csr.h>
 #include <asm/cacheflush.h>
+#include <asm/usercfi.h>
 
 unsigned long signal_minsigstksz __ro_after_init;
 
 extern u32 __user_rt_sigreturn[2];
 static size_t riscv_v_sc_size __ro_after_init;
+static size_t riscv_zicfiss_sc_size __ro_after_init;
 
 #define DEBUG_SIG 0
 
@@ -139,6 +141,62 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
 	return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
 }
 
+static long save_cfiss_state(struct pt_regs *regs, void __user *sc_cfi)
+{
+	struct __sc_riscv_cfi_state __user *state = sc_cfi;
+	unsigned long ss_ptr = 0;
+	long err = 0;
+
+	if (!IS_ENABLED(CONFIG_RISCV_USER_CFI) || !is_shstk_enabled(current))
+		return 0;
+
+	/*
+	 * Save a pointer to shadow stack itself on shadow stack as a form of token.
+	 * A token on shadow gives following properties
+	 * - Safe save and restore for shadow stack switching. Any save of shadow stack
+	 *   must have had saved a token on shadow stack. Similarly any restore of shadow
+	 *   stack must check the token before restore. Since writing to shadow stack with
+	 *   address of shadow stack itself is not easily allowed. A restore without a save
+	 *   is quite difficult for an attacker to perform.
+	 * - A natural break. A token in shadow stack provides a natural break in shadow stack
+	 *   So a single linear range can be bucketed into different shadow stack segments. Any
+	 *   sspopchk will detect the condition and fault to kernel as sw check exception.
+	 */
+	err |= save_user_shstk(current, &ss_ptr);
+	err |= __put_user(ss_ptr, &state->ss_ptr);
+	if (unlikely(err))
+		return -EFAULT;
+
+	return riscv_zicfiss_sc_size;
+}
+
+static long __restore_cfiss_state(struct pt_regs *regs, void __user *sc_cfi)
+{
+	struct __sc_riscv_cfi_state __user *state = sc_cfi;
+	unsigned long ss_ptr = 0;
+	long err;
+
+	/*
+	 * Restore shadow stack as a form of token stored on shadow stack itself as a safe
+	 * way to restore.
+	 * A token on shadow gives following properties
+	 * - Safe save and restore for shadow stack switching. Any save of shadow stack
+	 *   must have had saved a token on shadow stack. Similarly any restore of shadow
+	 *   stack must check the token before restore. Since writing to shadow stack with
+	 *   address of shadow stack itself is not easily allowed. A restore without a save
+	 *   is quite difficult for an attacker to perform.
+	 * - A natural break. A token in shadow stack provides a natural break in shadow stack
+	 *   So a single linear range can be bucketed into different shadow stack segments.
+	 *   sspopchk will detect the condition and fault to kernel as sw check exception.
+	 */
+	err = __copy_from_user(&ss_ptr, &state->ss_ptr, sizeof(unsigned long));
+
+	if (unlikely(err))
+		return err;
+
+	return restore_user_shstk(current, ss_ptr);
+}
+
 struct arch_ext_priv {
 	__u32 magic;
 	long (*save)(struct pt_regs *regs, void __user *sc_vec);
@@ -149,6 +207,10 @@ struct arch_ext_priv arch_ext_list[] = {
 		.magic = RISCV_V_MAGIC,
 		.save = &save_v_state,
 	},
+	{
+		.magic = RISCV_ZICFISS_MAGIC,
+		.save = &save_cfiss_state,
+	},
 };
 const size_t nr_arch_exts = ARRAY_SIZE(arch_ext_list);
 
@@ -200,6 +262,12 @@ static long restore_sigcontext(struct pt_regs *regs,
 
 			err = __restore_v_state(regs, sc_ext_ptr);
 			break;
+		case RISCV_ZICFISS_MAGIC:
+			if (!is_shstk_enabled(current) || size != riscv_zicfiss_sc_size)
+				return -EINVAL;
+
+			err = __restore_cfiss_state(regs, sc_ext_ptr);
+			break;
 		default:
 			return -EINVAL;
 		}
@@ -220,6 +288,10 @@ static size_t get_rt_frame_size(bool cal_all)
 		if (cal_all || riscv_v_vstate_query(task_pt_regs(current)))
 			total_context_size += riscv_v_sc_size;
 	}
+
+	if (is_shstk_enabled(current))
+		total_context_size += riscv_zicfiss_sc_size;
+
 	/*
 	 * Preserved a __riscv_ctx_hdr for END signal context header if an
 	 * extension uses __riscv_extra_ext_header
@@ -363,6 +435,11 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 #ifdef CONFIG_MMU
 	regs->ra = (unsigned long)VDSO_SYMBOL(
 		current->mm->context.vdso, rt_sigreturn);
+
+	/* if bcfi is enabled x1 (ra) and x5 (t0) must match. not sure if we need this? */
+	if (is_shstk_enabled(current))
+		regs->t0 = regs->ra;
+
 #else
 	/*
 	 * For the nommu case we don't have a VDSO.  Instead we push two
@@ -491,6 +568,9 @@ void __init init_rt_signal_env(void)
 {
 	riscv_v_sc_size = sizeof(struct __riscv_ctx_hdr) +
 			  sizeof(struct __sc_riscv_v_state) + riscv_v_vsize;
+
+	riscv_zicfiss_sc_size = sizeof(struct __riscv_ctx_hdr) +
+			  sizeof(struct __sc_riscv_cfi_state);
 	/*
 	 * Determine the stack space required for guaranteed signal delivery.
 	 * The signal_minsigstksz will be populated into the AT_MINSIGSTKSZ entry
diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
index c5fa90711089..04b0305943b1 100644
--- a/arch/riscv/kernel/usercfi.c
+++ b/arch/riscv/kernel/usercfi.c
@@ -52,6 +52,11 @@ void set_active_shstk(struct task_struct *task, unsigned long shstk_addr)
 	task->thread_info.user_cfi_state.user_shdw_stk = shstk_addr;
 }
 
+unsigned long get_active_shstk(struct task_struct *task)
+{
+	return task->thread_info.user_cfi_state.user_shdw_stk;
+}
+
 void set_shstk_status(struct task_struct *task, bool enable)
 {
 	task->thread_info.user_cfi_state.ubcfi_en = enable ? 1 : 0;
@@ -164,6 +169,58 @@ static int create_rstor_token(unsigned long ssp, unsigned long *token_addr)
 	return 0;
 }
 
+/*
+ * Save user shadow stack pointer on shadow stack itself and return pointer to saved location
+ * returns -EFAULT if operation was unsuccessful
+ */
+int save_user_shstk(struct task_struct *tsk, unsigned long *saved_shstk_ptr)
+{
+	unsigned long ss_ptr = 0;
+	unsigned long token_loc = 0;
+	int ret = 0;
+
+	if (saved_shstk_ptr == NULL)
+		return -EINVAL;
+
+	ss_ptr = get_active_shstk(tsk);
+	ret = create_rstor_token(ss_ptr, &token_loc);
+
+	if (!ret) {
+		*saved_shstk_ptr = token_loc;
+		set_active_shstk(tsk, token_loc);
+	}
+
+	return ret;
+}
+
+/*
+ * Restores user shadow stack pointer from token on shadow stack for task `tsk`
+ * returns -EFAULT if operation was unsuccessful
+ */
+int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr)
+{
+	unsigned long token = 0;
+
+	token = amo_user_shstk((unsigned long __user *)shstk_ptr, 0);
+
+	if (token == -1)
+		return -EFAULT;
+
+	/* invalid token, return EINVAL */
+	if ((token - shstk_ptr) != SHSTK_ENTRY_SIZE) {
+		pr_info_ratelimited(
+				"%s[%d]: bad restore token in %s: pc=%p sp=%p, token=%p, shstk_ptr=%p\n",
+				tsk->comm, task_pid_nr(tsk), __func__,
+				(void *)(task_pt_regs(tsk)->epc), (void *)(task_pt_regs(tsk)->sp),
+				(void *)token, (void *)shstk_ptr);
+		return -EINVAL;
+	}
+
+	/* all checks passed, set active shstk and return success */
+	set_active_shstk(tsk, token);
+	return 0;
+}
+
 static unsigned long allocate_shadow_stack(unsigned long addr, unsigned long size,
 				unsigned long token_offset,
 				bool set_tok)

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:05 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:05 -0800
Subject: [PATCH v8 20/29] riscv/kernel: update __show_regs to print shadow
 stack register
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-20-dce14aa30207@rivosinc.com>

Updating __show_regs to print captured shadow stack pointer as well.
On tasks where shadow stack is disabled, it'll simply print 0.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
---
 arch/riscv/kernel/process.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 226054db6c42..1aeb5c08a3c6 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -90,8 +90,8 @@ void __show_regs(struct pt_regs *regs)
 		regs->s8, regs->s9, regs->s10);
 	pr_cont(" s11: " REG_FMT " t3 : " REG_FMT " t4 : " REG_FMT "\n",
 		regs->s11, regs->t3, regs->t4);
-	pr_cont(" t5 : " REG_FMT " t6 : " REG_FMT "\n",
-		regs->t5, regs->t6);
+	pr_cont(" t5 : " REG_FMT " t6 : " REG_FMT " ssp : " REG_FMT "\n",
+		regs->t5, regs->t6, get_active_shstk(current));
 
 	pr_cont("status: " REG_FMT " badaddr: " REG_FMT " cause: " REG_FMT "\n",
 		regs->status, regs->badaddr, regs->cause);

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:06 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:06 -0800
Subject: [PATCH v8 21/29] riscv/ptrace: riscv cfi status and state via
 ptrace and in core files
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-21-dce14aa30207@rivosinc.com>

Expose a new register type NT_RISCV_USER_CFI for risc-v cfi status and
state. Intentionally both landing pad and shadow stack status and state
are rolled into cfi state. Creating two different NT_RISCV_USER_XXX would
not be useful and wastage of a note type. Enabling or disabling of feature
is not allowed via ptrace set interface. However setting `elp` state or
setting shadow stack pointer are allowed via ptrace set interface. It is
expected `gdb` might have use to fixup `elp` state or `shadow stack`
pointer.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/include/uapi/asm/ptrace.h | 18 ++++++++
 arch/riscv/kernel/ptrace.c           | 83 ++++++++++++++++++++++++++++++++++++
 include/uapi/linux/elf.h             |  1 +
 3 files changed, 102 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/ptrace.h b/arch/riscv/include/uapi/asm/ptrace.h
index 659ea3af5680..e6571fba8a8a 100644
--- a/arch/riscv/include/uapi/asm/ptrace.h
+++ b/arch/riscv/include/uapi/asm/ptrace.h
@@ -131,6 +131,24 @@ struct __sc_riscv_cfi_state {
 	unsigned long ss_ptr;   /* shadow stack pointer */
 };
 
+struct __cfi_status {
+	/* indirect branch tracking state */
+	__u64 lp_en : 1;
+	__u64 lp_lock : 1;
+	__u64 elp_state : 1;
+
+	/* shadow stack status */
+	__u64 shstk_en : 1;
+	__u64 shstk_lock : 1;
+
+	__u64 rsvd : sizeof(__u64) - 5;
+};
+
+struct user_cfi_state {
+	struct __cfi_status	cfi_status;
+	__u64 shstk_ptr;
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI_ASM_RISCV_PTRACE_H */
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index ea67e9fb7a58..1c546c01715e 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -19,6 +19,7 @@
 #include <linux/regset.h>
 #include <linux/sched.h>
 #include <linux/sched/task_stack.h>
+#include <asm/usercfi.h>
 
 enum riscv_regset {
 	REGSET_X,
@@ -31,6 +32,9 @@ enum riscv_regset {
 #ifdef CONFIG_RISCV_ISA_SUPM
 	REGSET_TAGGED_ADDR_CTRL,
 #endif
+#ifdef CONFIG_RISCV_USER_CFI
+	REGSET_CFI,
+#endif
 };
 
 static int riscv_gpr_get(struct task_struct *target,
@@ -184,6 +188,75 @@ static int tagged_addr_ctrl_set(struct task_struct *target,
 }
 #endif
 
+#ifdef CONFIG_RISCV_USER_CFI
+static int riscv_cfi_get(struct task_struct *target,
+			const struct user_regset *regset,
+			struct membuf to)
+{
+	struct user_cfi_state user_cfi;
+	struct pt_regs *regs;
+
+	regs = task_pt_regs(target);
+
+	user_cfi.cfi_status.lp_en = is_indir_lp_enabled(target);
+	user_cfi.cfi_status.lp_lock = is_indir_lp_locked(target);
+	user_cfi.cfi_status.elp_state = (regs->status & SR_ELP);
+
+	user_cfi.cfi_status.shstk_en = is_shstk_enabled(target);
+	user_cfi.cfi_status.shstk_lock = is_shstk_locked(target);
+	user_cfi.shstk_ptr = get_active_shstk(target);
+
+	return membuf_write(&to, &user_cfi, sizeof(user_cfi));
+}
+
+/*
+ * Does it make sense to allowing enable / disable of cfi via ptrace?
+ * Not allowing enable / disable / locking control via ptrace for now.
+ * Setting shadow stack pointer is allowed. GDB might use it to unwind or
+ * some other fixup. Similarly gdb might want to suppress elp and may want
+ * to reset elp state.
+ */
+static int riscv_cfi_set(struct task_struct *target,
+			const struct user_regset *regset,
+			unsigned int pos, unsigned int count,
+			const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+	struct user_cfi_state user_cfi;
+	struct pt_regs *regs;
+
+	regs = task_pt_regs(target);
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_cfi, 0, -1);
+	if (ret)
+		return ret;
+
+	/*
+	 * Not allowing enabling or locking shadow stack or landing pad
+	 * There is no disabling of shadow stack or landing pad via ptrace
+	 * rsvd field should be set to zero so that if those fields are needed in future
+	 */
+	if (user_cfi.cfi_status.lp_en || user_cfi.cfi_status.lp_lock ||
+		user_cfi.cfi_status.shstk_en || user_cfi.cfi_status.shstk_lock ||
+		!user_cfi.cfi_status.rsvd)
+		return -EINVAL;
+
+	/* If lpad is enabled on target and ptrace requests to set / clear elp, do that */
+	if (is_indir_lp_enabled(target)) {
+		if (user_cfi.cfi_status.elp_state) /* set elp state */
+			regs->status |= SR_ELP;
+		else
+			regs->status &= ~SR_ELP; /* clear elp state */
+	}
+
+	/* If shadow stack enabled on target, set new shadow stack pointer */
+	if (is_shstk_enabled(target))
+		set_active_shstk(target, user_cfi.shstk_ptr);
+
+	return 0;
+}
+#endif
+
 static const struct user_regset riscv_user_regset[] = {
 	[REGSET_X] = {
 		.core_note_type = NT_PRSTATUS,
@@ -224,6 +297,16 @@ static const struct user_regset riscv_user_regset[] = {
 		.set = tagged_addr_ctrl_set,
 	},
 #endif
+#ifdef CONFIG_RISCV_USER_CFI
+	[REGSET_CFI] = {
+		.core_note_type = NT_RISCV_USER_CFI,
+		.align = sizeof(__u64),
+		.n = sizeof(struct user_cfi_state) / sizeof(__u64),
+		.size = sizeof(__u64),
+		.regset_get = riscv_cfi_get,
+		.set = riscv_cfi_set,
+	},
+#endif
 };
 
 static const struct user_regset_view riscv_user_native_view = {
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index a920cf8934dc..83d16bc61709 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -451,6 +451,7 @@ typedef struct elf64_shdr {
 #define NT_RISCV_CSR	0x900		/* RISC-V Control and Status Registers */
 #define NT_RISCV_VECTOR	0x901		/* RISC-V vector registers */
 #define NT_RISCV_TAGGED_ADDR_CTRL 0x902	/* RISC-V tagged address control (prctl()) */
+#define NT_RISCV_USER_CFI	0x903		/* RISC-V shadow stack state */
 #define NT_LOONGARCH_CPUCFG	0xa00	/* LoongArch CPU config registers */
 #define NT_LOONGARCH_CSR	0xa01	/* LoongArch control and status registers */
 #define NT_LOONGARCH_LSX	0xa02	/* LoongArch Loongson SIMD Extension registers */

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:07 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:07 -0800
Subject: [PATCH v8 22/29] riscv/hwprobe: zicfilp / zicfiss enumeration in
 hwprobe
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-22-dce14aa30207@rivosinc.com>

Adding enumeration of zicfilp and zicfiss extensions in hwprobe syscall.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/include/uapi/asm/hwprobe.h | 2 ++
 arch/riscv/kernel/sys_hwprobe.c       | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
index 3af142b99f77..ca64b07927cb 100644
--- a/arch/riscv/include/uapi/asm/hwprobe.h
+++ b/arch/riscv/include/uapi/asm/hwprobe.h
@@ -73,6 +73,8 @@ struct riscv_hwprobe {
 #define		RISCV_HWPROBE_EXT_ZCMOP		(1ULL << 47)
 #define		RISCV_HWPROBE_EXT_ZAWRS		(1ULL << 48)
 #define		RISCV_HWPROBE_EXT_SUPM		(1ULL << 49)
+#define		RISCV_HWPROBE_EXT_ZICFILP	(1ULL << 50)
+#define		RISCV_HWPROBE_EXT_ZICFISS	(1ULL << 51)
 #define RISCV_HWPROBE_KEY_CPUPERF_0	5
 #define		RISCV_HWPROBE_MISALIGNED_UNKNOWN	(0 << 0)
 #define		RISCV_HWPROBE_MISALIGNED_EMULATED	(1 << 0)
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index 9050f3246264..716d72abec60 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -107,6 +107,8 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
 		EXT_KEY(ZCB);
 		EXT_KEY(ZCMOP);
 		EXT_KEY(ZICBOZ);
+		EXT_KEY(ZICFILP);
+		EXT_KEY(ZICFISS);
 		EXT_KEY(ZICOND);
 		EXT_KEY(ZIHINTNTL);
 		EXT_KEY(ZIHINTPAUSE);

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:08 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:08 -0800
Subject: [PATCH v8 23/29] riscv: Add Firmware Feature SBI extensions
 definitions
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-23-dce14aa30207@rivosinc.com>

From: Cl?ment L?ger <cleger at rivosinc.com>

Add necessary SBI definitions to use the FWFT extension.

Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
---
 arch/riscv/include/asm/sbi.h | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 98f631b051db..754e5cdabf46 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -34,6 +34,7 @@ enum sbi_ext_id {
 	SBI_EXT_PMU = 0x504D55,
 	SBI_EXT_DBCN = 0x4442434E,
 	SBI_EXT_STA = 0x535441,
+	SBI_EXT_FWFT = 0x46574654,
 
 	/* Experimentals extensions must lie within this range */
 	SBI_EXT_EXPERIMENTAL_START = 0x08000000,
@@ -281,6 +282,32 @@ struct sbi_sta_struct {
 
 #define SBI_SHMEM_DISABLE		-1
 
+/* SBI function IDs for FW feature extension */
+#define SBI_EXT_FWFT_SET		0x0
+#define SBI_EXT_FWFT_GET		0x1
+
+enum sbi_fwft_feature_t {
+	SBI_FWFT_MISALIGNED_EXC_DELEG		= 0x0,
+	SBI_FWFT_LANDING_PAD			= 0x1,
+	SBI_FWFT_SHADOW_STACK			= 0x2,
+	SBI_FWFT_DOUBLE_TRAP			= 0x3,
+	SBI_FWFT_PTE_AD_HW_UPDATING		= 0x4,
+	SBI_FWFT_LOCAL_RESERVED_START		= 0x5,
+	SBI_FWFT_LOCAL_RESERVED_END		= 0x3fffffff,
+	SBI_FWFT_LOCAL_PLATFORM_START		= 0x40000000,
+	SBI_FWFT_LOCAL_PLATFORM_END		= 0x7fffffff,
+
+	SBI_FWFT_GLOBAL_RESERVED_START		= 0x80000000,
+	SBI_FWFT_GLOBAL_RESERVED_END		= 0xbfffffff,
+	SBI_FWFT_GLOBAL_PLATFORM_START		= 0xc0000000,
+	SBI_FWFT_GLOBAL_PLATFORM_END		= 0xffffffff,
+};
+
+#define SBI_FWFT_GLOBAL_FEATURE_BIT		(1 << 31)
+#define SBI_FWFT_PLATFORM_FEATURE_BIT		(1 << 30)
+
+#define SBI_FWFT_SET_FLAG_LOCK			(1 << 0)
+
 /* SBI spec version fields */
 #define SBI_SPEC_VERSION_DEFAULT	0x1
 #define SBI_SPEC_VERSION_MAJOR_SHIFT	24

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:09 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:09 -0800
Subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack
 memory via FWFT sbi call
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>

Kernel will have to perform shadow stack operations on user shadow stack.
Like during signal delivery and sigreturn, shadow stack token must be
created and validated respectively. Thus shadow stack access for kernel
must be enabled.

In future when kernel shadow stacks are enabled for linux kernel, it must
be enabled as early as possible for better coverage and prevent imbalance
between regular stack and shadow stack. After `relocate_enable_mmu` has
been done, this is as early as possible it can enabled.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/kernel/asm-offsets.c |  4 ++++
 arch/riscv/kernel/head.S        | 12 ++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index 766bd33f10cb..a22ab8a41672 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -517,4 +517,8 @@ void asm_offsets(void)
 	DEFINE(FREGS_A6,	    offsetof(struct ftrace_regs, a6));
 	DEFINE(FREGS_A7,	    offsetof(struct ftrace_regs, a7));
 #endif
+	DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
+	DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
+	DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
+	DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);
 }
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 356d5397b2a2..6244408ca917 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -164,6 +164,12 @@ secondary_start_sbi:
 	call relocate_enable_mmu
 #endif
 	call .Lsetup_trap_vector
+	li a7, SBI_EXT_FWFT
+	li a6, SBI_EXT_FWFT_SET
+	li a0, SBI_FWFT_SHADOW_STACK
+	li a1, 1 /* enable supervisor to access shadow stack access */
+	li a2, SBI_FWFT_SET_FLAG_LOCK
+	ecall
 	scs_load_current
 	call smp_callin
 #endif /* CONFIG_SMP */
@@ -320,6 +326,12 @@ SYM_CODE_START(_start_kernel)
 	la tp, init_task
 	la sp, init_thread_union + THREAD_SIZE
 	addi sp, sp, -PT_SIZE_ON_STACK
+	li a7, SBI_EXT_FWFT
+	li a6, SBI_EXT_FWFT_SET
+	li a0, SBI_FWFT_SHADOW_STACK
+	li a1, 1 /* enable supervisor to access shadow stack access */
+	li a2, SBI_FWFT_SET_FLAG_LOCK
+	ecall
 	scs_load_current
 
 #ifdef CONFIG_KASAN

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:10 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:10 -0800
Subject: [PATCH v8 25/29] riscv: kernel command line option to opt out of
 user cfi
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-25-dce14aa30207@rivosinc.com>

This commit adds a kernel command line option using which user cfi can be
disabled.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/kernel/usercfi.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
index 04b0305943b1..223dfa482deb 100644
--- a/arch/riscv/kernel/usercfi.c
+++ b/arch/riscv/kernel/usercfi.c
@@ -17,6 +17,8 @@
 #include <asm/csr.h>
 #include <asm/usercfi.h>
 
+bool disable_riscv_usercfi;
+
 #define SHSTK_ENTRY_SIZE sizeof(void *)
 
 bool is_shstk_enabled(struct task_struct *task)
@@ -393,6 +395,9 @@ int arch_set_shadow_stack_status(struct task_struct *t, unsigned long status)
 	unsigned long size = 0, addr = 0;
 	bool enable_shstk = false;
 
+	if (disable_riscv_usercfi)
+		return 0;
+
 	if (!cpu_supports_shadow_stack())
 		return -EINVAL;
 
@@ -472,6 +477,9 @@ int arch_set_indir_br_lp_status(struct task_struct *t, unsigned long status)
 {
 	bool enable_indir_lp = false;
 
+	if (disable_riscv_usercfi)
+		return 0;
+
 	if (!cpu_supports_indirect_br_lp_instr())
 		return -EINVAL;
 
@@ -504,3 +512,15 @@ int arch_lock_indir_br_lp_status(struct task_struct *task,
 
 	return 0;
 }
+
+static int __init setup_global_riscv_enable(char *str)
+{
+	if (strcmp(str, "true") == 0)
+		disable_riscv_usercfi = true;
+
+	pr_info("Setting riscv usercfi to be %s\n", (disable_riscv_usercfi ? "disabled" : "enabled"));
+
+	return 1;
+}
+
+__setup("disable_riscv_usercfi=", setup_global_riscv_enable);

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:11 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:11 -0800
Subject: [PATCH v8 26/29] riscv: create a config for shadow stack and
 landing pad instr support
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-26-dce14aa30207@rivosinc.com>

This patch creates a config for shadow stack support and landing pad instr
support. Shadow stack support and landing instr support can be enabled by
selecting `CONFIG_RISCV_USER_CFI`. Selecting `CONFIG_RISCV_USER_CFI` wires
up path to enumerate CPU support and if cpu support exists, kernel will
support cpu assisted user mode cfi.

If CONFIG_RISCV_USER_CFI is selected, select `ARCH_USES_HIGH_VMA_FLAGS`,
`ARCH_HAS_USER_SHADOW_STACK` and DYNAMIC_SIGFRAME for riscv.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 arch/riscv/Kconfig | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5bdda86ada37..0887a9ae0c20 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -246,6 +246,26 @@ config ARCH_HAS_BROKEN_DWARF5
 	# https://github.com/llvm/llvm-project/commit/7ffabb61a5569444b5ac9322e22e5471cc5e4a77
 	depends on LD_IS_LLD && LLD_VERSION < 180000
 
+config RISCV_USER_CFI
+	def_bool y
+	bool "riscv userspace control flow integrity"
+	depends on 64BIT && $(cc-option,-mabi=lp64 -march=rv64ima_zicfiss)
+	depends on RISCV_ALTERNATIVE
+	select ARCH_HAS_USER_SHADOW_STACK
+	select ARCH_USES_HIGH_VMA_FLAGS
+	select DYNAMIC_SIGFRAME
+	help
+	  Provides CPU assisted control flow integrity to userspace tasks.
+	  Control flow integrity is provided by implementing shadow stack for
+	  backward edge and indirect branch tracking for forward edge in program.
+	  Shadow stack protection is a hardware feature that detects function
+	  return address corruption. This helps mitigate ROP attacks.
+	  Indirect branch tracking enforces that all indirect branches must land
+	  on a landing pad instruction else CPU will fault. This mitigates against
+	  JOP / COP attacks. Applications must be enabled to use it, and old user-
+	  space does not get protection "for free".
+	  default y
+
 config ARCH_MMAP_RND_BITS_MIN
 	default 18 if 64BIT
 	default 8

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:12 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:12 -0800
Subject: [PATCH v8 27/29] riscv: Documentation for landing pad / indirect
 branch tracking
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-27-dce14aa30207@rivosinc.com>

Adding documentation on landing pad aka indirect branch tracking on riscv
and kernel interfaces exposed so that user tasks can enable it.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 Documentation/arch/riscv/index.rst   |   1 +
 Documentation/arch/riscv/zicfilp.rst | 115 +++++++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/Documentation/arch/riscv/index.rst b/Documentation/arch/riscv/index.rst
index eecf347ce849..be7237b69682 100644
--- a/Documentation/arch/riscv/index.rst
+++ b/Documentation/arch/riscv/index.rst
@@ -14,6 +14,7 @@ RISC-V architecture
     uabi
     vector
     cmodx
+    zicfilp
 
     features
 
diff --git a/Documentation/arch/riscv/zicfilp.rst b/Documentation/arch/riscv/zicfilp.rst
new file mode 100644
index 000000000000..a188d78fcde6
--- /dev/null
+++ b/Documentation/arch/riscv/zicfilp.rst
@@ -0,0 +1,115 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+:Author: Deepak Gupta <debug at rivosinc.com>
+:Date:   12 January 2024
+
+====================================================
+Tracking indirect control transfers on RISC-V Linux
+====================================================
+
+This document briefly describes the interface provided to userspace by Linux
+to enable indirect branch tracking for user mode applications on RISV-V
+
+1. Feature Overview
+--------------------
+
+Memory corruption issues usually result in to crashes, however when in hands of
+an adversary and if used creatively can result into variety security issues.
+
+One of those security issues can be code re-use attacks on program where adversary
+can use corrupt function pointers and chain them together to perform jump oriented
+programming (JOP) or call oriented programming (COP) and thus compromising control
+flow integrity (CFI) of the program.
+
+Function pointers live in read-write memory and thus are susceptible to corruption
+and allows an adversary to reach any program counter (PC) in address space. On
+RISC-V zicfilp extension enforces a restriction on such indirect control
+transfers:
+
+- indirect control transfers must land on a landing pad instruction ``lpad``.
+  There are two exception to this rule:
+
+  - rs1 = x1 or rs1 = x5, i.e. a return from a function and returns are
+    protected using shadow stack (see zicfiss.rst)
+
+  - rs1 = x7. On RISC-V compiler usually does below to reach function
+    which is beyond the offset possible J-type instruction::
+
+      auipc x7, <imm>
+      jalr (x7)
+
+	Such form of indirect control transfer are still immutable and don't rely
+    on memory and thus rs1=x7 is exempted from tracking and considered software
+    guarded jumps.
+
+``lpad`` instruction is pseudo of ``auipc rd, <imm_20bit>`` with ``rd=x0`` and
+is a HINT nop. ``lpad`` instruction must be aligned on 4 byte boundary and
+compares 20 bit immediate withx7. If ``imm_20bit`` == 0, CPU don't perform any
+comparision with ``x7``. If ``imm_20bit`` != 0, then ``imm_20bit`` must match
+``x7`` else CPU will raise ``software check exception`` (``cause=18``) with
+``*tval = 2``.
+
+Compiler can generate a hash over function signatures and setup them (truncated
+to 20bit) in x7 at callsites and function prologues can have ``lpad`` with same
+function hash. This further reduces number of program counters a call site can
+reach.
+
+2. ELF and psABI
+-----------------
+
+Toolchain sets up :c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_FCFI` for property
+:c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_AND` in notes section of the object file.
+
+3. Linux enabling
+------------------
+
+User space programs can have multiple shared objects loaded in its address space
+and it's a difficult task to make sure all the dependencies have been compiled
+with support of indirect branch. Thus it's left to dynamic loader to enable
+indirect branch tracking for the program.
+
+4. prctl() enabling
+--------------------
+
+:c:macro:`PR_SET_INDIR_BR_LP_STATUS` / :c:macro:`PR_GET_INDIR_BR_LP_STATUS` /
+:c:macro:`PR_LOCK_INDIR_BR_LP_STATUS` are three prctls added to manage indirect
+branch tracking. prctls are arch agnostic and returns -EINVAL on other arches.
+
+* prctl(PR_SET_INDIR_BR_LP_STATUS, unsigned long arg)
+
+If arg1 is :c:macro:`PR_INDIR_BR_LP_ENABLE` and if CPU supports ``zicfilp``
+then kernel will enabled indirect branch tracking for the task. Dynamic loader
+can issue this :c:macro:`prctl` once it has determined that all the objects
+loaded in address space support indirect branch tracking. Additionally if there
+is a `dlopen` to an object which wasn't compiled with ``zicfilp``, dynamic
+loader can issue this prctl with arg1 set to 0 (i.e.
+:c:macro:`PR_INDIR_BR_LP_ENABLE` being clear)
+
+* prctl(PR_GET_INDIR_BR_LP_STATUS, unsigned long arg)
+
+Returns current status of indirect branch tracking. If enabled it'll return
+:c:macro:`PR_INDIR_BR_LP_ENABLE`
+
+* prctl(PR_LOCK_INDIR_BR_LP_STATUS, unsigned long arg)
+
+Locks current status of indirect branch tracking on the task. User space may
+want to run with strict security posture and wouldn't want loading of objects
+without ``zicfilp`` support in it and thus would want to disallow disabling of
+indirect branch tracking. In that case user space can use this prctl to lock
+current settings.
+
+5. violations related to indirect branch tracking
+--------------------------------------------------
+
+Pertaining to indirect branch tracking, CPU raises software check exception in
+following conditions:
+
+- missing ``lpad`` after indirect call / jmp
+- ``lpad`` not on 4 byte boundary
+- ``imm_20bit`` embedded in ``lpad`` instruction doesn't match with ``x7``
+
+In all 3 cases, ``*tval = 2`` is captured and software check exception is
+raised (``cause=18``)
+
+Linux kernel will treat this as :c:macro:`SIGSEV`` with code =
+:c:macro:`SEGV_CPERR` and follow normal course of signal delivery.

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:13 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:13 -0800
Subject: [PATCH v8 28/29] riscv: Documentation for shadow stack on riscv
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-28-dce14aa30207@rivosinc.com>

Adding documentation on shadow stack for user mode on riscv and kernel
interfaces exposed so that user tasks can enable it.

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 Documentation/arch/riscv/index.rst   |   1 +
 Documentation/arch/riscv/zicfiss.rst | 176 +++++++++++++++++++++++++++++++++++
 2 files changed, 177 insertions(+)

diff --git a/Documentation/arch/riscv/index.rst b/Documentation/arch/riscv/index.rst
index be7237b69682..e240eb0ceb70 100644
--- a/Documentation/arch/riscv/index.rst
+++ b/Documentation/arch/riscv/index.rst
@@ -15,6 +15,7 @@ RISC-V architecture
     vector
     cmodx
     zicfilp
+    zicfiss
 
     features
 
diff --git a/Documentation/arch/riscv/zicfiss.rst b/Documentation/arch/riscv/zicfiss.rst
new file mode 100644
index 000000000000..5ba389f15b3f
--- /dev/null
+++ b/Documentation/arch/riscv/zicfiss.rst
@@ -0,0 +1,176 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+:Author: Deepak Gupta <debug at rivosinc.com>
+:Date:   12 January 2024
+
+=========================================================
+Shadow stack to protect function returns on RISC-V Linux
+=========================================================
+
+This document briefly describes the interface provided to userspace by Linux
+to enable shadow stack for user mode applications on RISV-V
+
+1. Feature Overview
+--------------------
+
+Memory corruption issues usually result in to crashes, however when in hands of
+an adversary and if used creatively can result into variety security issues.
+
+One of those security issues can be code re-use attacks on program where
+adversary can use corrupt return addresses present on stack and chain them
+together to perform return oriented programming (ROP) and thus compromising
+control flow integrity (CFI) of the program.
+
+Return addresses live on stack and thus in read-write memory and thus are
+susceptible to corruption and allows an adversary to reach any program counter
+(PC) in address space. On RISC-V ``zicfiss`` extension provides an alternate
+stack termed as shadow stack on which return addresses can be safely placed in
+prolog of the function and retrieved in epilog. ``zicfiss`` extension makes
+following changes:
+
+- PTE encodings for shadow stack virtual memory
+  An earlier reserved encoding in first stage translation i.e.
+  PTE.R=0, PTE.W=1, PTE.X=0  becomes PTE encoding for shadow stack pages.
+
+- ``sspush x1/x5`` instruction pushes (stores) ``x1/x5`` to shadow stack.
+
+- ``sspopchk x1/x5`` instruction pops (loads) from shadow stack and compares
+  with ``x1/x5`` and if un-equal, CPU raises ``software check exception`` with
+  ``*tval = 3``
+
+Compiler toolchain makes sure that function prologue have ``sspush x1/x5`` to
+save return address on shadow stack in addition to regular stack. Similarly
+function epilogs have ``ld x5, offset(x2)`` followed by ``sspopchk x5`` to
+ensure that popped value from regular stack matches with popped value from
+shadow stack.
+
+2. Shadow stack protections and linux memory manager
+-----------------------------------------------------
+
+As mentioned earlier, shadow stack get new page table encodings and thus have
+some special properties assigned to them and instructions that operate on them
+as below:
+
+- Regular stores to shadow stack memory raises access store faults. This way
+  shadow stack memory is protected from stray inadvertant writes.
+
+- Regular loads to shadow stack memory are allowed. This allows stack trace
+  utilities or backtrace functions to read true callstack (not tampered).
+
+- Only shadow stack instructions can generate shadow stack load or shadow stack
+  store.
+
+- Shadow stack load / shadow stack store on read-only memory raises AMO/store
+  page fault. Thus both ``sspush x1/x5`` and ``sspopchk x1/x5`` will raise AMO/
+  store page fault. This simplies COW handling in kernel During fork, kernel
+  can convert shadow stack pages into read-only memory (as it does for regular
+  read-write memory) and as soon as subsequent ``sspush`` or ``sspopchk`` in
+  userspace is encountered, then kernel can perform COW.
+
+- Shadow stack load / shadow stack store on read-write, read-write-execute
+  memory raises an access fault. This is a fatal condition because shadow stack
+  should never be operating on read-write, read-write-execute memory.
+
+3. ELF and psABI
+-----------------
+
+Toolchain sets up :c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_BCFI` for property
+:c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_AND` in notes section of the object file.
+
+4. Linux enabling
+------------------
+
+User space programs can have multiple shared objects loaded in its address space
+and it's a difficult task to make sure all the dependencies have been compiled
+with support of shadow stack. Thus it's left to dynamic loader to enable
+shadow stack for the program.
+
+5. prctl() enabling
+--------------------
+
+:c:macro:`PR_SET_SHADOW_STACK_STATUS` / :c:macro:`PR_GET_SHADOW_STACK_STATUS` /
+:c:macro:`PR_LOCK_SHADOW_STACK_STATUS` are three prctls added to manage shadow
+stack enabling for tasks. prctls are arch agnostic and returns -EINVAL on other
+arches.
+
+* prctl(PR_SET_SHADOW_STACK_STATUS, unsigned long arg)
+
+If arg1 :c:macro:`PR_SHADOW_STACK_ENABLE` and if CPU supports ``zicfiss`` then
+kernel will enable shadow stack for the task. Dynamic loader can issue this
+:c:macro:`prctl` once it has determined that all the objects loaded in address
+space have support for shadow stack. Additionally if there is a
+:c:macro:`dlopen` to an object which wasn't compiled with ``zicfiss``, dynamic
+loader can issue this prctl with arg1 set to 0 (i.e.
+:c:macro:`PR_SHADOW_STACK_ENABLE` being clear)
+
+* prctl(PR_GET_SHADOW_STACK_STATUS, unsigned long *arg)
+
+Returns current status of indirect branch tracking. If enabled it'll return
+:c:macro:`PR_SHADOW_STACK_ENABLE`.
+
+* prctl(PR_LOCK_SHADOW_STACK_STATUS, unsigned long arg)
+
+Locks current status of shadow stack enabling on the task. User space may want
+to run with strict security posture and wouldn't want loading of objects
+without ``zicfiss`` support in it and thus would want to disallow disabling of
+shadow stack on current task. In that case user space can use this prctl to
+lock current settings.
+
+5. violations related to returns with shadow stack enabled
+-----------------------------------------------------------
+
+Pertaining to shadow stack, CPU raises software check exception in following
+condition:
+
+- On execution of ``sspopchk x1/x5``, ``x1/x5`` didn't match top of shadow
+  stack. If mismatch happens then cpu does ``*tval = 3`` and raise software
+  check exception.
+
+Linux kernel will treat this as :c:macro:`SIGSEV`` with code =
+:c:macro:`SEGV_CPERR` and follow normal course of signal delivery.
+
+6. Shadow stack tokens
+-----------------------
+Regular stores on shadow stacks are not allowed and thus can't be tampered
+with via arbitrary stray writes due to bugs. Method of pivoting / switching to
+shadow stack is simply writing to csr ``CSR_SSP`` changes active shadow stack.
+This can be problematic because usually value to be written to ``CSR_SSP`` will
+be loaded somewhere in writeable memory and thus allows an adversary to
+corruption bug in software to pivot to an any address in shadow stack range.
+Shadow stack tokens can help mitigate this problem by making sure that:
+
+- When software is switching away from a shadow stack, shadow stack pointer
+  should be saved on shadow stack itself and call it ``shadow stack token``
+
+- When software is switching to a shadow stack, it should read the
+  ``shadow stack token`` from shadow stack pointer and verify that
+  ``shadow stack token`` itself is pointer to shadow stack itself.
+
+- Once the token verification is done, software can perform the write to
+  ``CSR_SSP`` to switch shadow stack.
+
+Here software can be user mode task runtime itself which is managing various
+contexts as part of single thread. Software can be kernel as well when kernel
+has to deliver a signal to user task and must save shadow stack pointer. Kernel
+can perform similar procedure by saving a token on user shadow stack itself.
+This way whenever :c:macro:`sigreturn` happens, kernel can read the token and
+verify the token and then switch to shadow stack. Using this mechanism, kernel
+helps user task so that any corruption issue in user task is not exploited by
+adversary by arbitrarily using :c:macro:`sigreturn`. Adversary will have to
+make sure that there is a ``shadow stack token`` in addition to invoking
+:c:macro:`sigreturn`
+
+7. Signal shadow stack
+-----------------------
+Following structure has been added to sigcontext for RISC-V::
+
+    struct __sc_riscv_cfi_state {
+        unsigned long ss_ptr;
+    };
+
+As part of signal delivery, shadow stack token is saved on current shadow stack
+itself and updated pointer is saved away in :c:macro:`ss_ptr` field in
+:c:macro:`__sc_riscv_cfi_state` under :c:macro:`sigcontext`. Existing shadow
+stack allocation is used for signal delivery. During :c:macro:`sigreturn`,
+kernel will obtain :c:macro:`ss_ptr` from :c:macro:`sigcontext` and verify the
+saved token on shadow stack itself and switch shadow stack.

-- 
2.45.0



From debug at rivosinc.com  Mon Nov 11 12:54:14 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 11 Nov 2024 12:54:14 -0800
Subject: [PATCH v8 29/29] kselftest/riscv: kselftest for user mode cfi
In-Reply-To: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
Message-ID: <20241111-v5_user_cfi_series-v8-29-dce14aa30207@rivosinc.com>

Adds kselftest for RISC-V control flow integrity implementation for user
mode. There is not a lot going on in kernel for enabling landing pad for
user mode. cfi selftest are intended to be compiled with zicfilp and
zicfiss enabled compiler. Thus kselftest simply checks if landing pad and
shadow stack for the binary and process are enabled or not. selftest then
register a signal handler for SIGSEGV. Any control flow violation are
reported as SIGSEGV with si_code = SEGV_CPERR. Test will fail on receiving
any SEGV_CPERR. Shadow stack part has more changes in kernel and thus there
are separate tests for that

- Exercise `map_shadow_stack` syscall
- `fork` test to make sure COW works for shadow stack pages
- gup tests
  Kernel uses FOLL_FORCE when access happens to memory via
  /proc/<pid>/mem. Not breaking that for shadow stack.
- signal test. Make sure signal delivery results in token creation on
  shadow stack and consumes (and verifies) token on sigreturn
- shadow stack protection test. attempts to write using regular store
  instruction on shadow stack memory must result in access faults

Test outut
==========

"""
TAP version 13
1..5
  This is to ensure shadow stack is indeed enabled and working
  This is to ensure shadow stack is indeed enabled and working
ok 1 shstk fork test
ok 2 map shadow stack syscall
ok 3 shadow stack gup tests
ok 4 shadow stack signal tests
ok 5 memory protections of shadow stack memory
"""

Signed-off-by: Deepak Gupta <debug at rivosinc.com>
---
 tools/testing/selftests/riscv/Makefile             |   2 +-
 tools/testing/selftests/riscv/cfi/.gitignore       |   3 +
 tools/testing/selftests/riscv/cfi/Makefile         |  10 +
 tools/testing/selftests/riscv/cfi/cfi_rv_test.h    |  84 +++++
 tools/testing/selftests/riscv/cfi/riscv_cfi_test.c |  78 +++++
 tools/testing/selftests/riscv/cfi/shadowstack.c    | 373 +++++++++++++++++++++
 tools/testing/selftests/riscv/cfi/shadowstack.h    |  37 ++
 7 files changed, 586 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile
index 099b8c1f46f8..5671b4405a12 100644
--- a/tools/testing/selftests/riscv/Makefile
+++ b/tools/testing/selftests/riscv/Makefile
@@ -5,7 +5,7 @@
 ARCH ?= $(shell uname -m 2>/dev/null || echo not)
 
 ifneq (,$(filter $(ARCH),riscv))
-RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector
+RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector cfi
 else
 RISCV_SUBTARGETS :=
 endif
diff --git a/tools/testing/selftests/riscv/cfi/.gitignore b/tools/testing/selftests/riscv/cfi/.gitignore
new file mode 100644
index 000000000000..82545863bac6
--- /dev/null
+++ b/tools/testing/selftests/riscv/cfi/.gitignore
@@ -0,0 +1,3 @@
+cfitests
+riscv_cfi_test
+shadowstack
diff --git a/tools/testing/selftests/riscv/cfi/Makefile b/tools/testing/selftests/riscv/cfi/Makefile
new file mode 100644
index 000000000000..b65f7ff38a32
--- /dev/null
+++ b/tools/testing/selftests/riscv/cfi/Makefile
@@ -0,0 +1,10 @@
+CFLAGS += -I$(top_srcdir)/tools/include
+
+CFLAGS += -march=rv64gc_zicfilp_zicfiss
+
+TEST_GEN_PROGS := cfitests
+
+include ../../lib.mk
+
+$(OUTPUT)/cfitests: riscv_cfi_test.c shadowstack.c
+	$(CC) -o$@ $(CFLAGS) $(LDFLAGS) $^
diff --git a/tools/testing/selftests/riscv/cfi/cfi_rv_test.h b/tools/testing/selftests/riscv/cfi/cfi_rv_test.h
new file mode 100644
index 000000000000..0fefdc33f71e
--- /dev/null
+++ b/tools/testing/selftests/riscv/cfi/cfi_rv_test.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef SELFTEST_RISCV_CFI_H
+#define SELFTEST_RISCV_CFI_H
+#include <stddef.h>
+#include <sys/types.h>
+#include "shadowstack.h"
+
+#define RISCV_CFI_SELFTEST_COUNT RISCV_SHADOW_STACK_TESTS
+
+#define CHILD_EXIT_CODE_SSWRITE		10
+#define CHILD_EXIT_CODE_SIG_TEST	11
+
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)			\
+({									\
+	register long _num  __asm__ ("a7") = (num);			\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);		\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);		\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);		\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);		\
+	register long _arg5 __asm__ ("a4") = (long)(arg5);		\
+									\
+	__asm__ volatile(						\
+		"ecall\n"						\
+		: "+r"							\
+		(_arg1)							\
+		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),	\
+		  "r"(_num)						\
+		: "memory", "cc"					\
+	);								\
+	_arg1;								\
+})
+
+#define my_syscall3(num, arg1, arg2, arg3)				\
+({									\
+	register long _num  __asm__ ("a7") = (num);			\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);		\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);		\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);		\
+									\
+	__asm__ volatile(						\
+		"ecall\n"						\
+		: "+r" (_arg1)						\
+		: "r"(_arg2), "r"(_arg3),				\
+		  "r"(_num)						\
+		: "memory", "cc"					\
+	);								\
+	_arg1;								\
+})
+
+#ifndef __NR_prctl
+#define __NR_prctl 167
+#endif
+
+#ifndef __NR_map_shadow_stack
+#define __NR_map_shadow_stack 453
+#endif
+
+#define CSR_SSP 0x011
+
+#ifdef __ASSEMBLY__
+#define __ASM_STR(x)    x
+#else
+#define __ASM_STR(x)    #x
+#endif
+
+#define csr_read(csr)							\
+({									\
+	register unsigned long __v;					\
+	__asm__ __volatile__ ("csrr %0, " __ASM_STR(csr)		\
+				: "=r" (__v) :				\
+				: "memory");				\
+	__v;								\
+})
+
+#define csr_write(csr, val)						\
+({									\
+	unsigned long __v = (unsigned long) (val);			\
+	__asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0"		\
+				: : "rK" (__v)				\
+				: "memory");				\
+})
+
+#endif
diff --git a/tools/testing/selftests/riscv/cfi/riscv_cfi_test.c b/tools/testing/selftests/riscv/cfi/riscv_cfi_test.c
new file mode 100644
index 000000000000..7f04a935f79f
--- /dev/null
+++ b/tools/testing/selftests/riscv/cfi/riscv_cfi_test.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "../../kselftest.h"
+#include <sys/signal.h>
+#include <asm/ucontext.h>
+#include <linux/prctl.h>
+#include "cfi_rv_test.h"
+
+/* do not optimize cfi related test functions */
+#pragma GCC push_options
+#pragma GCC optimize("O0")
+
+void sigsegv_handler(int signum, siginfo_t *si, void *uc)
+{
+	struct ucontext *ctx = (struct ucontext *) uc;
+
+	if (si->si_code == SEGV_CPERR) {
+		ksft_print_msg("Control flow violation happened somewhere\n");
+		ksft_print_msg("PC where violation happened %lx\n", ctx->uc_mcontext.gregs[0]);
+		exit(-1);
+	}
+
+	/* all other cases are expected to be of shadow stack write case */
+	exit(CHILD_EXIT_CODE_SSWRITE);
+}
+
+bool register_signal_handler(void)
+{
+	struct sigaction sa = {};
+
+	sa.sa_sigaction = sigsegv_handler;
+	sa.sa_flags = SA_SIGINFO;
+	if (sigaction(SIGSEGV, &sa, NULL)) {
+		ksft_print_msg("Registering signal handler for landing pad violation failed\n");
+		return false;
+	}
+
+	return true;
+}
+
+int main(int argc, char *argv[])
+{
+	int ret = 0;
+	unsigned long lpad_status = 0, ss_status = 0;
+
+	ksft_print_header();
+
+	ksft_print_msg("Starting risc-v tests\n");
+
+	/*
+	 * Landing pad test. Not a lot of kernel changes to support landing
+	 * pad for user mode except lighting up a bit in senvcfg via a prctl
+	 * Enable landing pad through out the execution of test binary
+	 */
+	ret = my_syscall5(__NR_prctl, PR_GET_INDIR_BR_LP_STATUS, &lpad_status, 0, 0, 0);
+	if (ret)
+		ksft_exit_fail_msg("Get landing pad status failed with %d\n", ret);
+
+	if (!(lpad_status & PR_INDIR_BR_LP_ENABLE))
+		ksft_exit_fail_msg("Landing pad is not enabled, should be enabled via glibc\n");
+
+	ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &ss_status, 0, 0, 0);
+	if (ret)
+		ksft_exit_fail_msg("Get shadow stack failed with %d\n", ret);
+
+	if (!(ss_status & PR_SHADOW_STACK_ENABLE))
+		ksft_exit_fail_msg("Shadow stack is not enabled, should be enabled via glibc\n");
+
+	if (!register_signal_handler())
+		ksft_exit_fail_msg("Registering signal handler for SIGSEGV failed\n");
+
+	ksft_print_msg("Landing pad and shadow stack are enabled for binary\n");
+	execute_shadow_stack_tests();
+
+	return 0;
+}
+
+#pragma GCC pop_options
diff --git a/tools/testing/selftests/riscv/cfi/shadowstack.c b/tools/testing/selftests/riscv/cfi/shadowstack.c
new file mode 100644
index 000000000000..9d5301914578
--- /dev/null
+++ b/tools/testing/selftests/riscv/cfi/shadowstack.c
@@ -0,0 +1,373 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "../../kselftest.h"
+#include <sys/wait.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <asm-generic/unistd.h>
+#include <sys/mman.h>
+#include "shadowstack.h"
+#include "cfi_rv_test.h"
+
+/* do not optimize shadow stack related test functions */
+#pragma GCC push_options
+#pragma GCC optimize("O0")
+
+void zar(void)
+{
+	unsigned long ssp = 0;
+
+	ssp = csr_read(CSR_SSP);
+	ksft_print_msg("Spewing out shadow stack ptr: %lx\n"
+			"  This is to ensure shadow stack is indeed enabled and working\n",
+			ssp);
+}
+
+void bar(void)
+{
+	zar();
+}
+
+void foo(void)
+{
+	bar();
+}
+
+void zar_child(void)
+{
+	unsigned long ssp = 0;
+
+	ssp = csr_read(CSR_SSP);
+	ksft_print_msg("Spewing out shadow stack ptr: %lx\n"
+			"  This is to ensure shadow stack is indeed enabled and working\n",
+			ssp);
+}
+
+void bar_child(void)
+{
+	zar_child();
+}
+
+void foo_child(void)
+{
+	bar_child();
+}
+
+typedef void (call_func_ptr)(void);
+/*
+ * call couple of functions to test push pop.
+ */
+int shadow_stack_call_tests(call_func_ptr fn_ptr, bool parent)
+{
+	ksft_print_msg("Exercising dummy calls for sspush and sspopchk in"
+			" context of %s\n", parent ? "parent" : "child");
+
+	(fn_ptr)();
+
+	return 0;
+}
+
+/* forks a thread, and ensure shadow stacks fork out */
+bool shadow_stack_fork_test(unsigned long test_num, void *ctx)
+{
+	int pid = 0, child_status = 0, parent_pid = 0, ret = 0;
+	unsigned long ss_status = 0;
+
+	ksft_print_msg("Exercising shadow stack fork test\n");
+
+	ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &ss_status, 0, 0, 0);
+	if (ret) {
+		ksft_exit_skip("Shadow stack get status prctl failed with errorcode %d\n", ret);
+		return false;
+	}
+
+	if (!(ss_status & PR_SHADOW_STACK_ENABLE))
+		ksft_exit_skip("Shadow stack is not enabled, should be enabled via glibc\n");
+
+	parent_pid = getpid();
+	pid = fork();
+
+	if (pid) {
+		ksft_print_msg("Parent pid %d and child pid %d\n", parent_pid, pid);
+		shadow_stack_call_tests(&foo, true);
+	} else
+		shadow_stack_call_tests(&foo_child, false);
+
+	if (pid) {
+		ksft_print_msg("Waiting on child to finish\n");
+		wait(&child_status);
+	} else {
+		/* exit child gracefully */
+		exit(0);
+	}
+
+	if (pid && WIFSIGNALED(child_status)) {
+		ksft_print_msg("Child faulted, fork test failed\n");
+		return false;
+	}
+
+	return true;
+}
+
+/* exercise `map_shadow_stack`, pivot to it and call some functions to ensure it works */
+#define SHADOW_STACK_ALLOC_SIZE 4096
+bool shadow_stack_map_test(unsigned long test_num, void *ctx)
+{
+	unsigned long shdw_addr;
+	int ret = 0;
+
+	ksft_print_msg("Exercising shadow stack map test\n");
+
+	shdw_addr = my_syscall3(__NR_map_shadow_stack, NULL, SHADOW_STACK_ALLOC_SIZE, 0);
+
+	if (((long) shdw_addr) <= 0) {
+		ksft_print_msg("map_shadow_stack failed with error code %d\n", (int) shdw_addr);
+		return false;
+	}
+
+	ret = munmap((void *) shdw_addr, SHADOW_STACK_ALLOC_SIZE);
+
+	if (ret) {
+		ksft_print_msg("munmap failed with error code %d\n", ret);
+		return false;
+	}
+
+	return true;
+}
+
+/*
+ * shadow stack protection tests. map a shadow stack and
+ * validate all memory protections work on it
+ */
+bool shadow_stack_protection_test(unsigned long test_num, void *ctx)
+{
+	unsigned long shdw_addr;
+	unsigned long *write_addr = NULL;
+	int ret = 0, pid = 0, child_status = 0;
+
+	ksft_print_msg("Exercising shadow stack protection test\n");
+
+	shdw_addr = my_syscall3(__NR_map_shadow_stack, NULL, SHADOW_STACK_ALLOC_SIZE, 0);
+
+	if (((long) shdw_addr) <= 0) {
+		ksft_print_msg("map_shadow_stack failed with error code %d\n", (int) shdw_addr);
+		return false;
+	}
+
+	write_addr = (unsigned long *) shdw_addr;
+	pid = fork();
+
+	/* no child was created, return false */
+	if (pid == -1)
+		return false;
+
+	/*
+	 * try to perform a store from child on shadow stack memory
+	 * it should result in SIGSEGV
+	 */
+	if (!pid) {
+		/* below write must lead to SIGSEGV */
+		*write_addr = 0xdeadbeef;
+	} else {
+		wait(&child_status);
+	}
+
+	/* test fail, if 0xdeadbeef present on shadow stack address */
+	if (*write_addr == 0xdeadbeef) {
+		ksft_print_msg("Write suceeded on shadow stack memory, shadow stack protection test"
+		" failed\n");
+		return false;
+	}
+
+	/* if child reached here, then fail */
+	if (!pid) {
+		ksft_print_msg("Shadow stack protection test: child reached unreachable state\n");
+		return false;
+	}
+
+	/* if child exited via signal handler but not for write on ss */
+	if (WIFEXITED(child_status) &&
+		WEXITSTATUS(child_status) != CHILD_EXIT_CODE_SSWRITE) {
+		ksft_print_msg("Shadow stack protection test: child wasn't signaled for write on"
+		" shadow stack\n");
+		return false;
+	}
+
+	ret = munmap(write_addr, SHADOW_STACK_ALLOC_SIZE);
+	if (ret) {
+		ksft_print_msg("Shadow stack protection test: munmap failed with error code %d\n",
+		ret);
+		return false;
+	}
+
+	return true;
+}
+
+#define SS_MAGIC_WRITE_VAL 0xbeefdead
+
+int gup_tests(int mem_fd, unsigned long *shdw_addr)
+{
+	unsigned long val = 0;
+
+	lseek(mem_fd, (unsigned long)shdw_addr, SEEK_SET);
+	if (read(mem_fd, &val, sizeof(val)) < 0) {
+		ksft_print_msg("Reading shadow stack mem via gup failed\n");
+		return 1;
+	}
+
+	val = SS_MAGIC_WRITE_VAL;
+	lseek(mem_fd, (unsigned long)shdw_addr, SEEK_SET);
+	if (write(mem_fd, &val, sizeof(val)) < 0) {
+		ksft_print_msg("Writing shadow stack mem via gup failed\n");
+		return 1;
+	}
+
+	if (*shdw_addr != SS_MAGIC_WRITE_VAL) {
+		ksft_print_msg("GUP write to shadow stack memory failed\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+bool shadow_stack_gup_tests(unsigned long test_num, void *ctx)
+{
+	unsigned long shdw_addr = 0;
+	unsigned long *write_addr = NULL;
+	int fd = 0;
+	bool ret = false;
+
+	ksft_print_msg("Exercising shadow stack gup tests\n");
+	shdw_addr = my_syscall3(__NR_map_shadow_stack, NULL, SHADOW_STACK_ALLOC_SIZE, 0);
+
+	if (((long) shdw_addr) <= 0) {
+		ksft_print_msg("map_shadow_stack failed with error code %d\n", (int) shdw_addr);
+		return false;
+	}
+
+	write_addr = (unsigned long *) shdw_addr;
+
+	fd = open("/proc/self/mem", O_RDWR);
+	if (fd == -1)
+		return false;
+
+	if (gup_tests(fd, write_addr)) {
+		ksft_print_msg("gup tests failed\n");
+		goto out;
+	}
+
+	ret = true;
+out:
+	if (shdw_addr && munmap(write_addr, SHADOW_STACK_ALLOC_SIZE)) {
+		ksft_print_msg("munmap failed with error code %d\n", ret);
+		ret = false;
+	}
+
+	return ret;
+}
+
+volatile bool break_loop;
+
+void sigusr1_handler(int signo)
+{
+	break_loop = true;
+}
+
+bool sigusr1_signal_test(void)
+{
+	struct sigaction sa = {};
+
+	sa.sa_handler = sigusr1_handler;
+	sa.sa_flags = 0;
+	sigemptyset(&sa.sa_mask);
+	if (sigaction(SIGUSR1, &sa, NULL)) {
+		ksft_print_msg("Registering signal handler for SIGUSR1 failed\n");
+		return false;
+	}
+
+	return true;
+}
+/*
+ * shadow stack signal test. shadow stack must be enabled.
+ * register a signal, fork another thread which is waiting
+ * on signal. Send a signal from parent to child, verify
+ * that signal was received by child. If not test fails
+ */
+bool shadow_stack_signal_test(unsigned long test_num, void *ctx)
+{
+	int pid = 0, child_status = 0, ret = 0;
+	unsigned long ss_status = 0;
+
+	ksft_print_msg("Exercising shadow stack signal test\n");
+
+	ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &ss_status, 0, 0, 0);
+	if (ret) {
+		ksft_print_msg("Shadow stack get status prctl failed with errorcode %d\n", ret);
+		return false;
+	}
+
+	if (!(ss_status & PR_SHADOW_STACK_ENABLE))
+		ksft_print_msg("Shadow stack is not enabled, should be enabled via glibc\n");
+
+	/* this should be caught by signal handler and do an exit */
+	if (!sigusr1_signal_test()) {
+		ksft_print_msg("Registering sigusr1 handler failed\n");
+		exit(-1);
+	}
+
+	pid = fork();
+
+	if (pid == -1) {
+		ksft_print_msg("Signal test: fork failed\n");
+		goto out;
+	}
+
+	if (pid == 0) {
+		while (!break_loop)
+			sleep(1);
+
+		exit(11);
+		/* child shouldn't go beyond here */
+	}
+
+	/* send SIGUSR1 to child */
+	kill(pid, SIGUSR1);
+	wait(&child_status);
+
+out:
+
+	return (WIFEXITED(child_status) &&
+			WEXITSTATUS(child_status) == 11);
+}
+
+int execute_shadow_stack_tests(void)
+{
+	int ret = 0;
+	unsigned long test_count = 0;
+	unsigned long shstk_status = 0;
+	bool test_pass = false;
+
+	ksft_print_msg("Executing RISC-V shadow stack self tests\n");
+	ksft_set_plan(RISCV_SHADOW_STACK_TESTS);
+
+	ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, &shstk_status, 0, 0, 0);
+
+	if (ret != 0)
+		ksft_exit_fail_msg("Get shadow stack status failed with %d\n", ret);
+
+	/*
+	 * If we are here that means get shadow stack status succeeded and
+	 * thus shadow stack support is baked in the kernel.
+	 */
+	while (test_count < ARRAY_SIZE(shstk_tests)) {
+		test_pass = (*shstk_tests[test_count].t_func)(test_count, NULL);
+		ksft_test_result(test_pass, shstk_tests[test_count].name);
+		test_count++;
+	}
+
+	ksft_finished();
+
+	return 0;
+}
+
+#pragma GCC pop_options
diff --git a/tools/testing/selftests/riscv/cfi/shadowstack.h b/tools/testing/selftests/riscv/cfi/shadowstack.h
new file mode 100644
index 000000000000..b43e74136a26
--- /dev/null
+++ b/tools/testing/selftests/riscv/cfi/shadowstack.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef SELFTEST_SHADOWSTACK_TEST_H
+#define SELFTEST_SHADOWSTACK_TEST_H
+#include <stddef.h>
+#include <linux/prctl.h>
+
+/*
+ * a cfi test returns true for success or false for fail
+ * takes a number for test number to index into array and void pointer.
+ */
+typedef bool (*shstk_test_func)(unsigned long test_num, void *);
+
+struct shadow_stack_tests {
+	char *name;
+	shstk_test_func t_func;
+};
+
+bool shadow_stack_fork_test(unsigned long test_num, void *ctx);
+bool shadow_stack_map_test(unsigned long test_num, void *ctx);
+bool shadow_stack_protection_test(unsigned long test_num, void *ctx);
+bool shadow_stack_gup_tests(unsigned long test_num, void *ctx);
+bool shadow_stack_signal_test(unsigned long test_num, void *ctx);
+
+static struct shadow_stack_tests shstk_tests[] = {
+	{ "shstk fork test\n", shadow_stack_fork_test },
+	{ "map shadow stack syscall\n", shadow_stack_map_test },
+	{ "shadow stack gup tests\n", shadow_stack_gup_tests },
+	{ "shadow stack signal tests\n", shadow_stack_signal_test},
+	{ "memory protections of shadow stack memory\n", shadow_stack_protection_test }
+};
+
+#define RISCV_SHADOW_STACK_TESTS ARRAY_SIZE(shstk_tests)
+
+int execute_shadow_stack_tests(void);
+
+#endif

-- 
2.45.0



From robh at kernel.org  Mon Nov 11 13:52:20 2024
From: robh at kernel.org (Rob Herring)
Date: Mon, 11 Nov 2024 15:52:20 -0600
Subject: [PATCH v3 2/4] riscv: export __cpuid_to_hartid_map
In-Reply-To: <20241105183513.1358736-3-valentina.fernandezalanis@microchip.com>
References: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
 <20241105183513.1358736-3-valentina.fernandezalanis@microchip.com>
Message-ID: <20241111215220.GA1993016-robh@kernel.org>

On Tue, Nov 05, 2024 at 06:35:11PM +0000, Valentina Fernandez wrote:
> EXPORT_SYMBOL_GPL() is missing for __cpuid_to_hartid_map array.
> Export this symbol to allow drivers compiled as modules to use
> cpuid_to_hartid_map().
> 
> Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
> ---
>  arch/riscv/kernel/smp.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
> index c180a647a30e..d58b5e751286 100644
> --- a/arch/riscv/kernel/smp.c
> +++ b/arch/riscv/kernel/smp.c
> @@ -43,6 +43,7 @@ enum ipi_message_type {
>  unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = {
>  	[0 ... NR_CPUS-1] = INVALID_HARTID
>  };
> +EXPORT_SYMBOL_GPL(__cpuid_to_hartid_map);

Why can't riscv implement cpu_logical_map() like other arches?

We really should have a common implementation too, but that's probably 
too much to ask I guess.

Rob



From atishp at rivosinc.com  Mon Nov 11 15:23:18 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Mon, 11 Nov 2024 15:23:18 -0800
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is provided
In-Reply-To: <20241026121758.143259-1-irogers@google.com>
References: <20241026121758.143259-1-irogers@google.com>
Message-ID: <CAHBxVyF5c4CW7kdPoBENv7o7mObo=yaHdf7peATY+Jq6Aug=Bw@mail.gmail.com>

On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
>
> At the RISC-V summit the topic of avoiding event data being in the
> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
> events being the priority when no PMU is provided so that legacy
> events maybe supported via json. Originally Mark Rutland also
> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
> M? processors, but James Clark more recently tested this and believes
> the driver issues there may not have existed or have been resolved. In
> any case, it is inconsistent that with a PMU event names avoid legacy
> encodings, but when wildcarding PMUs (ie without a PMU with the event
> name) the legacy encodings have priority.
>
> The patch doing this work was reverted in a v6.10 release candidate
> as, even though the patch was posted for weeks and had been on
> linux-next for weeks without issue, Linus was in the habit of using
> explicit legacy events with unsupported precision options on his
> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
> where ARM decided to call the events bus_cycles and cycles, the latter
> being also a legacy event name. ARM haven't renamed the cycles event
> to a more consistent cpu_cycles and avoided the problem. With these
> changes the problematic event will now be skipped, a large warning
> produced, and perf record will continue for the other PMU events. This
> solution was proposed by Arnaldo.
>
> Two minor changes have been added to help with the error message and
> to work around issues occurring with "perf stat metrics (shadow stat)
> test".
>
> The patches have only been tested on my x86 non-hybrid laptop.
>
> Ian Rogers (4):
>   perf evsel: Add pmu_name helper
>   perf stat: Fix find_stat for mixed legacy/non-legacy events
>   perf record: Skip don't fail for events that don't open
>   perf parse-events: Reapply "Prefer sysfs/JSON hardware events over
>     legacy"
>
>  tools/perf/builtin-record.c    | 22 +++++++---
>  tools/perf/util/evsel.c        | 10 +++++
>  tools/perf/util/evsel.h        |  1 +
>  tools/perf/util/parse-events.c | 26 +++++++++---
>  tools/perf/util/parse-events.l | 76 +++++++++++++++++-----------------
>  tools/perf/util/parse-events.y | 60 ++++++++++++++++++---------
>  tools/perf/util/pmus.c         | 20 +++++++--
>  tools/perf/util/stat-shadow.c  |  3 +-
>  8 files changed, 145 insertions(+), 73 deletions(-)
>

Thanks for the series. Tested on RISC-V qemu with counter delegation enabled.
I am able to get the event encodings specified in the json file
instead of legacy event encodings.

--------------------------------
root at debian:~/host# ./perf stat -e cycles -e instructions -vvv ls
Control descriptor is not initialized
Opening: cycles
------------------------------------------------------------
perf_event_attr:
  type                             4 (cpu)
  size                             136
  config                           0x1 (cycles)
  sample_type                      IDENTIFIER
  read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
  disabled                         1
  inherit                          1
  enable_on_exec                   1
  { bp_len, config2 }              0x7f9
------------------------------------------------------------
sys_perf_event_open: pid 424  cpu -1  group_fd -1  flags 0x8 = 3
Opening: instructions
------------------------------------------------------------
perf_event_attr:
  type                             4 (cpu)
  size                             136
  config                           0x2 (instructions)
  sample_type                      IDENTIFIER
  read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
  disabled                         1
  inherit                          1
  enable_on_exec                   1
  { bp_len, config2 }              0x7fc
------------------------------------------------------------
sys_perf_event_open: pid 424  cpu -1  group_fd -1  flags 0x8 = 4
-----------------------------------------------------------------------------------

However, we may still have to provide the encodings in the driver for
vendors due to the reasons described in the
thread. Hopefully, we can get rid of legacy PMU events one day which
will allow us to remove those driver bindings in the future.

Tested-by: Atish Patra <atishp at rivosinc.com>

> --
> 2.47.0.163.g1226f6d8fa-goog
>


From atishp at rivosinc.com  Mon Nov 11 15:38:44 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Mon, 11 Nov 2024 15:38:44 -0800
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is provided
In-Reply-To: <CAP-5=fUHjxL5QbsyQQU-3EYiVhiO6wt=F5MfSfDcAffKP7WWAg@mail.gmail.com>
References: <20241026121758.143259-1-irogers@google.com> <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
 <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org> <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
 <d9bfd75a-003a-4f65-abba-b8bcaad13682@linaro.org> <CAP-5=fUHjxL5QbsyQQU-3EYiVhiO6wt=F5MfSfDcAffKP7WWAg@mail.gmail.com>
Message-ID: <CAHBxVyFVsKy+PKvyffOfOw6fU7BGa9+cm6d3uYzSG-8GY2jhxA@mail.gmail.com>

On Mon, Nov 11, 2024 at 9:19?AM Ian Rogers <irogers at google.com> wrote:
>
> On Mon, Nov 11, 2024 at 2:45?AM James Clark <james.clark at linaro.org> wrote:
> >
> >
> >
> > On 08/11/2024 6:37 pm, Atish Kumar Patra wrote:
> > > On Fri, Nov 8, 2024 at 4:16?AM James Clark <james.clark at linaro.org> wrote:
> > >>
> > >>
> > >>
> > >> On 07/11/2024 18:51, Ian Rogers wrote:
> > >>> On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
> > >>>>
> > >>>> At the RISC-V summit the topic of avoiding event data being in the
> > >>>> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
> > >>>> events being the priority when no PMU is provided so that legacy
> > >>>> events maybe supported via json. Originally Mark Rutland also
> > >>>> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
> > >>>> M? processors, but James Clark more recently tested this and believes
> > >>>> the driver issues there may not have existed or have been resolved. In
> > >>>> any case, it is inconsistent that with a PMU event names avoid legacy
> > >>>> encodings, but when wildcarding PMUs (ie without a PMU with the event
> > >>>> name) the legacy encodings have priority.
> > >>>>
> > >>>> The patch doing this work was reverted in a v6.10 release candidate
> > >>>> as, even though the patch was posted for weeks and had been on
> > >>>> linux-next for weeks without issue, Linus was in the habit of using
> > >>>> explicit legacy events with unsupported precision options on his
> > >>>> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
> > >>>> where ARM decided to call the events bus_cycles and cycles, the latter
> > >>>> being also a legacy event name. ARM haven't renamed the cycles event
> > >>>> to a more consistent cpu_cycles and avoided the problem. With these
> > >>>> changes the problematic event will now be skipped, a large warning
> > >>>> produced, and perf record will continue for the other PMU events. This
> > >>>> solution was proposed by Arnaldo.
> > >>>>
> > >>>> Two minor changes have been added to help with the error message and
> > >>>> to work around issues occurring with "perf stat metrics (shadow stat)
> > >>>> test".
> > >>>>
> > >>>> The patches have only been tested on my x86 non-hybrid laptop.
> > >>>
> > >>> Hi Atish and James,
> > >>>
> > >>> Could I get your tags for this series?
> > >>>
> > >
> > > Hi Ian,
> > > Thanks for your patches. It definitely helps to have a clean slate
> > > implementation
> > > for the perf tool. However, I have some open questions about other use cases
> > > that we discussed during the RVI Summit.
> > >
> > >>> The patches were originally motivated by wanting to make the behavior
> > >>> of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
> > >>> wildcarded to "cpu" in the first case. This was divergent because of
> > >>> ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
> > >>> config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
> > >>> type>, config=<encoding from event>) when a PMU name was given. This
> > >>> aligns with RISC-V wanting to use json encodings to avoid complexity
> > >>> in the PMU driver.
> > >>>
> > >>
> > >> I couldn't find the thread, but I remember fairly recently it was
> > >> mentioned that RISC-V would be supporting the legacy events after all,
> > >> maybe it was a comment from Atish? I'm not sure if that changes the
> > >> requirements for this or not?
> > >>
> > >> I still can't really imagine how tooling would work if every tool has to
> > >> maintain the mappings of basic events like instructions and branches.
> > >> For example all the perf_event_open tests in ltp use the legacy events.
> > >>
> > >
> > > No it has not changed. While this series helps to avoid clunky vendor
> > > specific encodings
> > > in the driver for perf tool, I am still unsure how we will manage
> > > other applications
> > > (directly passing legacy events through perf_event_open or
> > > perf_evlist__open) will work.
> > >
> > > I have only anecdotal data about folks relying perf legacy events
> > > directly to profile
> > > their application. All of them use mostly cycle/instruction events though.
> > > Are there any users who use other legacy events directly without perf tool ?
> > >
> > > If not, we may have only cycle/instruction mapping in the driver and
> > > rely on json for everything else.
> > > The other use case is virtualization. I have been playing with these
> > > patches to find a clean solution to
> > > enable all the use cases. If you have any other ideas, please let me know.
> > >
> >
> > Yeah I would expect it's mostly cycles and instructions. I searched a
> > bit for PERF_COUNT_HW_BRANCH_MISSES and only found tool/developer type
> > usages, which I suppose we could expect to have to handle the mappings
> > like perf. Although it's not the easiest thing to search for and
> > obviously that only includes open source.
> >
> > Usages do exist though, there are people posting on stack overflow using
> > it, and other various bug tracker listings. So you would expect those
> > same users to have to use raw event codes and some switch statement to
> > pick the right one for their hardware, or use Perf.
>
> I don't have any magic to solve this. My thoughts:
>
> 1) I thought legacy events were just going to hang around forever,
> although the name hinting they'd kind of been deprecated. At LPC '23
> Atish and Mark Rutland originally asked for the sysfs/json to be the
> preference. I thought Kan was going to push back given the upheaval,
> especially updating every test expectation. It went through but we're
> in this weird state where wildcard events are encoded using legacy and
> PMU specifying events aren't. What this series hopes to solve.
>
> 2) I think it is important that perf tool be a reference
> implementation where others can look (strace, etc.) to base their
> implementation. Moving perf to sysfs/json is 1 step closer to legacy
> event deprecation. Please yell if deprecation isn't what is wanted as
> personally other than cleanliness I don't mind. If we do decide not to
> have sysfs/json be the priority then I think it sensible to revert the
> changes making it the priority for events that specify a PMU. I'd like
> some level of consistency.
>
> 3) I'd like event parsing to be a library that is as easy to link
> against as libbpf (i.e. not a viral license). Event parsing is really
> just mapping an event name to 1 or more perf_event_attr. The PMU
> abstraction is tied into the event parsing, but this has only been
> more true recently. The evsel/evlist is tied into event parsing but
> that feels separable. As most json isn't distributed under a viral
> license this feels achievable, then I suspect most tools can use this
> library rather than have to reinvent a wheel.

That would be the ideal solution IMHO for any other tools.

For virtualization, the guest OS would pass the event attribute as RAW
if the matching json
file is present. The hypervisor would simply program that in mhpmevent CSR.

In absence of the json file, guest OS would pass the legacy event
encoding which must be
mapped to a vendor specific encoding present in the driver. Hopefully,
this can be removed
in the future once legacy events are deprecated.  Thoughts ?

>
> Still looking for tags :-)
>

Done. Sorry for the delay. Just wanted to ensure that this solutions
works properly
for all the above cases I mentioned.

> Thanks,
> Ian


From guoren at kernel.org  Mon Nov 11 17:49:15 2024
From: guoren at kernel.org (Guo Ren)
Date: Tue, 12 Nov 2024 09:49:15 +0800
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241111164259.GA20042@willie-the-truck>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com> <20241111164259.GA20042@willie-the-truck>
Message-ID: <CAJF2gTTuvmtmKVFMZCTMxEWHrpSpqPE8QO4MC5njPAskGEmpig@mail.gmail.com>

On Tue, Nov 12, 2024 at 12:43?AM Will Deacon <will at kernel.org> wrote:
>
> On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > In order to produce a generic kernel, a user can select
> > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > spinlock implementation if Zabha or Ziccrse are not present.
> >
> > Note that we can't use alternatives here because the discovery of
> > extensions is done too late and we need to start with the qspinlock
> > implementation because the ticket spinlock implementation would pollute
> > the spinlock value, so let's use static keys.
>
> I think the static key toggling takes a mutex (jump_label_lock()) which
> can take a spinlock (lock->wait_lock) internally, so I don't grok how
> this works:
>
> > +static void __init riscv_spinlock_init(void)
> > +{
> > +     char *using_ext = NULL;
> > +
> > +     if (IS_ENABLED(CONFIG_RISCV_TICKET_SPINLOCKS)) {
> > +             pr_info("Ticket spinlock: enabled\n");
> > +             return;
> > +     }
> > +
> > +     if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) &&
> > +         IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) &&
> > +         riscv_isa_extension_available(NULL, ZABHA) &&
> > +         riscv_isa_extension_available(NULL, ZACAS)) {
> > +             using_ext = "using Zabha";
> > +     } else if (riscv_isa_extension_available(NULL, ZICCRSE)) {
> > +             using_ext = "using Ziccrse";
> > +     }
> > +#if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
> > +     else {
> > +             static_branch_disable(&qspinlock_key);
> > +             pr_info("Ticket spinlock: enabled\n");
> > +             return;
> > +     }
> > +#endif
>
> i.e. we've potentially already used the qspinlock at this point.
Yes, I've used qspinlock here. But riscv_spinlock_init is called with
irq_disabled and smp_off. That means this qspinlock only performs a
test-set lock behavior by qspinlock fast-path.

The qspinlock is a clean implementation. After qspin_unlock, the lock
value remains at zero, but the ticket lock makes the value dirty. So
we use Qspinlock at first or change it to ticket-lock before irq & smp
up.

>
> Will



-- 
Best Regards
 Guo Ren


From ybzjyhk at gmail.com  Mon Nov 11 18:12:26 2024
From: ybzjyhk at gmail.com (h1k0n)
Date: Tue, 12 Nov 2024 10:12:26 +0800
Subject: D1 vlenb
In-Reply-To: <20240911-xtheadvector-v10-3-8d3930091246@rivosinc.com>
References: <20240911-xtheadvector-v10-3-8d3930091246@rivosinc.com>
Message-ID: <20241112021227.357-1-ybzjyhk@gmail.com>



From troymitchell988 at gmail.com  Mon Nov 11 19:07:38 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Tue, 12 Nov 2024 11:07:38 +0800
Subject: [PATCH v3 0/2] riscv: spacemit: add i2c support to K1 SoC
Message-ID: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>

Hi all,

This patch implements I2C driver for the SpacemiT K1 SoC,
providing basic support for I2C read/write communication which
compatible with standard I2C bus specifications.

In this version, the driver defaults to use fast-speed-mode and
interrupts for transmission, and does not support DMA, high-speed mode, or FIFO.

The docs of I2C can be found here, in chapter 16.1 I2C [1]

Link: https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#part5 [1]
---
Change in v3:
- Patch #1:
	- Change the maxItems of reg from 2 to 1 in properties
	- Modify reg in dts example 
	- Changed the enum selection for clock-frequency to a range,
	  setting a minimum value of 1 and a maximum value of 3,300,000.
- Patch #2:
	- Drop unused judgement in `spacemit_i2c_xfer_msg`
	- Fix the dangling else warning in `spacemit_i2c_is_last_msg`
	- Fix the error check for `i2c->base`
	- Modify Kconfig dependencies
Link to v2:
https://lore.kernel.org/all/20241028053220.346283-1-TroyMitchell988 at gmail.com/

Change in v2:
- Patch #1:
	- Change the maxItems of reg from 1 to 2 in properties
	- Change 'i2c' to 'I2C' in the commit message.
	- Drop fifo-disable property
	- Drop alias in dts example
	- Move `unevaluatedProperties` after `required:` block
- Patch #2:
	- Alphabetize Makefile and Kconfig
	- Change `.remove_new` to `.remove` in `struct platform_driver`
	- Change `dev_alert` to `dev_warn_ratelimited` in `spacemit_i2c_bus_reset`
	- Change `spacemit_i2c_read/write_reg` to `read/writel`
	- Change `spacemit_i2c_dt_match` to `spacemit_i2c_of_match`
	- Clean up code flow
	- Fix unnecessary line wraps
	- Move `spacemit_i2c_handle_err` to a suitable location
	- Modify Kconfig dependencies
	- Use `PTR_ERR(i2c->base)` directly as the `dev_err_probe` parameter instead of
	  the intermediate variable
Link to v1:
https://lore.kernel.org/all/20241015075134.1449458-1-TroyMitchell988 at gmail.com/
---

Troy Mitchell (2):
  dt-bindings: i2c: spacemit: add support for K1 SoC
  i2c: spacemit: add support for SpacemiT K1 SoC

 .../bindings/i2c/spacemit,k1-i2c.yaml         |  51 ++
 drivers/i2c/busses/Kconfig                    |  18 +
 drivers/i2c/busses/Makefile                   |   1 +
 drivers/i2c/busses/i2c-k1.c                   | 658 ++++++++++++++++++
 4 files changed, 728 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
 create mode 100644 drivers/i2c/busses/i2c-k1.c

--
2.34.1

---
Troy Mitchell (2):
      dt-bindings: i2c: spacemit: add support for K1 SoC
      i2c: spacemit: add support for SpacemiT K1 SoC

 .../devicetree/bindings/i2c/spacemit,k1-i2c.yaml   |  52 ++
 drivers/i2c/busses/Kconfig                         |  19 +
 drivers/i2c/busses/Makefile                        |   1 +
 drivers/i2c/busses/i2c-k1.c                        | 656 +++++++++++++++++++++
 4 files changed, 728 insertions(+)
---
base-commit: 8e929cb546ee42c9a61d24fae60605e9e3192354
change-id: 20241031-k1-i2c-master-fe7f7b0dce93
prerequisite-change-id: 20240626-k1-01-basic-dt-1aa31eeebcd2:v5
prerequisite-patch-id: 47dcf6861f7d434d25855b379e6d7ef4ce369c9c
prerequisite-patch-id: 77787fe82911923aff15ccf565e8fa451538c3a6
prerequisite-patch-id: b0bdb1742d96c5738f05262c3b0059102761390b
prerequisite-patch-id: 3927d39d8d77e35d5bfe53d9950da574ff8f2054
prerequisite-patch-id: a98039136a4796252a6029e474f03906f2541643
prerequisite-patch-id: c95f6dc0547a2a63a76e3cba0cf5c623b212b4e6
prerequisite-patch-id: 66e750e438ee959ddc2a6f0650814a2d8c989139
prerequisite-patch-id: 29a0fd8c36c1a4340f0d0b68a4c34d2b8abfb1ab
prerequisite-patch-id: 0bdfff661c33c380d1cf00a6c68688e05f88c0b3
prerequisite-patch-id: 99f15718e0bfbb7ed1a96dfa19f35841b004dae9

Best regards,
-- 
Troy Mitchell <TroyMitchell988 at gmail.com>



From troymitchell988 at gmail.com  Mon Nov 11 19:07:39 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Tue, 12 Nov 2024 11:07:39 +0800
Subject: [PATCH v3 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
References: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
Message-ID: <20241112-k1-i2c-master-v3-1-5005b70dc208@gmail.com>

From: Troy Mitchell <troymitchell988 at gmail.com>

The I2C of K1 supports fast-speed-mode and high-speed-mode,
and supports FIFO transmission.

Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
---
 .../devicetree/bindings/i2c/spacemit,k1-i2c.yaml   | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
new file mode 100644
index 000000000000..e8cce360bf03
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: I2C controller embedded in SpacemiT's K1 SoC
+
+maintainers:
+  - Troy Mitchell <troymitchell988 at gmail.com>
+
+properties:
+  compatible:
+    const: spacemit,k1-i2c
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-frequency:
+    description:
+      Desired I2C bus clock frequency in Hz.
+      K1 supports standard, fast, high-speed modes, from 1 to 3300000.
+    default: 100000
+    minimum: 1
+    maximum: 3300000
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c at d4010800 {
+        compatible = "spacemit,k1-i2c";
+        reg = <0xd4010800 0x38>;
+        interrupt-parent = <&plic>;
+        interrupts = <36>;
+        clocks = <&ccu 90>;
+        clock-frequency = <100000>;
+    };
+
+...

-- 
2.34.1



From troymitchell988 at gmail.com  Mon Nov 11 19:07:40 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Tue, 12 Nov 2024 11:07:40 +0800
Subject: [PATCH v3 2/2] i2c: spacemit: add support for SpacemiT K1 SoC
In-Reply-To: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
References: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
Message-ID: <20241112-k1-i2c-master-v3-2-5005b70dc208@gmail.com>

From: Troy Mitchell <troymitchell988 at gmail.com>

This patch introduces basic I2C support for the SpacemiT K1 SoC,
utilizing interrupts for transfers.

The driver has been tested using i2c-tools on a Bananapi-F3 board,
and basic I2C read/write operations have been confirmed to work.

Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
---
 drivers/i2c/busses/Kconfig  |  19 ++
 drivers/i2c/busses/Makefile |   1 +
 drivers/i2c/busses/i2c-k1.c | 656 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 676 insertions(+)

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 6b3ba7e5723a..91630f55667f 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -779,6 +779,25 @@ config I2C_JZ4780
 
 	 If you don't know what to do here, say N.
 
+config I2C_K1
+	tristate "Spacemit K1 I2C adapter"
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	depends on OF
+	help
+	  This option enables support for the I2C interface on the Spacemit K1
+	  platform.
+
+	  If you enable this configuration, the kernel will include support for
+	  the I2C adapter specific to the Spacemit K1 platform. This driver ca
+	  be used to manage I2C bus transactions, which are necessary for
+	  interfacing with I2C peripherals such as sensors, EEPROMs, and other
+	  devices.
+
+	  This driver can also be compiled as a module. If you choose to build
+	  it as a module, the resulting kernel module will be named `i2c-k1`.
+	  Loading this module will enable the I2C functionality for the K1
+	  platform dynamically, without requiring a rebuild of the kernel.
+
 config I2C_KEBA
 	tristate "KEBA I2C controller support"
 	depends on HAS_IOMEM
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index ecc07c50f2a0..9744b0e58598 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
 obj-$(CONFIG_I2C_IMX_LPI2C)	+= i2c-imx-lpi2c.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_JZ4780)	+= i2c-jz4780.o
+obj-$(CONFIG_I2C_K1)		+= i2c-k1.o
 obj-$(CONFIG_I2C_KEBA)		+= i2c-keba.o
 obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
 obj-$(CONFIG_I2C_LPC2K)		+= i2c-lpc2k.o
diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c
new file mode 100644
index 000000000000..12bb71625e0a
--- /dev/null
+++ b/drivers/i2c/busses/i2c-k1.c
@@ -0,0 +1,656 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Troy Mitchell <troymitchell988 at gmail.com>
+ */
+
+ #include <linux/clk.h>
+ #include <linux/i2c.h>
+ #include <linux/iopoll.h>
+ #include <linux/module.h>
+ #include <linux/of_address.h>
+ #include <linux/platform_device.h>
+
+/* spacemit i2c registers */
+#define ICR          0x0		/* Control Register */
+#define ISR          0x4		/* Status Register */
+#define ISAR         0x8		/* Slave Address Register */
+#define IDBR         0xc		/* Data Buffer Register */
+#define ILCR         0x10		/* Load Count Register */
+#define IWCR         0x14		/* Wait Count Register */
+#define IRST_CYC     0x18		/* Bus reset cycle counter */
+#define IBMR         0x1c		/* Bus monitor register */
+#define IWFIFO       0x20		/* Write FIFO Register */
+#define IWFIFO_WPTR  0x24		/* Write FIFO Write Pointer Register */
+#define IWFIFO_RPTR  0x28		/* Write FIFO Read Pointer Register */
+#define IRFIFO       0x2c		/* Read FIFO Register */
+#define IRFIFO_WPTR  0x30		/* Read FIFO Write Pointer Register */
+#define IRFIFO_RPTR  0x34		/* Read FIFO Read Pointer Register */
+
+/* register ICR fields */
+#define CR_START        BIT(0)		/* start bit */
+#define CR_STOP         BIT(1)		/* stop bit */
+#define CR_ACKNAK       BIT(2)		/* send ACK(0) or NAK(1) */
+#define CR_TB           BIT(3)		/* transfer byte bit */
+#define CR_TXBEGIN      BIT(4)		/* transaction begin */
+#define CR_FIFOEN       BIT(5)		/* enable FIFO mode */
+#define CR_GPIOEN       BIT(6)		/* enable GPIO mode for SCL in HS */
+#define CR_DMAEN        BIT(7)		/* enable DMA for TX and RX FIFOs */
+#define CR_MODE_FAST    BIT(8)		/* bus mode (master operation) */
+#define CR_MODE_HIGH    BIT(9)		/* bus mode (master operation) */
+#define CR_UR           BIT(10)		/* unit reset */
+#define CR_RSTREQ       BIT(11)		/* i2c bus reset request */
+#define CR_MA           BIT(12)		/* master abort */
+#define CR_SCLE         BIT(13)		/* master clock enable */
+#define CR_IUE          BIT(14)		/* unit enable */
+#define CR_HS_STRETCH   BIT(16)		/* I2C hs stretch */
+#define CR_ALDIE        BIT(18)		/* enable arbitration interrupt */
+#define CR_DTEIE        BIT(19)		/* enable tx interrupts */
+#define CR_DRFIE        BIT(20)		/* enable rx interrupts */
+#define CR_GCD          BIT(21)		/* general call disable */
+#define CR_BEIE         BIT(22)		/* enable bus error ints */
+#define CR_SADIE        BIT(23)		/* slave address detected int enable */
+#define CR_SSDIE        BIT(24)		/* slave STOP detected int enable */
+#define CR_MSDIE        BIT(25)		/* master STOP detected int enable */
+#define CR_MSDE         BIT(26)		/* master STOP detected enable */
+#define CR_TXDONEIE     BIT(27)		/* transaction done int enable */
+#define CR_TXEIE        BIT(28)		/* transmit FIFO empty int enable */
+#define CR_RXHFIE       BIT(29)		/* receive FIFO half-full int enable */
+#define CR_RXFIE        BIT(30)		/* receive FIFO full int enable */
+#define CR_RXOVIE       BIT(31)		/* receive FIFO overrun int enable */
+
+/* register ISR fields */
+#define SR_RWM          BIT(13)		/* read/write mode */
+#define SR_ACKNAK       BIT(14)		/* ACK/NACK status */
+#define SR_UB           BIT(15)		/* unit busy */
+#define SR_IBB          BIT(16)		/* i2c bus busy */
+#define SR_EBB          BIT(17)		/* early bus busy */
+#define SR_ALD          BIT(18)		/* arbitration loss detected */
+#define SR_ITE          BIT(19)		/* tx buffer empty */
+#define SR_IRF          BIT(20)		/* rx buffer full */
+#define SR_GCAD         BIT(21)		/* general call address detected */
+#define SR_BED          BIT(22)		/* bus error no ACK/NAK */
+#define SR_SAD          BIT(23)		/* slave address detected */
+#define SR_SSD          BIT(24)		/* slave stop detected */
+#define SR_MSD          BIT(26)		/* master stop detected */
+#define SR_TXDONE       BIT(27)		/* transaction done */
+#define SR_TXE          BIT(28)		/* tx FIFO empty */
+#define SR_RXHF         BIT(29)		/* rx FIFO half-full */
+#define SR_RXF          BIT(30)		/* rx FIFO full */
+#define SR_RXOV         BIT(31)		/* RX FIFO overrun */
+
+/* register ILCR fields */
+#define LCR_SLV         0x000001FF	/* SLV: bit[8:0] */
+#define LCR_FLV         0x0003FE00	/* FLV: bit[17:9] */
+#define LCR_HLVH        0x07FC0000	/* HLVH: bit[26:18] */
+#define LCR_HLVL        0xF8000000	/* HLVL: bit[31:27] */
+
+/* register IWCR fields */
+#define WCR_COUNT       0x0000001F	/* COUNT: bit[4:0] */
+#define WCR_COUNT1      0x000003E0	/* HS_COUNT1: bit[9:5] */
+#define WCR_COUNT2      0x00007C00	/* HS_COUNT2: bit[14:10] */
+
+/* register IBMR fields */
+#define BMR_SDA         BIT(0)		/* SDA line level */
+#define BMR_SCL         BIT(1)		/* SCL line level */
+
+/* register IWFIFO fields */
+#define WFIFO_DATA_MSK      0x000000FF  /* data: bit[7:0] */
+#define WFIFO_CTRL_MSK      0x000003E0  /* control: bit[11:8] */
+#define WFIFO_CTRL_START    BIT(8)      /* start bit */
+#define WFIFO_CTRL_STOP     BIT(9)      /* stop bit */
+#define WFIFO_CTRL_ACKNAK   BIT(10)     /* send ACK(0) or NAK(1) */
+#define WFIFO_CTRL_TB       BIT(11)     /* transfer byte bit */
+
+/* status register init value */
+#define I2C_INT_STATUS_MASK    0xfffc0000  /* SR bits[31:18] */
+#define I2C_INT_CTRL_MASK      (CR_ALDIE | CR_DTEIE | CR_DRFIE | \
+				CR_BEIE | CR_TXDONEIE | CR_TXEIE | \
+				CR_RXHFIE | CR_RXFIE | CR_RXOVIE | \
+				CR_MSDIE)
+
+/* i2c bus recover timeout: us */
+#define I2C_BUS_RECOVER_TIMEOUT		(100000)
+
+#define I2C_FAST_MODE_FREQ		(400000)
+
+enum spacemit_i2c_state {
+	STATE_IDLE,
+	STATE_START,
+	STATE_READ,
+	STATE_WRITE,
+};
+
+enum spacemit_i2c_dir {
+	DIR_WRITE,
+	DIR_READ
+};
+
+/* i2c-spacemit driver's main struct */
+struct spacemit_i2c_dev {
+	struct device *dev;
+	struct i2c_adapter adapt;
+
+	/* hardware resources */
+	void __iomem *base;
+	int irq;
+
+	struct i2c_msg *msgs;
+	int msg_num;
+	struct i2c_msg *cur_msg;
+
+	/* index of the current message being processed */
+	int msg_idx;
+	u8 *msg_buf;
+	/* the number of unprocessed bytes remaining in each message  */
+	size_t unprocessed;
+
+	enum spacemit_i2c_state state;
+	enum spacemit_i2c_dir dir;
+	struct completion complete;
+	u32 status;
+	u32 err;
+};
+
+static void spacemit_i2c_enable(struct spacemit_i2c_dev *i2c)
+{
+	u32 val;
+
+	val = readl(i2c->base + ICR);
+	writel(val | CR_IUE, i2c->base + ICR);
+}
+
+static void spacemit_i2c_disable(struct spacemit_i2c_dev *i2c)
+{
+	u32 val;
+
+	val = readl(i2c->base + ICR);
+	val &= ~CR_IUE;
+	writel(val, i2c->base + ICR);
+}
+
+static void spacemit_i2c_reset(struct spacemit_i2c_dev *i2c)
+{
+	writel(CR_UR, i2c->base + ICR);
+	udelay(5);
+	writel(0, i2c->base + ICR);
+}
+
+static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c);
+
+static void spacemit_i2c_bus_reset(struct spacemit_i2c_dev *i2c)
+{
+	u32 status;
+
+	/* if bus is locked, reset unit. 0: locked */
+	status = readl(i2c->base + IBMR);
+	if ((status & BMR_SDA) && (status & BMR_SCL))
+		return;
+
+	spacemit_i2c_reset(i2c);
+	usleep_range(10, 20);
+
+	/* check scl status again */
+	status = readl(i2c->base + IBMR);
+	if (!(status & BMR_SCL))
+		dev_warn_ratelimited(i2c->dev, "unit reset failed\n");
+}
+
+static int spacemit_i2c_recover_bus_busy(struct spacemit_i2c_dev *i2c)
+{
+	int ret = 0;
+	u32 val;
+
+	val = readl(i2c->base + ISR);
+	if (likely(!(val & (SR_UB | SR_IBB))))
+		return 0;
+
+	ret = readl_poll_timeout(i2c->base + ISR, val, !(val & (SR_UB | SR_IBB)),
+				 1500, I2C_BUS_RECOVER_TIMEOUT);
+	if (unlikely(ret)) {
+		spacemit_i2c_reset(i2c);
+		ret = -EAGAIN;
+	}
+
+	return ret;
+}
+
+static void spacemit_i2c_check_bus_release(struct spacemit_i2c_dev *i2c)
+{
+	/* in case bus is not released after transfer completes */
+	if (unlikely(readl(i2c->base + ISR) & SR_EBB)) {
+		spacemit_i2c_bus_reset(i2c);
+		usleep_range(90, 150);
+	}
+}
+
+static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c)
+{
+	u32 val = 0;
+
+	/*
+	 * Unmask interrupt bits for all xfer mode:
+	 * bus error, arbitration loss detected.
+	 * For transaction complete signal, we use master stop
+	 * interrupt, so we don't need to unmask CR_TXDONEIE.
+	 */
+	val |= CR_BEIE | CR_ALDIE;
+
+	/*
+	 * Unmask interrupt bits for interrupt xfer mode:
+	 * DBR rx full.
+	 * For tx empty interrupt CR_DTEIE, we only
+	 * need to enable when trigger byte transfer to start
+	 * data sending.
+	 */
+	val |= CR_DRFIE;
+
+	/* set speed bits: default fast mode */
+	val |= CR_MODE_FAST;
+
+	/* disable response to general call */
+	val |= CR_GCD;
+
+	/* enable SCL clock output */
+	val |= CR_SCLE;
+
+	/* enable master stop detected */
+	val |= CR_MSDE | CR_MSDIE;
+
+	writel(val, i2c->base + ICR);
+}
+
+static inline void
+spacemit_i2c_clear_int_status(struct spacemit_i2c_dev *i2c, u32 mask)
+{
+	writel(mask & I2C_INT_STATUS_MASK, i2c->base + ISR);
+}
+
+static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c)
+{
+	u32 slave_addr_rw, val;
+
+	i2c->dir = i2c->cur_msg->flags & I2C_M_RD;
+	i2c->state = STATE_START;
+
+	if (i2c->cur_msg->flags & I2C_M_RD)
+		slave_addr_rw = ((i2c->cur_msg->addr & 0x7f) << 1) | 1;
+	else
+		slave_addr_rw = (i2c->cur_msg->addr & 0x7f) << 1;
+
+	writel(slave_addr_rw, i2c->base + IDBR);
+
+	val = readl(i2c->base + ICR);
+
+	/* send start pulse */
+	val &= ~CR_STOP;
+	val |= CR_START | CR_TB | CR_DTEIE;
+	writel(val, i2c->base + ICR);
+}
+
+static void spacemit_i2c_stop(struct spacemit_i2c_dev *i2c)
+{
+	u32 val;
+
+	val = readl(i2c->base + ICR);
+
+	val |= CR_STOP | CR_ALDIE | CR_TB;
+
+	if (i2c->dir == DIR_READ)
+		val |= CR_ACKNAK;
+
+	writel(val, i2c->base + ICR);
+}
+
+static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
+{
+	unsigned long time_left;
+
+	for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) {
+		i2c->cur_msg = i2c->msgs + i2c->msg_idx;
+		i2c->msg_buf = i2c->cur_msg->buf;
+		i2c->err = 0;
+		i2c->status = 0;
+		i2c->unprocessed = i2c->cur_msg->len;
+
+		reinit_completion(&i2c->complete);
+
+		spacemit_i2c_start(i2c);
+
+		time_left = wait_for_completion_timeout(&i2c->complete,
+							i2c->adapt.timeout);
+		if (unlikely(time_left == 0)) {
+			dev_alert(i2c->dev, "msg completion timeout\n");
+			spacemit_i2c_bus_reset(i2c);
+			spacemit_i2c_reset(i2c);
+			return -ETIMEDOUT;
+		}
+
+		if (unlikely(i2c->err))
+			return spacemit_i2c_handle_err(i2c);
+	}
+
+	return 0;
+}
+
+static int spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c)
+{
+	if (i2c->dir == DIR_READ) {
+		if (i2c->unprocessed == 1 && i2c->msg_idx == i2c->msg_num - 1)
+			return 1;
+	} else if (i2c->dir == DIR_WRITE) {
+		if (!i2c->unprocessed && i2c->msg_idx == i2c->msg_num - 1)
+			return 1;
+	}
+
+	return 0;
+}
+
+static void spacemit_i2c_handle_write(struct spacemit_i2c_dev *i2c)
+{
+	/* if transfer completes, ISR will handle it */
+	if (i2c->status & SR_MSD)
+		return;
+
+	if (i2c->unprocessed) {
+		writel(*i2c->msg_buf++, i2c->base + IDBR);
+		i2c->unprocessed--;
+		return;
+	}
+
+	/* STATE_IDLE avoids trigger next byte */
+	i2c->state = STATE_IDLE;
+	complete(&i2c->complete);
+}
+
+static void spacemit_i2c_handle_read(struct spacemit_i2c_dev *i2c)
+{
+	if (i2c->unprocessed) {
+		*i2c->msg_buf++ = readl(i2c->base + IDBR);
+		i2c->unprocessed--;
+	}
+
+	/* if transfer completes, ISR will handle it */
+	if (i2c->status & (SR_MSD | SR_ACKNAK))
+		return;
+
+	/* it has to append stop bit in icr that read last byte */
+	if (i2c->unprocessed)
+		return;
+
+	/* STATE_IDLE avoids trigger next byte */
+	i2c->state = STATE_IDLE;
+	complete(&i2c->complete);
+}
+
+static void spacemit_i2c_handle_start(struct spacemit_i2c_dev *i2c)
+{
+	if (i2c->dir == DIR_READ) {
+		i2c->state = STATE_READ;
+		return;
+	}
+
+	if (i2c->dir == DIR_WRITE) {
+		i2c->state = STATE_WRITE;
+		spacemit_i2c_handle_write(i2c);
+	}
+}
+
+static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c)
+{
+	if (!i2c->err)
+		return 0;
+
+	dev_dbg(i2c->dev, "i2c error status: 0x%08x\n",	i2c->status);
+
+	if (i2c->err & (SR_BED | SR_ALD))
+		spacemit_i2c_reset(i2c);
+
+	if (i2c->err & (SR_RXOV | SR_ALD))
+		return -EAGAIN;
+
+	return (i2c->status & SR_ACKNAK) ? -ENXIO : -EIO;
+}
+
+static void spacemit_i2c_err_check(struct spacemit_i2c_dev *i2c)
+{
+	u32 val;
+	/*
+	 * send transaction complete signal:
+	 * error happens, detect master stop
+	 */
+	if (likely(i2c->err || (i2c->status & SR_MSD))) {
+		/*
+		 * Here the transaction is already done, we don't need any
+		 * other interrupt signals from now, in case any interrupt
+		 * happens before spacemit_i2c_xfer to disable irq and i2c unit,
+		 * we mask all the interrupt signals and clear the interrupt
+		 * status.
+		 */
+		val = readl(i2c->base + ICR);
+		val &= ~I2C_INT_CTRL_MASK;
+		writel(val, i2c->base + ICR);
+
+		spacemit_i2c_clear_int_status(i2c, I2C_INT_STATUS_MASK);
+
+		i2c->state = STATE_IDLE;
+		complete(&i2c->complete);
+	}
+}
+
+static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
+{
+	struct spacemit_i2c_dev *i2c = devid;
+	u32 status, val;
+
+	status = readl(i2c->base + ISR);
+	if (!status)
+		return IRQ_HANDLED;
+
+	i2c->status = status;
+
+	i2c->err = status & (SR_BED | SR_RXOV | SR_ALD);
+
+	spacemit_i2c_clear_int_status(i2c, status);
+
+	if (unlikely(i2c->err))
+		goto err_out;
+
+	val = readl(i2c->base + ICR);
+
+	val &= ~(CR_TB | CR_ACKNAK | CR_STOP | CR_START);
+	writel(val, i2c->base + ICR);
+
+	switch (i2c->state) {
+	case STATE_START:
+		spacemit_i2c_handle_start(i2c);
+		break;
+	case STATE_READ:
+		spacemit_i2c_handle_read(i2c);
+		break;
+	case STATE_WRITE:
+		spacemit_i2c_handle_write(i2c);
+		break;
+	default:
+		break;
+	}
+
+	if (i2c->state != STATE_IDLE) {
+		if (spacemit_i2c_is_last_msg(i2c)) {
+			/* trigger next byte with stop */
+			spacemit_i2c_stop(i2c);
+		} else {
+			/* trigger next byte */
+			val |= CR_ALDIE | CR_TB;
+			writel(val, i2c->base + ICR);
+		}
+	}
+
+err_out:
+	spacemit_i2c_err_check(i2c);
+	return IRQ_HANDLED;
+}
+
+static void spacemit_i2c_calc_timeout(struct spacemit_i2c_dev *i2c)
+{
+	unsigned long timeout;
+	int idx = 0, cnt = 0, freq;
+
+	while (idx < i2c->msg_num) {
+		cnt += (i2c->msgs + idx)->len + 1;
+		idx++;
+	}
+
+	freq = I2C_FAST_MODE_FREQ;
+	/*
+	 * multiply by 9 because each byte in I2C transmission requires
+	 * 9 clock cycles: 8 bits of data plus 1 ACK/NACK bit.
+	 */
+	timeout = cnt * 9 * USEC_PER_SEC / freq;
+
+	i2c->adapt.timeout = usecs_to_jiffies(timeout + USEC_PER_SEC / 2) / i2c->msg_num;
+}
+
+static inline int spacemit_i2c_xfer_core(struct spacemit_i2c_dev *i2c)
+{
+	int ret = 0;
+
+	spacemit_i2c_reset(i2c);
+
+	spacemit_i2c_calc_timeout(i2c);
+
+	spacemit_i2c_init(i2c);
+
+	spacemit_i2c_enable(i2c);
+	enable_irq(i2c->irq);
+
+	/* i2c wait for bus busy */
+	ret = spacemit_i2c_recover_bus_busy(i2c);
+	if (unlikely(ret))
+		return ret;
+
+	ret = spacemit_i2c_xfer_msg(i2c);
+	if (unlikely(ret < 0)) {
+		dev_dbg(i2c->dev, "i2c transfer error\n");
+		/* timeout error should not be overridden, and the transfer
+		 * error will be confirmed by err handle function latter,
+		 * the reset should be invalid argument error.
+		 */
+		if (ret != -ETIMEDOUT)
+			ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int
+spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg msgs[], int num)
+{
+	struct spacemit_i2c_dev *i2c = i2c_get_adapdata(adapt);
+	int ret;
+
+	i2c->msgs = msgs;
+	i2c->msg_num = num;
+
+	ret = spacemit_i2c_xfer_core(i2c);
+	if (likely(!ret))
+		spacemit_i2c_check_bus_release(i2c);
+
+	disable_irq(i2c->irq);
+
+	spacemit_i2c_disable(i2c);
+
+	if (unlikely((ret == -ETIMEDOUT || ret == -EAGAIN)))
+		dev_alert(i2c->dev, "i2c transfer failed, ret %d err 0x%x\n", ret, i2c->err);
+
+	return ret < 0 ? ret : num;
+}
+
+static u32 spacemit_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+}
+
+static const struct i2c_algorithm spacemit_i2c_algo = {
+	.xfer = spacemit_i2c_xfer,
+	.functionality = spacemit_i2c_func,
+};
+
+static int spacemit_i2c_probe(struct platform_device *pdev)
+{
+	struct spacemit_i2c_dev *i2c;
+	struct device_node *of_node = pdev->dev.of_node;
+	struct clk *clk;
+	int ret = 0;
+
+	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
+
+	i2c->dev = &pdev->dev;
+
+	i2c->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(i2c->base))
+		return dev_err_probe(&pdev->dev, PTR_ERR(i2c->base), "failed to do ioremap");
+
+	i2c->irq = platform_get_irq(pdev, 0);
+	if (i2c->irq < 0)
+		return dev_err_probe(&pdev->dev, i2c->irq, "failed to get irq resource");
+
+	ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
+			       IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(i2c->dev), i2c);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to request irq");
+
+	disable_irq(i2c->irq);
+
+	clk = devm_clk_get_enabled(&pdev->dev, NULL);
+	if (IS_ERR(clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(clk), "failed to enable clock");
+
+	i2c_set_adapdata(&i2c->adapt, i2c);
+	i2c->adapt.owner = THIS_MODULE;
+	i2c->adapt.algo = &spacemit_i2c_algo;
+	i2c->adapt.dev.parent = i2c->dev;
+	i2c->adapt.nr = pdev->id;
+
+	i2c->adapt.dev.of_node = of_node;
+	i2c->adapt.algo_data = i2c;
+
+	strscpy(i2c->adapt.name, "spacemit-i2c-adapter", sizeof(i2c->adapt.name));
+
+	init_completion(&i2c->complete);
+
+	ret = i2c_add_numbered_adapter(&i2c->adapt);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to add i2c adapter");
+
+	platform_set_drvdata(pdev, i2c);
+
+	return 0;
+}
+
+static void spacemit_i2c_remove(struct platform_device *pdev)
+{
+	struct spacemit_i2c_dev *i2c = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&i2c->adapt);
+}
+
+static const struct of_device_id spacemit_i2c_of_match[] = {
+	{ .compatible = "spacemit,k1-i2c", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, spacemit_i2c_of_match);
+
+static struct platform_driver spacemit_i2c_driver = {
+	.probe = spacemit_i2c_probe,
+	.remove = spacemit_i2c_remove,
+	.driver = {
+		.name = "i2c-k1",
+		.of_match_table = spacemit_i2c_of_match,
+	},
+};
+module_platform_driver(spacemit_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("I2C bus driver for SpacemiT K1 SoC");

-- 
2.34.1



From u.kleine-koenig at baylibre.com  Tue Nov 12 00:35:20 2024
From: u.kleine-koenig at baylibre.com (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Tue, 12 Nov 2024 09:35:20 +0100
Subject: [PATCH] firmware: Switch back to struct platform_driver::remove()
Message-ID: <36974feb6035201d53384557259ec72fe311053b.1731397962.git.u.kleine-koenig@baylibre.com>

After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
return void") .remove() is (again) the right callback to implement for
platform drivers.

Convert all platform drivers below drivers/firmware to use .remove(),
with the eventual goal to drop struct platform_driver::remove_new(). As
.remove() and .remove_new() have the same prototypes, conversion is done
by just changing the structure member name in the driver initializer.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>
---
Hello,

I did a single patch for all of drivers/firmware. While I usually prefer
to do one logical change per patch, this seems to be overengineering
here as the individual changes are really trivial and shouldn't be much
in the way for stable backports.

There is no dedicated maintainer for drivers/firmware, maybe Sudeep as
biggest committer there can take it? Or would it be sensible to split
this patch?

This is based on yesterday's next, if conflicts arise when you apply it
at some later time and don't want to resolve them, feel free to just
drop the changes to the conflicting files. I'll notice and followup at a
later time then. Or ask me for a fixed resend. (Having said that, I
recommend b4 am -3 + git am -3 which should resolve most conflicts just
fine.)

Best regards
Uwe

 drivers/firmware/arm_scmi/driver.c            | 2 +-
 drivers/firmware/arm_scpi.c                   | 2 +-
 drivers/firmware/google/coreboot_table.c      | 2 +-
 drivers/firmware/imx/imx-dsp.c                | 2 +-
 drivers/firmware/microchip/mpfs-auto-update.c | 2 +-
 drivers/firmware/mtk-adsp-ipc.c               | 2 +-
 drivers/firmware/qemu_fw_cfg.c                | 2 +-
 drivers/firmware/raspberrypi.c                | 2 +-
 drivers/firmware/stratix10-rsu.c              | 2 +-
 drivers/firmware/stratix10-svc.c              | 2 +-
 drivers/firmware/xilinx/zynqmp.c              | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 1f53ca1f87e3..1b5fb2c4ce86 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -3333,7 +3333,7 @@ static struct platform_driver scmi_driver = {
 		   .dev_groups = versions_groups,
 		   },
 	.probe = scmi_probe,
-	.remove_new = scmi_remove,
+	.remove = scmi_remove,
 };
 
 static struct dentry *scmi_debugfs_init(void)
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index f4d47577f83e..87c323de17b9 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -1049,7 +1049,7 @@ static struct platform_driver scpi_driver = {
 		.dev_groups = versions_groups,
 	},
 	.probe = scpi_probe,
-	.remove_new = scpi_remove,
+	.remove = scpi_remove,
 };
 module_platform_driver(scpi_driver);
 
diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
index 208652a8087c..882db32e51be 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -220,7 +220,7 @@ MODULE_DEVICE_TABLE(of, coreboot_of_match);
 
 static struct platform_driver coreboot_table_driver = {
 	.probe = coreboot_table_probe,
-	.remove_new = coreboot_table_remove,
+	.remove = coreboot_table_remove,
 	.driver = {
 		.name = "coreboot_table",
 		.acpi_match_table = ACPI_PTR(cros_coreboot_acpi_match),
diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c
index 01c8ef14eaec..ed79e823157a 100644
--- a/drivers/firmware/imx/imx-dsp.c
+++ b/drivers/firmware/imx/imx-dsp.c
@@ -180,7 +180,7 @@ static struct platform_driver imx_dsp_driver = {
 		.name = "imx-dsp",
 	},
 	.probe = imx_dsp_probe,
-	.remove_new = imx_dsp_remove,
+	.remove = imx_dsp_remove,
 };
 builtin_platform_driver(imx_dsp_driver);
 
diff --git a/drivers/firmware/microchip/mpfs-auto-update.c b/drivers/firmware/microchip/mpfs-auto-update.c
index 0f7ec8848202..38a03698cec9 100644
--- a/drivers/firmware/microchip/mpfs-auto-update.c
+++ b/drivers/firmware/microchip/mpfs-auto-update.c
@@ -458,7 +458,7 @@ static struct platform_driver mpfs_auto_update_driver = {
 		.name = "mpfs-auto-update",
 	},
 	.probe = mpfs_auto_update_probe,
-	.remove_new = mpfs_auto_update_remove,
+	.remove = mpfs_auto_update_remove,
 };
 module_platform_driver(mpfs_auto_update_driver);
 
diff --git a/drivers/firmware/mtk-adsp-ipc.c b/drivers/firmware/mtk-adsp-ipc.c
index fdb083f42ebf..2b79371c61c9 100644
--- a/drivers/firmware/mtk-adsp-ipc.c
+++ b/drivers/firmware/mtk-adsp-ipc.c
@@ -132,7 +132,7 @@ static struct platform_driver mtk_adsp_ipc_driver = {
 		.name = "mtk-adsp-ipc",
 	},
 	.probe = mtk_adsp_ipc_probe,
-	.remove_new = mtk_adsp_ipc_remove,
+	.remove = mtk_adsp_ipc_remove,
 };
 builtin_platform_driver(mtk_adsp_ipc_driver);
 
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index 85c525745b31..d58da3e4500a 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -757,7 +757,7 @@ MODULE_DEVICE_TABLE(acpi, fw_cfg_sysfs_acpi_match);
 
 static struct platform_driver fw_cfg_sysfs_driver = {
 	.probe = fw_cfg_sysfs_probe,
-	.remove_new = fw_cfg_sysfs_remove,
+	.remove = fw_cfg_sysfs_remove,
 	.driver = {
 		.name = "fw_cfg",
 		.of_match_table = fw_cfg_sysfs_mmio_match,
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index 18cc34987108..7ecde6921a0a 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -406,7 +406,7 @@ static struct platform_driver rpi_firmware_driver = {
 	},
 	.probe		= rpi_firmware_probe,
 	.shutdown	= rpi_firmware_shutdown,
-	.remove_new	= rpi_firmware_remove,
+	.remove		= rpi_firmware_remove,
 };
 module_platform_driver(rpi_firmware_driver);
 
diff --git a/drivers/firmware/stratix10-rsu.c b/drivers/firmware/stratix10-rsu.c
index e20cee9c2d32..1ea39a0a76c7 100644
--- a/drivers/firmware/stratix10-rsu.c
+++ b/drivers/firmware/stratix10-rsu.c
@@ -802,7 +802,7 @@ static void stratix10_rsu_remove(struct platform_device *pdev)
 
 static struct platform_driver stratix10_rsu_driver = {
 	.probe = stratix10_rsu_probe,
-	.remove_new = stratix10_rsu_remove,
+	.remove = stratix10_rsu_remove,
 	.driver = {
 		.name = "stratix10-rsu",
 		.dev_groups = rsu_groups,
diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index 528f37417aea..c5c78b869561 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -1271,7 +1271,7 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev)
 
 static struct platform_driver stratix10_svc_driver = {
 	.probe = stratix10_svc_drv_probe,
-	.remove_new = stratix10_svc_drv_remove,
+	.remove = stratix10_svc_drv_remove,
 	.driver = {
 		.name = "stratix10-svc",
 		.of_match_table = stratix10_svc_drv_match,
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index cdb565c41119..720fa8b5d8e9 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -2118,6 +2118,6 @@ static struct platform_driver zynqmp_firmware_driver = {
 		.dev_groups = zynqmp_firmware_groups,
 	},
 	.probe = zynqmp_firmware_probe,
-	.remove_new = zynqmp_firmware_remove,
+	.remove = zynqmp_firmware_remove,
 };
 module_platform_driver(zynqmp_firmware_driver);

base-commit: 6d59cab07b8d74d0f0422b750038123334f6ecc2
-- 
2.45.2



From marcin.grad at completesolutions.pl  Tue Nov 12 00:51:17 2024
From: marcin.grad at completesolutions.pl (Marcin Gard)
Date: Tue, 12 Nov 2024 08:51:17 GMT
Subject: =?UTF-8?Q?Prosz=C4=99_o_kontakt?=
Message-ID: <20241112084500-0.1.ep.1pbf3.0.y662nn1xei@completesolutions.pl>

Dzie? dobry,

Czy jest mo?liwo?? nawi?zania wsp??pracy z Pa?stwem?

Z ch?ci? porozmawiam z osob? zajmuj?c? si? dzia?aniami zwi?zanymi ze sprzeda??.

Pomagamy skutecznie pozyskiwa? nowych klient?w.

Zapraszam do kontaktu.


Pozdrawiam serdecznie
Marcin Gard


From lkp at intel.com  Tue Nov 12 01:47:06 2024
From: lkp at intel.com (kernel test robot)
Date: Tue, 12 Nov 2024 17:47:06 +0800
Subject: [PATCH v8 12/29] riscv/shstk: If needed allocate a new shadow
 stack on clone
In-Reply-To: <20241111-v5_user_cfi_series-v8-12-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-12-dce14aa30207@rivosinc.com>
Message-ID: <202411121717.INT1geTN-lkp@intel.com>

Hi Deepak,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 64f7b77f0bd9271861ed9e410e9856b6b0b21c48]

url:    https://github.com/intel-lab-lkp/linux/commits/Deepak-Gupta/mm-Introduce-ARCH_HAS_USER_SHADOW_STACK/20241112-050530
base:   64f7b77f0bd9271861ed9e410e9856b6b0b21c48
patch link:    https://lore.kernel.org/r/20241111-v5_user_cfi_series-v8-12-dce14aa30207%40rivosinc.com
patch subject: [PATCH v8 12/29] riscv/shstk: If needed allocate a new shadow stack on clone
config: riscv-defconfig (https://download.01.org/0day-ci/archive/20241112/202411121717.INT1geTN-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241112/202411121717.INT1geTN-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411121717.INT1geTN-lkp at intel.com/

All warnings (new ones prefixed by >>):

   In file included from arch/riscv/kernel/process.c:17:
   In file included from include/linux/ptrace.h:10:
   In file included from include/linux/pid_namespace.h:7:
   In file included from include/linux/mm.h:2213:
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
>> arch/riscv/kernel/process.c:245:36: warning: expression result unused [-Wunused-value]
     245 |                 ssp ? set_active_shstk(p, ssp) : 0;
         |                                                  ^
   2 warnings generated.


vim +245 arch/riscv/kernel/process.c

   209	
   210	int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
   211	{
   212		unsigned long clone_flags = args->flags;
   213		unsigned long usp = args->stack;
   214		unsigned long tls = args->tls;
   215		unsigned long ssp = 0;
   216		struct pt_regs *childregs = task_pt_regs(p);
   217	
   218		/* Ensure all threads in this mm have the same pointer masking mode. */
   219		if (IS_ENABLED(CONFIG_RISCV_ISA_SUPM) && p->mm && (clone_flags & CLONE_VM))
   220			set_bit(MM_CONTEXT_LOCK_PMLEN, &p->mm->context.flags);
   221	
   222		memset(&p->thread.s, 0, sizeof(p->thread.s));
   223	
   224		/* p->thread holds context to be restored by __switch_to() */
   225		if (unlikely(args->fn)) {
   226			/* Kernel thread */
   227			memset(childregs, 0, sizeof(struct pt_regs));
   228			/* Supervisor/Machine, irqs on: */
   229			childregs->status = SR_PP | SR_PIE;
   230	
   231			p->thread.s[0] = (unsigned long)args->fn;
   232			p->thread.s[1] = (unsigned long)args->fn_arg;
   233		} else {
   234			/* allocate new shadow stack if needed. In case of CLONE_VM we have to */
   235			ssp = shstk_alloc_thread_stack(p, args);
   236			if (IS_ERR_VALUE(ssp))
   237				return PTR_ERR((void *)ssp);
   238	
   239			*childregs = *(current_pt_regs());
   240			/* Turn off status.VS */
   241			riscv_v_vstate_off(childregs);
   242			if (usp) /* User fork */
   243				childregs->sp = usp;
   244			/* if needed, set new ssp */
 > 245			ssp ? set_active_shstk(p, ssp) : 0;
   246			if (clone_flags & CLONE_SETTLS)
   247				childregs->tp = tls;
   248			childregs->a0 = 0; /* Return value of fork() */
   249			p->thread.s[0] = 0;
   250		}
   251		p->thread.riscv_v_flags = 0;
   252		if (has_vector())
   253			riscv_v_thread_alloc(p);
   254		p->thread.ra = (unsigned long)ret_from_fork;
   255		p->thread.sp = (unsigned long)childregs; /* kernel sp */
   256		return 0;
   257	}
   258	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From alexghiti at rivosinc.com  Tue Nov 12 03:34:22 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Tue, 12 Nov 2024 12:34:22 +0100
Subject: [PATCH -fixes] drivers: perf: Fix wrong put_cpu() placement
Message-ID: <20241112113422.617954-1-alexghiti@rivosinc.com>

Unfortunately, the wrong patch version was merged which places the
put_cpu() after enabling a static key, which is not safe as pointed by
Will [1], so move put_cpu() before to avoid this.

Fixes: 2840dadf0dde ("drivers: perf: Fix smp_processor_id() use in preemptible code")
Reported-by: Atish Patra <atishp at rivosinc.com>
Link: https://lore.kernel.org/all/20240827125335.GD4772 at willie-the-truck/ [1]
Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
---
 drivers/perf/riscv_pmu_sbi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 391ca1422cae..1aa303f76cc7 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -1393,8 +1393,9 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
 			goto out_unregister;
 
 		cpu = get_cpu();
-
 		ret = pmu_sbi_snapshot_setup(pmu, cpu);
+		put_cpu();
+
 		if (ret) {
 			/* Snapshot is an optional feature. Continue if not available */
 			pmu_sbi_snapshot_free(pmu);
@@ -1408,7 +1409,6 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
 			 */
 			static_branch_enable(&sbi_pmu_snapshot_available);
 		}
-		put_cpu();
 	}
 
 	register_sysctl("kernel", sbi_pmu_sysctl_table);
-- 
2.39.2



From bjorn at kernel.org  Tue Nov 12 03:36:51 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Tue, 12 Nov 2024 12:36:51 +0100
Subject: [PATCH] tools: add forwarding header for
 arch/riscv/include/asm/fence.h
In-Reply-To: <mvmbjymxdsc.fsf@suse.de>
References: <mvm5xq44bqh.fsf@suse.de>
 <d380fd10-ebc4-4d66-becb-13995372d41a@ghiti.fr> <mvmfrnyxg2n.fsf@suse.de>
 <26452229-7461-48aa-987a-28444ace4f28@ghiti.fr> <mvmbjymxdsc.fsf@suse.de>
Message-ID: <87h68cu1ik.fsf@all.your.base.are.belong.to.us>

Andreas Schwab <schwab at suse.de> writes:

> On Nov 11 2024, Alexandre Ghiti wrote:
>
>> Indeed, Bjorn's patches did not make it into rc7...
>
> That needs to be fixed ASAP!

Ok, if we want to unbreak the tools builds, two series are required for
6.12.

[1] which addresses the asm/fence.h path issue
[2] which addresses the same issue, but for non-cross builds

[2] can be pulled to RISC-V fixes, but [1] reside in the bpf-next tree
(target 6.13). Details here: [3].

To reiterate what I asked Andrii, but for RISC-V fixes: Would it be
possible to pull these patches [2] into the RISC-V tree, having a
duplicate set in bpf-next? Or are we stuck with stable backporting, as
Andrii suggests?


Bj?rn

[1] https://lore.kernel.org/linux-riscv/20240927131355.350918-1-bjorn at kernel.org/
[2] https://lore.kernel.org/linux-riscv/20241106193208.290067-1-bjorn at kernel.org/
[3] https://lore.kernel.org/linux-riscv/CAEf4BzZbq9OwSGi4pdb5_q8YkErfFiQFKYXg3g1rjpdejafx+Q at mail.gmail.com/


From gregkh at linuxfoundation.org  Tue Nov 12 03:39:32 2024
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 12 Nov 2024 12:39:32 +0100
Subject: [PATCH] firmware: Switch back to struct platform_driver::remove()
In-Reply-To: <36974feb6035201d53384557259ec72fe311053b.1731397962.git.u.kleine-koenig@baylibre.com>
References: <36974feb6035201d53384557259ec72fe311053b.1731397962.git.u.kleine-koenig@baylibre.com>
Message-ID: <2024111223-gizzard-scabby-eb98@gregkh>

On Tue, Nov 12, 2024 at 09:35:20AM +0100, Uwe Kleine-K?nig wrote:
> After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
> return void") .remove() is (again) the right callback to implement for
> platform drivers.
> 
> Convert all platform drivers below drivers/firmware to use .remove(),
> with the eventual goal to drop struct platform_driver::remove_new(). As
> .remove() and .remove_new() have the same prototypes, conversion is done
> by just changing the structure member name in the driver initializer.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at baylibre.com>
> ---
> Hello,
> 
> I did a single patch for all of drivers/firmware. While I usually prefer
> to do one logical change per patch, this seems to be overengineering
> here as the individual changes are really trivial and shouldn't be much
> in the way for stable backports.
> 
> There is no dedicated maintainer for drivers/firmware, maybe Sudeep as
> biggest committer there can take it? Or would it be sensible to split
> this patch?

I'll just take it now, thanks!

greg k-h


From will at kernel.org  Tue Nov 12 04:05:10 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 12 Nov 2024 12:05:10 +0000
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <CAJF2gTTuvmtmKVFMZCTMxEWHrpSpqPE8QO4MC5njPAskGEmpig@mail.gmail.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com>
 <20241111164259.GA20042@willie-the-truck>
 <CAJF2gTTuvmtmKVFMZCTMxEWHrpSpqPE8QO4MC5njPAskGEmpig@mail.gmail.com>
Message-ID: <20241112120510.GA21181@willie-the-truck>

On Tue, Nov 12, 2024 at 09:49:15AM +0800, Guo Ren wrote:
> On Tue, Nov 12, 2024 at 12:43?AM Will Deacon <will at kernel.org> wrote:
> >
> > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > In order to produce a generic kernel, a user can select
> > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > spinlock implementation if Zabha or Ziccrse are not present.
> > >
> > > Note that we can't use alternatives here because the discovery of
> > > extensions is done too late and we need to start with the qspinlock
> > > implementation because the ticket spinlock implementation would pollute
> > > the spinlock value, so let's use static keys.
> >
> > I think the static key toggling takes a mutex (jump_label_lock()) which
> > can take a spinlock (lock->wait_lock) internally, so I don't grok how
> > this works:
> >
> > > +static void __init riscv_spinlock_init(void)
> > > +{
> > > +     char *using_ext = NULL;
> > > +
> > > +     if (IS_ENABLED(CONFIG_RISCV_TICKET_SPINLOCKS)) {
> > > +             pr_info("Ticket spinlock: enabled\n");
> > > +             return;
> > > +     }
> > > +
> > > +     if (IS_ENABLED(CONFIG_RISCV_ISA_ZABHA) &&
> > > +         IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) &&
> > > +         riscv_isa_extension_available(NULL, ZABHA) &&
> > > +         riscv_isa_extension_available(NULL, ZACAS)) {
> > > +             using_ext = "using Zabha";
> > > +     } else if (riscv_isa_extension_available(NULL, ZICCRSE)) {
> > > +             using_ext = "using Ziccrse";
> > > +     }
> > > +#if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
> > > +     else {
> > > +             static_branch_disable(&qspinlock_key);
> > > +             pr_info("Ticket spinlock: enabled\n");
> > > +             return;
> > > +     }
> > > +#endif
> >
> > i.e. we've potentially already used the qspinlock at this point.
> Yes, I've used qspinlock here. But riscv_spinlock_init is called with
> irq_disabled and smp_off. That means this qspinlock only performs a
> test-set lock behavior by qspinlock fast-path.

That's... horrendous.

Will


From ajones at ventanamicro.com  Tue Nov 12 05:35:06 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Tue, 12 Nov 2024 14:35:06 +0100
Subject: [PATCH v2 1/1] iommu/riscv: Add support for platform msi
In-Reply-To: <20241112133504.491984-3-ajones@ventanamicro.com>
References: <20241112133504.491984-3-ajones@ventanamicro.com>
Message-ID: <20241112133504.491984-4-ajones@ventanamicro.com>

Apply platform_device_msi_init_and_alloc_irqs() to add support for
MSIs when the IOMMU is a platform device.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/iommu/riscv/iommu-platform.c | 102 ++++++++++++++++++++++-----
 1 file changed, 84 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
index da336863f152..34b925909816 100644
--- a/drivers/iommu/riscv/iommu-platform.c
+++ b/drivers/iommu/riscv/iommu-platform.c
@@ -11,18 +11,43 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 
 #include "iommu-bits.h"
 #include "iommu.h"
 
+static void riscv_iommu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
+{
+	struct device *dev = msi_desc_to_dev(desc);
+	struct riscv_iommu_device *iommu = dev_get_drvdata(dev);
+	u16 idx = desc->msi_index;
+	u64 addr;
+
+	addr = ((u64)msg->address_hi << 32) | msg->address_lo;
+
+	if (addr != (addr & RISCV_IOMMU_MSI_CFG_TBL_ADDR)) {
+		dev_err_once(dev,
+			     "uh oh, the IOMMU can't send MSIs to 0x%llx, sending to 0x%llx instead\n",
+			     addr, addr & RISCV_IOMMU_MSI_CFG_TBL_ADDR);
+	}
+
+	addr &= RISCV_IOMMU_MSI_CFG_TBL_ADDR;
+
+	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_ADDR(idx), addr);
+	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_DATA(idx), msg->data);
+	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_MSI_CFG_TBL_CTRL(idx), 0);
+}
+
 static int riscv_iommu_platform_probe(struct platform_device *pdev)
 {
+	enum riscv_iommu_igs_settings igs;
 	struct device *dev = &pdev->dev;
 	struct riscv_iommu_device *iommu = NULL;
 	struct resource *res = NULL;
-	int vec;
+	int vec, ret;
 
 	iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL);
 	if (!iommu)
@@ -40,16 +65,6 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	iommu->caps = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_CAPABILITIES);
 	iommu->fctl = riscv_iommu_readl(iommu, RISCV_IOMMU_REG_FCTL);
 
-	/* For now we only support WSI */
-	switch (FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps)) {
-	case RISCV_IOMMU_CAPABILITIES_IGS_WSI:
-	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
-		break;
-	default:
-		return dev_err_probe(dev, -ENODEV,
-				     "unable to use wire-signaled interrupts\n");
-	}
-
 	iommu->irqs_count = platform_irq_count(pdev);
 	if (iommu->irqs_count <= 0)
 		return dev_err_probe(dev, -ENODEV,
@@ -57,13 +72,58 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	if (iommu->irqs_count > RISCV_IOMMU_INTR_COUNT)
 		iommu->irqs_count = RISCV_IOMMU_INTR_COUNT;
 
-	for (vec = 0; vec < iommu->irqs_count; vec++)
-		iommu->irqs[vec] = platform_get_irq(pdev, vec);
+	igs = FIELD_GET(RISCV_IOMMU_CAPABILITIES_IGS, iommu->caps);
+	switch (igs) {
+	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
+	case RISCV_IOMMU_CAPABILITIES_IGS_MSI:
+		if (is_of_node(dev->fwnode))
+			of_msi_configure(dev, to_of_node(dev->fwnode));
+
+		if (!dev_get_msi_domain(dev)) {
+			dev_warn(dev, "failed to find an MSI domain\n");
+			goto msi_fail;
+		}
+
+		ret = platform_device_msi_init_and_alloc_irqs(dev, iommu->irqs_count,
+							      riscv_iommu_write_msi_msg);
+		if (ret) {
+			dev_warn(dev, "failed to allocate MSIs\n");
+			goto msi_fail;
+		}
+
+		for (vec = 0; vec < iommu->irqs_count; vec++)
+			iommu->irqs[vec] = msi_get_virq(dev, vec);
+
+		/* Enable message-signaled interrupts, fctl.WSI */
+		if (iommu->fctl & RISCV_IOMMU_FCTL_WSI) {
+			iommu->fctl ^= RISCV_IOMMU_FCTL_WSI;
+			riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
+		}
+
+		dev_info(dev, "using MSIs\n");
+		break;
+
+msi_fail:
+		if (igs != RISCV_IOMMU_CAPABILITIES_IGS_BOTH) {
+			return dev_err_probe(dev, -ENODEV,
+					     "unable to use wire-signaled interrupts\n");
+		}
+
+		fallthrough;
 
-	/* Enable wire-signaled interrupts, fctl.WSI */
-	if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
-		iommu->fctl |= RISCV_IOMMU_FCTL_WSI;
-		riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
+	case RISCV_IOMMU_CAPABILITIES_IGS_WSI:
+		for (vec = 0; vec < iommu->irqs_count; vec++)
+			iommu->irqs[vec] = platform_get_irq(pdev, vec);
+
+		/* Enable wire-signaled interrupts, fctl.WSI */
+		if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
+			iommu->fctl |= RISCV_IOMMU_FCTL_WSI;
+			riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FCTL, iommu->fctl);
+		}
+		dev_info(dev, "using wire-signaled interrupts\n");
+		break;
+	default:
+		return dev_err_probe(dev, -ENODEV, "invalid IGS\n");
 	}
 
 	return riscv_iommu_init(iommu);
@@ -71,7 +131,13 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 
 static void riscv_iommu_platform_remove(struct platform_device *pdev)
 {
-	riscv_iommu_remove(dev_get_drvdata(&pdev->dev));
+	struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev);
+	bool msi = !(iommu->fctl & RISCV_IOMMU_FCTL_WSI);
+
+	riscv_iommu_remove(iommu);
+
+	if (msi)
+		platform_device_msi_free_irqs_all(&pdev->dev);
 };
 
 static const struct of_device_id riscv_iommu_of_match[] = {
-- 
2.47.0



From ajones at ventanamicro.com  Tue Nov 12 05:35:05 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Tue, 12 Nov 2024 14:35:05 +0100
Subject: [PATCH v2 0/1] iommu/riscv: Add platform msi support
Message-ID: <20241112133504.491984-3-ajones@ventanamicro.com>

Add MSI support for a platform IOMMU. May be tested with QEMU when
including [1].

Based on linux-next commit 28955f4fa282 ("Add linux-next specific files for 20241112")

[1] https://lore.kernel.org/all/20241106133407.604587-1-dbarboza at ventanamicro.com/

v2:
 - Dropped patch1 of the v1 series since it wasn't necessary [Tomasz]
 - Improved error/warning messages [Samuel]

Andrew Jones (1):
  iommu/riscv: Add support for platform msi

 drivers/iommu/riscv/iommu-platform.c | 102 ++++++++++++++++++++++-----
 1 file changed, 84 insertions(+), 18 deletions(-)

-- 
2.47.0



From james.clark at linaro.org  Tue Nov 12 06:12:52 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 12 Nov 2024 14:12:52 +0000
Subject: [PATCH v1 3/4] perf record: Skip don't fail for events that don't
 open
In-Reply-To: <CAP-5=fVODgnWgfCpA7x3B8JFQhkt_unUeTjhWWdSDpKECdTSYg@mail.gmail.com>
References: <20241026121758.143259-1-irogers@google.com>
 <20241026121758.143259-4-irogers@google.com>
 <7c1a0bbf-12fd-46ef-9db2-183dfa70a334@linaro.org>
 <CAP-5=fVODgnWgfCpA7x3B8JFQhkt_unUeTjhWWdSDpKECdTSYg@mail.gmail.com>
Message-ID: <9bfdc5a0-ed1d-40f6-8a72-6129e1587ca7@linaro.org>



On 11/11/2024 5:00 pm, Ian Rogers wrote:
> On Mon, Nov 11, 2024 at 7:49?AM James Clark <james.clark at linaro.org> wrote:
>>
>>
>>
>> On 26/10/2024 1:17 pm, Ian Rogers wrote:
>>> Whilst for many tools it is an expected behavior that failure to open
>>> a perf event is a failure, ARM decided to name PMU events the same as
>>> legacy events and then failed to rename such events on a server uncore
>>> SLC PMU. As perf's default behavior when no PMU is specified is to
>>> open the event on all PMUs that advertise/"have" the event, this
>>> yielded failures when trying to make the priority of legacy and
>>> sysfs/json events uniform - something requested by RISC-V and ARM. A
>>> legacy event user on ARM hardware may find their event opened on an
>>> uncore PMU which for perf record will fail. Arnaldo suggested skipping
>>> such events which this patch implements. Rather than have the skipping
>>> conditional on running on ARM, the skipping is done on all
>>> architectures as such a fundamental behavioral difference could lead
>>> to problems with tools built/depending on perf.
>>>
>>> An example of perf record failing to open events on x86 is:
>>> ```
>>> $ perf record -e data_read,cycles,LLC-prefetch-read -a sleep 0.1
>>> Error:
>>> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0' which will be removed.
>>> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
>>> "dmesg | grep -i perf" may provide additional information.
>>>
>>> Error:
>>> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_1' which will be removed.
>>> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
>>> "dmesg | grep -i perf" may provide additional information.
>>>
>>
>> This makes me wonder if this message was overly wordy to begin with.
>> This line is fine:
>>
>>    Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0'
>>    which will be removed.
>>
>> The next bit about the syscall just repeats. The exit code could be
>> included on the previous line. And the dmesg bit is general advice that
>> could possibly be printed once at the end.
> 
> Thanks for the time spent investigating this!
> 
> I agree on this. I wonder if we should have short and long messages,
> or message+help like we do for parse events. One patch series like
> this is improving EBUSY:
> https://lore.kernel.org/lkml/20241106003007.2112584-1-ctshao at google.com/
> The issue with printing at the end is knowing where/when the end is.
> Printing once is easy enough.
> 
>>> Error:
>>> Failure to open event 'LLC-prefetch-read' on PMU 'cpu' which will be removed.
>>> The LLC-prefetch-read event is not supported.
>>> [ perf record: Woken up 1 times to write data ]
>>> [ perf record: Captured and wrote 2.188 MB perf.data (87 samples) ]
>>>
>>> $ perf report --stats
>>> Aggregated stats:
>>>                  TOTAL events:      17255
>>>                   MMAP events:        284  ( 1.6%)
>>>                   COMM events:       1961  (11.4%)
>>>                   EXIT events:          1  ( 0.0%)
>>>                   FORK events:       1960  (11.4%)
>>>                 SAMPLE events:         87  ( 0.5%)
>>>                  MMAP2 events:      12836  (74.4%)
>>>                KSYMBOL events:         83  ( 0.5%)
>>>              BPF_EVENT events:         36  ( 0.2%)
>>>         FINISHED_ROUND events:          2  ( 0.0%)
>>>               ID_INDEX events:          1  ( 0.0%)
>>>             THREAD_MAP events:          1  ( 0.0%)
>>>                CPU_MAP events:          1  ( 0.0%)
>>>              TIME_CONV events:          1  ( 0.0%)
>>>          FINISHED_INIT events:          1  ( 0.0%)
>>> cycles stats:
>>>                 SAMPLE events:         87
>>> ```
>>>
>>> Note, if all events fail to open then the data file will contain no
>>> samples. This is deliberate as at the point the events are opened
>>> there are other events, such as the dummy event for sideband data, and
>>> these events will succeed in opening even if the user specified ones
>>
>> Is a file with only sideband events useful? Is it possible to fail the
>> record command if the event doesn't open anywhere?
>>
>> I noticed this leads to some different behavior and a libperf warning
>> when you have paranoid=3:
>>
>>     $ perf record -e cycles -C 0 -- true
>>
>>     Error:
>>     Failure to open event 'cpu_atom/cycles/u' on PMU 'cpu_atom' which will
>>     be removed.
>>     ...
>>     Consider adjusting /proc/sys/kernel/perf_event_paranoid setting
>>     ...
>>     libperf: Miscounted nr_mmaps 0 vs 28
>>     WARNING: No sample_id_all support, falling back to unordered
>>     processing
>>     [ perf record: Woken up 1 times to write data ]
>>     [ perf record: Captured and wrote 0.021 MB perf.data ]
> 
> So paranoid=3 is a Debian extension that Peter Z doesn't agree with
> and so isn't enabled in regular kernels. So we're dealing with cycles,
> which we'd expect to open or fall-back to a software event like
> task-clock. It feels like things could happen better here but that's
> not necessarily the fault of this patch.
> 

paranoid=3 is a bit of a red-herring. I actually meant any paranoid 
value other than -1. The important part is "-C 0" because only root is 
allowed to open on a CPU. Or "-a" also causes the issue.

Previously you got the command failure and the hint about the paranoid 
value, but now you get the libperf error too and it still makes the file.

I still don't think a file with only sideband events is useful, I don't 
think there's even a commandline that you can run currently that results 
in that? You always need at least one event to open for it to succeed 
and I'm thinking we could keep that.

It would be nice to fix the libperf warning too because it's warning 
about something that was already warned about.

>>> don't. Having a mix of open and broken events leads to a problem of
>>> identifying different sources of events.
>>   >
>>
>> In my basic test I saw that the opened event was identified correctly in
>> perf report, unless you have an example that you encountered that we
>> should fix?
> 
> I didn't find any but we also don't tend to test failing to open
> events. I could imagine things failing in `perf test` on neoverse
> testing given the l3 advertising the cycles event.
> 
>> One place I saw an issue was with auxtrace events. If there's an event
>> name clash then you're likely to not be able to open the file afterwards
>> because the auxtrace code can't handle an event that didn't open. But I
>> don't know of any name clashes there (I just faked one for testing), and
>> maybe that could be fixed up later in the auxtrace code if there is ever
>> a real one.
>>
>> Other than the above it does seem to work ok.
> 
> Cool, can this be taken as a Tested-by?
> 

Yep, although with a caveat that I faked the second cycles PMU that 
wouldn't open, but I don't think that should make a difference:

Tested-by: James Clark <james.clark at linaro.org>

I can also test with the real thing if you like but would take a bit 
longer as I have to borrow it off Leo.

> Thanks,
> Ian
> 
>>> The issue with legacy events is that on RISC-V they want the driver to
>>> not have mappings from legacy to non-legacy config encodings for each
>>> vendor/model due to size, complexity and difficulty to update. It was
>>> reported that on ARM Apple-M? CPUs the legacy mapping in the driver
>>> was broken and the sysfs/json events should always take precedent,
>>> however, it isn't clear this is still the case. It is the case that
>>> without working around this issue a legacy event like cycles without a
>>> PMU can encode differently than when specified with a PMU - the
>>> non-PMU version favoring legacy encodings, the PMU one avoiding legacy
>>> encodings.
>>>
>>> The patch removes events and then adjusts the idx value for each
>>> evsel. This is done so that the dense xyarrays used for file
>>> descriptors, etc. don't contain broken entries. As event opening
>>> happens relatively late in the record process, use of the idx value
>>> before the open will have become corrupted, so it is expected there
>>> are latent bugs hidden behind this change - the change is best
>>> effort. As the only vendor that has broken event names is ARM, this
>>> will principally effect ARM users. They will also experience warning
>>> messages like those above because of the uncore PMU advertising legacy
>>> event names.
>>
>>
>>
>>>
>>> Suggested-by: Arnaldo Carvalho de Melo <acme at kernel.org>
>>> Signed-off-by: Ian Rogers <irogers at google.com>
>>> ---
>>>    tools/perf/builtin-record.c | 22 +++++++++++++++++-----
>>>    1 file changed, 17 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
>>> index f83252472921..7e99743f7e42 100644
>>> --- a/tools/perf/builtin-record.c
>>> +++ b/tools/perf/builtin-record.c
>>> @@ -1364,6 +1364,7 @@ static int record__open(struct record *rec)
>>>        struct perf_session *session = rec->session;
>>>        struct record_opts *opts = &rec->opts;
>>>        int rc = 0;
>>> +     bool skipped = false;
>>>
>>>        evlist__for_each_entry(evlist, pos) {
>>>    try_again:
>>> @@ -1379,15 +1380,26 @@ static int record__open(struct record *rec)
>>>                                pos = evlist__reset_weak_group(evlist, pos, true);
>>>                                goto try_again;
>>>                        }
>>> -                     rc = -errno;
>>>                        evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg));
>>> -                     ui__error("%s\n", msg);
>>> -                     goto out;
>>> +                     ui__error("Failure to open event '%s' on PMU '%s' which will be removed.\n%s\n",
>>> +                               evsel__name(pos), evsel__pmu_name(pos), msg);
>>> +                     pos->skippable = true;
>>> +                     skipped = true;
>>> +             } else {
>>> +                     pos->supported = true;
>>>                }
>>> -
>>> -             pos->supported = true;
>>>        }
>>>
>>> +     if (skipped) {
>>> +             struct evsel *tmp;
>>> +             int idx = 0;
>>> +
>>> +             evlist__for_each_entry_safe(evlist, tmp, pos) {
>>> +                     if (pos->skippable)
>>> +                             evlist__remove(evlist, pos);
>>> +                     pos->core.idx = idx++;
>>> +             }
>>> +     }
>>>        if (symbol_conf.kptr_restrict && !evlist__exclude_kernel(evlist)) {
>>>                pr_warning(
>>>    "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
>>



From parthiban at linumiz.com  Tue Nov 12 06:13:27 2024
From: parthiban at linumiz.com (Parthiban)
Date: Tue, 12 Nov 2024 19:43:27 +0530
Subject: [PATCH v10 2/3] pwm: Add Allwinner's D1/T113-S3/R329 SoCs PWM
 support
In-Reply-To: <20241011102751.153248-3-privatesub2@gmail.com>
References: <20241011102751.153248-1-privatesub2@gmail.com>
 <20241011102751.153248-3-privatesub2@gmail.com>
Message-ID: <2f7ee626-8416-4a05-9add-26e100b16268@linumiz.com>

On 10/11/24 3:57 PM, Aleksandr Shubin wrote:
> Allwinner's D1, T113-S3 and R329 SoCs have a quite different PWM
> controllers with ones supported by pwm-sun4i driver.
> 
> This patch adds a PWM controller driver for Allwinner's D1,
> T113-S3 and R329 SoCs. The main difference between these SoCs
> is the number of channels defined by the DT property.

Thanks for your efforts. A133 uses the same IP and tried using the pwm for
LVDS backlight with below diff,

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
index 2b4ecbf3e724..67a8d52fccf0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
@@ -204,6 +204,16 @@ watchdog at 30090a0 {
                        clocks = <&dcxo24M>;
                };
 
+               pwm: pwm at 300a000 {
+                       compatible = "allwinner,sun20i-d1-pwm";
+                       reg = <0x300a000 0x400>;
+                       clocks = <&ccu CLK_BUS_PWM>, <&dcxo24M>, <&ccu CLK_APB1>;
+                       clock-names = "bus", "hosc", "apb";
+                       resets = <&ccu RST_BUS_PWM>;
+                       #pwm-cells = <0x3>;
+                       status = "disabled";
+               };
+

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a133-helper-board.dts b/arch/arm64/boot/dts/allwinner/sun50i-a133-helper-board.dts
index aa82c1d2799f..3355df370812 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a133-helper-board.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a133-helper-board.dts
@@ -19,6 +19,14 @@ aliases {
                serial0 = &uart0;
        };
 
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm 0 50000 0>;
+               brightness-levels = <0 5 10 15 20 30 40 55 70 85 100>;
+               default-brightness-level = <2>;
+               enable-gpios = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* PD23 */
+       };
+

Although the backlight tunrned on and pwm probed fine, I couldn't really
control the backlight brightness levels.

root at helper-board-a133:~# dmesg  | grep -i pwm
[    0.969739] sun20i-pwm 300a000.pwm: apb clock must be greater than hosc clock
[    1.486000] sun20i-pwm 300a000.pwm: .apply is not idempotent (ena=1 pol=0 5000/49959) -> (ena=1 pol=0 5000/49917)
[  410.760633] sun20i-pwm 300a000.pwm: .apply is not idempotent (ena=1 pol=0 49959/49959) -> (ena=1 pol=0 49917/49917)
[  425.284650] sun20i-pwm 300a000.pwm: .apply is not idempotent (ena=1 pol=0 5000/49959) -> (ena=1 pol=0 5000/49917)
[  428.180657] sun20i-pwm 300a000.pwm: .apply is not idempotent (ena=1 pol=0 2500/49959) -> (ena=1 pol=0 2500/49917)
[  431.952648] sun20i-pwm 300a000.pwm: .apply is not idempotent (ena=1 pol=0 49959/49959) -> (ena=1 pol=0 49917/49917)

Did I miss something?

> 
> Co-developed-by: Brandon Cheo Fusi <fusibrandon13 at gmail.com>
> Signed-off-by: Brandon Cheo Fusi <fusibrandon13 at gmail.com>
> Signed-off-by: Aleksandr Shubin <privatesub2 at gmail.com>
> ---
>  drivers/pwm/Kconfig      |  10 ++
>  drivers/pwm/Makefile     |   1 +
>  drivers/pwm/pwm-sun20i.c | 379 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 390 insertions(+)
>  create mode 100644 drivers/pwm/pwm-sun20i.c
> 
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index 0915c1e7df16..778151aa3860 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -652,6 +652,16 @@ config PWM_SUN4I
>  	  To compile this driver as a module, choose M here: the module
>  	  will be called pwm-sun4i.
>  
> +config PWM_SUN20I
> +	tristate "Allwinner D1/T113s/R329 PWM support"
> +	depends on ARCH_SUNXI || COMPILE_TEST
> +	depends on COMMON_CLK
> +	help
> +	  Generic PWM framework driver for Allwinner D1/T113s/R329 SoCs.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called pwm-sun20i.
> +
>  config PWM_SUNPLUS
>  	tristate "Sunplus PWM support"
>  	depends on ARCH_SUNPLUS || COMPILE_TEST
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 9081e0c0e9e0..85ad1fe0dde1 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -60,6 +60,7 @@ obj-$(CONFIG_PWM_STM32)		+= pwm-stm32.o
>  obj-$(CONFIG_PWM_STM32_LP)	+= pwm-stm32-lp.o
>  obj-$(CONFIG_PWM_STMPE)		+= pwm-stmpe.o
>  obj-$(CONFIG_PWM_SUN4I)		+= pwm-sun4i.o
> +obj-$(CONFIG_PWM_SUN20I)	+= pwm-sun20i.o
>  obj-$(CONFIG_PWM_SUNPLUS)	+= pwm-sunplus.o
>  obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
>  obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
> diff --git a/drivers/pwm/pwm-sun20i.c b/drivers/pwm/pwm-sun20i.c
> new file mode 100644
> index 000000000000..7d1b47843bb6
> --- /dev/null
> +++ b/drivers/pwm/pwm-sun20i.c
> @@ -0,0 +1,379 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PWM Controller Driver for sunxi platforms (D1, T113-S3 and R329)
> + *
> + * Limitations:
> + * - When the parameters change, current running period will not be completed
> + *   and run new settings immediately.
> + * - It output HIGH-Z state when PWM channel disabled.
> + *
> + * Copyright (c) 2023 Aleksandr Shubin <privatesub2 at gmail.com>
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/reset.h>
> +
> +#define SUN20I_PWM_CLK_CFG(chan)		(0x20 + ((chan) * 0x4))
> +#define SUN20I_PWM_CLK_CFG_SRC			GENMASK(8, 7)
> +#define SUN20I_PWM_CLK_CFG_DIV_M		GENMASK(3, 0)
> +#define SUN20I_PWM_CLK_DIV_M_MAX		8
> +
> +#define SUN20I_PWM_CLK_GATE			0x40
> +#define SUN20I_PWM_CLK_GATE_BYPASS(chan)	BIT((chan) + 16)
> +#define SUN20I_PWM_CLK_GATE_GATING(chan)	BIT(chan)
> +
> +#define SUN20I_PWM_ENABLE			0x80
> +#define SUN20I_PWM_ENABLE_EN(chan)		BIT(chan)
> +
> +#define SUN20I_PWM_CTL(chan)			(0x100 + (chan) * 0x20)
> +#define SUN20I_PWM_CTL_ACT_STA			BIT(8)
> +#define SUN20I_PWM_CTL_PRESCAL_K		GENMASK(7, 0)
> +#define SUN20I_PWM_CTL_PRESCAL_K_MAX		field_max(SUN20I_PWM_CTL_PRESCAL_K)
> +
> +#define SUN20I_PWM_PERIOD(chan)			(0x104 + (chan) * 0x20)
> +#define SUN20I_PWM_PERIOD_ENTIRE_CYCLE		GENMASK(31, 16)
> +#define SUN20I_PWM_PERIOD_ACT_CYCLE		GENMASK(15, 0)
> +
> +#define SUN20I_PWM_PCNTR_SIZE			BIT(16)
> +
> +/*
> + * SUN20I_PWM_MAGIC is used to quickly compute the values of the clock dividers
> + * div_m (SUN20I_PWM_CLK_CFG_DIV_M) & prescale_k (SUN20I_PWM_CTL_PRESCAL_K)
> + * without using a loop. These dividers limit the # of cycles in a period
> + * to SUN20I_PWM_PCNTR_SIZE by applying a scaling factor of
> + * 1/(div_m * (prescale_k + 1)) to the clock source.
> + *
> + * SUN20I_PWM_MAGIC is derived by solving for div_m and prescale_k
> + * such that for a given requested period,
> + *
> + * i) div_m is minimized for any prescale_k ? SUN20I_PWM_CTL_PRESCAL_K_MAX,
> + * ii) prescale_k is minimized.
> + *
> + * The derivation proceeds as follows, with val = # of cycles for requested
> + * period:
> + *
> + * for a given value of div_m we want the smallest prescale_k such that
> + *
> + * (val >> div_m) // (prescale_k + 1) ? 65536 (SUN20I_PWM_PCNTR_SIZE)
> + *
> + * This is equivalent to:
> + *
> + * (val >> div_m) ? 65536 * (prescale_k + 1) + prescale_k
> + * ? (val >> div_m) ? 65537 * prescale_k + 65536
> + * ? (val >> div_m) - 65536 ? 65537 * prescale_k
> + * ? ((val >> div_m) - 65536) / 65537 ? prescale_k
> + *
> + * As prescale_k is integer, this becomes
> + *
> + * ((val >> div_m) - 65536) // 65537 ? prescale_k
> + *
> + * And is minimized at
> + *
> + * ((val >> div_m) - 65536) // 65537
> + *
> + * Now we pick the smallest div_m that satifies prescale_k ? 255
> + * (i.e SUN20I_PWM_CTL_PRESCAL_K_MAX),
> + *
> + * ((val >> div_m) - 65536) // 65537 ? 255
> + * ? (val >> div_m) - 65536 ? 255 * 65537 + 65536
> + * ? val >> div_m ? 255 * 65537 + 2 * 65536
> + * ? val >> div_m < (255 * 65537 + 2 * 65536 + 1)
> + * ? div_m = fls((val) / (255 * 65537 + 2 * 65536 + 1))
> + *
> + * Suggested by Uwe Kleine-K?nig
> + */
> +#define SUN20I_PWM_MAGIC			(255 * 65537 + 2 * 65536 + 1)
> +
> +struct sun20i_pwm_chip {
> +	struct clk *clk_bus, *clk_hosc, *clk_apb;
> +	struct reset_control *rst;
> +	void __iomem *base;
> +	struct mutex mutex; /* Protect PWM apply state */
> +};
> +
> +static inline struct sun20i_pwm_chip *to_sun20i_pwm_chip(struct pwm_chip *chip)
> +{
> +	return pwmchip_get_drvdata(chip);
> +}
> +
> +static inline u32 sun20i_pwm_readl(struct sun20i_pwm_chip *chip,
> +				   unsigned long offset)
> +{
> +	return readl(chip->base + offset);
> +}
> +
> +static inline void sun20i_pwm_writel(struct sun20i_pwm_chip *chip,
> +				     u32 val, unsigned long offset)
> +{
> +	writel(val, chip->base + offset);
> +}
> +
> +static int sun20i_pwm_get_state(struct pwm_chip *chip,
> +				struct pwm_device *pwm,
> +				struct pwm_state *state)
> +{
> +	struct sun20i_pwm_chip *sun20i_chip = to_sun20i_pwm_chip(chip);
> +	u16 ent_cycle, act_cycle, prescale_k;
> +	u64 clk_rate, tmp;
> +	u8 div_m;
> +	u32 val;
> +
> +	mutex_lock(&sun20i_chip->mutex);
> +
> +	val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_CLK_CFG(pwm->hwpwm / 2));
> +	div_m = FIELD_GET(SUN20I_PWM_CLK_CFG_DIV_M, val);
> +	if (div_m > SUN20I_PWM_CLK_DIV_M_MAX)
> +		div_m = SUN20I_PWM_CLK_DIV_M_MAX;
> +
> +	if (FIELD_GET(SUN20I_PWM_CLK_CFG_SRC, val) == 0)
> +		clk_rate = clk_get_rate(sun20i_chip->clk_hosc);
> +	else
> +		clk_rate = clk_get_rate(sun20i_chip->clk_apb);
> +
> +	val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_CTL(pwm->hwpwm));
> +	state->polarity = (SUN20I_PWM_CTL_ACT_STA & val) ?
> +			   PWM_POLARITY_NORMAL : PWM_POLARITY_INVERSED;
> +
> +	prescale_k = FIELD_GET(SUN20I_PWM_CTL_PRESCAL_K, val) + 1;
> +
> +	val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_ENABLE);
> +	state->enabled = (SUN20I_PWM_ENABLE_EN(pwm->hwpwm) & val) ? true : false;
> +
> +	val = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_PERIOD(pwm->hwpwm));
> +
> +	mutex_unlock(&sun20i_chip->mutex);
> +
> +	act_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ACT_CYCLE, val);
> +	ent_cycle = FIELD_GET(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, val);
> +
> +	/*
> +	 * The duration of the active phase should not be longer
> +	 * than the duration of the period
> +	 */
> +	if (act_cycle > ent_cycle)
> +		act_cycle = ent_cycle;
> +
> +	/*
> +	 * We have act_cycle <= ent_cycle <= 0xffff, prescale_k <= 0x100,
> +	 * div_m <= 8. So the multiplication fits into an u64 without
> +	 * overflow.
> +	 */
> +	tmp = ((u64)(act_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> +	state->duty_cycle = DIV_ROUND_UP_ULL(tmp, clk_rate);
> +	tmp = ((u64)(ent_cycle) * prescale_k << div_m) * NSEC_PER_SEC;
> +	state->period = DIV_ROUND_UP_ULL(tmp, clk_rate);
> +
> +	return 0;
> +}
> +
> +static int sun20i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> +			    const struct pwm_state *state)
> +{
> +	struct sun20i_pwm_chip *sun20i_chip = to_sun20i_pwm_chip(chip);
> +	u64 bus_rate, hosc_rate, val, ent_cycle, act_cycle;
> +	u32 clk_gate, clk_cfg, pwm_en, ctl, reg_period;
> +	u32 prescale_k, div_m;
> +	bool use_bus_clk;
> +
> +	guard(mutex)(&sun20i_chip->mutex);
> +
> +	pwm_en = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_ENABLE);
> +
> +	if (state->enabled != pwm->state.enabled) {
> +		clk_gate = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_CLK_GATE);
> +
> +		if (!state->enabled) {
> +			clk_gate &= ~SUN20I_PWM_CLK_GATE_GATING(pwm->hwpwm);
> +			pwm_en &= ~SUN20I_PWM_ENABLE_EN(pwm->hwpwm);
> +			sun20i_pwm_writel(sun20i_chip, pwm_en, SUN20I_PWM_ENABLE);
> +			sun20i_pwm_writel(sun20i_chip, clk_gate, SUN20I_PWM_CLK_GATE);
> +
> +			return 0;
> +		}
> +	}
> +
> +	ctl = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_CTL(pwm->hwpwm));
> +	clk_cfg = sun20i_pwm_readl(sun20i_chip, SUN20I_PWM_CLK_CFG(pwm->hwpwm / 2));
> +	hosc_rate = clk_get_rate(sun20i_chip->clk_hosc);
> +	bus_rate = clk_get_rate(sun20i_chip->clk_apb);
> +	if (pwm_en & SUN20I_PWM_ENABLE_EN(pwm->hwpwm ^ 1)) {
> +		/* if the neighbor channel is enabled, check period only */
> +		use_bus_clk = FIELD_GET(SUN20I_PWM_CLK_CFG_SRC, clk_cfg) != 0;
> +		val = mul_u64_u64_div_u64(state->period,
> +					  (use_bus_clk ? bus_rate : hosc_rate),
> +					  NSEC_PER_SEC);
> +
> +		div_m = FIELD_GET(SUN20I_PWM_CLK_CFG_DIV_M, clk_cfg);
> +	} else {
> +		/*
> +		 * Select the clock source based on the period,
> +		 * since bus_rate > hosc_rate, which means bus_rate
> +		 * can provide a higher frequency than hosc_rate.
> +		 */
> +		use_bus_clk = false;
> +		val = mul_u64_u64_div_u64(state->period, hosc_rate, NSEC_PER_SEC);
> +		if (val <= 1) {
> +			use_bus_clk = true;
> +			val = mul_u64_u64_div_u64(state->period, bus_rate, NSEC_PER_SEC);
> +			if (val <= 1)
> +				return -EINVAL;
> +		}
> +		div_m = fls(DIV_ROUND_DOWN_ULL(val, SUN20I_PWM_MAGIC));
> +		if (div_m > SUN20I_PWM_CLK_DIV_M_MAX)
> +			return -EINVAL;
> +
> +		/* set up the CLK_DIV_M and clock CLK_SRC */
> +		clk_cfg = FIELD_PREP(SUN20I_PWM_CLK_CFG_DIV_M, div_m);
> +		clk_cfg |= FIELD_PREP(SUN20I_PWM_CLK_CFG_SRC, use_bus_clk);
> +
> +		sun20i_pwm_writel(sun20i_chip, clk_cfg, SUN20I_PWM_CLK_CFG(pwm->hwpwm / 2));
> +	}
> +
> +	/* calculate prescale_k, PWM entire cycle */
> +	ent_cycle = val >> div_m;
> +	prescale_k = DIV_ROUND_DOWN_ULL(ent_cycle, 65537);
> +	if (prescale_k > SUN20I_PWM_CTL_PRESCAL_K_MAX)
> +		prescale_k = SUN20I_PWM_CTL_PRESCAL_K_MAX;
> +
> +	do_div(ent_cycle, prescale_k + 1);
> +
> +	/* for N cycles, PPRx.PWM_ENTIRE_CYCLE = (N-1) */
> +	reg_period = FIELD_PREP(SUN20I_PWM_PERIOD_ENTIRE_CYCLE, ent_cycle - 1);
> +
> +	/* set duty cycle */
> +	val = mul_u64_u64_div_u64(state->duty_cycle,
> +				  (use_bus_clk ? bus_rate : hosc_rate),
> +				  NSEC_PER_SEC);
> +	act_cycle = val >> div_m;
> +	do_div(act_cycle, prescale_k + 1);
> +
> +	/*
> +	 * The formula of the output period and the duty-cycle for PWM are as follows.
> +	 * T period = PWM0_PRESCALE_K / PWM01_CLK * (PPR0.PWM_ENTIRE_CYCLE + 1)
> +	 * T high-level = PWM0_PRESCALE_K / PWM01_CLK * PPR0.PWM_ACT_CYCLE
> +	 * Duty-cycle = T high-level / T period
> +	 */
> +	reg_period |= FIELD_PREP(SUN20I_PWM_PERIOD_ACT_CYCLE, act_cycle);
> +	sun20i_pwm_writel(sun20i_chip, reg_period, SUN20I_PWM_PERIOD(pwm->hwpwm));
> +
> +	ctl = FIELD_PREP(SUN20I_PWM_CTL_PRESCAL_K, prescale_k);
> +	if (state->polarity == PWM_POLARITY_NORMAL)
> +		ctl |= SUN20I_PWM_CTL_ACT_STA;
> +
> +	sun20i_pwm_writel(sun20i_chip, ctl, SUN20I_PWM_CTL(pwm->hwpwm));
> +
> +	if (state->enabled != pwm->state.enabled && state->enabled) {
> +		clk_gate &= ~SUN20I_PWM_CLK_GATE_BYPASS(pwm->hwpwm);
> +		clk_gate |= SUN20I_PWM_CLK_GATE_GATING(pwm->hwpwm);
> +		pwm_en |= SUN20I_PWM_ENABLE_EN(pwm->hwpwm);
> +		sun20i_pwm_writel(sun20i_chip, pwm_en, SUN20I_PWM_ENABLE);
> +		sun20i_pwm_writel(sun20i_chip, clk_gate, SUN20I_PWM_CLK_GATE);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct pwm_ops sun20i_pwm_ops = {
> +	.apply = sun20i_pwm_apply,
> +	.get_state = sun20i_pwm_get_state,
> +};
> +
> +static const struct of_device_id sun20i_pwm_dt_ids[] = {
> +	{ .compatible = "allwinner,sun20i-d1-pwm" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, sun20i_pwm_dt_ids);
> +
> +static void sun20i_pwm_reset_ctrl_release(void *data)
> +{
> +	struct reset_control *rst = data;
> +
> +	reset_control_assert(rst);
> +}
> +
> +static int sun20i_pwm_probe(struct platform_device *pdev)
> +{
> +	struct pwm_chip *chip;
> +	struct sun20i_pwm_chip *sun20i_chip;
> +	int ret;
> +
> +	chip = devm_pwmchip_alloc(&pdev->dev, 8, sizeof(*sun20i_chip));
> +	if (IS_ERR(chip))
> +		return PTR_ERR(chip);
> +	sun20i_chip = to_sun20i_pwm_chip(chip);
> +
> +	sun20i_chip->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(sun20i_chip->base))
> +		return PTR_ERR(sun20i_chip->base);
> +
> +	sun20i_chip->clk_bus = devm_clk_get_enabled(&pdev->dev, "bus");
> +	if (IS_ERR(sun20i_chip->clk_bus))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_bus),
> +				     "failed to get bus clock\n");
> +
> +	sun20i_chip->clk_hosc = devm_clk_get_enabled(&pdev->dev, "hosc");

A133 also have r_pwm,

+               r_pwm: pwm at 7020c00 {
+                       compatible = "allwinner,sun20i-d1-pwm";
+                       reg = <0x7020c00 0x400>;
+                       clocks = <&ccu CLK_R_APB1_PWM>, <&ccu CLK_R_APB1_BUS_PWM>, <&ccu CLK_APB1>;
+                       clock-names = "bus", "mod", "apb";
+                       resets = <&r_ccu RST_R_APB1_BUS_PWM>;
+                       #pwm-cells = <0x3>;
+                       status = "disabled";
+               };
+

with "bus" clock and "mod" clock for gating it. Calling it as "hosc" doesn't
makes sense IMO. pwm-sun4i.c handles it already. Do we also need to handled "mod"?

> +	if (IS_ERR(sun20i_chip->clk_hosc))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_hosc),
> +				     "failed to get hosc clock\n");
> +
> +	sun20i_chip->clk_apb = devm_clk_get_enabled(&pdev->dev, "apb");
> +	if (IS_ERR(sun20i_chip->clk_apb))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->clk_apb),
> +				     "failed to get apb clock\n");
> +
> +	if (clk_get_rate(sun20i_chip->clk_apb) > clk_get_rate(sun20i_chip->clk_hosc))
> +		dev_info(&pdev->dev, "apb clock must be greater than hosc clock");

This is always the case if am not wrong. This condition check needed?

Thanks,
Parthiban

> +
> +	sun20i_chip->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> +	if (IS_ERR(sun20i_chip->rst))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(sun20i_chip->rst),
> +				     "failed to get bus reset\n");
> +
> +	ret = of_property_read_u32(pdev->dev.of_node, "allwinner,pwm-channels",
> +				   &chip->npwm);
> +
> +	if (chip->npwm > 16) {
> +		dev_info(&pdev->dev, "limiting number of PWM lines from %u to 16",
> +			 chip->npwm);
> +		chip->npwm = 16;
> +	}
> +
> +	/* Deassert reset */
> +	ret = reset_control_deassert(sun20i_chip->rst);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret, "failed to deassert reset\n");
> +
> +	ret = devm_add_action_or_reset(&pdev->dev, sun20i_pwm_reset_ctrl_release, sun20i_chip->rst);
> +	if (ret)
> +		return ret;
> +
> +	chip->ops = &sun20i_pwm_ops;
> +
> +	mutex_init(&sun20i_chip->mutex);
> +
> +	ret = devm_pwmchip_add(&pdev->dev, chip);
> +	if (ret < 0)
> +		return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
> +
> +	return 0;
> +}
> +
> +static struct platform_driver sun20i_pwm_driver = {
> +	.driver = {
> +		.name = "sun20i-pwm",
> +		.of_match_table = sun20i_pwm_dt_ids,
> +	},
> +	.probe = sun20i_pwm_probe,
> +};
> +module_platform_driver(sun20i_pwm_driver);
> +
> +MODULE_AUTHOR("Aleksandr Shubin <privatesub2 at gmail.com>");
> +MODULE_DESCRIPTION("Allwinner sun20i PWM driver");
> +MODULE_LICENSE("GPL");



From james.clark at linaro.org  Tue Nov 12 06:21:59 2024
From: james.clark at linaro.org (James Clark)
Date: Tue, 12 Nov 2024 14:21:59 +0000
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is
 provided
In-Reply-To: <CAP-5=fUHjxL5QbsyQQU-3EYiVhiO6wt=F5MfSfDcAffKP7WWAg@mail.gmail.com>
References: <20241026121758.143259-1-irogers@google.com>
 <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
 <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org>
 <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
 <d9bfd75a-003a-4f65-abba-b8bcaad13682@linaro.org>
 <CAP-5=fUHjxL5QbsyQQU-3EYiVhiO6wt=F5MfSfDcAffKP7WWAg@mail.gmail.com>
Message-ID: <ccac5d65-b01f-4624-97cd-e350ce6de840@linaro.org>



On 11/11/2024 5:19 pm, Ian Rogers wrote:
> On Mon, Nov 11, 2024 at 2:45?AM James Clark <james.clark at linaro.org> wrote:
>>
>>
>>
>> On 08/11/2024 6:37 pm, Atish Kumar Patra wrote:
>>> On Fri, Nov 8, 2024 at 4:16?AM James Clark <james.clark at linaro.org> wrote:
>>>>
>>>>
>>>>
>>>> On 07/11/2024 18:51, Ian Rogers wrote:
>>>>> On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
>>>>>>
>>>>>> At the RISC-V summit the topic of avoiding event data being in the
>>>>>> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
>>>>>> events being the priority when no PMU is provided so that legacy
>>>>>> events maybe supported via json. Originally Mark Rutland also
>>>>>> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
>>>>>> M? processors, but James Clark more recently tested this and believes
>>>>>> the driver issues there may not have existed or have been resolved. In
>>>>>> any case, it is inconsistent that with a PMU event names avoid legacy
>>>>>> encodings, but when wildcarding PMUs (ie without a PMU with the event
>>>>>> name) the legacy encodings have priority.
>>>>>>
>>>>>> The patch doing this work was reverted in a v6.10 release candidate
>>>>>> as, even though the patch was posted for weeks and had been on
>>>>>> linux-next for weeks without issue, Linus was in the habit of using
>>>>>> explicit legacy events with unsupported precision options on his
>>>>>> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
>>>>>> where ARM decided to call the events bus_cycles and cycles, the latter
>>>>>> being also a legacy event name. ARM haven't renamed the cycles event
>>>>>> to a more consistent cpu_cycles and avoided the problem. With these
>>>>>> changes the problematic event will now be skipped, a large warning
>>>>>> produced, and perf record will continue for the other PMU events. This
>>>>>> solution was proposed by Arnaldo.
>>>>>>
>>>>>> Two minor changes have been added to help with the error message and
>>>>>> to work around issues occurring with "perf stat metrics (shadow stat)
>>>>>> test".
>>>>>>
>>>>>> The patches have only been tested on my x86 non-hybrid laptop.
>>>>>
>>>>> Hi Atish and James,
>>>>>
>>>>> Could I get your tags for this series?
>>>>>
>>>
>>> Hi Ian,
>>> Thanks for your patches. It definitely helps to have a clean slate
>>> implementation
>>> for the perf tool. However, I have some open questions about other use cases
>>> that we discussed during the RVI Summit.
>>>
>>>>> The patches were originally motivated by wanting to make the behavior
>>>>> of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
>>>>> wildcarded to "cpu" in the first case. This was divergent because of
>>>>> ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
>>>>> config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
>>>>> type>, config=<encoding from event>) when a PMU name was given. This
>>>>> aligns with RISC-V wanting to use json encodings to avoid complexity
>>>>> in the PMU driver.
>>>>>
>>>>
>>>> I couldn't find the thread, but I remember fairly recently it was
>>>> mentioned that RISC-V would be supporting the legacy events after all,
>>>> maybe it was a comment from Atish? I'm not sure if that changes the
>>>> requirements for this or not?
>>>>
>>>> I still can't really imagine how tooling would work if every tool has to
>>>> maintain the mappings of basic events like instructions and branches.
>>>> For example all the perf_event_open tests in ltp use the legacy events.
>>>>
>>>
>>> No it has not changed. While this series helps to avoid clunky vendor
>>> specific encodings
>>> in the driver for perf tool, I am still unsure how we will manage
>>> other applications
>>> (directly passing legacy events through perf_event_open or
>>> perf_evlist__open) will work.
>>>
>>> I have only anecdotal data about folks relying perf legacy events
>>> directly to profile
>>> their application. All of them use mostly cycle/instruction events though.
>>> Are there any users who use other legacy events directly without perf tool ?
>>>
>>> If not, we may have only cycle/instruction mapping in the driver and
>>> rely on json for everything else.
>>> The other use case is virtualization. I have been playing with these
>>> patches to find a clean solution to
>>> enable all the use cases. If you have any other ideas, please let me know.
>>>
>>
>> Yeah I would expect it's mostly cycles and instructions. I searched a
>> bit for PERF_COUNT_HW_BRANCH_MISSES and only found tool/developer type
>> usages, which I suppose we could expect to have to handle the mappings
>> like perf. Although it's not the easiest thing to search for and
>> obviously that only includes open source.
>>
>> Usages do exist though, there are people posting on stack overflow using
>> it, and other various bug tracker listings. So you would expect those
>> same users to have to use raw event codes and some switch statement to
>> pick the right one for their hardware, or use Perf.
> 
> I don't have any magic to solve this. My thoughts:
> 
> 1) I thought legacy events were just going to hang around forever,
> although the name hinting they'd kind of been deprecated. At LPC '23
> Atish and Mark Rutland originally asked for the sysfs/json to be the
> preference. I thought Kan was going to push back given the upheaval,
> especially updating every test expectation. It went through but we're
> in this weird state where wildcard events are encoded using legacy and
> PMU specifying events aren't. What this series hopes to solve.
> 
> 2) I think it is important that perf tool be a reference
> implementation where others can look (strace, etc.) to base their
> implementation. Moving perf to sysfs/json is 1 step closer to legacy
> event deprecation. Please yell if deprecation isn't what is wanted as
> personally other than cleanliness I don't mind. If we do decide not to
> have sysfs/json be the priority then I think it sensible to revert the
> changes making it the priority for events that specify a PMU. I'd like
> some level of consistency.

Personally this change feels like it's encouraging fragmentation, the 
cleanest would be if RISC-V supports the legacy events like the other 
platforms. It's not a huge set of events anyway, and then existing 
software continues to work in addition to Perf continuing to work.

If we're still thinking that RISC-V will support the legacy events 
anyway in the future, then it weakens the argument to change this and 
risk any breakages that fall out of it.

I'm also not sure whether they really are legacy or just a common base 
set of events. Since the extended type thing was added even the legacy 
events support hybrid, so it's not like they expired from lack of 
features. Even if we claim they're legacy, is that really ever going to 
make them go away?

Although I admit nobody has come out with a definitive use case that 
doesn't use either the cycles or instructions events, so maybe its all fine.

> 
> 3) I'd like event parsing to be a library that is as easy to link
> against as libbpf (i.e. not a viral license). Event parsing is really
> just mapping an event name to 1 or more perf_event_attr. The PMU
> abstraction is tied into the event parsing, but this has only been
> more true recently. The evsel/evlist is tied into event parsing but
> that feels separable. As most json isn't distributed under a viral
> license this feels achievable, then I suspect most tools can use this
> library rather than have to reinvent a wheel.
> 
> Still looking for tags :-)
> 
> Thanks,
> Ian



From roypat at amazon.co.uk  Tue Nov 12 06:40:32 2024
From: roypat at amazon.co.uk (Patrick Roy)
Date: Tue, 12 Nov 2024 14:40:32 +0000
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <10e4d078-3cdb-4d1c-a1a3-80e91b247217@redhat.com>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <4aa0ccf4-ebbe-4244-bc85-8bc8dcd14e74@redhat.com>
 <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
 <d1a69eb7-85d5-4ffa-88e2-f4841713c1d7@redhat.com>
 <90c9d8c0-814e-4c86-86ef-439cb5552cb6@amazon.co.uk>
 <10e4d078-3cdb-4d1c-a1a3-80e91b247217@redhat.com>
Message-ID: <02f77d32-e2a1-431b-bb67-33d36c06acd3@amazon.co.uk>


Hi David, 

sorry for the late response, I ended up catching the flu last week and
was out of commission for a while :(

On Mon, 2024-11-04 at 21:30 +0000, David Hildenbrand wrote:
>>> We talked about shared (faultable) vs. private (unfaultable), and how it
>>> would interact with the directmap patches here.
>>>
>>> As discussed, having private (unfaultable) memory with the direct-map
>>> removed and shared (faultable) memory with the direct-mapping can make
>>> sense for non-TDX/AMD-SEV/... non-CoCo use cases. Not sure about CoCo,
>>> the discussion here seems to indicate that it might currently not be
>>> required.
>>>
>>> So one thing we could do is that shared (faultable) will have a direct
>>> mapping and be gup-able and private (unfaultable) memory will not have a
>>> direct mapping and is, by design, not gup-able.>
>>> Maybe it could make sense to not have a direct map for all guest_memfd
>>> memory, making it behave like secretmem (and it would be easy to
>>> implement)? But I'm not sure if that is really desirable in VM context.
>>
>> This would work for us (in this scenario, the swiotlb areas would be
>> "traditional" memory, e.g. set to shared via mem attributes instead of
>> "shared" inside KVM), it's kinda what I had prototyped in my v1 of this
>> series (well, we'd need to figure out how to get the mappings of gmem
>> back into KVM, since in this setup, short-circuiting it into
>> userspace_addr wouldn't work, unless we banish swiotlb into a different
>> memslot altogether somehow).
> 
> Right.

"right" as in, "yes we could do that"? :p

>> But I don't think it'd work for pKVM, iirc
>> they need GUP on gmem, and also want direct map removal (... but maybe,
>> the gmem VMA for non-CoCo usecase and the gmem VMA for pKVM could be
>> behave differently?  non-CoCo gets essentially memfd_secret, pKVM gets
>> GUP+no faults of private mem).
> 
> Good question. So far my perception was that the directmap removal on
> "private/unfaultable" would be sufficient.
> 
>>
>>> Having a mixture of "has directmap" and "has no directmap" for shared
>>> (faultable) memory should not be done. Similarly, private memory really
>>> should stay "unfaultable".
>>
>> You've convinced me that having both GUP-able and non GUP-able
>> memory in the same VMA will be tricky. However, I'm less convinced on
>> why private memory should stay unfaultable; only that it shouldn't be
>> faultable into a VMA that also allows GUP. Can we have two VMAs? One
>> that disallows GUP, but allows userspace access to shared and private,
>> and one that allows GUP, but disallows accessing private memory? Maybe
>> via some `PROT_NOGUP` flag to `mmap`? I guess this is a slightly
>> different spin of the above idea.
> 
> What we are trying to achieve is making guest_memfd not behave
> completely different on that level for different "types" of VMs. So one
> of the goals should be to try to unify it as much as possible.
> 
> shared -> faultable: GUP-able
> private -> unfaultable: unGUP-able
> 
> 
> And it makes sense, because a lot of future work will rely on some
> important properties: for example, if private memory cannot be faulted
> in + GUPed, core-MM will never have obtained valid references to such a
> page. There is no need to split large folios into smaller ones for
> tracking purposes; there is no need to maintain per-page refcounts and
> pincounts ...
> 
> It doesn't mean that we cannot consider it if really required, but there
> really has to be a strong case for it, because it will all get really messy.
> 
> For example, one issue is that a folio only has a single mapping
> (folio->mapping), and that is used in the GUP-fast path (no VMA) to
> determine whether GUP-fast is allowed or not.
> 
> So you'd have to force everything through GUP-slow, where you could
> consider VMA properties :( It sounds quite suboptimal.
> 
> I don't think multiple VMAs are what we really want. See below.

Ah, okay, I see. Thanks for explaining, this all makes a lot of sense to
me now!

>>
>>> I think one of the points raised during the bi-weekly call was that
>>> using a viommu/swiotlb might be the right call, such that all memory can
>>> be considered private (unfaultable) that is not explicitly
>>> shared/expected to be modified by the hypervisor (-> faultable, ->
>>> GUP-able).
>>>
>>> Further, I think Sean had some good points why we should explore that
>>> direction, but I recall that there were some issue to be sorted out
>>> (interpreted instructions requiring direct map when accessing "private"
>>> memory?), not sure if that is already working/can be made working in KVM.
>>
>> Yeah, the big one is MMIO instruction emulation on x86, which does guest
>> page table walks and instruction fetch (and particularly the latter
>> cannot be known ahead-of-time by the guest, aka cannot be explicitly
>> "shared"). That's what the majority of my v2 series was about. For
>> traditional memslots, KVM handles these via get_user and friends, but if
>> we don't have a VMA that allows faulting all of gmem, then that's
>> impossible, and we're in "temporarily restore direct map" land. Which
>> comes with significantly performance penalties due to TLB flushes.
> 
> Agreed.
> 
>> >> What's your opinion after the call and the next step for use cases
> like
>>> you have in mind (IIRC firecracker, which wants to not have the
>>> direct-map for guest memory where it can be avoided)?
>>
>> Yea, the usecase is for Firecracker to not have direct map entries for
>> guest memory, unless needed for I/O (-> swiotlb).
>>
>> As for next steps, let's determine once and for all if we can do the
>> KVM-internal guest memory accesses for MMIO emulation through userspace
>> mappings (although if we can't I'll have some serious soul-searching to
>> do, because all other solutions we talked about so far also have fairly
>> big drawbacks; on-demand direct map reinsertion has terrible
>> performance
> So IIUC, KVM would have to access "unfaultable" guest_memfd memory using
> fd+offset, and that's problematic because "no-directmap".
> 
> So you'd have to map+unmap the directmap repeatedly, and still expose it
> temporarily in the direct map to others. I see how that is undesirable,
> even when trying to cache hotspots (partly destroying the purpose of the
> directmap removal).
> 
> 
> Would a per-MM kernel mapping of these pages work, so KVM can access them?
> 
> It sounds a bit like what is required for clean per-MM allocations [1]:
> establish a per-MM kernel mapping of (selected?) pages. Not necessarily
> all of them.
> 
> Yes, we'd be avoiding VMAs, GUP, mapcounts, pincounts and everything
> involved with ordinary user mappings for these private/unfaultable
> thingies. Just like as discussed in, and similar to [1].
> 
> Just throwing it out there, maybe we really want to avoid the directmap
> (keep it unmapped) and maintain a per-mm mapping for a bunch of folios
> that can be easily removed when required by guest_memfd (ftruncate,
> conversion private->shared) on request.

I remember talking to someone at some point about whether we could reuse
the proc-local stuff for guest memory, but I cannot remember the outcome
of that discussion... (or maybe I just wanted to have a discussion about
it, but forgot to follow up on that thought?).  I guess we wouldn't use
proc-local _allocations_, but rather just set up proc-local mappings of
the gmem allocations that have been removed from the direct map.

I'm wondering, where exactly would be the differences to Sean's idea
about messing with the CR3 register inside KVM to temporarily install
page tables that contain all the gmem stuff, conceptually? Wouldn't we
run into the same interrupt problems that Sean foresaw for the CR3
stuff? (which, admittedly, I still don't quite follow what these are :(
).

(I've cc'd Fares Mehanna as well)

> [1] https://lore.kernel.org/all/20240911143421.85612-1-faresx at amazon.de/T/#u
> 
> -- 
> Cheers,
> 
> David / dhildenb
> 

Best,
Patrick


From roypat at amazon.co.uk  Tue Nov 12 06:48:48 2024
From: roypat at amazon.co.uk (Patrick Roy)
Date: Tue, 12 Nov 2024 14:48:48 +0000
Subject: [RFC PATCH v3 1/6] arch: introduce set_direct_map_valid_noflush()
In-Reply-To: <440b2682-dbfb-4a5c-927c-2397413a7f9c@suse.cz>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <20241030134912.515725-2-roypat@amazon.co.uk>
 <a774e13e-0616-4d96-bb51-bac0fcb2cb9b@redhat.com>
 <440b2682-dbfb-4a5c-927c-2397413a7f9c@suse.cz>
Message-ID: <bb534fec-b45d-4ff8-aa55-7201766936b5@amazon.co.uk>



On Mon, 2024-11-11 at 12:12 +0000, Vlastimil Babka wrote:
> On 10/31/24 10:57, David Hildenbrand wrote:
>> On 30.10.24 14:49, Patrick Roy wrote:
>>> From: "Mike Rapoport (Microsoft)" <rppt at kernel.org>
>>>
>>> From: Mike Rapoport (Microsoft) <rppt at kernel.org>
>>>
>>> Add an API that will allow updates of the direct/linear map for a set of
>>> physically contiguous pages.
>>>
>>> It will be used in the following patches.
>>>
>>> Signed-off-by: Mike Rapoport (Microsoft) <rppt at kernel.org>
>>> Signed-off-by: Patrick Roy <roypat at amazon.co.uk>
>>
>>
>> [...]
>>
>>>   #ifdef CONFIG_DEBUG_PAGEALLOC
>>>   void __kernel_map_pages(struct page *page, int numpages, int enable)
>>>   {
>>> diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
>>> index e7aec20fb44f1..3030d9245f5ac 100644
>>> --- a/include/linux/set_memory.h
>>> +++ b/include/linux/set_memory.h
>>> @@ -34,6 +34,12 @@ static inline int set_direct_map_default_noflush(struct page *page)
>>>      return 0;
>>>   }
>>>
>>> +static inline int set_direct_map_valid_noflush(struct page *page,
>>> +                                           unsigned nr, bool valid)
>>
>> I recall that "unsigned" is frowned upon; "unsigned int".
>>
>>> +{
>>> +    return 0;
>>> +}
>>
>> Can we add some kernel doc for this?
>>
>> In particular
>>
>> (a) What does it mean when we return 0? That it worked? Then, this
> 
> Seems so.
> 
>>      dummy function looks wrong. Or this it return the
> 
> That's !CONFIG_ARCH_HAS_SET_DIRECT_MAP and other functions around do it the
> same way. Looks like the current callers can only exist with the CONFIG_
> enabled in the first place.

Yeah, it looks a bit weird, but these functions seem to generally return
0 if the operation is not supported. ARM specifically has 

	if (!can_set_direct_map())
		return 0;

inside `set_direct_map_invalid_{noflush,default}`. Documenting this
definitely cannot hurt, I'll keep it on my todo list for the next
iteration :)

>>      number of processed entries? Then we'd have a possible "int" vs.
>>      "unsigned int" inconsistency.
>>
>> (b) What are the semantics when we fail halfway through the operation
>>      when processing nr > 1? Is it "all or nothing"?
> 
> Looking at x86 implementation it seems like it can just bail out in the
> middle, but then I'm not sure if it can really fail in the middle, hmm...

If I understood Mike correctly when talking about this at LPC, then it
can only fail if during break-up of huge mappings, it fails to allocate
page tables to hold the lower-granularity mappings (which happens before
any present bits are modified).

Best,
Patrick


From david at redhat.com  Tue Nov 12 06:52:58 2024
From: david at redhat.com (David Hildenbrand)
Date: Tue, 12 Nov 2024 15:52:58 +0100
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <02f77d32-e2a1-431b-bb67-33d36c06acd3@amazon.co.uk>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <4aa0ccf4-ebbe-4244-bc85-8bc8dcd14e74@redhat.com>
 <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
 <d1a69eb7-85d5-4ffa-88e2-f4841713c1d7@redhat.com>
 <90c9d8c0-814e-4c86-86ef-439cb5552cb6@amazon.co.uk>
 <10e4d078-3cdb-4d1c-a1a3-80e91b247217@redhat.com>
 <02f77d32-e2a1-431b-bb67-33d36c06acd3@amazon.co.uk>
Message-ID: <f4c5d0a6-a582-44e3-8949-c199cc0bfba7@redhat.com>

On 12.11.24 15:40, Patrick Roy wrote:
> 
> Hi David,
> 
> sorry for the late response, I ended up catching the flu last week and
> was out of commission for a while :(
> 
> On Mon, 2024-11-04 at 21:30 +0000, David Hildenbrand wrote:
>>>> We talked about shared (faultable) vs. private (unfaultable), and how it
>>>> would interact with the directmap patches here.
>>>>
>>>> As discussed, having private (unfaultable) memory with the direct-map
>>>> removed and shared (faultable) memory with the direct-mapping can make
>>>> sense for non-TDX/AMD-SEV/... non-CoCo use cases. Not sure about CoCo,
>>>> the discussion here seems to indicate that it might currently not be
>>>> required.
>>>>
>>>> So one thing we could do is that shared (faultable) will have a direct
>>>> mapping and be gup-able and private (unfaultable) memory will not have a
>>>> direct mapping and is, by design, not gup-able.>
>>>> Maybe it could make sense to not have a direct map for all guest_memfd
>>>> memory, making it behave like secretmem (and it would be easy to
>>>> implement)? But I'm not sure if that is really desirable in VM context.
>>>
>>> This would work for us (in this scenario, the swiotlb areas would be
>>> "traditional" memory, e.g. set to shared via mem attributes instead of
>>> "shared" inside KVM), it's kinda what I had prototyped in my v1 of this
>>> series (well, we'd need to figure out how to get the mappings of gmem
>>> back into KVM, since in this setup, short-circuiting it into
>>> userspace_addr wouldn't work, unless we banish swiotlb into a different
>>> memslot altogether somehow).
>>
>> Right.
> 
> "right" as in, "yes we could do that"? :p

"right" as in "I see how that could work" :)

[...]

> 
> I remember talking to someone at some point about whether we could reuse
> the proc-local stuff for guest memory, but I cannot remember the outcome
> of that discussion... (or maybe I just wanted to have a discussion about
> it, but forgot to follow up on that thought?).  I guess we wouldn't use
> proc-local _allocations_, but rather just set up proc-local mappings of
> the gmem allocations that have been removed from the direct map.

Yes. And likely only for memory we really access / try access, if possible.

> 
> I'm wondering, where exactly would be the differences to Sean's idea
> about messing with the CR3 register inside KVM to temporarily install
> page tables that contain all the gmem stuff, conceptually? Wouldn't we
> run into the same interrupt problems that Sean foresaw for the CR3
> stuff? (which, admittedly, I still don't quite follow what these are :(
> ).

I'd need some more details on that. If anything would rely on the direct 
mapping (from IRQ context?) than ... we obviously cannot remove the 
direct mapping :)

-- 
Cheers,

David / dhildenb



From geert+renesas at glider.be  Tue Nov 12 07:31:51 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue, 12 Nov 2024 16:31:51 +0100
Subject: [PATCH] irqchip: THEAD_C901_ACLINT_SSWI should depend on ARCH_THEAD
Message-ID: <1097d054ed4c67f714679de1253e45a034e647a0.1731425416.git.geert+renesas@glider.be>

The T-HEAD ACLINT S-mode IPI Interrupt Controller is only present on
T-HEAD SoCs.  Hence add a dependency on ARCH_THEAD, to prevent asking
the user about this driver when configuring a kernel without T-HEAD SoC
support.

Fixes: 25caea955cc95050 ("irqchip: Add T-HEAD C900 ACLINT SSWI driver")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 drivers/irqchip/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 28c19bde55206847..3f4cfcbecc5a4041 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -617,6 +617,7 @@ config THEAD_C900_ACLINT_SSWI
 	bool "THEAD C9XX ACLINT S-mode IPI Interrupt Controller"
 	depends on RISCV
 	depends on SMP
+	depends on ARCH_THEAD || COMPILE_TEST
 	select IRQ_DOMAIN_HIERARCHY
 	select GENERIC_IRQ_IPI_MUX
 	help
-- 
2.34.1



From robh at kernel.org  Tue Nov 12 07:52:40 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 12 Nov 2024 09:52:40 -0600
Subject: [PATCH 1/3] dt-bindings: interrupt-controller: Add Sophgo SG2042
 MSI
In-Reply-To: <5186bb9c7feebb87136eb5e5e117fb1142dba4c2.1731296803.git.unicorn_wang@outlook.com>
References: <cover.1731296803.git.unicorn_wang@outlook.com>
 <5186bb9c7feebb87136eb5e5e117fb1142dba4c2.1731296803.git.unicorn_wang@outlook.com>
Message-ID: <20241112155240.GA956207-robh@kernel.org>

On Mon, Nov 11, 2024 at 12:01:36PM +0800, Chen Wang wrote:
> From: Chen Wang <unicorn_wang at outlook.com>
> 
> Add binding for Sophgo SG2042 MSI controller.
> 
> Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
> ---
>  .../sophgo,sg2042-msi.yaml                    | 78 +++++++++++++++++++
>  1 file changed, 78 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml b/Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml
> new file mode 100644
> index 000000000000..9fe99b74c211
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml
> @@ -0,0 +1,78 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/sophgo,sg2042-msi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Sophgo SG2042 MSI Controller
> +
> +maintainers:
> +  - Chen Wang <unicorn_wang at outlook.com>
> +
> +description:
> +  This interrupt controller is in Sophgo SG2042 for transforming interrupts from
> +  PCIe MSI to PLIC interrupts.
> +
> +allOf:
> +  - $ref: /schemas/interrupts.yaml#
> +  - $ref: /schemas/interrupt-controller/msi-controller.yaml#
> +
> +properties:
> +  compatible:
> +    const: sophgo,sg2042-msi
> +
> +  reg:
> +    items:
> +      - description: clear register
> +
> +  reg-names:
> +    items:
> +      - const: clr
> +
> +  sophgo,msi-doorbell-addr:
> +    description:
> +      u64 value of the MSI doorbell address
> +    $ref: /schemas/types.yaml#/definitions/uint64

Why not use a 'reg' entry?

In any case, this should be a translatable address (i.e. honor 
#address-cells/#size-cells and ranges).

> +
> +  sophgo,msi-base-vec:
> +    description:
> +      u32 value of the base of parent PLIC vector allocated
> +      to MSI.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 64
> +    maximum: 95
> +
> +  sophgo,msi-num-vecs:
> +    description:
> +      u32 value of the number of parent PLIC vectors allocated
> +      to MSI.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 1
> +    maximum: 32

Use 'msi-ranges' for these.

> +
> +  msi-controller: true
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - msi-controller
> +  - sophgo,msi-doorbell-addr
> +  - sophgo,msi-base-vec
> +  - sophgo,msi-num-vecs
> +
> +additionalProperties: true
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    msi: msi-controller at 30000000 {
> +      compatible = "sophgo,sg2042-msi";
> +      reg = <0x30000000 0x4>;
> +      reg-names = "clr";
> +      msi-controller;
> +      sophgo,msi-doorbell-addr = <0x00000070 0x30010300>;
> +      sophgo,msi-base-vec = <64>;
> +      sophgo,msi-num-vecs = <32>;
> +      interrupt-parent = <&plic>;
> +    };
> -- 
> 2.34.1
> 


From robh at kernel.org  Tue Nov 12 07:59:13 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 12 Nov 2024 09:59:13 -0600
Subject: [PATCH 1/5] dt-bindings: pci: Add Sophgo SG2042 PCIe host
In-Reply-To: <1edbed1276a459a144f0cb0815859a1eb40bfcbf.1731303328.git.unicorn_wang@outlook.com>
References: <cover.1731303328.git.unicorn_wang@outlook.com>
 <1edbed1276a459a144f0cb0815859a1eb40bfcbf.1731303328.git.unicorn_wang@outlook.com>
Message-ID: <20241112155913.GA973575-robh@kernel.org>

On Mon, Nov 11, 2024 at 01:59:37PM +0800, Chen Wang wrote:
> From: Chen Wang <unicorn_wang at outlook.com>
> 
> Add binding for Sophgo SG2042 PCIe host controller.
> 
> Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
> ---
>  .../bindings/pci/sophgo,sg2042-pcie-host.yaml | 88 +++++++++++++++++++
>  1 file changed, 88 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml b/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
> new file mode 100644
> index 000000000000..d4d2232f354f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/sophgo,sg2042-pcie-host.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Sophgo SG2042 PCIe Host (Cadence PCIe Wrapper)
> +
> +description: |+

Don't need '|+'

> +  Sophgo SG2042 PCIe host controller is based on the Cadence PCIe core.

> +  It shares common features with the PCIe core and inherits common properties
> +  defined in Documentation/devicetree/bindings/pci/cdns-pcie-host.yaml.

That's clear from the $ref. No need to say that in prose.

> +
> +maintainers:
> +  - Chen Wang <unicorn_wang at outlook.com>
> +
> +properties:
> +  compatible:
> +    const: sophgo,sg2042-pcie-host
> +
> +  reg:
> +    maxItems: 2
> +
> +  reg-names:
> +    items:
> +      - const: reg
> +      - const: cfg
> +
> +  sophgo,syscon-pcie-ctrl:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: Phandle to the SYSCON entry

Please describe what you need to access.

> +
> +  sophgo,link-id:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: Cadence IP link ID.

Is this an index or related to the syscon? Nak for the former, use 
linux,pci-domain. For the latter, add an arg to sophgo,syscon-pcie-ctrl.

> +
> +  sophgo,internal-msi:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description: Identifies whether the PCIE node uses internal MSI controller.

Wouldn't 'msi-parent' work for this purpose?

> +
> +  vendor-id:
> +    const: 0x1f1c
> +
> +  device-id:
> +    const: 0x2042
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  interrupt-names:
> +    const: msi
> +
> +allOf:
> +  - $ref: cdns-pcie-host.yaml#
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - sophgo,syscon-pcie-ctrl
> +  - sophgo,link-id
> +  - vendor-id
> +  - device-id
> +  - ranges

ranges is already required in the common schemas.

> +
> +additionalProperties: true
> +
> +examples:
> +  - |
> +    pcie at 62000000 {
> +      compatible = "sophgo,sg2042-pcie-host";
> +      device_type = "pci";
> +      reg = <0x62000000  0x00800000>,
> +            <0x48000000  0x00001000>;
> +      reg-names = "reg", "cfg";
> +      #address-cells = <3>;
> +      #size-cells = <2>;
> +      ranges = <0x81000000 0 0x00000000 0xde000000 0 0x00010000>,
> +               <0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>;
> +      bus-range = <0x80 0xbf>;
> +      vendor-id = <0x1f1c>;
> +      device-id = <0x2042>;
> +      cdns,no-bar-match-nbits = <48>;
> +      sophgo,link-id = <0>;
> +      sophgo,syscon-pcie-ctrl = <&cdns_pcie1_ctrl>;
> +      sophgo,internal-msi;
> +      interrupt-parent = <&intc>;
> +    };
> -- 
> 2.34.1
> 


From robh at kernel.org  Tue Nov 12 07:59:52 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Tue, 12 Nov 2024 09:59:52 -0600
Subject: [PATCH 3/5] dt-bindings: mfd: syscon: Add sg2042 pcie ctrl
 compatible
In-Reply-To: <4f030066767c2a3b3acabe24e3dfbb8d87b42bfe.1731303328.git.unicorn_wang@outlook.com>
References: <cover.1731303328.git.unicorn_wang@outlook.com>
 <4f030066767c2a3b3acabe24e3dfbb8d87b42bfe.1731303328.git.unicorn_wang@outlook.com>
Message-ID: <173142719146.983081.8984976211275970968.robh@kernel.org>


On Mon, 11 Nov 2024 14:00:15 +0800, Chen Wang wrote:
> From: Chen Wang <unicorn_wang at outlook.com>
> 
> Document SOPHGO SG2042 compatible for PCIe control registers.
> These registers are shared by pcie controller nodes.
> 
> Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
> ---
>  Documentation/devicetree/bindings/mfd/syscon.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring (Arm) <robh at kernel.org>



From irogers at google.com  Tue Nov 12 08:25:13 2024
From: irogers at google.com (Ian Rogers)
Date: Tue, 12 Nov 2024 08:25:13 -0800
Subject: [PATCH v1 3/4] perf record: Skip don't fail for events that don't open
In-Reply-To: <9bfdc5a0-ed1d-40f6-8a72-6129e1587ca7@linaro.org>
References: <20241026121758.143259-1-irogers@google.com> <20241026121758.143259-4-irogers@google.com>
 <7c1a0bbf-12fd-46ef-9db2-183dfa70a334@linaro.org> <CAP-5=fVODgnWgfCpA7x3B8JFQhkt_unUeTjhWWdSDpKECdTSYg@mail.gmail.com>
 <9bfdc5a0-ed1d-40f6-8a72-6129e1587ca7@linaro.org>
Message-ID: <CAP-5=fXB_GHd8x-c8Q4Y+5=G=YJJBJ+Q7hT6_rGFEzmi7q8nsA@mail.gmail.com>

On Tue, Nov 12, 2024 at 6:12?AM James Clark <james.clark at linaro.org> wrote:
>
>
>
> On 11/11/2024 5:00 pm, Ian Rogers wrote:
> > On Mon, Nov 11, 2024 at 7:49?AM James Clark <james.clark at linaro.org> wrote:
> >>
> >>
> >>
> >> On 26/10/2024 1:17 pm, Ian Rogers wrote:
> >>> Whilst for many tools it is an expected behavior that failure to open
> >>> a perf event is a failure, ARM decided to name PMU events the same as
> >>> legacy events and then failed to rename such events on a server uncore
> >>> SLC PMU. As perf's default behavior when no PMU is specified is to
> >>> open the event on all PMUs that advertise/"have" the event, this
> >>> yielded failures when trying to make the priority of legacy and
> >>> sysfs/json events uniform - something requested by RISC-V and ARM. A
> >>> legacy event user on ARM hardware may find their event opened on an
> >>> uncore PMU which for perf record will fail. Arnaldo suggested skipping
> >>> such events which this patch implements. Rather than have the skipping
> >>> conditional on running on ARM, the skipping is done on all
> >>> architectures as such a fundamental behavioral difference could lead
> >>> to problems with tools built/depending on perf.
> >>>
> >>> An example of perf record failing to open events on x86 is:
> >>> ```
> >>> $ perf record -e data_read,cycles,LLC-prefetch-read -a sleep 0.1
> >>> Error:
> >>> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0' which will be removed.
> >>> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> >>> "dmesg | grep -i perf" may provide additional information.
> >>>
> >>> Error:
> >>> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_1' which will be removed.
> >>> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> >>> "dmesg | grep -i perf" may provide additional information.
> >>>
> >>
> >> This makes me wonder if this message was overly wordy to begin with.
> >> This line is fine:
> >>
> >>    Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0'
> >>    which will be removed.
> >>
> >> The next bit about the syscall just repeats. The exit code could be
> >> included on the previous line. And the dmesg bit is general advice that
> >> could possibly be printed once at the end.
> >
> > Thanks for the time spent investigating this!
> >
> > I agree on this. I wonder if we should have short and long messages,
> > or message+help like we do for parse events. One patch series like
> > this is improving EBUSY:
> > https://lore.kernel.org/lkml/20241106003007.2112584-1-ctshao at google.com/
> > The issue with printing at the end is knowing where/when the end is.
> > Printing once is easy enough.
> >
> >>> Error:
> >>> Failure to open event 'LLC-prefetch-read' on PMU 'cpu' which will be removed.
> >>> The LLC-prefetch-read event is not supported.
> >>> [ perf record: Woken up 1 times to write data ]
> >>> [ perf record: Captured and wrote 2.188 MB perf.data (87 samples) ]
> >>>
> >>> $ perf report --stats
> >>> Aggregated stats:
> >>>                  TOTAL events:      17255
> >>>                   MMAP events:        284  ( 1.6%)
> >>>                   COMM events:       1961  (11.4%)
> >>>                   EXIT events:          1  ( 0.0%)
> >>>                   FORK events:       1960  (11.4%)
> >>>                 SAMPLE events:         87  ( 0.5%)
> >>>                  MMAP2 events:      12836  (74.4%)
> >>>                KSYMBOL events:         83  ( 0.5%)
> >>>              BPF_EVENT events:         36  ( 0.2%)
> >>>         FINISHED_ROUND events:          2  ( 0.0%)
> >>>               ID_INDEX events:          1  ( 0.0%)
> >>>             THREAD_MAP events:          1  ( 0.0%)
> >>>                CPU_MAP events:          1  ( 0.0%)
> >>>              TIME_CONV events:          1  ( 0.0%)
> >>>          FINISHED_INIT events:          1  ( 0.0%)
> >>> cycles stats:
> >>>                 SAMPLE events:         87
> >>> ```
> >>>
> >>> Note, if all events fail to open then the data file will contain no
> >>> samples. This is deliberate as at the point the events are opened
> >>> there are other events, such as the dummy event for sideband data, and
> >>> these events will succeed in opening even if the user specified ones
> >>
> >> Is a file with only sideband events useful? Is it possible to fail the
> >> record command if the event doesn't open anywhere?
> >>
> >> I noticed this leads to some different behavior and a libperf warning
> >> when you have paranoid=3:
> >>
> >>     $ perf record -e cycles -C 0 -- true
> >>
> >>     Error:
> >>     Failure to open event 'cpu_atom/cycles/u' on PMU 'cpu_atom' which will
> >>     be removed.
> >>     ...
> >>     Consider adjusting /proc/sys/kernel/perf_event_paranoid setting
> >>     ...
> >>     libperf: Miscounted nr_mmaps 0 vs 28
> >>     WARNING: No sample_id_all support, falling back to unordered
> >>     processing
> >>     [ perf record: Woken up 1 times to write data ]
> >>     [ perf record: Captured and wrote 0.021 MB perf.data ]
> >
> > So paranoid=3 is a Debian extension that Peter Z doesn't agree with
> > and so isn't enabled in regular kernels. So we're dealing with cycles,
> > which we'd expect to open or fall-back to a software event like
> > task-clock. It feels like things could happen better here but that's
> > not necessarily the fault of this patch.
> >
>
> paranoid=3 is a bit of a red-herring. I actually meant any paranoid
> value other than -1. The important part is "-C 0" because only root is
> allowed to open on a CPU. Or "-a" also causes the issue.
>
> Previously you got the command failure and the hint about the paranoid
> value, but now you get the libperf error too and it still makes the file.
>
> I still don't think a file with only sideband events is useful, I don't
> think there's even a commandline that you can run currently that results
> in that? You always need at least one event to open for it to succeed
> and I'm thinking we could keep that.

You can currently do `perf record -e dummy ...` for example in this
ARM SPE test (I see similar in offcpu, attr test, intel_pt, switch
tracking):
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/tests/shell/test_arm_spe.sh?h=perf-tools-next#n94
If we add a condition that an evlist with only sideband events is
erroneous, and fail perf record, then I think that will break these
expectations. Any change like that would at least need to fix up the
tests, but the tests could be a good indicator that users are also
doing things like this and that may lead to complaints.

> It would be nice to fix the libperf warning too because it's warning
> about something that was already warned about.

Do you have something in mind to clean up the warning? Perhaps you can
send it as a patch.

> >>> don't. Having a mix of open and broken events leads to a problem of
> >>> identifying different sources of events.
> >>   >
> >>
> >> In my basic test I saw that the opened event was identified correctly in
> >> perf report, unless you have an example that you encountered that we
> >> should fix?
> >
> > I didn't find any but we also don't tend to test failing to open
> > events. I could imagine things failing in `perf test` on neoverse
> > testing given the l3 advertising the cycles event.
> >
> >> One place I saw an issue was with auxtrace events. If there's an event
> >> name clash then you're likely to not be able to open the file afterwards
> >> because the auxtrace code can't handle an event that didn't open. But I
> >> don't know of any name clashes there (I just faked one for testing), and
> >> maybe that could be fixed up later in the auxtrace code if there is ever
> >> a real one.
> >>
> >> Other than the above it does seem to work ok.
> >
> > Cool, can this be taken as a Tested-by?
> >
>
> Yep, although with a caveat that I faked the second cycles PMU that
> wouldn't open, but I don't think that should make a difference:
>
> Tested-by: James Clark <james.clark at linaro.org>

Thanks James, as this patch is before reapplying the "Prefer
sysfs/JSON hardware events over legacy" patch, can I take it that the
tag is for the whole series?

> I can also test with the real thing if you like but would take a bit
> longer as I have to borrow it off Leo.

More testing is always good.

Thanks,
Ian

> > Thanks,
> > Ian
> >
> >>> The issue with legacy events is that on RISC-V they want the driver to
> >>> not have mappings from legacy to non-legacy config encodings for each
> >>> vendor/model due to size, complexity and difficulty to update. It was
> >>> reported that on ARM Apple-M? CPUs the legacy mapping in the driver
> >>> was broken and the sysfs/json events should always take precedent,
> >>> however, it isn't clear this is still the case. It is the case that
> >>> without working around this issue a legacy event like cycles without a
> >>> PMU can encode differently than when specified with a PMU - the
> >>> non-PMU version favoring legacy encodings, the PMU one avoiding legacy
> >>> encodings.
> >>>
> >>> The patch removes events and then adjusts the idx value for each
> >>> evsel. This is done so that the dense xyarrays used for file
> >>> descriptors, etc. don't contain broken entries. As event opening
> >>> happens relatively late in the record process, use of the idx value
> >>> before the open will have become corrupted, so it is expected there
> >>> are latent bugs hidden behind this change - the change is best
> >>> effort. As the only vendor that has broken event names is ARM, this
> >>> will principally effect ARM users. They will also experience warning
> >>> messages like those above because of the uncore PMU advertising legacy
> >>> event names.
> >>
> >>
> >>
> >>>
> >>> Suggested-by: Arnaldo Carvalho de Melo <acme at kernel.org>
> >>> Signed-off-by: Ian Rogers <irogers at google.com>
> >>> ---
> >>>    tools/perf/builtin-record.c | 22 +++++++++++++++++-----
> >>>    1 file changed, 17 insertions(+), 5 deletions(-)
> >>>
> >>> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> >>> index f83252472921..7e99743f7e42 100644
> >>> --- a/tools/perf/builtin-record.c
> >>> +++ b/tools/perf/builtin-record.c
> >>> @@ -1364,6 +1364,7 @@ static int record__open(struct record *rec)
> >>>        struct perf_session *session = rec->session;
> >>>        struct record_opts *opts = &rec->opts;
> >>>        int rc = 0;
> >>> +     bool skipped = false;
> >>>
> >>>        evlist__for_each_entry(evlist, pos) {
> >>>    try_again:
> >>> @@ -1379,15 +1380,26 @@ static int record__open(struct record *rec)
> >>>                                pos = evlist__reset_weak_group(evlist, pos, true);
> >>>                                goto try_again;
> >>>                        }
> >>> -                     rc = -errno;
> >>>                        evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg));
> >>> -                     ui__error("%s\n", msg);
> >>> -                     goto out;
> >>> +                     ui__error("Failure to open event '%s' on PMU '%s' which will be removed.\n%s\n",
> >>> +                               evsel__name(pos), evsel__pmu_name(pos), msg);
> >>> +                     pos->skippable = true;
> >>> +                     skipped = true;
> >>> +             } else {
> >>> +                     pos->supported = true;
> >>>                }
> >>> -
> >>> -             pos->supported = true;
> >>>        }
> >>>
> >>> +     if (skipped) {
> >>> +             struct evsel *tmp;
> >>> +             int idx = 0;
> >>> +
> >>> +             evlist__for_each_entry_safe(evlist, tmp, pos) {
> >>> +                     if (pos->skippable)
> >>> +                             evlist__remove(evlist, pos);
> >>> +                     pos->core.idx = idx++;
> >>> +             }
> >>> +     }
> >>>        if (symbol_conf.kptr_restrict && !evlist__exclude_kernel(evlist)) {
> >>>                pr_warning(
> >>>    "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
> >>
>


From samuel.holland at sifive.com  Tue Nov 12 08:38:11 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Tue, 12 Nov 2024 10:38:11 -0600
Subject: [PATCH] irqchip: THEAD_C901_ACLINT_SSWI should depend on
 ARCH_THEAD
In-Reply-To: <1097d054ed4c67f714679de1253e45a034e647a0.1731425416.git.geert+renesas@glider.be>
References: <1097d054ed4c67f714679de1253e45a034e647a0.1731425416.git.geert+renesas@glider.be>
Message-ID: <338c06d8-627e-4ca9-b5d0-6ce87b5cc83c@sifive.com>

Hi Geert,

On 2024-11-12 9:31 AM, Geert Uytterhoeven wrote:
> The T-HEAD ACLINT S-mode IPI Interrupt Controller is only present on
> T-HEAD SoCs.  Hence add a dependency on ARCH_THEAD, to prevent asking

This is not correct. This interrupt controller is part of the T-HEAD CPU IP, so
it is included in SoCs from other vendors (Allwinner, Sophgo, etc.) that use
T-HEAD CPUs as well.

Regards,
Samuel

> the user about this driver when configuring a kernel without T-HEAD SoC
> support.
> 
> Fixes: 25caea955cc95050 ("irqchip: Add T-HEAD C900 ACLINT SSWI driver")
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
>  drivers/irqchip/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 28c19bde55206847..3f4cfcbecc5a4041 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -617,6 +617,7 @@ config THEAD_C900_ACLINT_SSWI
>  	bool "THEAD C9XX ACLINT S-mode IPI Interrupt Controller"
>  	depends on RISCV
>  	depends on SMP
> +	depends on ARCH_THEAD || COMPILE_TEST
>  	select IRQ_DOMAIN_HIERARCHY
>  	select GENERIC_IRQ_IPI_MUX
>  	help



From geert at linux-m68k.org  Tue Nov 12 08:44:07 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 12 Nov 2024 17:44:07 +0100
Subject: [PATCH] irqchip: THEAD_C901_ACLINT_SSWI should depend on ARCH_THEAD
In-Reply-To: <338c06d8-627e-4ca9-b5d0-6ce87b5cc83c@sifive.com>
References: <1097d054ed4c67f714679de1253e45a034e647a0.1731425416.git.geert+renesas@glider.be>
 <338c06d8-627e-4ca9-b5d0-6ce87b5cc83c@sifive.com>
Message-ID: <CAMuHMdX-MV1W2MBV0WQuXkEU-qvfbsb_pcAFrHCGWUFT7TYd6Q@mail.gmail.com>

Hi Samuel,

On Tue, Nov 12, 2024 at 5:38?PM Samuel Holland
<samuel.holland at sifive.com> wrote:
> On 2024-11-12 9:31 AM, Geert Uytterhoeven wrote:
> > The T-HEAD ACLINT S-mode IPI Interrupt Controller is only present on
> > T-HEAD SoCs.  Hence add a dependency on ARCH_THEAD, to prevent asking
>
> This is not correct. This interrupt controller is part of the T-HEAD CPU IP, so
> it is included in SoCs from other vendors (Allwinner, Sophgo, etc.) that use
> T-HEAD CPUs as well.

In that case I am withdrawing this patch.
Thanks for the explanation!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From irogers at google.com  Tue Nov 12 09:23:20 2024
From: irogers at google.com (Ian Rogers)
Date: Tue, 12 Nov 2024 09:23:20 -0800
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is provided
In-Reply-To: <ccac5d65-b01f-4624-97cd-e350ce6de840@linaro.org>
References: <20241026121758.143259-1-irogers@google.com> <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
 <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org> <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
 <d9bfd75a-003a-4f65-abba-b8bcaad13682@linaro.org> <CAP-5=fUHjxL5QbsyQQU-3EYiVhiO6wt=F5MfSfDcAffKP7WWAg@mail.gmail.com>
 <ccac5d65-b01f-4624-97cd-e350ce6de840@linaro.org>
Message-ID: <CAP-5=fXK4NmdY_uTYWSsS+TgnpYK8y_wgm_W_rnqUYQ0BrPZFg@mail.gmail.com>

On Tue, Nov 12, 2024 at 6:22?AM James Clark <james.clark at linaro.org> wrote:
>
> On 11/11/2024 5:19 pm, Ian Rogers wrote:
> > On Mon, Nov 11, 2024 at 2:45?AM James Clark <james.clark at linaro.org> wrote:
> >>
> >> On 08/11/2024 6:37 pm, Atish Kumar Patra wrote:
> >>> On Fri, Nov 8, 2024 at 4:16?AM James Clark <james.clark at linaro.org> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 07/11/2024 18:51, Ian Rogers wrote:
> >>>>> On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
> >>>>>>
> >>>>>> At the RISC-V summit the topic of avoiding event data being in the
> >>>>>> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
> >>>>>> events being the priority when no PMU is provided so that legacy
> >>>>>> events maybe supported via json. Originally Mark Rutland also
> >>>>>> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
> >>>>>> M? processors, but James Clark more recently tested this and believes
> >>>>>> the driver issues there may not have existed or have been resolved. In
> >>>>>> any case, it is inconsistent that with a PMU event names avoid legacy
> >>>>>> encodings, but when wildcarding PMUs (ie without a PMU with the event
> >>>>>> name) the legacy encodings have priority.
> >>>>>>
> >>>>>> The patch doing this work was reverted in a v6.10 release candidate
> >>>>>> as, even though the patch was posted for weeks and had been on
> >>>>>> linux-next for weeks without issue, Linus was in the habit of using
> >>>>>> explicit legacy events with unsupported precision options on his
> >>>>>> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
> >>>>>> where ARM decided to call the events bus_cycles and cycles, the latter
> >>>>>> being also a legacy event name. ARM haven't renamed the cycles event
> >>>>>> to a more consistent cpu_cycles and avoided the problem. With these
> >>>>>> changes the problematic event will now be skipped, a large warning
> >>>>>> produced, and perf record will continue for the other PMU events. This
> >>>>>> solution was proposed by Arnaldo.
> >>>>>>
> >>>>>> Two minor changes have been added to help with the error message and
> >>>>>> to work around issues occurring with "perf stat metrics (shadow stat)
> >>>>>> test".
> >>>>>>
> >>>>>> The patches have only been tested on my x86 non-hybrid laptop.
> >>>>>
> >>>>> Hi Atish and James,
> >>>>>
> >>>>> Could I get your tags for this series?
> >>>>>
> >>>
> >>> Hi Ian,
> >>> Thanks for your patches. It definitely helps to have a clean slate
> >>> implementation
> >>> for the perf tool. However, I have some open questions about other use cases
> >>> that we discussed during the RVI Summit.
> >>>
> >>>>> The patches were originally motivated by wanting to make the behavior
> >>>>> of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
> >>>>> wildcarded to "cpu" in the first case. This was divergent because of
> >>>>> ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
> >>>>> config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
> >>>>> type>, config=<encoding from event>) when a PMU name was given. This
> >>>>> aligns with RISC-V wanting to use json encodings to avoid complexity
> >>>>> in the PMU driver.
> >>>>>
> >>>>
> >>>> I couldn't find the thread, but I remember fairly recently it was
> >>>> mentioned that RISC-V would be supporting the legacy events after all,
> >>>> maybe it was a comment from Atish? I'm not sure if that changes the
> >>>> requirements for this or not?
> >>>>
> >>>> I still can't really imagine how tooling would work if every tool has to
> >>>> maintain the mappings of basic events like instructions and branches.
> >>>> For example all the perf_event_open tests in ltp use the legacy events.
> >>>>
> >>>
> >>> No it has not changed. While this series helps to avoid clunky vendor
> >>> specific encodings
> >>> in the driver for perf tool, I am still unsure how we will manage
> >>> other applications
> >>> (directly passing legacy events through perf_event_open or
> >>> perf_evlist__open) will work.
> >>>
> >>> I have only anecdotal data about folks relying perf legacy events
> >>> directly to profile
> >>> their application. All of them use mostly cycle/instruction events though.
> >>> Are there any users who use other legacy events directly without perf tool ?
> >>>
> >>> If not, we may have only cycle/instruction mapping in the driver and
> >>> rely on json for everything else.
> >>> The other use case is virtualization. I have been playing with these
> >>> patches to find a clean solution to
> >>> enable all the use cases. If you have any other ideas, please let me know.
> >>>
> >>
> >> Yeah I would expect it's mostly cycles and instructions. I searched a
> >> bit for PERF_COUNT_HW_BRANCH_MISSES and only found tool/developer type
> >> usages, which I suppose we could expect to have to handle the mappings
> >> like perf. Although it's not the easiest thing to search for and
> >> obviously that only includes open source.
> >>
> >> Usages do exist though, there are people posting on stack overflow using
> >> it, and other various bug tracker listings. So you would expect those
> >> same users to have to use raw event codes and some switch statement to
> >> pick the right one for their hardware, or use Perf.
> >
> > I don't have any magic to solve this. My thoughts:
> >
> > 1) I thought legacy events were just going to hang around forever,
> > although the name hinting they'd kind of been deprecated. At LPC '23
> > Atish and Mark Rutland originally asked for the sysfs/json to be the
> > preference. I thought Kan was going to push back given the upheaval,
> > especially updating every test expectation. It went through but we're
> > in this weird state where wildcard events are encoded using legacy and
> > PMU specifying events aren't. What this series hopes to solve.
> >
> > 2) I think it is important that perf tool be a reference
> > implementation where others can look (strace, etc.) to base their
> > implementation. Moving perf to sysfs/json is 1 step closer to legacy
> > event deprecation. Please yell if deprecation isn't what is wanted as
> > personally other than cleanliness I don't mind. If we do decide not to
> > have sysfs/json be the priority then I think it sensible to revert the
> > changes making it the priority for events that specify a PMU. I'd like
> > some level of consistency.
>
> Personally this change feels like it's encouraging fragmentation, the
> cleanest would be if RISC-V supports the legacy events like the other
> platforms. It's not a huge set of events anyway, and then existing
> software continues to work in addition to Perf continuing to work.

So I try to be agnostic on the issue but we got to this point because
of events being broken on ARM Apple chips. I fixed an issue where the
ARM core PMU appeared as an uncore PMU as ARM's PMU naming differs
from everyone else's. That fix made it so we used legacy events for
the ARM core PMU, the PMU driver didn't handle this correctly (at the
time) on ARM Apple Linux breaking perf over multiple Linux releases
affecting a number of users.

Having a pool of standard events isn't on the face of it a crazy idea,
I'll try to remember things that have come up:

1) instructions and cycles seem like fairly easy events to agree upon.
However, we also have cpu-cycles that means cycles. With legacy events
the hyphen is often used as a PMU separator. Now what does the cpu
mean here? On ARM you also have cpu_cycles as a sysfs event, ie an
underscore and not a hyphen:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/drivers/perf/arm_pmuv3.c?h=perf-tools-next#n192
What does 'cpu' mean when ARM has no core PMU called 'cpu' and in
heterogeneous systems there are multiple notions of 'cpu' for the core
PMU.
What's my point? Just trying to make a minimal 2 event set of common
events with the way things currently parse leads to ambiguity.

2) missing/ambiguous legacy events. Beyond instructions and cycles
there are cache references, cache misses, branch instructions, branch
misses, bus cycles, stalled cycles frontend, stalled cycles backend
and reference CPU cycles. This set of events captures an out-of-order
machine with a single bus, but even then there's ambiguity over
whether the events include speculatively executed instructions or not.
What's my point? Using these events leads to unpredictable counts in
software. With a sysfs/json event there is a description but none was
ever given about what these legacy events should do, or do if you have
a system with >1 bus, counts for speculatively executed instructions,
isn't out-of-order, etc.

3) "legacy cache" events never really took off. The legacy cache event
names encoded data around speculation and appeared less ambiguous, a
good source for all the names supported by perf is here:
https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/evsel.c?h=perf-tools-next#n734
but choices were made like prefetch is the same as a speculative read
in the encoding. Vendors no doubt agree and disagree on this. LLC and
L2 are synonyms, but today LLC generally means L3 and often an
entirely separate PMU.
What's my point? The code tried to do a smarter less ambiguous thing
than PERF_TYPE_HARDWARE with PERF_TYPE_HW_CACHE but again it was
flawed, carried too many architectural assumptions and without the
drivers adopting it neither did users.

4) PMU drivers mapping issues and the aforementioned ARM Apple Linux
breakage, RISC-V wanting to keep mappings out of a more simplistic
driver.

So I wasn't there for all of this, but I think this is what led to the
legacy events effectively becoming deprecated.

> If we're still thinking that RISC-V will support the legacy events
> anyway in the future, then it weakens the argument to change this and
> risk any breakages that fall out of it.

Agreed, that's why I keep saying I'm only doing this because ARM and
RISC-V want it. What I want is that for things like the encoding of
"cpu-cycles" and "cpu/cpu-cycles/" when there is only 1 PMU providing
such an event called "cpu" the perf_event_attr encodings should match,
we don't have this today but did prior to changing the priority to fix
the ARM Apple Linux issue.

I think for what Atish is asking for perhaps the best route is to add
vendor standard events like ARM has. Anything done in Linux won't
carry over to other operating systems you can be trying to virtualize.
This doesn't to me feel like a problem we should be trying to solve
either in the kernel/driver or the tool, well I've not heard an idea
how we can.

> I'm also not sure whether they really are legacy or just a common base
> set of events. Since the extended type thing was added even the legacy
> events support hybrid, so it's not like they expired from lack of
> features. Even if we claim they're legacy, is that really ever going to
> make them go away?

So for heterogeneous chips ARM first did BIG.little over ten years
ago. More recently Intel did hybrid and it wasn't until Intel added
hybrid support for legacy events that the idea of this worked. As you
know, ARM''s support came later. Does software outside of the perf
tool know to encode information in the extended type information in
legacy events? I doubt it. For example, libpfm4 has only recently been
adding support for heterogeneous CPUs.

So yes there are legacy events and they are a common pool of events
which is convenient for developers, however, this approach quickly
showed shortcomings and often lacked proper vendor support. My company
advocates developers against using common events, which admittedly is
more work for the developer, because we've had multiple issues over
the years primarily due to baked in assumptions.

Thanks,
Ian

> Although I admit nobody has come out with a definitive use case that
> doesn't use either the cycles or instructions events, so maybe its all fine.
>
> >
> > 3) I'd like event parsing to be a library that is as easy to link
> > against as libbpf (i.e. not a viral license). Event parsing is really
> > just mapping an event name to 1 or more perf_event_attr. The PMU
> > abstraction is tied into the event parsing, but this has only been
> > more true recently. The evsel/evlist is tied into event parsing but
> > that feels separable. As most json isn't distributed under a viral
> > license this feels achievable, then I suspect most tools can use this
> > library rather than have to reinvent a wheel.
> >
> > Still looking for tags :-)
> >
> > Thanks,
> > Ian
>


From conor at kernel.org  Tue Nov 12 10:03:14 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 12 Nov 2024 18:03:14 +0000
Subject: [PATCH v3 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <20241112-k1-i2c-master-v3-1-5005b70dc208@gmail.com>
References: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
 <20241112-k1-i2c-master-v3-1-5005b70dc208@gmail.com>
Message-ID: <20241112-aged-trailing-cffda6af0944@spud>

On Tue, Nov 12, 2024 at 11:07:39AM +0800, Troy Mitchell wrote:
> From: Troy Mitchell <troymitchell988 at gmail.com>
> 
> The I2C of K1 supports fast-speed-mode and high-speed-mode,
> and supports FIFO transmission.
> 
> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
> ---
>  .../devicetree/bindings/i2c/spacemit,k1-i2c.yaml   | 52 ++++++++++++++++++++++
>  1 file changed, 52 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> new file mode 100644
> index 000000000000..e8cce360bf03
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> @@ -0,0 +1,52 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: I2C controller embedded in SpacemiT's K1 SoC
> +
> +maintainers:
> +  - Troy Mitchell <troymitchell988 at gmail.com>
> +
> +properties:
> +  compatible:
> +    const: spacemit,k1-i2c
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-frequency:
> +    description:
> +      Desired I2C bus clock frequency in Hz.
> +      K1 supports standard, fast, high-speed modes, from 1 to 3300000.
> +    default: 100000
> +    minimum: 1
> +    maximum: 3300000

It's sufficient to define just default and max btw, the min is set in
i2c-controller.yaml (in dt-schema itself). Don't respin for that alone.

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    i2c at d4010800 {
> +        compatible = "spacemit,k1-i2c";
> +        reg = <0xd4010800 0x38>;
> +        interrupt-parent = <&plic>;
> +        interrupts = <36>;
> +        clocks = <&ccu 90>;
> +        clock-frequency = <100000>;
> +    };
> +
> +...
> 
> -- 
> 2.34.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241112/5844c152/attachment.sig>

From conor at kernel.org  Tue Nov 12 10:03:51 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 12 Nov 2024 18:03:51 +0000
Subject: D1 vlenb
In-Reply-To: <20241112021227.357-1-ybzjyhk@gmail.com>
References: <20240911-xtheadvector-v10-3-8d3930091246@rivosinc.com>
 <20241112021227.357-1-ybzjyhk@gmail.com>
Message-ID: <20241112-blooming-reheat-d9a23401f6d6@spud>

On Tue, Nov 12, 2024 at 10:12:26AM +0800, h1k0n wrote:

This message is entirely empty FYI
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241112/2466562a/attachment.sig>

From geert+renesas at glider.be  Tue Nov 12 10:39:37 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue, 12 Nov 2024 19:39:37 +0100
Subject: [PATCH] dma-mapping: Save base/size instead of pointer to shared DMA pool
Message-ID: <f8cef6845a6141f0277e31a71fe153612daae776.1731436631.git.geert+renesas@glider.be>

On RZ/Five, which is non-coherent, and uses CONFIG_DMA_GLOBAL_POOL=y:

    Oops - store (or AMO) access fault [#1]
    CPU: 0 UID: 0 PID: 1 Comm: swapper Not tainted 6.12.0-rc1-00015-g8a6e02d0c00e #201
    Hardware name: Renesas SMARC EVK based on r9a07g043f01 (DT)
    epc : __memset+0x60/0x100
     ra : __dma_alloc_from_coherent+0x150/0x17a
    epc : ffffffff8062d2bc ra : ffffffff80053a94 sp : ffffffc60000ba20
     gp : ffffffff812e9938 tp : ffffffd601920000 t0 : ffffffc6000d0000
     t1 : 0000000000000000 t2 : ffffffffe9600000 s0 : ffffffc60000baa0
     s1 : ffffffc6000d0000 a0 : ffffffc6000d0000 a1 : 0000000000000000
     a2 : 0000000000001000 a3 : ffffffc6000d1000 a4 : 0000000000000000
     a5 : 0000000000000000 a6 : ffffffd601adacc0 a7 : ffffffd601a841a8
     s2 : ffffffd6018573c0 s3 : 0000000000001000 s4 : ffffffd6019541e0
     s5 : 0000000200000022 s6 : ffffffd6018f8410 s7 : ffffffd6018573e8
     s8 : 0000000000000001 s9 : 0000000000000001 s10: 0000000000000010
     s11: 0000000000000000 t3 : 0000000000000000 t4 : ffffffffdefe62d1
     t5 : 000000001cd6a3a9 t6 : ffffffd601b2aad6
    status: 0000000200000120 badaddr: ffffffc6000d0000 cause: 0000000000000007
    [<ffffffff8062d2bc>] __memset+0x60/0x100
    [<ffffffff80053e1a>] dma_alloc_from_global_coherent+0x1c/0x28
    [<ffffffff80053056>] dma_direct_alloc+0x98/0x112
    [<ffffffff8005238c>] dma_alloc_attrs+0x78/0x86
    [<ffffffff8035fdb4>] rz_dmac_probe+0x3f6/0x50a
    [<ffffffff803a0694>] platform_probe+0x4c/0x8a

If CONFIG_DMA_GLOBAL_POOL=y, the reserved_mem structure passed to
rmem_dma_setup() is saved for later use, by saving the passed pointer.
However, when dma_init_reserved_memory() is called later, the pointer
has become stale, causing a crash.

E.g. in the RZ/Five case, the referenced memory now contains the
reserved_mem structure for the "mmode_resv0 at 30000" node (with base
0x30000 and size 0x10000), instead of the correct "pma_resv0 at 58000000"
node (with base 0x58000000 and size 0x8000000).

Fix this by saving the needed reserved_mem structure's contents instead.

Fixes: 8a6e02d0c00e7b62 ("of: reserved_mem: Restructure how the reserved memory regions are processed")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 kernel/dma/coherent.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index ff5683a57f77126d..3b2bdca9f1d4b027 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -330,7 +330,8 @@ int dma_init_global_coherent(phys_addr_t phys_addr, size_t size)
 #include <linux/of_reserved_mem.h>
 
 #ifdef CONFIG_DMA_GLOBAL_POOL
-static struct reserved_mem *dma_reserved_default_memory __initdata;
+static phys_addr_t dma_reserved_default_memory_base __initdata;
+static phys_addr_t dma_reserved_default_memory_size __initdata;
 #endif
 
 static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
@@ -376,9 +377,10 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
 
 #ifdef CONFIG_DMA_GLOBAL_POOL
 	if (of_get_flat_dt_prop(node, "linux,dma-default", NULL)) {
-		WARN(dma_reserved_default_memory,
+		WARN(dma_reserved_default_memory_size,
 		     "Reserved memory: region for default DMA coherent area is redefined\n");
-		dma_reserved_default_memory = rmem;
+		dma_reserved_default_memory_base = rmem->base;
+		dma_reserved_default_memory_size = rmem->size;
 	}
 #endif
 
@@ -391,10 +393,10 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
 #ifdef CONFIG_DMA_GLOBAL_POOL
 static int __init dma_init_reserved_memory(void)
 {
-	if (!dma_reserved_default_memory)
+	if (!dma_reserved_default_memory_size)
 		return -ENOMEM;
-	return dma_init_global_coherent(dma_reserved_default_memory->base,
-					dma_reserved_default_memory->size);
+	return dma_init_global_coherent(dma_reserved_default_memory_base,
+					dma_reserved_default_memory_size);
 }
 core_initcall(dma_init_reserved_memory);
 #endif /* CONFIG_DMA_GLOBAL_POOL */
-- 
2.34.1



From geert+renesas at glider.be  Tue Nov 12 10:53:22 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue, 12 Nov 2024 19:53:22 +0100
Subject: [PATCH] dma-mapping: Save base/size instead of pointer to shared DMA pool
Message-ID: <f8cef6845a6141f0277e31a71fe153612daae776.1731436631.git.geert+renesas@glider.be>

On RZ/Five, which is non-coherent, and uses CONFIG_DMA_GLOBAL_POOL=y:

    Oops - store (or AMO) access fault [#1]
    CPU: 0 UID: 0 PID: 1 Comm: swapper Not tainted 6.12.0-rc1-00015-g8a6e02d0c00e #201
    Hardware name: Renesas SMARC EVK based on r9a07g043f01 (DT)
    epc : __memset+0x60/0x100
     ra : __dma_alloc_from_coherent+0x150/0x17a
    epc : ffffffff8062d2bc ra : ffffffff80053a94 sp : ffffffc60000ba20
     gp : ffffffff812e9938 tp : ffffffd601920000 t0 : ffffffc6000d0000
     t1 : 0000000000000000 t2 : ffffffffe9600000 s0 : ffffffc60000baa0
     s1 : ffffffc6000d0000 a0 : ffffffc6000d0000 a1 : 0000000000000000
     a2 : 0000000000001000 a3 : ffffffc6000d1000 a4 : 0000000000000000
     a5 : 0000000000000000 a6 : ffffffd601adacc0 a7 : ffffffd601a841a8
     s2 : ffffffd6018573c0 s3 : 0000000000001000 s4 : ffffffd6019541e0
     s5 : 0000000200000022 s6 : ffffffd6018f8410 s7 : ffffffd6018573e8
     s8 : 0000000000000001 s9 : 0000000000000001 s10: 0000000000000010
     s11: 0000000000000000 t3 : 0000000000000000 t4 : ffffffffdefe62d1
     t5 : 000000001cd6a3a9 t6 : ffffffd601b2aad6
    status: 0000000200000120 badaddr: ffffffc6000d0000 cause: 0000000000000007
    [<ffffffff8062d2bc>] __memset+0x60/0x100
    [<ffffffff80053e1a>] dma_alloc_from_global_coherent+0x1c/0x28
    [<ffffffff80053056>] dma_direct_alloc+0x98/0x112
    [<ffffffff8005238c>] dma_alloc_attrs+0x78/0x86
    [<ffffffff8035fdb4>] rz_dmac_probe+0x3f6/0x50a
    [<ffffffff803a0694>] platform_probe+0x4c/0x8a

If CONFIG_DMA_GLOBAL_POOL=y, the reserved_mem structure passed to
rmem_dma_setup() is saved for later use, by saving the passed pointer.
However, when dma_init_reserved_memory() is called later, the pointer
has become stale, causing a crash.

E.g. in the RZ/Five case, the referenced memory now contains the
reserved_mem structure for the "mmode_resv0 at 30000" node (with base
0x30000 and size 0x10000), instead of the correct "pma_resv0 at 58000000"
node (with base 0x58000000 and size 0x8000000).

Fix this by saving the needed reserved_mem structure's contents instead.

Fixes: 8a6e02d0c00e7b62 ("of: reserved_mem: Restructure how the reserved memory regions are processed")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 kernel/dma/coherent.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index ff5683a57f77126d..3b2bdca9f1d4b027 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -330,7 +330,8 @@ int dma_init_global_coherent(phys_addr_t phys_addr, size_t size)
 #include <linux/of_reserved_mem.h>
 
 #ifdef CONFIG_DMA_GLOBAL_POOL
-static struct reserved_mem *dma_reserved_default_memory __initdata;
+static phys_addr_t dma_reserved_default_memory_base __initdata;
+static phys_addr_t dma_reserved_default_memory_size __initdata;
 #endif
 
 static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
@@ -376,9 +377,10 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
 
 #ifdef CONFIG_DMA_GLOBAL_POOL
 	if (of_get_flat_dt_prop(node, "linux,dma-default", NULL)) {
-		WARN(dma_reserved_default_memory,
+		WARN(dma_reserved_default_memory_size,
 		     "Reserved memory: region for default DMA coherent area is redefined\n");
-		dma_reserved_default_memory = rmem;
+		dma_reserved_default_memory_base = rmem->base;
+		dma_reserved_default_memory_size = rmem->size;
 	}
 #endif
 
@@ -391,10 +393,10 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
 #ifdef CONFIG_DMA_GLOBAL_POOL
 static int __init dma_init_reserved_memory(void)
 {
-	if (!dma_reserved_default_memory)
+	if (!dma_reserved_default_memory_size)
 		return -ENOMEM;
-	return dma_init_global_coherent(dma_reserved_default_memory->base,
-					dma_reserved_default_memory->size);
+	return dma_init_global_coherent(dma_reserved_default_memory_base,
+					dma_reserved_default_memory_size);
 }
 core_initcall(dma_init_reserved_memory);
 #endif /* CONFIG_DMA_GLOBAL_POOL */
-- 
2.34.1



From atishp at rivosinc.com  Tue Nov 12 11:06:54 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Tue, 12 Nov 2024 11:06:54 -0800
Subject: [PATCH -fixes] drivers: perf: Fix wrong put_cpu() placement
In-Reply-To: <20241112113422.617954-1-alexghiti@rivosinc.com>
References: <20241112113422.617954-1-alexghiti@rivosinc.com>
Message-ID: <CAHBxVyFUoiBNbJUCieS1cnVyTwUOModNL6b70wbMV4-z3GJEzQ@mail.gmail.com>

On Tue, Nov 12, 2024 at 3:34?AM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
>
> Unfortunately, the wrong patch version was merged which places the
> put_cpu() after enabling a static key, which is not safe as pointed by
> Will [1], so move put_cpu() before to avoid this.
>
> Fixes: 2840dadf0dde ("drivers: perf: Fix smp_processor_id() use in preemptible code")
> Reported-by: Atish Patra <atishp at rivosinc.com>
> Link: https://lore.kernel.org/all/20240827125335.GD4772 at willie-the-truck/ [1]
> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> ---
>  drivers/perf/riscv_pmu_sbi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index 391ca1422cae..1aa303f76cc7 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -1393,8 +1393,9 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
>                         goto out_unregister;
>
>                 cpu = get_cpu();
> -
>                 ret = pmu_sbi_snapshot_setup(pmu, cpu);
> +               put_cpu();
> +
>                 if (ret) {
>                         /* Snapshot is an optional feature. Continue if not available */
>                         pmu_sbi_snapshot_free(pmu);
> @@ -1408,7 +1409,6 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
>                          */
>                         static_branch_enable(&sbi_pmu_snapshot_available);
>                 }
> -               put_cpu();
>         }
>
>         register_sysctl("kernel", sbi_pmu_sysctl_table);
> --
> 2.39.2
>

Reviewed-by: Atish Patra <atishp at rivosinc.com>
Tested-by: Atish Patra <atishp at rivosinc.com>


From leo.yan at arm.com  Tue Nov 12 11:53:43 2024
From: leo.yan at arm.com (Leo Yan)
Date: Tue, 12 Nov 2024 19:53:43 +0000
Subject: [PATCH v1 3/4] perf record: Skip don't fail for events that
 don't open
In-Reply-To: <20241026121758.143259-4-irogers@google.com>
References: <20241026121758.143259-1-irogers@google.com>
 <20241026121758.143259-4-irogers@google.com>
Message-ID: <20241112195343.GA404636@e132581.arm.com>

On Sat, Oct 26, 2024 at 05:17:57AM -0700, Ian Rogers wrote:
> 
> Whilst for many tools it is an expected behavior that failure to open
> a perf event is a failure, ARM decided to name PMU events the same as
> legacy events and then failed to rename such events on a server uncore
> SLC PMU. As perf's default behavior when no PMU is specified is to
> open the event on all PMUs that advertise/"have" the event, this
> yielded failures when trying to make the priority of legacy and
> sysfs/json events uniform - something requested by RISC-V and ARM. A
> legacy event user on ARM hardware may find their event opened on an
> uncore PMU which for perf record will fail. Arnaldo suggested skipping
> such events which this patch implements. Rather than have the skipping
> conditional on running on ARM, the skipping is done on all
> architectures as such a fundamental behavioral difference could lead
> to problems with tools built/depending on perf.
> 
> An example of perf record failing to open events on x86 is:
> ```
> $ perf record -e data_read,cycles,LLC-prefetch-read -a sleep 0.1
> Error:
> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0' which will be removed.
> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> "dmesg | grep -i perf" may provide additional information.
> 
> Error:
> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_1' which will be removed.
> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> "dmesg | grep -i perf" may provide additional information.
> 
> Error:
> Failure to open event 'LLC-prefetch-read' on PMU 'cpu' which will be removed.
> The LLC-prefetch-read event is not supported.
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 2.188 MB perf.data (87 samples) ]
> 
> $ perf report --stats
> Aggregated stats:
>                TOTAL events:      17255
>                 MMAP events:        284  ( 1.6%)
>                 COMM events:       1961  (11.4%)
>                 EXIT events:          1  ( 0.0%)
>                 FORK events:       1960  (11.4%)
>               SAMPLE events:         87  ( 0.5%)
>                MMAP2 events:      12836  (74.4%)
>              KSYMBOL events:         83  ( 0.5%)
>            BPF_EVENT events:         36  ( 0.2%)
>       FINISHED_ROUND events:          2  ( 0.0%)
>             ID_INDEX events:          1  ( 0.0%)
>           THREAD_MAP events:          1  ( 0.0%)
>              CPU_MAP events:          1  ( 0.0%)
>            TIME_CONV events:          1  ( 0.0%)
>        FINISHED_INIT events:          1  ( 0.0%)
> cycles stats:
>               SAMPLE events:         87
> ```

Thanks for James reminding me.  Tested on AVA platform:

# tree /sys/bus/event_source/devices/arm_dsu_*/events
  ...
  /sys/bus/event_source/devices/arm_dsu_9/events
  ??? bus_access
  ??? bus_cycles
  ??? cycles
  ??? l3d_cache
  ??? l3d_cache_allocate
  ??? l3d_cache_refill
  ??? l3d_cache_wb
  ??? memory_error

# ./perf record -- sleep 0.1
 Error:
 Failure to open event 'cycles:PH' on PMU 'arm_dsu_0' which will be
 removed.
 cycles:PH: PMU Hardware doesn't support sampling/overflow-interrupts.
 Try 'perf stat'
 Error:
 Failure to open event 'cycles:PH' on PMU 'arm_dsu_1' which will be
 removed.
 cycles:PH: PMU Hardware doesn't support sampling/overflow-interrupts.
 Try 'perf stat'
 ...
 Error:
 Failure to open event 'cycles:PH' on PMU 'arm_dsu_15' which will be
 removed.
 cycles:PH: PMU Hardware doesn't support sampling/overflow-interrupts.
 Try 'perf stat'
 [ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 0.008 MB perf.data (8 samples) ]

# ./perf report --stats

 Aggregated stats:
                TOTAL events:         67
                 MMAP events:         40  (59.7%)
                 COMM events:          1  ( 1.5%)
               SAMPLE events:          8  (11.9%)
              KSYMBOL events:          6  ( 9.0%)
            BPF_EVENT events:          6  ( 9.0%)
       FINISHED_ROUND events:          1  ( 1.5%)
             ID_INDEX events:          1  ( 1.5%)
           THREAD_MAP events:          1  ( 1.5%)
              CPU_MAP events:          1  ( 1.5%)
            TIME_CONV events:          1  ( 1.5%)
        FINISHED_INIT events:          1  ( 1.5%)
 cycles:P stats:
               SAMPLE events:          8

# ./perf stat -- sleep 0.1

 Performance counter stats for 'sleep 0.1':

              0.87 msec task-clock                       #    0.009 CPUs utilized
                 1      context-switches                 #    1.148 K/sec
                 0      cpu-migrations                   #    0.000 /sec
                52      page-faults                      #   59.685 K/sec
           877,835      instructions                     #    1.14  insn per cycle
                                                  #    0.25  stalled cycles per insn
           772,102      cycles                           #  886.210 M/sec
           191,914      stalled-cycles-frontend          #   24.86% frontend cycles idle
           219,183      stalled-cycles-backend           #   28.39% backend cycles idle
           184,099      branches                         #  211.307 M/sec
             8,548      branch-misses                    #    4.64% of all branches

       0.101623529 seconds time elapsed

       0.001645000 seconds user
       0.000000000 seconds sys

Tested-by: Leo Yan <leo.yan at arm.com>


From atishp at rivosinc.com  Tue Nov 12 11:55:21 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Tue, 12 Nov 2024 11:55:21 -0800
Subject: [PATCH v1 0/4] Prefer sysfs/JSON events also when no PMU is provided
In-Reply-To: <CAP-5=fXK4NmdY_uTYWSsS+TgnpYK8y_wgm_W_rnqUYQ0BrPZFg@mail.gmail.com>
References: <20241026121758.143259-1-irogers@google.com> <CAP-5=fXf9HtqKZyvfXNbKLTB-dL_Ax5Hd0_Gn1J-y0T1SE9wLQ@mail.gmail.com>
 <78eb729c-7594-460f-9d79-97fb683d8b5e@linaro.org> <CAHBxVyFXWpczMmWJbpWoLUjQ4nfNC2_h1yZqSd7kSr6N8Rvm5Q@mail.gmail.com>
 <d9bfd75a-003a-4f65-abba-b8bcaad13682@linaro.org> <CAP-5=fUHjxL5QbsyQQU-3EYiVhiO6wt=F5MfSfDcAffKP7WWAg@mail.gmail.com>
 <ccac5d65-b01f-4624-97cd-e350ce6de840@linaro.org> <CAP-5=fXK4NmdY_uTYWSsS+TgnpYK8y_wgm_W_rnqUYQ0BrPZFg@mail.gmail.com>
Message-ID: <CAHBxVyFQsBSiYrSmhnP9ov=3yt8D1fQ8reuEZCNhwWyxBEd+PA@mail.gmail.com>

On Tue, Nov 12, 2024 at 9:23?AM Ian Rogers <irogers at google.com> wrote:
>
> On Tue, Nov 12, 2024 at 6:22?AM James Clark <james.clark at linaro.org> wrote:
> >
> > On 11/11/2024 5:19 pm, Ian Rogers wrote:
> > > On Mon, Nov 11, 2024 at 2:45?AM James Clark <james.clark at linaro.org> wrote:
> > >>
> > >> On 08/11/2024 6:37 pm, Atish Kumar Patra wrote:
> > >>> On Fri, Nov 8, 2024 at 4:16?AM James Clark <james.clark at linaro.org> wrote:
> > >>>>
> > >>>>
> > >>>>
> > >>>> On 07/11/2024 18:51, Ian Rogers wrote:
> > >>>>> On Sat, Oct 26, 2024 at 5:18?AM Ian Rogers <irogers at google.com> wrote:
> > >>>>>>
> > >>>>>> At the RISC-V summit the topic of avoiding event data being in the
> > >>>>>> RISC-V PMU kernel driver came up. There is a preference for sysfs/JSON
> > >>>>>> events being the priority when no PMU is provided so that legacy
> > >>>>>> events maybe supported via json. Originally Mark Rutland also
> > >>>>>> expressed at LPC 2023 that doing this would resolve bugs on ARM Apple
> > >>>>>> M? processors, but James Clark more recently tested this and believes
> > >>>>>> the driver issues there may not have existed or have been resolved. In
> > >>>>>> any case, it is inconsistent that with a PMU event names avoid legacy
> > >>>>>> encodings, but when wildcarding PMUs (ie without a PMU with the event
> > >>>>>> name) the legacy encodings have priority.
> > >>>>>>
> > >>>>>> The patch doing this work was reverted in a v6.10 release candidate
> > >>>>>> as, even though the patch was posted for weeks and had been on
> > >>>>>> linux-next for weeks without issue, Linus was in the habit of using
> > >>>>>> explicit legacy events with unsupported precision options on his
> > >>>>>> Neoverse-N1. This machine has SLC PMU events for bus and CPU cycles
> > >>>>>> where ARM decided to call the events bus_cycles and cycles, the latter
> > >>>>>> being also a legacy event name. ARM haven't renamed the cycles event
> > >>>>>> to a more consistent cpu_cycles and avoided the problem. With these
> > >>>>>> changes the problematic event will now be skipped, a large warning
> > >>>>>> produced, and perf record will continue for the other PMU events. This
> > >>>>>> solution was proposed by Arnaldo.
> > >>>>>>
> > >>>>>> Two minor changes have been added to help with the error message and
> > >>>>>> to work around issues occurring with "perf stat metrics (shadow stat)
> > >>>>>> test".
> > >>>>>>
> > >>>>>> The patches have only been tested on my x86 non-hybrid laptop.
> > >>>>>
> > >>>>> Hi Atish and James,
> > >>>>>
> > >>>>> Could I get your tags for this series?
> > >>>>>
> > >>>
> > >>> Hi Ian,
> > >>> Thanks for your patches. It definitely helps to have a clean slate
> > >>> implementation
> > >>> for the perf tool. However, I have some open questions about other use cases
> > >>> that we discussed during the RVI Summit.
> > >>>
> > >>>>> The patches were originally motivated by wanting to make the behavior
> > >>>>> of events parsed like "cycles" match that of "cpu/cycles/", the PMU is
> > >>>>> wildcarded to "cpu" in the first case. This was divergent because of
> > >>>>> ARM we switched from preferring legacy (type = PERF_TYPE_HARDWARE,
> > >>>>> config = PERF_COUNT_HW_CPU_CYCLES) to sysfs/json (type=<core PMU's
> > >>>>> type>, config=<encoding from event>) when a PMU name was given. This
> > >>>>> aligns with RISC-V wanting to use json encodings to avoid complexity
> > >>>>> in the PMU driver.
> > >>>>>
> > >>>>
> > >>>> I couldn't find the thread, but I remember fairly recently it was
> > >>>> mentioned that RISC-V would be supporting the legacy events after all,
> > >>>> maybe it was a comment from Atish? I'm not sure if that changes the
> > >>>> requirements for this or not?
> > >>>>
> > >>>> I still can't really imagine how tooling would work if every tool has to
> > >>>> maintain the mappings of basic events like instructions and branches.
> > >>>> For example all the perf_event_open tests in ltp use the legacy events.
> > >>>>
> > >>>
> > >>> No it has not changed. While this series helps to avoid clunky vendor
> > >>> specific encodings
> > >>> in the driver for perf tool, I am still unsure how we will manage
> > >>> other applications
> > >>> (directly passing legacy events through perf_event_open or
> > >>> perf_evlist__open) will work.
> > >>>
> > >>> I have only anecdotal data about folks relying perf legacy events
> > >>> directly to profile
> > >>> their application. All of them use mostly cycle/instruction events though.
> > >>> Are there any users who use other legacy events directly without perf tool ?
> > >>>
> > >>> If not, we may have only cycle/instruction mapping in the driver and
> > >>> rely on json for everything else.
> > >>> The other use case is virtualization. I have been playing with these
> > >>> patches to find a clean solution to
> > >>> enable all the use cases. If you have any other ideas, please let me know.
> > >>>
> > >>
> > >> Yeah I would expect it's mostly cycles and instructions. I searched a
> > >> bit for PERF_COUNT_HW_BRANCH_MISSES and only found tool/developer type
> > >> usages, which I suppose we could expect to have to handle the mappings
> > >> like perf. Although it's not the easiest thing to search for and
> > >> obviously that only includes open source.
> > >>
> > >> Usages do exist though, there are people posting on stack overflow using
> > >> it, and other various bug tracker listings. So you would expect those
> > >> same users to have to use raw event codes and some switch statement to
> > >> pick the right one for their hardware, or use Perf.
> > >
> > > I don't have any magic to solve this. My thoughts:
> > >
> > > 1) I thought legacy events were just going to hang around forever,
> > > although the name hinting they'd kind of been deprecated. At LPC '23
> > > Atish and Mark Rutland originally asked for the sysfs/json to be the
> > > preference. I thought Kan was going to push back given the upheaval,
> > > especially updating every test expectation. It went through but we're
> > > in this weird state where wildcard events are encoded using legacy and
> > > PMU specifying events aren't. What this series hopes to solve.
> > >
> > > 2) I think it is important that perf tool be a reference
> > > implementation where others can look (strace, etc.) to base their
> > > implementation. Moving perf to sysfs/json is 1 step closer to legacy
> > > event deprecation. Please yell if deprecation isn't what is wanted as
> > > personally other than cleanliness I don't mind. If we do decide not to
> > > have sysfs/json be the priority then I think it sensible to revert the
> > > changes making it the priority for events that specify a PMU. I'd like
> > > some level of consistency.
> >
> > Personally this change feels like it's encouraging fragmentation, the
> > cleanest would be if RISC-V supports the legacy events like the other
> > platforms. It's not a huge set of events anyway, and then existing
> > software continues to work in addition to Perf continuing to work.
>
> So I try to be agnostic on the issue but we got to this point because
> of events being broken on ARM Apple chips. I fixed an issue where the
> ARM core PMU appeared as an uncore PMU as ARM's PMU naming differs
> from everyone else's. That fix made it so we used legacy events for
> the ARM core PMU, the PMU driver didn't handle this correctly (at the
> time) on ARM Apple Linux breaking perf over multiple Linux releases
> affecting a number of users.
>
> Having a pool of standard events isn't on the face of it a crazy idea,
> I'll try to remember things that have come up:
>
> 1) instructions and cycles seem like fairly easy events to agree upon.
> However, we also have cpu-cycles that means cycles. With legacy events
> the hyphen is often used as a PMU separator. Now what does the cpu
> mean here? On ARM you also have cpu_cycles as a sysfs event, ie an
> underscore and not a hyphen:
> https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/drivers/perf/arm_pmuv3.c?h=perf-tools-next#n192
> What does 'cpu' mean when ARM has no core PMU called 'cpu' and in
> heterogeneous systems there are multiple notions of 'cpu' for the core
> PMU.
> What's my point? Just trying to make a minimal 2 event set of common
> events with the way things currently parse leads to ambiguity.
>
> 2) missing/ambiguous legacy events. Beyond instructions and cycles
> there are cache references, cache misses, branch instructions, branch
> misses, bus cycles, stalled cycles frontend, stalled cycles backend
> and reference CPU cycles. This set of events captures an out-of-order
> machine with a single bus, but even then there's ambiguity over
> whether the events include speculatively executed instructions or not.
> What's my point? Using these events leads to unpredictable counts in
> software. With a sysfs/json event there is a description but none was
> ever given about what these legacy events should do, or do if you have
> a system with >1 bus, counts for speculatively executed instructions,
> isn't out-of-order, etc.
>
> 3) "legacy cache" events never really took off. The legacy cache event
> names encoded data around speculation and appeared less ambiguous, a
> good source for all the names supported by perf is here:
> https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/evsel.c?h=perf-tools-next#n734
> but choices were made like prefetch is the same as a speculative read
> in the encoding. Vendors no doubt agree and disagree on this. LLC and
> L2 are synonyms, but today LLC generally means L3 and often an
> entirely separate PMU.
> What's my point? The code tried to do a smarter less ambiguous thing
> than PERF_TYPE_HARDWARE with PERF_TYPE_HW_CACHE but again it was
> flawed, carried too many architectural assumptions and without the
> drivers adopting it neither did users.
>
> 4) PMU drivers mapping issues and the aforementioned ARM Apple Linux
> breakage, RISC-V wanting to keep mappings out of a more simplistic
> driver.
>
> So I wasn't there for all of this, but I think this is what led to the
> legacy events effectively becoming deprecated.
>
> > If we're still thinking that RISC-V will support the legacy events
> > anyway in the future, then it weakens the argument to change this and
> > risk any breakages that fall out of it.
>
> Agreed, that's why I keep saying I'm only doing this because ARM and
> RISC-V want it. What I want is that for things like the encoding of

In the beginning, we wanted it for the RISC-V ecosystem because we had
an opportunity to start
from a clean slate and attempt a better implementation. However, the
burden of supporting the existing
existing users who try to run their preferred way of profiling
applications by using
legacy events (especially cycle/instructions) are forcing us to follow
the convention (have the encodings specified in the driver as well.
) unfortunately.

However, we can add the encodings under a Kconfig which can be
disabled or removed in the future if we get
to a point where there are no legacy users.

> "cpu-cycles" and "cpu/cpu-cycles/" when there is only 1 PMU providing
> such an event called "cpu" the perf_event_attr encodings should match,
> we don't have this today but did prior to changing the priority to fix
> the ARM Apple Linux issue.
>
> I think for what Atish is asking for perhaps the best route is to add
> vendor standard events like ARM has. Anything done in Linux won't
> carry over to other operating systems you can be trying to virtualize.
> This doesn't to me feel like a problem we should be trying to solve
> either in the kernel/driver or the tool, well I've not heard an idea
> how we can.
>

Apart from the non-Linux guests using SBI PMU events, the host
hypervisor(also running Linux) may need
event mapping available in the driver for the following reasons even
for guests running Linux.

1. The guest Linux is not running the updated perf tool with the
correct json file
2. VMM wants to fake the unique identifiers (vendorid, archid, implid)
for migration or some
other reasons.

Both these use cases are probably corner cases at best. That's why, I
am inclined to keep the encoding
in the driver to begin with with the hope we won't need to serve these
use cases in the future.

The driver will use the raw events coming from json as a preferred
method for all the events anyways. In that case,
the hypervisor doesn't have to do anything apart from filtering. In
absence of it, the events are encoded as legacy
(HARDWARE or HARDWARE_CACHE) and the hypervisor will try its best to
map those to a platform specific encoding.

> > I'm also not sure whether they really are legacy or just a common base
> > set of events. Since the extended type thing was added even the legacy
> > events support hybrid, so it's not like they expired from lack of
> > features. Even if we claim they're legacy, is that really ever going to
> > make them go away?
>
> So for heterogeneous chips ARM first did BIG.little over ten years
> ago. More recently Intel did hybrid and it wasn't until Intel added
> hybrid support for legacy events that the idea of this worked. As you
> know, ARM''s support came later. Does software outside of the perf
> tool know to encode information in the extended type information in
> legacy events? I doubt it. For example, libpfm4 has only recently been
> adding support for heterogeneous CPUs.
>
> So yes there are legacy events and they are a common pool of events
> which is convenient for developers, however, this approach quickly
> showed shortcomings and often lacked proper vendor support. My company
> advocates developers against using common events, which admittedly is
> more work for the developer, because we've had multiple issues over
> the years primarily due to baked in assumptions.
>
> Thanks,
> Ian
>
> > Although I admit nobody has come out with a definitive use case that
> > doesn't use either the cycles or instructions events, so maybe its all fine.
> >
> > >
> > > 3) I'd like event parsing to be a library that is as easy to link
> > > against as libbpf (i.e. not a viral license). Event parsing is really
> > > just mapping an event name to 1 or more perf_event_attr. The PMU
> > > abstraction is tied into the event parsing, but this has only been
> > > more true recently. The evsel/evlist is tied into event parsing but
> > > that feels separable. As most json isn't distributed under a viral
> > > license this feels achievable, then I suspect most tools can use this
> > > library rather than have to reinvent a wheel.
> > >
> > > Still looking for tags :-)
> > >
> > > Thanks,
> > > Ian
> >


From helgaas at kernel.org  Tue Nov 12 13:20:55 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 12 Nov 2024 15:20:55 -0600
Subject: [PATCH 2/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver
In-Reply-To: <5051f2375ff6218e7d44ce0c298efd5f9ee56964.1731303328.git.unicorn_wang@outlook.com>
Message-ID: <20241112212055.GA1859446@bhelgaas>

On Mon, Nov 11, 2024 at 01:59:56PM +0800, Chen Wang wrote:
> From: Chen Wang <unicorn_wang at outlook.com>
> 
> Add support for PCIe controller in SG2042 SoC. The controller
> uses the Cadence PCIe core programmed by pcie-cadence*.c. The
> PCIe controller will work in host mode only.

> +++ b/drivers/pci/controller/cadence/Kconfig
> @@ -67,4 +67,15 @@ config PCI_J721E_EP
>  	  Say Y here if you want to support the TI J721E PCIe platform
>  	  controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe
>  	  core.
> +
> +config PCIE_SG2042
> +	bool "Sophgo SG2042 PCIe controller (host mode)"
> +	depends on ARCH_SOPHGO || COMPILE_TEST
> +	depends on OF
> +	select PCIE_CADENCE_HOST
> +	help
> +	  Say Y here if you want to support the Sophgo SG2042 PCIe platform
> +	  controller in host mode. Sophgo SG2042 PCIe controller uses Cadence
> +	  PCIe core.

Reorder to keep these menu items in alphabetical order by vendor.

> +++ b/drivers/pci/controller/cadence/pcie-sg2042.c

> + * SG2042 PCIe controller supports two ways to report MSI:
> + * - Method A, the PICe controller implements an MSI interrupt controller inside,
> + *   and connect to PLIC upward through one interrupt line. Provides
> + *   memory-mapped msi address, and by programming the upper 32 bits of the
> + *   address to zero, it can be compatible with old pcie devices that only
> + *   support 32-bit msi address.
> + * - Method B, the PICe controller connects to PLIC upward through an
> + *   independent MSI controller "sophgo,sg2042-msi" on the SOC. The MSI
> + *   controller provides multiple(up to 32) interrupt sources to PLIC.
> + *   Compared with the first method, the advantage is that the interrupt source
> + *   is expanded, but because for SG2042, the msi address provided by the MSI
> + *   controller is fixed and only supports 64-bit address(> 2^32), it is not
> + *   compatible with old pcie devices that only support 32-bit msi address.
> + * Method A & B can be configured in DTS with property "sophgo,internal-msi",
> + * default is Method B.

s/PICe/PCIe/ (multiple)
s/msi/MSI/ (multiple)
s/pcie/PCIe/ (multiple)

Wrap comment (and code below) to fit in 80 columns.  Add blank lines
between paragraphs.

> +#define SG2042_CDNS_PLAT_CPU_TO_BUS_ADDR	0xCFFFFFFFFF

Remove (see below).

> +static void sg2042_pcie_msi_irq_compose_msi_msg(struct irq_data *d,
> +						struct msi_msg *msg)
> +{
> +	struct sg2042_pcie *pcie = irq_data_get_irq_chip_data(d);
> +	struct device *dev = pcie->cdns_pcie->dev;
> +
> +	msg->address_lo = lower_32_bits(pcie->msi_phys) + BYTE_NUM_PER_MSI_VEC * d->hwirq;
> +	msg->address_hi = upper_32_bits(pcie->msi_phys);
> +	msg->data = 1;
> +
> +	pcie->num_applied_vecs = d->hwirq;

This looks questionable.  How do you know d->hwirq increases every
time this is called?

> +	dev_info(dev, "compose msi msg hwirq[%d] address_hi[%#x] address_lo[%#x]\n",
> +		 (int)d->hwirq, msg->address_hi, msg->address_lo);

This seems too verbose to be a dev_info().  Maybe a dev_dbg() or
remove it altogether.

> + * We use the usual two domain structure, the top one being a generic PCI/MSI
> + * domain, the bottom one being SG2042-specific and handling the actual HW
> + * interrupt allocation.
> + * At the same time, for internal MSI controller(Method A), bottom chip uses a
> + * chained handler to handle the controller's MSI IRQ edge triggered.

Add blank line between paragraphs.

> +static int sg2042_pcie_setup_msi_external(struct sg2042_pcie *pcie)
> +{
> +	struct device *dev = pcie->cdns_pcie->dev;
> +	struct device_node *np = dev->of_node;
> +	struct irq_domain *parent_domain;
> +	struct device_node *parent_np;
> +
> +	if (!of_find_property(np, "interrupt-parent", NULL)) {
> +		dev_err(dev, "Can't find interrupt-parent!\n");
> +		return -EINVAL;
> +	}
> +
> +	parent_np = of_irq_find_parent(np);
> +	if (!parent_np) {
> +		dev_err(dev, "Can't find node of interrupt-parent!\n");

Can you use some kind of %pOF format to include more information here?
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/core-api/printk-formats.rst?id=v6.11#n463

> +		return -ENXIO;
> +	}
> +
> +	parent_domain = irq_find_host(parent_np);
> +	of_node_put(parent_np);
> +	if (!parent_domain) {
> +		dev_err(dev, "Can't find domain of interrupt-parent!\n");

And here?

> +		return -ENXIO;
> +	}
> +
> +	return sg2042_pcie_create_msi_domain(pcie, parent_domain);
> +}

> +static int sg2042_pcie_init_msi_data(struct sg2042_pcie *pcie)
> +{
> +	struct device *dev = pcie->cdns_pcie->dev;
> +	u32 value;
> +	int ret;
> +
> +	raw_spin_lock_init(&pcie->lock);
> +
> +	/*
> +	 * Though the PCIe controller can address >32-bit address space, to
> +	 * facilitate endpoints that support only 32-bit MSI target address,
> +	 * the mask is set to 32-bit to make sure that MSI target address is
> +	 * always a 32-bit address
> +	 */
> +	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
> +	if (ret < 0)
> +		return ret;
> +
> +	pcie->msi_virt = dma_alloc_coherent(dev, BYTE_NUM_PER_MSI_VEC * MAX_MSI_IRQS,
> +					    &pcie->msi_phys, GFP_KERNEL);
> +	if (!pcie->msi_virt)
> +		return -ENOMEM;
> +
> +	/* Program the msi address and size */

s/msi/MSI/

> +	if (pcie->link_id == 1) {
> +		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_LOW,
> +			     lower_32_bits(pcie->msi_phys));
> +		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_HIGH,
> +			     upper_32_bits(pcie->msi_phys));
> +
> +		regmap_read(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, &value);
> +		value = (value & REG_LINK1_MSI_ADDR_SIZE_MASK) | MAX_MSI_IRQS;
> +		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, value);
> +	} else {
> +		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_LOW,
> +			     lower_32_bits(pcie->msi_phys));
> +		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_HIGH,
> +			     upper_32_bits(pcie->msi_phys));
> +
> +		regmap_read(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, &value);
> +		value = (value & REG_LINK0_MSI_ADDR_SIZE_MASK) | (MAX_MSI_IRQS << 16);
> +		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, value);
> +	}

Lot of pcie->link_id checking going on here.  Consider saving these
offsets in the struct sg2042_pcie so you don't need to test
everywhere.

> +	return 0;
> +}

> +static int sg2042_pcie_setup_msi(struct sg2042_pcie *pcie, struct platform_device *pdev)
> +{
> +	struct device *dev = pcie->cdns_pcie->dev;
> +	struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
> +	struct irq_domain *parent_domain;
> +	int ret = 0;
> +
> +	parent_domain = irq_domain_create_linear(fwnode, MSI_DEF_NUM_VECTORS,
> +						 &sg2042_pcie_msi_domain_ops, pcie);
> +	if (!parent_domain) {
> +		dev_err(dev, "Failed to create IRQ domain\n");
> +		return -ENOMEM;
> +	}
> +	irq_domain_update_bus_token(parent_domain, DOMAIN_BUS_NEXUS);
> +
> +	ret = sg2042_pcie_create_msi_domain(pcie, parent_domain);
> +	if (ret) {
> +		irq_domain_remove(parent_domain);
> +		return ret;
> +	}
> +
> +	ret = sg2042_pcie_init_msi_data(pcie);
> +	if (ret) {
> +		dev_err(dev, "Failed to initialize msi data!\n");

s/msi/MSI/

> +		return ret;
> +	}
> +
> +	ret = platform_get_irq_byname(pdev, "msi");
> +	if (ret <= 0) {
> +		dev_err(dev, "failed to get MSI irq\n");
> +		return ret;
> +	}
> +	pcie->msi_irq = ret;
> +
> +	irq_set_chained_handler_and_data(pcie->msi_irq,
> +					 sg2042_pcie_msi_chained_isr, pcie);
> +
> +	return 0;
> +}
> +
> +static void sg2042_pcie_free_msi(struct sg2042_pcie *pcie)
> +{
> +	struct device *dev = pcie->cdns_pcie->dev;
> +
> +	if (pcie->msi_irq)
> +		irq_set_chained_handler_and_data(pcie->msi_irq, NULL, NULL);
> +
> +	if (pcie->msi_virt)
> +		dma_free_coherent(dev, BYTE_NUM_PER_MSI_VEC * MAX_MSI_IRQS,
> +				  pcie->msi_virt, pcie->msi_phys);
> +}
> +
> +static u64 sg2042_cdns_pcie_cpu_addr_fixup(struct cdns_pcie *pcie, u64 cpu_addr)
> +{
> +	return cpu_addr & SG2042_CDNS_PLAT_CPU_TO_BUS_ADDR;
> +}

Remove.  This translation between CPU and PCI bus addresses should be
described in the DT "ranges" property of the PCI host bridge.

See
https://lore.kernel.org/linux-pci/20241029-pci_fixup_addr-v7-3-8310dc24fb7c at nxp.com/
for a similar fix.

> +static const struct cdns_pcie_ops sg2042_cdns_pcie_ops = {
> +	.cpu_addr_fixup = sg2042_cdns_pcie_cpu_addr_fixup,
> +};
> +
> +/*
> + * SG2042 only support 4-byte aligned access, so for the rootbus (i.e. to read
> + * the PCIe controller itself, read32 is required. For non-rootbus (i.e. to read
> + * the PCIe peripheral registers, supports 1/2/4 byte aligned access, so
> + * directly use read should be fine.
> + * The same is true for write.

Add blank line between paragraphs or rewrap into a single paragraph.

> +static int sg2042_pcie_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct pci_host_bridge *bridge;
> +	struct device_node *np_syscon;
> +	struct cdns_pcie *cdns_pcie;
> +	struct sg2042_pcie *pcie;
> +	struct cdns_pcie_rc *rc;
> +	struct regmap *syscon;
> +	int ret;
> +
> +	if (!IS_ENABLED(CONFIG_PCIE_CADENCE_HOST))
> +		return -ENODEV;
> +
> +	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
> +	if (!bridge) {
> +		dev_err(dev, "Failed to alloc host bridge!\n");
> +		return -ENOMEM;
> +	}

Add blank line.

> +	bridge->ops = &sg2042_pcie_host_ops;
> +
> +	rc = pci_host_bridge_priv(bridge);
> +	cdns_pcie = &rc->pcie;
> +	cdns_pcie->dev = dev;
> +	cdns_pcie->ops = &sg2042_cdns_pcie_ops;
> +	pcie->cdns_pcie = cdns_pcie;
> +
> +	np_syscon = of_parse_phandle(np, "sophgo,syscon-pcie-ctrl", 0);
> +	if (!np_syscon) {
> +		dev_err(dev, "Failed to get syscon node\n");
> +		return -ENOMEM;
> +	}
> +	syscon = syscon_node_to_regmap(np_syscon);
> +	if (IS_ERR(syscon)) {
> +		dev_err(dev, "Failed to get regmap for syscon\n");
> +		return -ENOMEM;
> +	}
> +	pcie->syscon = syscon;
> +
> +	if (of_property_read_u32(np, "sophgo,link-id", &pcie->link_id)) {
> +		dev_err(dev, "Unable to parse link ID\n");
> +		return -EINVAL;
> +	}
> +
> +	pcie->internal_msi = 0;
> +	if (of_property_read_bool(np, "sophgo,internal-msi"))
> +		pcie->internal_msi = 1;
> +
> +	platform_set_drvdata(pdev, pcie);
> +
> +	pm_runtime_enable(dev);
> +
> +	ret = pm_runtime_get_sync(dev);
> +	if (ret < 0) {
> +		dev_err(dev, "pm_runtime_get_sync failed\n");
> +		goto err_get_sync;
> +	}
> +
> +	if (pcie->internal_msi) {
> +		ret = sg2042_pcie_setup_msi(pcie, pdev);
> +		if (ret < 0)
> +			goto err_setup_msi;
> +	} else {
> +		ret = sg2042_pcie_setup_msi_external(pcie);
> +		if (ret < 0)
> +			goto err_setup_msi;
> +	}
> +
> +	ret = cdns_pcie_init_phy(dev, cdns_pcie);
> +	if (ret) {
> +		dev_err(dev, "Failed to init phy!\n");
> +		goto err_setup_msi;
> +	}
> +
> +	ret = cdns_pcie_host_setup(rc);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to setup host!\n");
> +		goto err_host_setup;
> +	}
> +
> +	return 0;
> +
> +err_host_setup:
> +	cdns_pcie_disable_phy(cdns_pcie);
> +
> +err_setup_msi:
> +	sg2042_pcie_free_msi(pcie);
> +
> +err_get_sync:
> +	pm_runtime_put(dev);
> +	pm_runtime_disable(dev);
> +
> +	return ret;
> +}
> +
> +static void sg2042_pcie_shutdown(struct platform_device *pdev)
> +{
> +	struct sg2042_pcie *pcie = platform_get_drvdata(pdev);
> +	struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
> +	struct device *dev = &pdev->dev;
> +
> +	sg2042_pcie_free_msi(pcie);
> +
> +	cdns_pcie_disable_phy(cdns_pcie);
> +
> +	pm_runtime_put(dev);
> +	pm_runtime_disable(dev);
> +}
> +
> +static const struct of_device_id sg2042_pcie_of_match[] = {
> +	{ .compatible = "sophgo,sg2042-pcie-host" },
> +	{},
> +};
> +
> +static struct platform_driver sg2042_pcie_driver = {
> +	.driver = {
> +		.name		= "sg2042-pcie",
> +		.of_match_table	= sg2042_pcie_of_match,
> +		.pm		= &cdns_pcie_pm_ops,
> +	},
> +	.probe		= sg2042_pcie_probe,
> +	.shutdown	= sg2042_pcie_shutdown,
> +};
> +builtin_platform_driver(sg2042_pcie_driver);
> -- 
> 2.34.1
> 


From irogers at google.com  Tue Nov 12 14:24:15 2024
From: irogers at google.com (Ian Rogers)
Date: Tue, 12 Nov 2024 14:24:15 -0800
Subject: [PATCH v1 3/4] perf record: Skip don't fail for events that don't open
In-Reply-To: <20241112195343.GA404636@e132581.arm.com>
References: <20241026121758.143259-1-irogers@google.com> <20241026121758.143259-4-irogers@google.com>
 <20241112195343.GA404636@e132581.arm.com>
Message-ID: <CAP-5=fXuyZbn3Jiq=RQaLTqybgji50Ko8jrpsinFqo+OOPBeRw@mail.gmail.com>

On Tue, Nov 12, 2024 at 11:53?AM Leo Yan <leo.yan at arm.com> wrote:
>
> On Sat, Oct 26, 2024 at 05:17:57AM -0700, Ian Rogers wrote:
> >
> > Whilst for many tools it is an expected behavior that failure to open
> > a perf event is a failure, ARM decided to name PMU events the same as
> > legacy events and then failed to rename such events on a server uncore
> > SLC PMU. As perf's default behavior when no PMU is specified is to
> > open the event on all PMUs that advertise/"have" the event, this
> > yielded failures when trying to make the priority of legacy and
> > sysfs/json events uniform - something requested by RISC-V and ARM. A
> > legacy event user on ARM hardware may find their event opened on an
> > uncore PMU which for perf record will fail. Arnaldo suggested skipping
> > such events which this patch implements. Rather than have the skipping
> > conditional on running on ARM, the skipping is done on all
> > architectures as such a fundamental behavioral difference could lead
> > to problems with tools built/depending on perf.
> >
> > An example of perf record failing to open events on x86 is:
> > ```
> > $ perf record -e data_read,cycles,LLC-prefetch-read -a sleep 0.1
> > Error:
> > Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0' which will be removed.
> > The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> > "dmesg | grep -i perf" may provide additional information.
> >
> > Error:
> > Failure to open event 'data_read' on PMU 'uncore_imc_free_running_1' which will be removed.
> > The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
> > "dmesg | grep -i perf" may provide additional information.
> >
> > Error:
> > Failure to open event 'LLC-prefetch-read' on PMU 'cpu' which will be removed.
> > The LLC-prefetch-read event is not supported.
> > [ perf record: Woken up 1 times to write data ]
> > [ perf record: Captured and wrote 2.188 MB perf.data (87 samples) ]
> >
> > $ perf report --stats
> > Aggregated stats:
> >                TOTAL events:      17255
> >                 MMAP events:        284  ( 1.6%)
> >                 COMM events:       1961  (11.4%)
> >                 EXIT events:          1  ( 0.0%)
> >                 FORK events:       1960  (11.4%)
> >               SAMPLE events:         87  ( 0.5%)
> >                MMAP2 events:      12836  (74.4%)
> >              KSYMBOL events:         83  ( 0.5%)
> >            BPF_EVENT events:         36  ( 0.2%)
> >       FINISHED_ROUND events:          2  ( 0.0%)
> >             ID_INDEX events:          1  ( 0.0%)
> >           THREAD_MAP events:          1  ( 0.0%)
> >              CPU_MAP events:          1  ( 0.0%)
> >            TIME_CONV events:          1  ( 0.0%)
> >        FINISHED_INIT events:          1  ( 0.0%)
> > cycles stats:
> >               SAMPLE events:         87
> > ```
>
> Thanks for James reminding me.  Tested on AVA platform:
>
> # tree /sys/bus/event_source/devices/arm_dsu_*/events
>   ...
>   /sys/bus/event_source/devices/arm_dsu_9/events
>   ??? bus_access
>   ??? bus_cycles
>   ??? cycles
>   ??? l3d_cache
>   ??? l3d_cache_allocate
>   ??? l3d_cache_refill
>   ??? l3d_cache_wb
>   ??? memory_error
>
> # ./perf record -- sleep 0.1
>  Error:
>  Failure to open event 'cycles:PH' on PMU 'arm_dsu_0' which will be
>  removed.
>  cycles:PH: PMU Hardware doesn't support sampling/overflow-interrupts.
>  Try 'perf stat'
>  Error:
>  Failure to open event 'cycles:PH' on PMU 'arm_dsu_1' which will be
>  removed.
>  cycles:PH: PMU Hardware doesn't support sampling/overflow-interrupts.
>  Try 'perf stat'
>  ...
>  Error:
>  Failure to open event 'cycles:PH' on PMU 'arm_dsu_15' which will be
>  removed.
>  cycles:PH: PMU Hardware doesn't support sampling/overflow-interrupts.
>  Try 'perf stat'
>  [ perf record: Woken up 1 times to write data ]
>  [ perf record: Captured and wrote 0.008 MB perf.data (8 samples) ]
>
> # ./perf report --stats
>
>  Aggregated stats:
>                 TOTAL events:         67
>                  MMAP events:         40  (59.7%)
>                  COMM events:          1  ( 1.5%)
>                SAMPLE events:          8  (11.9%)
>               KSYMBOL events:          6  ( 9.0%)
>             BPF_EVENT events:          6  ( 9.0%)
>        FINISHED_ROUND events:          1  ( 1.5%)
>              ID_INDEX events:          1  ( 1.5%)
>            THREAD_MAP events:          1  ( 1.5%)
>               CPU_MAP events:          1  ( 1.5%)
>             TIME_CONV events:          1  ( 1.5%)
>         FINISHED_INIT events:          1  ( 1.5%)
>  cycles:P stats:
>                SAMPLE events:          8
>
> # ./perf stat -- sleep 0.1
>
>  Performance counter stats for 'sleep 0.1':
>
>               0.87 msec task-clock                       #    0.009 CPUs utilized
>                  1      context-switches                 #    1.148 K/sec
>                  0      cpu-migrations                   #    0.000 /sec
>                 52      page-faults                      #   59.685 K/sec
>            877,835      instructions                     #    1.14  insn per cycle
>                                                   #    0.25  stalled cycles per insn
>            772,102      cycles                           #  886.210 M/sec
>            191,914      stalled-cycles-frontend          #   24.86% frontend cycles idle
>            219,183      stalled-cycles-backend           #   28.39% backend cycles idle
>            184,099      branches                         #  211.307 M/sec
>              8,548      branch-misses                    #    4.64% of all branches
>
>        0.101623529 seconds time elapsed
>
>        0.001645000 seconds user
>        0.000000000 seconds sys
>
> Tested-by: Leo Yan <leo.yan at arm.com>

Thanks Leo! As the Tested-by makes sense only if you've applied all 4
patches, which your testing and James' testing shows you've both done,
I'll add the tags to all 4 patches. I'll do likewise with Atish,
rebase and resend the patches.

Thanks,
Ian


From patchwork-bot+linux-riscv at kernel.org  Tue Nov 12 14:53:09 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Tue, 12 Nov 2024 22:53:09 +0000
Subject: [PATCH -fixes] drivers: perf: Fix wrong put_cpu() placement
In-Reply-To: <20241112113422.617954-1-alexghiti@rivosinc.com>
References: <20241112113422.617954-1-alexghiti@rivosinc.com>
Message-ID: <173145198951.701548.549721495064478963.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Palmer Dabbelt <palmer at rivosinc.com>:

On Tue, 12 Nov 2024 12:34:22 +0100 you wrote:
> Unfortunately, the wrong patch version was merged which places the
> put_cpu() after enabling a static key, which is not safe as pointed by
> Will [1], so move put_cpu() before to avoid this.
> 
> Fixes: 2840dadf0dde ("drivers: perf: Fix smp_processor_id() use in preemptible code")
> Reported-by: Atish Patra <atishp at rivosinc.com>
> Link: https://lore.kernel.org/all/20240827125335.GD4772 at willie-the-truck/ [1]
> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> 
> [...]

Here is the summary with links:
  - [-fixes] drivers: perf: Fix wrong put_cpu() placement
    https://git.kernel.org/riscv/c/57f7c7dc78cd

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Tue Nov 12 14:53:10 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Tue, 12 Nov 2024 22:53:10 +0000
Subject: [PATCH] irqchip/riscv-imsic: Fix output text of base address
In-Reply-To: <20240909085610.46625-2-ajones@ventanamicro.com>
References: <20240909085610.46625-2-ajones@ventanamicro.com>
Message-ID: <173145199075.701548.7255466685517081428.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Thomas Gleixner <tglx at linutronix.de>:

On Mon,  9 Sep 2024 10:56:11 +0200 you wrote:
> The "per-CPU IDs ... at base ..." info log is outputting a physical
> address, not a PPN.
> 
> Fixes: 027e125acdba ("irqchip/riscv-imsic: Add device MSI domain support for platform devices")
> Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
> ---
>  drivers/irqchip/irq-riscv-imsic-platform.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Here is the summary with links:
  - irqchip/riscv-imsic: Fix output text of base address
    https://git.kernel.org/riscv/c/4a1361e9a5c5

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Tue Nov 12 14:53:12 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Tue, 12 Nov 2024 22:53:12 +0000
Subject: [PATCH] irqchip/sifive-plic: Fix error codes
In-Reply-To: <20240903-correct_error_codes_sifive_plic-v1-1-d929b79663a2@rivosinc.com>
References: <20240903-correct_error_codes_sifive_plic-v1-1-d929b79663a2@rivosinc.com>
Message-ID: <173145199270.701548.8713115624337765162.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Thomas Gleixner <tglx at linutronix.de>:

On Tue, 03 Sep 2024 16:36:19 -0700 you wrote:
> Set error to -ENOMEM if kcalloc() fails or if irq_domain_add_linear()
> fails inside of plic_probe().
> 
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> Reported-by: kernel test robot <lkp at intel.com>
> Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
> Closes: https://lore.kernel.org/r/202409031122.yBh8HrxA-lkp at intel.com/
> 
> [...]

Here is the summary with links:
  - irqchip/sifive-plic: Fix error codes
    https://git.kernel.org/riscv/c/6eabf656048d

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Tue Nov 12 14:53:14 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Tue, 12 Nov 2024 22:53:14 +0000
Subject: [PATCH] mmc: core: Only set maximum DMA segment size if DMA is
 supported
In-Reply-To: <20240924210123.2288529-1-linux@roeck-us.net>
References: <20240924210123.2288529-1-linux@roeck-us.net>
Message-ID: <173145199424.701548.5612261824540957185.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (fixes)
by Ulf Hansson <ulf.hansson at linaro.org>:

On Tue, 24 Sep 2024 14:01:23 -0700 you wrote:
> Since upstream commit 334304ac2bac ("dma-mapping: don't return errors
> from dma_set_max_seg_size") calling dma_set_max_seg_size() on a device
> not supporting DMA results in a warning traceback. This is seen when
> booting the sifive_u machine from SD. The underlying SPI controller
> (sifive,spi0 compatible) explicitly sets dma_mask to NULL.
> 
> Avoid the backtrace by only calling dma_set_max_seg_size() if DMA is
> supported.
> 
> [...]

Here is the summary with links:
  - mmc: core: Only set maximum DMA segment size if DMA is supported
    https://git.kernel.org/riscv/c/c26339faed11

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From zhangjiao2 at cmss.chinamobile.com  Tue Nov 12 17:20:29 2024
From: zhangjiao2 at cmss.chinamobile.com (zhangjiao2)
Date: Wed, 13 Nov 2024 09:20:29 +0800
Subject: [PATCH] pinctrl: k210: Modify the wrong "#undef"
Message-ID: <20241113012029.3204-1-zhangjiao2@cmss.chinamobile.com>

From: zhang jiao <zhangjiao2 at cmss.chinamobile.com>

Here shuld be undef "K210_PC_DEFAULT", not "DEFAULT".

Signed-off-by: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
---
 drivers/pinctrl/pinctrl-k210.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
index caf20215aaba..eddb01796a83 100644
--- a/drivers/pinctrl/pinctrl-k210.c
+++ b/drivers/pinctrl/pinctrl-k210.c
@@ -181,7 +181,7 @@ static const u32 k210_pinconf_mode_id_to_mode[] = {
 	[K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
 };
 
-#undef DEFAULT
+#undef K210_PC_DEFAULT
 
 /*
  * Pin functions configuration information.
-- 
2.33.0





From lkp at intel.com  Tue Nov 12 19:15:51 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 13 Nov 2024 11:15:51 +0800
Subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack
 memory via FWFT sbi call
In-Reply-To: <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
Message-ID: <202411131001.zfDosm7U-lkp@intel.com>

Hi Deepak,

kernel test robot noticed the following build errors:

[auto build test ERROR on 64f7b77f0bd9271861ed9e410e9856b6b0b21c48]

url:    https://github.com/intel-lab-lkp/linux/commits/Deepak-Gupta/mm-Introduce-ARCH_HAS_USER_SHADOW_STACK/20241112-050530
base:   64f7b77f0bd9271861ed9e410e9856b6b0b21c48
patch link:    https://lore.kernel.org/r/20241111-v5_user_cfi_series-v8-24-dce14aa30207%40rivosinc.com
patch subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack memory via FWFT sbi call
config: riscv-randconfig-r063-20241113 (https://download.01.org/0day-ci/archive/20241113/202411131001.zfDosm7U-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241113/202411131001.zfDosm7U-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411131001.zfDosm7U-lkp at intel.com/

All errors (new ones prefixed by >>):

         |                                                       ~~~~~~~~~~ ^
   include/asm-generic/io.h:744:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     744 |         insb(addr, buffer, count);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/io.h:104:53: note: expanded from macro 'insb'
     104 | #define insb(addr, buffer, count) __insb(PCI_IOBASE + (addr), buffer, count)
         |                                          ~~~~~~~~~~ ^
   In file included from arch/riscv/kernel/asm-offsets.c:12:
   In file included from include/linux/ftrace.h:10:
   In file included from include/linux/trace_recursion.h:5:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:752:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     752 |         insw(addr, buffer, count);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/io.h:105:53: note: expanded from macro 'insw'
     105 | #define insw(addr, buffer, count) __insw(PCI_IOBASE + (addr), buffer, count)
         |                                          ~~~~~~~~~~ ^
   In file included from arch/riscv/kernel/asm-offsets.c:12:
   In file included from include/linux/ftrace.h:10:
   In file included from include/linux/trace_recursion.h:5:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:760:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     760 |         insl(addr, buffer, count);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/io.h:106:53: note: expanded from macro 'insl'
     106 | #define insl(addr, buffer, count) __insl(PCI_IOBASE + (addr), buffer, count)
         |                                          ~~~~~~~~~~ ^
   In file included from arch/riscv/kernel/asm-offsets.c:12:
   In file included from include/linux/ftrace.h:10:
   In file included from include/linux/trace_recursion.h:5:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:769:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     769 |         outsb(addr, buffer, count);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/io.h:118:55: note: expanded from macro 'outsb'
     118 | #define outsb(addr, buffer, count) __outsb(PCI_IOBASE + (addr), buffer, count)
         |                                            ~~~~~~~~~~ ^
   In file included from arch/riscv/kernel/asm-offsets.c:12:
   In file included from include/linux/ftrace.h:10:
   In file included from include/linux/trace_recursion.h:5:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:778:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     778 |         outsw(addr, buffer, count);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/io.h:119:55: note: expanded from macro 'outsw'
     119 | #define outsw(addr, buffer, count) __outsw(PCI_IOBASE + (addr), buffer, count)
         |                                            ~~~~~~~~~~ ^
   In file included from arch/riscv/kernel/asm-offsets.c:12:
   In file included from include/linux/ftrace.h:10:
   In file included from include/linux/trace_recursion.h:5:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:787:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
     787 |         outsl(addr, buffer, count);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/io.h:120:55: note: expanded from macro 'outsl'
     120 | #define outsl(addr, buffer, count) __outsl(PCI_IOBASE + (addr), buffer, count)
         |                                            ~~~~~~~~~~ ^
   In file included from arch/riscv/kernel/asm-offsets.c:12:
   In file included from include/linux/ftrace.h:10:
   In file included from include/linux/trace_recursion.h:5:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:14:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:1115:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
    1115 |         return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
         |                                                   ~~~~~~~~~~ ^
>> arch/riscv/kernel/asm-offsets.c:520:23: error: use of undeclared identifier 'SBI_EXT_FWFT'
     520 |         DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
         |                              ^
>> arch/riscv/kernel/asm-offsets.c:521:27: error: use of undeclared identifier 'SBI_EXT_FWFT_SET'
     521 |         DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
         |                                  ^
>> arch/riscv/kernel/asm-offsets.c:522:32: error: use of undeclared identifier 'SBI_FWFT_SHADOW_STACK'
     522 |         DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
         |                                       ^
>> arch/riscv/kernel/asm-offsets.c:523:33: error: use of undeclared identifier 'SBI_FWFT_SET_FLAG_LOCK'
     523 |         DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);
         |                                        ^
   14 warnings and 4 errors generated.
   make[3]: *** [scripts/Makefile.build:102: arch/riscv/kernel/asm-offsets.s] Error 1
   make[3]: Target 'prepare' not remade because of errors.
   make[2]: *** [Makefile:1203: prepare0] Error 2
   make[2]: Target 'prepare' not remade because of errors.
   make[1]: *** [Makefile:224: __sub-make] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [Makefile:224: __sub-make] Error 2
   make: Target 'prepare' not remade because of errors.


vim +/SBI_EXT_FWFT +520 arch/riscv/kernel/asm-offsets.c

    95	
    96		DEFINE(PT_SIZE, sizeof(struct pt_regs));
    97		OFFSET(PT_EPC, pt_regs, epc);
    98		OFFSET(PT_RA, pt_regs, ra);
    99		OFFSET(PT_FP, pt_regs, s0);
   100		OFFSET(PT_S0, pt_regs, s0);
   101		OFFSET(PT_S1, pt_regs, s1);
   102		OFFSET(PT_S2, pt_regs, s2);
   103		OFFSET(PT_S3, pt_regs, s3);
   104		OFFSET(PT_S4, pt_regs, s4);
   105		OFFSET(PT_S5, pt_regs, s5);
   106		OFFSET(PT_S6, pt_regs, s6);
   107		OFFSET(PT_S7, pt_regs, s7);
   108		OFFSET(PT_S8, pt_regs, s8);
   109		OFFSET(PT_S9, pt_regs, s9);
   110		OFFSET(PT_S10, pt_regs, s10);
   111		OFFSET(PT_S11, pt_regs, s11);
   112		OFFSET(PT_SP, pt_regs, sp);
   113		OFFSET(PT_TP, pt_regs, tp);
   114		OFFSET(PT_A0, pt_regs, a0);
   115		OFFSET(PT_A1, pt_regs, a1);
   116		OFFSET(PT_A2, pt_regs, a2);
   117		OFFSET(PT_A3, pt_regs, a3);
   118		OFFSET(PT_A4, pt_regs, a4);
   119		OFFSET(PT_A5, pt_regs, a5);
   120		OFFSET(PT_A6, pt_regs, a6);
   121		OFFSET(PT_A7, pt_regs, a7);
   122		OFFSET(PT_T0, pt_regs, t0);
   123		OFFSET(PT_T1, pt_regs, t1);
   124		OFFSET(PT_T2, pt_regs, t2);
   125		OFFSET(PT_T3, pt_regs, t3);
   126		OFFSET(PT_T4, pt_regs, t4);
   127		OFFSET(PT_T5, pt_regs, t5);
   128		OFFSET(PT_T6, pt_regs, t6);
   129		OFFSET(PT_GP, pt_regs, gp);
   130		OFFSET(PT_ORIG_A0, pt_regs, orig_a0);
   131		OFFSET(PT_STATUS, pt_regs, status);
   132		OFFSET(PT_BADADDR, pt_regs, badaddr);
   133		OFFSET(PT_CAUSE, pt_regs, cause);
   134	
   135		OFFSET(SUSPEND_CONTEXT_REGS, suspend_context, regs);
   136	
   137		OFFSET(HIBERN_PBE_ADDR, pbe, address);
   138		OFFSET(HIBERN_PBE_ORIG, pbe, orig_address);
   139		OFFSET(HIBERN_PBE_NEXT, pbe, next);
   140	
   141		OFFSET(KVM_ARCH_GUEST_ZERO, kvm_vcpu_arch, guest_context.zero);
   142		OFFSET(KVM_ARCH_GUEST_RA, kvm_vcpu_arch, guest_context.ra);
   143		OFFSET(KVM_ARCH_GUEST_SP, kvm_vcpu_arch, guest_context.sp);
   144		OFFSET(KVM_ARCH_GUEST_GP, kvm_vcpu_arch, guest_context.gp);
   145		OFFSET(KVM_ARCH_GUEST_TP, kvm_vcpu_arch, guest_context.tp);
   146		OFFSET(KVM_ARCH_GUEST_T0, kvm_vcpu_arch, guest_context.t0);
   147		OFFSET(KVM_ARCH_GUEST_T1, kvm_vcpu_arch, guest_context.t1);
   148		OFFSET(KVM_ARCH_GUEST_T2, kvm_vcpu_arch, guest_context.t2);
   149		OFFSET(KVM_ARCH_GUEST_S0, kvm_vcpu_arch, guest_context.s0);
   150		OFFSET(KVM_ARCH_GUEST_S1, kvm_vcpu_arch, guest_context.s1);
   151		OFFSET(KVM_ARCH_GUEST_A0, kvm_vcpu_arch, guest_context.a0);
   152		OFFSET(KVM_ARCH_GUEST_A1, kvm_vcpu_arch, guest_context.a1);
   153		OFFSET(KVM_ARCH_GUEST_A2, kvm_vcpu_arch, guest_context.a2);
   154		OFFSET(KVM_ARCH_GUEST_A3, kvm_vcpu_arch, guest_context.a3);
   155		OFFSET(KVM_ARCH_GUEST_A4, kvm_vcpu_arch, guest_context.a4);
   156		OFFSET(KVM_ARCH_GUEST_A5, kvm_vcpu_arch, guest_context.a5);
   157		OFFSET(KVM_ARCH_GUEST_A6, kvm_vcpu_arch, guest_context.a6);
   158		OFFSET(KVM_ARCH_GUEST_A7, kvm_vcpu_arch, guest_context.a7);
   159		OFFSET(KVM_ARCH_GUEST_S2, kvm_vcpu_arch, guest_context.s2);
   160		OFFSET(KVM_ARCH_GUEST_S3, kvm_vcpu_arch, guest_context.s3);
   161		OFFSET(KVM_ARCH_GUEST_S4, kvm_vcpu_arch, guest_context.s4);
   162		OFFSET(KVM_ARCH_GUEST_S5, kvm_vcpu_arch, guest_context.s5);
   163		OFFSET(KVM_ARCH_GUEST_S6, kvm_vcpu_arch, guest_context.s6);
   164		OFFSET(KVM_ARCH_GUEST_S7, kvm_vcpu_arch, guest_context.s7);
   165		OFFSET(KVM_ARCH_GUEST_S8, kvm_vcpu_arch, guest_context.s8);
   166		OFFSET(KVM_ARCH_GUEST_S9, kvm_vcpu_arch, guest_context.s9);
   167		OFFSET(KVM_ARCH_GUEST_S10, kvm_vcpu_arch, guest_context.s10);
   168		OFFSET(KVM_ARCH_GUEST_S11, kvm_vcpu_arch, guest_context.s11);
   169		OFFSET(KVM_ARCH_GUEST_T3, kvm_vcpu_arch, guest_context.t3);
   170		OFFSET(KVM_ARCH_GUEST_T4, kvm_vcpu_arch, guest_context.t4);
   171		OFFSET(KVM_ARCH_GUEST_T5, kvm_vcpu_arch, guest_context.t5);
   172		OFFSET(KVM_ARCH_GUEST_T6, kvm_vcpu_arch, guest_context.t6);
   173		OFFSET(KVM_ARCH_GUEST_SEPC, kvm_vcpu_arch, guest_context.sepc);
   174		OFFSET(KVM_ARCH_GUEST_SSTATUS, kvm_vcpu_arch, guest_context.sstatus);
   175		OFFSET(KVM_ARCH_GUEST_HSTATUS, kvm_vcpu_arch, guest_context.hstatus);
   176		OFFSET(KVM_ARCH_GUEST_SCOUNTEREN, kvm_vcpu_arch, guest_csr.scounteren);
   177	
   178		OFFSET(KVM_ARCH_HOST_ZERO, kvm_vcpu_arch, host_context.zero);
   179		OFFSET(KVM_ARCH_HOST_RA, kvm_vcpu_arch, host_context.ra);
   180		OFFSET(KVM_ARCH_HOST_SP, kvm_vcpu_arch, host_context.sp);
   181		OFFSET(KVM_ARCH_HOST_GP, kvm_vcpu_arch, host_context.gp);
   182		OFFSET(KVM_ARCH_HOST_TP, kvm_vcpu_arch, host_context.tp);
   183		OFFSET(KVM_ARCH_HOST_T0, kvm_vcpu_arch, host_context.t0);
   184		OFFSET(KVM_ARCH_HOST_T1, kvm_vcpu_arch, host_context.t1);
   185		OFFSET(KVM_ARCH_HOST_T2, kvm_vcpu_arch, host_context.t2);
   186		OFFSET(KVM_ARCH_HOST_S0, kvm_vcpu_arch, host_context.s0);
   187		OFFSET(KVM_ARCH_HOST_S1, kvm_vcpu_arch, host_context.s1);
   188		OFFSET(KVM_ARCH_HOST_A0, kvm_vcpu_arch, host_context.a0);
   189		OFFSET(KVM_ARCH_HOST_A1, kvm_vcpu_arch, host_context.a1);
   190		OFFSET(KVM_ARCH_HOST_A2, kvm_vcpu_arch, host_context.a2);
   191		OFFSET(KVM_ARCH_HOST_A3, kvm_vcpu_arch, host_context.a3);
   192		OFFSET(KVM_ARCH_HOST_A4, kvm_vcpu_arch, host_context.a4);
   193		OFFSET(KVM_ARCH_HOST_A5, kvm_vcpu_arch, host_context.a5);
   194		OFFSET(KVM_ARCH_HOST_A6, kvm_vcpu_arch, host_context.a6);
   195		OFFSET(KVM_ARCH_HOST_A7, kvm_vcpu_arch, host_context.a7);
   196		OFFSET(KVM_ARCH_HOST_S2, kvm_vcpu_arch, host_context.s2);
   197		OFFSET(KVM_ARCH_HOST_S3, kvm_vcpu_arch, host_context.s3);
   198		OFFSET(KVM_ARCH_HOST_S4, kvm_vcpu_arch, host_context.s4);
   199		OFFSET(KVM_ARCH_HOST_S5, kvm_vcpu_arch, host_context.s5);
   200		OFFSET(KVM_ARCH_HOST_S6, kvm_vcpu_arch, host_context.s6);
   201		OFFSET(KVM_ARCH_HOST_S7, kvm_vcpu_arch, host_context.s7);
   202		OFFSET(KVM_ARCH_HOST_S8, kvm_vcpu_arch, host_context.s8);
   203		OFFSET(KVM_ARCH_HOST_S9, kvm_vcpu_arch, host_context.s9);
   204		OFFSET(KVM_ARCH_HOST_S10, kvm_vcpu_arch, host_context.s10);
   205		OFFSET(KVM_ARCH_HOST_S11, kvm_vcpu_arch, host_context.s11);
   206		OFFSET(KVM_ARCH_HOST_T3, kvm_vcpu_arch, host_context.t3);
   207		OFFSET(KVM_ARCH_HOST_T4, kvm_vcpu_arch, host_context.t4);
   208		OFFSET(KVM_ARCH_HOST_T5, kvm_vcpu_arch, host_context.t5);
   209		OFFSET(KVM_ARCH_HOST_T6, kvm_vcpu_arch, host_context.t6);
   210		OFFSET(KVM_ARCH_HOST_SEPC, kvm_vcpu_arch, host_context.sepc);
   211		OFFSET(KVM_ARCH_HOST_SSTATUS, kvm_vcpu_arch, host_context.sstatus);
   212		OFFSET(KVM_ARCH_HOST_HSTATUS, kvm_vcpu_arch, host_context.hstatus);
   213		OFFSET(KVM_ARCH_HOST_SSCRATCH, kvm_vcpu_arch, host_sscratch);
   214		OFFSET(KVM_ARCH_HOST_STVEC, kvm_vcpu_arch, host_stvec);
   215		OFFSET(KVM_ARCH_HOST_SCOUNTEREN, kvm_vcpu_arch, host_scounteren);
   216	
   217		OFFSET(KVM_ARCH_TRAP_SEPC, kvm_cpu_trap, sepc);
   218		OFFSET(KVM_ARCH_TRAP_SCAUSE, kvm_cpu_trap, scause);
   219		OFFSET(KVM_ARCH_TRAP_STVAL, kvm_cpu_trap, stval);
   220		OFFSET(KVM_ARCH_TRAP_HTVAL, kvm_cpu_trap, htval);
   221		OFFSET(KVM_ARCH_TRAP_HTINST, kvm_cpu_trap, htinst);
   222	
   223		/* F extension */
   224	
   225		OFFSET(KVM_ARCH_FP_F_F0, kvm_cpu_context, fp.f.f[0]);
   226		OFFSET(KVM_ARCH_FP_F_F1, kvm_cpu_context, fp.f.f[1]);
   227		OFFSET(KVM_ARCH_FP_F_F2, kvm_cpu_context, fp.f.f[2]);
   228		OFFSET(KVM_ARCH_FP_F_F3, kvm_cpu_context, fp.f.f[3]);
   229		OFFSET(KVM_ARCH_FP_F_F4, kvm_cpu_context, fp.f.f[4]);
   230		OFFSET(KVM_ARCH_FP_F_F5, kvm_cpu_context, fp.f.f[5]);
   231		OFFSET(KVM_ARCH_FP_F_F6, kvm_cpu_context, fp.f.f[6]);
   232		OFFSET(KVM_ARCH_FP_F_F7, kvm_cpu_context, fp.f.f[7]);
   233		OFFSET(KVM_ARCH_FP_F_F8, kvm_cpu_context, fp.f.f[8]);
   234		OFFSET(KVM_ARCH_FP_F_F9, kvm_cpu_context, fp.f.f[9]);
   235		OFFSET(KVM_ARCH_FP_F_F10, kvm_cpu_context, fp.f.f[10]);
   236		OFFSET(KVM_ARCH_FP_F_F11, kvm_cpu_context, fp.f.f[11]);
   237		OFFSET(KVM_ARCH_FP_F_F12, kvm_cpu_context, fp.f.f[12]);
   238		OFFSET(KVM_ARCH_FP_F_F13, kvm_cpu_context, fp.f.f[13]);
   239		OFFSET(KVM_ARCH_FP_F_F14, kvm_cpu_context, fp.f.f[14]);
   240		OFFSET(KVM_ARCH_FP_F_F15, kvm_cpu_context, fp.f.f[15]);
   241		OFFSET(KVM_ARCH_FP_F_F16, kvm_cpu_context, fp.f.f[16]);
   242		OFFSET(KVM_ARCH_FP_F_F17, kvm_cpu_context, fp.f.f[17]);
   243		OFFSET(KVM_ARCH_FP_F_F18, kvm_cpu_context, fp.f.f[18]);
   244		OFFSET(KVM_ARCH_FP_F_F19, kvm_cpu_context, fp.f.f[19]);
   245		OFFSET(KVM_ARCH_FP_F_F20, kvm_cpu_context, fp.f.f[20]);
   246		OFFSET(KVM_ARCH_FP_F_F21, kvm_cpu_context, fp.f.f[21]);
   247		OFFSET(KVM_ARCH_FP_F_F22, kvm_cpu_context, fp.f.f[22]);
   248		OFFSET(KVM_ARCH_FP_F_F23, kvm_cpu_context, fp.f.f[23]);
   249		OFFSET(KVM_ARCH_FP_F_F24, kvm_cpu_context, fp.f.f[24]);
   250		OFFSET(KVM_ARCH_FP_F_F25, kvm_cpu_context, fp.f.f[25]);
   251		OFFSET(KVM_ARCH_FP_F_F26, kvm_cpu_context, fp.f.f[26]);
   252		OFFSET(KVM_ARCH_FP_F_F27, kvm_cpu_context, fp.f.f[27]);
   253		OFFSET(KVM_ARCH_FP_F_F28, kvm_cpu_context, fp.f.f[28]);
   254		OFFSET(KVM_ARCH_FP_F_F29, kvm_cpu_context, fp.f.f[29]);
   255		OFFSET(KVM_ARCH_FP_F_F30, kvm_cpu_context, fp.f.f[30]);
   256		OFFSET(KVM_ARCH_FP_F_F31, kvm_cpu_context, fp.f.f[31]);
   257		OFFSET(KVM_ARCH_FP_F_FCSR, kvm_cpu_context, fp.f.fcsr);
   258	
   259		/* D extension */
   260	
   261		OFFSET(KVM_ARCH_FP_D_F0, kvm_cpu_context, fp.d.f[0]);
   262		OFFSET(KVM_ARCH_FP_D_F1, kvm_cpu_context, fp.d.f[1]);
   263		OFFSET(KVM_ARCH_FP_D_F2, kvm_cpu_context, fp.d.f[2]);
   264		OFFSET(KVM_ARCH_FP_D_F3, kvm_cpu_context, fp.d.f[3]);
   265		OFFSET(KVM_ARCH_FP_D_F4, kvm_cpu_context, fp.d.f[4]);
   266		OFFSET(KVM_ARCH_FP_D_F5, kvm_cpu_context, fp.d.f[5]);
   267		OFFSET(KVM_ARCH_FP_D_F6, kvm_cpu_context, fp.d.f[6]);
   268		OFFSET(KVM_ARCH_FP_D_F7, kvm_cpu_context, fp.d.f[7]);
   269		OFFSET(KVM_ARCH_FP_D_F8, kvm_cpu_context, fp.d.f[8]);
   270		OFFSET(KVM_ARCH_FP_D_F9, kvm_cpu_context, fp.d.f[9]);
   271		OFFSET(KVM_ARCH_FP_D_F10, kvm_cpu_context, fp.d.f[10]);
   272		OFFSET(KVM_ARCH_FP_D_F11, kvm_cpu_context, fp.d.f[11]);
   273		OFFSET(KVM_ARCH_FP_D_F12, kvm_cpu_context, fp.d.f[12]);
   274		OFFSET(KVM_ARCH_FP_D_F13, kvm_cpu_context, fp.d.f[13]);
   275		OFFSET(KVM_ARCH_FP_D_F14, kvm_cpu_context, fp.d.f[14]);
   276		OFFSET(KVM_ARCH_FP_D_F15, kvm_cpu_context, fp.d.f[15]);
   277		OFFSET(KVM_ARCH_FP_D_F16, kvm_cpu_context, fp.d.f[16]);
   278		OFFSET(KVM_ARCH_FP_D_F17, kvm_cpu_context, fp.d.f[17]);
   279		OFFSET(KVM_ARCH_FP_D_F18, kvm_cpu_context, fp.d.f[18]);
   280		OFFSET(KVM_ARCH_FP_D_F19, kvm_cpu_context, fp.d.f[19]);
   281		OFFSET(KVM_ARCH_FP_D_F20, kvm_cpu_context, fp.d.f[20]);
   282		OFFSET(KVM_ARCH_FP_D_F21, kvm_cpu_context, fp.d.f[21]);
   283		OFFSET(KVM_ARCH_FP_D_F22, kvm_cpu_context, fp.d.f[22]);
   284		OFFSET(KVM_ARCH_FP_D_F23, kvm_cpu_context, fp.d.f[23]);
   285		OFFSET(KVM_ARCH_FP_D_F24, kvm_cpu_context, fp.d.f[24]);
   286		OFFSET(KVM_ARCH_FP_D_F25, kvm_cpu_context, fp.d.f[25]);
   287		OFFSET(KVM_ARCH_FP_D_F26, kvm_cpu_context, fp.d.f[26]);
   288		OFFSET(KVM_ARCH_FP_D_F27, kvm_cpu_context, fp.d.f[27]);
   289		OFFSET(KVM_ARCH_FP_D_F28, kvm_cpu_context, fp.d.f[28]);
   290		OFFSET(KVM_ARCH_FP_D_F29, kvm_cpu_context, fp.d.f[29]);
   291		OFFSET(KVM_ARCH_FP_D_F30, kvm_cpu_context, fp.d.f[30]);
   292		OFFSET(KVM_ARCH_FP_D_F31, kvm_cpu_context, fp.d.f[31]);
   293		OFFSET(KVM_ARCH_FP_D_FCSR, kvm_cpu_context, fp.d.fcsr);
   294	
   295		/*
   296		 * THREAD_{F,X}* might be larger than a S-type offset can handle, but
   297		 * these are used in performance-sensitive assembly so we can't resort
   298		 * to loading the long immediate every time.
   299		 */
   300		DEFINE(TASK_THREAD_RA_RA,
   301			  offsetof(struct task_struct, thread.ra)
   302			- offsetof(struct task_struct, thread.ra)
   303		);
   304		DEFINE(TASK_THREAD_SP_RA,
   305			  offsetof(struct task_struct, thread.sp)
   306			- offsetof(struct task_struct, thread.ra)
   307		);
   308		DEFINE(TASK_THREAD_S0_RA,
   309			  offsetof(struct task_struct, thread.s[0])
   310			- offsetof(struct task_struct, thread.ra)
   311		);
   312		DEFINE(TASK_THREAD_S1_RA,
   313			  offsetof(struct task_struct, thread.s[1])
   314			- offsetof(struct task_struct, thread.ra)
   315		);
   316		DEFINE(TASK_THREAD_S2_RA,
   317			  offsetof(struct task_struct, thread.s[2])
   318			- offsetof(struct task_struct, thread.ra)
   319		);
   320		DEFINE(TASK_THREAD_S3_RA,
   321			  offsetof(struct task_struct, thread.s[3])
   322			- offsetof(struct task_struct, thread.ra)
   323		);
   324		DEFINE(TASK_THREAD_S4_RA,
   325			  offsetof(struct task_struct, thread.s[4])
   326			- offsetof(struct task_struct, thread.ra)
   327		);
   328		DEFINE(TASK_THREAD_S5_RA,
   329			  offsetof(struct task_struct, thread.s[5])
   330			- offsetof(struct task_struct, thread.ra)
   331		);
   332		DEFINE(TASK_THREAD_S6_RA,
   333			  offsetof(struct task_struct, thread.s[6])
   334			- offsetof(struct task_struct, thread.ra)
   335		);
   336		DEFINE(TASK_THREAD_S7_RA,
   337			  offsetof(struct task_struct, thread.s[7])
   338			- offsetof(struct task_struct, thread.ra)
   339		);
   340		DEFINE(TASK_THREAD_S8_RA,
   341			  offsetof(struct task_struct, thread.s[8])
   342			- offsetof(struct task_struct, thread.ra)
   343		);
   344		DEFINE(TASK_THREAD_S9_RA,
   345			  offsetof(struct task_struct, thread.s[9])
   346			- offsetof(struct task_struct, thread.ra)
   347		);
   348		DEFINE(TASK_THREAD_S10_RA,
   349			  offsetof(struct task_struct, thread.s[10])
   350			- offsetof(struct task_struct, thread.ra)
   351		);
   352		DEFINE(TASK_THREAD_S11_RA,
   353			  offsetof(struct task_struct, thread.s[11])
   354			- offsetof(struct task_struct, thread.ra)
   355		);
   356	
   357		DEFINE(TASK_THREAD_F0_F0,
   358			  offsetof(struct task_struct, thread.fstate.f[0])
   359			- offsetof(struct task_struct, thread.fstate.f[0])
   360		);
   361		DEFINE(TASK_THREAD_F1_F0,
   362			  offsetof(struct task_struct, thread.fstate.f[1])
   363			- offsetof(struct task_struct, thread.fstate.f[0])
   364		);
   365		DEFINE(TASK_THREAD_F2_F0,
   366			  offsetof(struct task_struct, thread.fstate.f[2])
   367			- offsetof(struct task_struct, thread.fstate.f[0])
   368		);
   369		DEFINE(TASK_THREAD_F3_F0,
   370			  offsetof(struct task_struct, thread.fstate.f[3])
   371			- offsetof(struct task_struct, thread.fstate.f[0])
   372		);
   373		DEFINE(TASK_THREAD_F4_F0,
   374			  offsetof(struct task_struct, thread.fstate.f[4])
   375			- offsetof(struct task_struct, thread.fstate.f[0])
   376		);
   377		DEFINE(TASK_THREAD_F5_F0,
   378			  offsetof(struct task_struct, thread.fstate.f[5])
   379			- offsetof(struct task_struct, thread.fstate.f[0])
   380		);
   381		DEFINE(TASK_THREAD_F6_F0,
   382			  offsetof(struct task_struct, thread.fstate.f[6])
   383			- offsetof(struct task_struct, thread.fstate.f[0])
   384		);
   385		DEFINE(TASK_THREAD_F7_F0,
   386			  offsetof(struct task_struct, thread.fstate.f[7])
   387			- offsetof(struct task_struct, thread.fstate.f[0])
   388		);
   389		DEFINE(TASK_THREAD_F8_F0,
   390			  offsetof(struct task_struct, thread.fstate.f[8])
   391			- offsetof(struct task_struct, thread.fstate.f[0])
   392		);
   393		DEFINE(TASK_THREAD_F9_F0,
   394			  offsetof(struct task_struct, thread.fstate.f[9])
   395			- offsetof(struct task_struct, thread.fstate.f[0])
   396		);
   397		DEFINE(TASK_THREAD_F10_F0,
   398			  offsetof(struct task_struct, thread.fstate.f[10])
   399			- offsetof(struct task_struct, thread.fstate.f[0])
   400		);
   401		DEFINE(TASK_THREAD_F11_F0,
   402			  offsetof(struct task_struct, thread.fstate.f[11])
   403			- offsetof(struct task_struct, thread.fstate.f[0])
   404		);
   405		DEFINE(TASK_THREAD_F12_F0,
   406			  offsetof(struct task_struct, thread.fstate.f[12])
   407			- offsetof(struct task_struct, thread.fstate.f[0])
   408		);
   409		DEFINE(TASK_THREAD_F13_F0,
   410			  offsetof(struct task_struct, thread.fstate.f[13])
   411			- offsetof(struct task_struct, thread.fstate.f[0])
   412		);
   413		DEFINE(TASK_THREAD_F14_F0,
   414			  offsetof(struct task_struct, thread.fstate.f[14])
   415			- offsetof(struct task_struct, thread.fstate.f[0])
   416		);
   417		DEFINE(TASK_THREAD_F15_F0,
   418			  offsetof(struct task_struct, thread.fstate.f[15])
   419			- offsetof(struct task_struct, thread.fstate.f[0])
   420		);
   421		DEFINE(TASK_THREAD_F16_F0,
   422			  offsetof(struct task_struct, thread.fstate.f[16])
   423			- offsetof(struct task_struct, thread.fstate.f[0])
   424		);
   425		DEFINE(TASK_THREAD_F17_F0,
   426			  offsetof(struct task_struct, thread.fstate.f[17])
   427			- offsetof(struct task_struct, thread.fstate.f[0])
   428		);
   429		DEFINE(TASK_THREAD_F18_F0,
   430			  offsetof(struct task_struct, thread.fstate.f[18])
   431			- offsetof(struct task_struct, thread.fstate.f[0])
   432		);
   433		DEFINE(TASK_THREAD_F19_F0,
   434			  offsetof(struct task_struct, thread.fstate.f[19])
   435			- offsetof(struct task_struct, thread.fstate.f[0])
   436		);
   437		DEFINE(TASK_THREAD_F20_F0,
   438			  offsetof(struct task_struct, thread.fstate.f[20])
   439			- offsetof(struct task_struct, thread.fstate.f[0])
   440		);
   441		DEFINE(TASK_THREAD_F21_F0,
   442			  offsetof(struct task_struct, thread.fstate.f[21])
   443			- offsetof(struct task_struct, thread.fstate.f[0])
   444		);
   445		DEFINE(TASK_THREAD_F22_F0,
   446			  offsetof(struct task_struct, thread.fstate.f[22])
   447			- offsetof(struct task_struct, thread.fstate.f[0])
   448		);
   449		DEFINE(TASK_THREAD_F23_F0,
   450			  offsetof(struct task_struct, thread.fstate.f[23])
   451			- offsetof(struct task_struct, thread.fstate.f[0])
   452		);
   453		DEFINE(TASK_THREAD_F24_F0,
   454			  offsetof(struct task_struct, thread.fstate.f[24])
   455			- offsetof(struct task_struct, thread.fstate.f[0])
   456		);
   457		DEFINE(TASK_THREAD_F25_F0,
   458			  offsetof(struct task_struct, thread.fstate.f[25])
   459			- offsetof(struct task_struct, thread.fstate.f[0])
   460		);
   461		DEFINE(TASK_THREAD_F26_F0,
   462			  offsetof(struct task_struct, thread.fstate.f[26])
   463			- offsetof(struct task_struct, thread.fstate.f[0])
   464		);
   465		DEFINE(TASK_THREAD_F27_F0,
   466			  offsetof(struct task_struct, thread.fstate.f[27])
   467			- offsetof(struct task_struct, thread.fstate.f[0])
   468		);
   469		DEFINE(TASK_THREAD_F28_F0,
   470			  offsetof(struct task_struct, thread.fstate.f[28])
   471			- offsetof(struct task_struct, thread.fstate.f[0])
   472		);
   473		DEFINE(TASK_THREAD_F29_F0,
   474			  offsetof(struct task_struct, thread.fstate.f[29])
   475			- offsetof(struct task_struct, thread.fstate.f[0])
   476		);
   477		DEFINE(TASK_THREAD_F30_F0,
   478			  offsetof(struct task_struct, thread.fstate.f[30])
   479			- offsetof(struct task_struct, thread.fstate.f[0])
   480		);
   481		DEFINE(TASK_THREAD_F31_F0,
   482			  offsetof(struct task_struct, thread.fstate.f[31])
   483			- offsetof(struct task_struct, thread.fstate.f[0])
   484		);
   485		DEFINE(TASK_THREAD_FCSR_F0,
   486			  offsetof(struct task_struct, thread.fstate.fcsr)
   487			- offsetof(struct task_struct, thread.fstate.f[0])
   488		);
   489	
   490		/*
   491		 * We allocate a pt_regs on the stack when entering the kernel.  This
   492		 * ensures the alignment is sane.
   493		 */
   494		DEFINE(PT_SIZE_ON_STACK, ALIGN(sizeof(struct pt_regs), STACK_ALIGN));
   495	
   496		OFFSET(KERNEL_MAP_VIRT_ADDR, kernel_mapping, virt_addr);
   497		OFFSET(SBI_HART_BOOT_TASK_PTR_OFFSET, sbi_hart_boot_data, task_ptr);
   498		OFFSET(SBI_HART_BOOT_STACK_PTR_OFFSET, sbi_hart_boot_data, stack_ptr);
   499	
   500		DEFINE(STACKFRAME_SIZE_ON_STACK, ALIGN(sizeof(struct stackframe), STACK_ALIGN));
   501		OFFSET(STACKFRAME_FP, stackframe, fp);
   502		OFFSET(STACKFRAME_RA, stackframe, ra);
   503	
   504	#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
   505		DEFINE(FREGS_SIZE_ON_STACK, ALIGN(sizeof(struct ftrace_regs), STACK_ALIGN));
   506		DEFINE(FREGS_EPC,	    offsetof(struct ftrace_regs, epc));
   507		DEFINE(FREGS_RA,	    offsetof(struct ftrace_regs, ra));
   508		DEFINE(FREGS_SP,	    offsetof(struct ftrace_regs, sp));
   509		DEFINE(FREGS_S0,	    offsetof(struct ftrace_regs, s0));
   510		DEFINE(FREGS_T1,	    offsetof(struct ftrace_regs, t1));
   511		DEFINE(FREGS_A0,	    offsetof(struct ftrace_regs, a0));
   512		DEFINE(FREGS_A1,	    offsetof(struct ftrace_regs, a1));
   513		DEFINE(FREGS_A2,	    offsetof(struct ftrace_regs, a2));
   514		DEFINE(FREGS_A3,	    offsetof(struct ftrace_regs, a3));
   515		DEFINE(FREGS_A4,	    offsetof(struct ftrace_regs, a4));
   516		DEFINE(FREGS_A5,	    offsetof(struct ftrace_regs, a5));
   517		DEFINE(FREGS_A6,	    offsetof(struct ftrace_regs, a6));
   518		DEFINE(FREGS_A7,	    offsetof(struct ftrace_regs, a7));
   519	#endif
 > 520		DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
 > 521		DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
 > 522		DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
 > 523		DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From derekmn at amazon.com  Tue Nov 12 19:31:29 2024
From: derekmn at amazon.com (Manwaring, Derek)
Date: Tue, 12 Nov 2024 20:31:29 -0700
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <DM8PR11MB57505F62D149EF153F89B8BAE75D2@DM8PR11MB5750.namprd11.prod.outlook.com>
References: <DM8PR11MB57505F62D149EF153F89B8BAE75D2@DM8PR11MB5750.namprd11.prod.outlook.com>
Message-ID: <96c24397-b081-4570-adb2-8d4443f3359c@amazon.com>

On 2024-11-08 at 10:36, Elena Reshetova wrote:
> On 2024-11-06 at 17:04, Derek Manwaring wrote:
> > On 2024-11-04 at 08:33+0000, Elena Reshetova wrote:
> > > This statement *is* for integrity section. We have a separate TDX guidance
> > > on side-channels (including speculative) [3] and some speculative attacks
> > > that affect confidentiality (for example spectre v1) are listed as not covered
> > > by TDX but remaining SW responsibility (as they are now).
> >
> > Thanks for the additional info, Elena. Given that clarification, I
> > definitely see direct map removal and TDX as complementary.
>
> Jus to clarify to make sure my comment is not misunderstood.
> What I meant is that we cannot generally assume that confidentiality
> leaks from CoCo guests to host/VMM via speculative channels
> are completely impossible. Spectre V1 is a prime example of such a
> possible leak. Dave also elaborated on other potential vectors earlier.
>
> The usefulness of direct map removal for CoCo guests as a concrete
> mitigation for certain types of memory attacks must be precisely
> evaluated per each attack vector, attack vector direction (host -> guest,
> guest ->host, etc) and per each countermeasure that CoCo vendors
> provide for each such case. I don't know if there is any existing study
> that examines this for major CoCo vendors. I think this is what must
> be done for this work in order to have a strong reasoning for its usefulness.

Thanks, that makes sense. I'm a little hyperfocused on guest->host which
is the opposite direction of what is generally used for the CoCo threat
model. I think what both cases care about though is guest->guest. For
me, guest->host matters because it's a route for guest->guest (at least
in the non-CoCo world). There's some good discussion on this in David's
series on attack vector controls [1].

Like you mention, beyond direction it matters which CoCo countermeasures
are at play and how far they go during transient execution. That part is
not clear to me for the host->guest direction involving the direct map,
but agree any countermeasures like direct map removal should be
evaluated based on a better understanding of what those existing
countermeasures already cover and what attack is intended to be
mitigated.

Derek


[1] https://lore.kernel.org/lkml/LV3PR12MB92658EA6CCF18F90DAAA168394532 at LV3PR12MB9265.namprd12.prod.outlook.com/


From dlemoal at kernel.org  Tue Nov 12 20:41:36 2024
From: dlemoal at kernel.org (Damien Le Moal)
Date: Wed, 13 Nov 2024 13:41:36 +0900
Subject: [PATCH] pinctrl: k210: Modify the wrong "#undef"
In-Reply-To: <20241113012029.3204-1-zhangjiao2@cmss.chinamobile.com>
References: <20241113012029.3204-1-zhangjiao2@cmss.chinamobile.com>
Message-ID: <deafaca0-63e0-4c5a-8d34-21567f78a5cb@kernel.org>

On 11/13/24 10:20, zhangjiao2 wrote:
> From: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
> 
> Here shuld be undef "K210_PC_DEFAULT", not "DEFAULT".

Here ? Please be specific.
Also:

s/shuld/must

So something like:

The definition of the array k210_pinconf_mode_id_to_mode is done using the
temporary macro K210_PC_DEFAULT. When this macro is not needed anymore and its
definition removed, make sure to use its name in the #undef statement instead of
the incorrect "DEFAULT" name.

> 
> Signed-off-by: zhang jiao <zhangjiao2 at cmss.chinamobile.com>

This needs a Fixes tag as well.

> ---
>  drivers/pinctrl/pinctrl-k210.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
> index caf20215aaba..eddb01796a83 100644
> --- a/drivers/pinctrl/pinctrl-k210.c
> +++ b/drivers/pinctrl/pinctrl-k210.c
> @@ -181,7 +181,7 @@ static const u32 k210_pinconf_mode_id_to_mode[] = {
>  	[K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
>  };
>  
> -#undef DEFAULT
> +#undef K210_PC_DEFAULT
>  
>  /*
>   * Pin functions configuration information.


-- 
Damien Le Moal
Western Digital Research


From zhangjiao2 at cmss.chinamobile.com  Tue Nov 12 22:09:50 2024
From: zhangjiao2 at cmss.chinamobile.com (zhangjiao2)
Date: Wed, 13 Nov 2024 14:09:50 +0800
Subject: [PATCH v2] pinctrl: k210: Undef K210_PC_DEFAULT
Message-ID: <20241113060950.5247-1-zhangjiao2@cmss.chinamobile.com>

From: zhang jiao <zhangjiao2 at cmss.chinamobile.com>

When the temporary macro K210_PC_DEFAULT is no need anymore,
better use its name in the #undef statement instead of
the incorrect "DEFAULT" name.

Fixes: d4c34d09ab03 ("pinctrl: Add RISC-V Canaan Kendryte K210 FPIOA driver")
Signed-off-by: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
---
v1->v2:
	Modify commit info and add a Fixes tag.

 drivers/pinctrl/pinctrl-k210.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
index caf20215aaba..eddb01796a83 100644
--- a/drivers/pinctrl/pinctrl-k210.c
+++ b/drivers/pinctrl/pinctrl-k210.c
@@ -181,7 +181,7 @@ static const u32 k210_pinconf_mode_id_to_mode[] = {
 	[K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
 };
 
-#undef DEFAULT
+#undef K210_PC_DEFAULT
 
 /*
  * Pin functions configuration information.
-- 
2.33.0





From tglx at linutronix.de  Tue Nov 12 22:14:52 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Wed, 13 Nov 2024 07:14:52 +0100
Subject: [PATCH 2/3] irqchip: Add the Sophgo SG2042 MSI interrupt
 controller
In-Reply-To: <8076fe2af9f2b007a42c986ed193ba50ff674bfa.1731296803.git.unicorn_wang@outlook.com>
References: <cover.1731296803.git.unicorn_wang@outlook.com>
 <8076fe2af9f2b007a42c986ed193ba50ff674bfa.1731296803.git.unicorn_wang@outlook.com>
Message-ID: <87cyizmzhf.ffs@tglx>

On Mon, Nov 11 2024 at 12:01, Chen Wang wrote:
> +struct sg2042_msi_data {
> +	void __iomem	*reg_clr; /* clear reg, see TRM, 10.1.33, GP_INTR0_CLR */

Please make these tail comments tabular aligned so they actually stand
out.

  https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#comment-style

> +
> +	u64		doorbell_addr; /* see TRM, 10.1.32, GP_INTR0_SET */
> +
> +	u32		irq_first; /* The vector number that MSIs starts */
> +	u32		num_irqs;  /* The number of vectors for MSIs */
> +
> +	unsigned long	*msi_map;
> +	struct mutex	msi_map_lock; /* lock for msi_map */
> +};
> +
> +static int sg2042_msi_allocate_hwirq(struct sg2042_msi_data *priv, int num_req)
> +{
> +	int first;
> +
> +	mutex_lock(&priv->msi_map_lock);

Please use

       guard(mutex)(&priv->msi_map_lock);

which removes all the mutex_unlock() hackery and boils this down

> +
> +	first = bitmap_find_free_region(priv->msi_map, priv->num_irqs,
> +					get_count_order(num_req));
> +	if (first < 0) {
> +		mutex_unlock(&priv->msi_map_lock);
> +		return -ENOSPC;
> +	}
> +
> +	mutex_unlock(&priv->msi_map_lock);
> +
> +	return priv->irq_first + first;

to

	guard(mutex)(&priv->msi_map_lock);
	first = bitmap_find_free_region(priv->msi_map, priv->num_irqs,
					get_count_order(num_req));
	return first >= 0 ? priv->irq_first + first : -ENOSPC;

See?

> +}
> +
> +static void sg2042_msi_free_hwirq(struct sg2042_msi_data *priv,
> +				  int hwirq, int num_req)
> +{
> +	int first = hwirq - priv->irq_first;
> +
> +	mutex_lock(&priv->msi_map_lock);

Ditto.

> +	bitmap_release_region(priv->msi_map, first, get_count_order(num_req));
> +	mutex_unlock(&priv->msi_map_lock);
> +}

> +static void sg2042_msi_irq_compose_msi_msg(struct irq_data *data,
> +					   struct msi_msg *msg)
> +{
> +	struct sg2042_msi_data *priv = irq_data_get_irq_chip_data(data);
> +
> +	msg->address_hi = upper_32_bits(priv->doorbell_addr);
> +	msg->address_lo = lower_32_bits(priv->doorbell_addr);
> +	msg->data = 1 << (data->hwirq - priv->irq_first);
> +
> +	pr_debug("%s hwirq[%d]: address_hi[%#x], address_lo[%#x], data[%#x]\n",
> +		 __func__,

No point in having this line break. You have 100 characters. Please fix
this all over the place.

> +		 (int)data->hwirq, msg->address_hi, msg->address_lo, msg->data);

(int) ? Why can't you use the proper conversion specifier instead of %d?

> +static int sg2042_msi_middle_domain_alloc(struct irq_domain *domain,
> +					  unsigned int virq,
> +					  unsigned int nr_irqs, void *args)
> +{
> +	struct sg2042_msi_data *priv = domain->host_data;
> +	int hwirq, err, i;
> +
> +	hwirq = sg2042_msi_allocate_hwirq(priv, nr_irqs);
> +	if (hwirq < 0)
> +		return hwirq;
> +
> +	for (i = 0; i < nr_irqs; i++) {
> +		err = sg2042_msi_parent_domain_alloc(domain, virq + i, hwirq + i);
> +		if (err)
> +			goto err_hwirq;
> +
> +		pr_debug("%s: virq[%d], hwirq[%d]\n",
> +			 __func__, virq + i, (int)hwirq + i);

No line break required.

> +		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
> +					      &sg2042_msi_middle_irq_chip, priv);
> +	}

> +static int sg2042_msi_init_domains(struct sg2042_msi_data *priv,
> +				   struct device_node *node)
> +{
> +	struct irq_domain *plic_domain, *middle_domain;
> +	struct device_node *plic_node;
> +	struct fwnode_handle *fwnode = of_node_to_fwnode(node);

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations

> +	if (!of_find_property(node, "interrupt-parent", NULL)) {
> +		pr_err("Can't find interrupt-parent!\n");
> +		return -EINVAL;
> +	}
> +
> +	plic_node = of_irq_find_parent(node);
> +	if (!plic_node) {
> +		pr_err("Failed to find the PLIC node!\n");
> +		return -ENXIO;
> +	}
> +
> +	plic_domain = irq_find_host(plic_node);
> +	of_node_put(plic_node);
> +	if (!plic_domain) {
> +		pr_err("Failed to find the PLIC domain\n");
> +		return -ENXIO;
> +	}
> +
> +	middle_domain = irq_domain_create_hierarchy(plic_domain, 0, priv->num_irqs,
> +						    fwnode,
> +						    &pch_msi_middle_domain_ops,
> +						    priv);

So now you have created a domain. How is that supposed to be used by the
PCI layer?

> +	if (!middle_domain) {
> +		pr_err("Failed to create the MSI middle domain\n");
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}

> +static int sg2042_msi_probe(struct platform_device *pdev)
> +{

....

> +	data->msi_map = bitmap_zalloc(data->num_irqs, GFP_KERNEL);
> +	if (!data->msi_map)
> +		return -ENOMEM;
> +
> +	return sg2042_msi_init_domains(data, pdev->dev.of_node);

In case of error this leaks data->msi_map, no?

> +static struct platform_driver sg2042_msi_driver = {
> +	.driver = {
> +		.name = "sg2042-msi",
> +		.of_match_table = of_match_ptr(sg2042_msi_of_match),
> +	},
> +	.probe = sg2042_msi_probe,
> +};

Please see the documentation I pointed you to above and search for
struct initializers.

Thanks,

        tglx


From dlemoal at kernel.org  Tue Nov 12 22:30:36 2024
From: dlemoal at kernel.org (Damien Le Moal)
Date: Wed, 13 Nov 2024 15:30:36 +0900
Subject: [PATCH v2] pinctrl: k210: Undef K210_PC_DEFAULT
In-Reply-To: <20241113060950.5247-1-zhangjiao2@cmss.chinamobile.com>
References: <20241113060950.5247-1-zhangjiao2@cmss.chinamobile.com>
Message-ID: <cad32ff9-fcb0-477e-8a8b-a7d4bb80fdfe@kernel.org>

On 11/13/24 15:09, zhangjiao2 wrote:
> From: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
> 
> When the temporary macro K210_PC_DEFAULT is no need anymore,

s/no need/not needed

> better use its name in the #undef statement instead of

s/better use/use

> the incorrect "DEFAULT" name.
> 
> Fixes: d4c34d09ab03 ("pinctrl: Add RISC-V Canaan Kendryte K210 FPIOA driver")
> Signed-off-by: zhang jiao <zhangjiao2 at cmss.chinamobile.com>

With the typos fixed,

Reviewed-by: Damien Le Moal <dlemoal at kernel.org>

-- 
Damien Le Moal
Western Digital Research


From zhangjiao2 at cmss.chinamobile.com  Tue Nov 12 22:36:11 2024
From: zhangjiao2 at cmss.chinamobile.com (zhangjiao2)
Date: Wed, 13 Nov 2024 14:36:11 +0800
Subject: [PATCH v3] pinctrl: k210: Undef K210_PC_DEFAULT
Message-ID: <20241113063611.5330-1-zhangjiao2@cmss.chinamobile.com>

From: zhang jiao <zhangjiao2 at cmss.chinamobile.com>

When the temporary macro K210_PC_DEFAULT is no need anymore,
use its name in the #undef statement instead of
the incorrect "DEFAULT" name.

Fixes: d4c34d09ab03 ("pinctrl: Add RISC-V Canaan Kendryte K210 FPIOA driver")
Signed-off-by: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
---
v2->v3:
	Modify commit info.

 drivers/pinctrl/pinctrl-k210.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
index caf20215aaba..eddb01796a83 100644
--- a/drivers/pinctrl/pinctrl-k210.c
+++ b/drivers/pinctrl/pinctrl-k210.c
@@ -181,7 +181,7 @@ static const u32 k210_pinconf_mode_id_to_mode[] = {
 	[K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
 };
 
-#undef DEFAULT
+#undef K210_PC_DEFAULT
 
 /*
  * Pin functions configuration information.
-- 
2.33.0





From dlemoal at kernel.org  Tue Nov 12 22:41:34 2024
From: dlemoal at kernel.org (Damien Le Moal)
Date: Wed, 13 Nov 2024 15:41:34 +0900
Subject: [PATCH v3] pinctrl: k210: Undef K210_PC_DEFAULT
In-Reply-To: <20241113063611.5330-1-zhangjiao2@cmss.chinamobile.com>
References: <20241113063611.5330-1-zhangjiao2@cmss.chinamobile.com>
Message-ID: <e3ff8ec3-1995-408d-aa75-6afc11f51ebd@kernel.org>

On 11/13/24 15:36, zhangjiao2 wrote:
> From: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
> 
> When the temporary macro K210_PC_DEFAULT is no need anymore,

You forgot to fix "no need -> not needed".
And you forgot to add my review tag as well.

> use its name in the #undef statement instead of
> the incorrect "DEFAULT" name.
> 
> Fixes: d4c34d09ab03 ("pinctrl: Add RISC-V Canaan Kendryte K210 FPIOA driver")
> Signed-off-by: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
> ---
> v2->v3:
> 	Modify commit info.
> 
>  drivers/pinctrl/pinctrl-k210.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
> index caf20215aaba..eddb01796a83 100644
> --- a/drivers/pinctrl/pinctrl-k210.c
> +++ b/drivers/pinctrl/pinctrl-k210.c
> @@ -181,7 +181,7 @@ static const u32 k210_pinconf_mode_id_to_mode[] = {
>  	[K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
>  };
>  
> -#undef DEFAULT
> +#undef K210_PC_DEFAULT
>  
>  /*
>   * Pin functions configuration information.


-- 
Damien Le Moal
Western Digital Research


From unicorn_wang at outlook.com  Tue Nov 12 22:43:17 2024
From: unicorn_wang at outlook.com (Chen Wang)
Date: Wed, 13 Nov 2024 14:43:17 +0800
Subject: [PATCH 2/3] irqchip: Add the Sophgo SG2042 MSI interrupt
 controller
In-Reply-To: <87cyizmzhf.ffs@tglx>
References: <cover.1731296803.git.unicorn_wang@outlook.com>
 <8076fe2af9f2b007a42c986ed193ba50ff674bfa.1731296803.git.unicorn_wang@outlook.com>
 <87cyizmzhf.ffs@tglx>
Message-ID: <PN1P287MB28185C9DA26A773775BDC4C6FE5A2@PN1P287MB2818.INDP287.PROD.OUTLOOK.COM>


On 2024/11/13 14:14, Thomas Gleixner wrote:
> On Mon, Nov 11 2024 at 12:01, Chen Wang wrote:
>> +struct sg2042_msi_data {
>> +	void __iomem	*reg_clr; /* clear reg, see TRM, 10.1.33, GP_INTR0_CLR */
> Please make these tail comments tabular aligned so they actually stand
> out.
>
>    https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#comment-style
Got, will fix this.
>> +
>> +	u64		doorbell_addr; /* see TRM, 10.1.32, GP_INTR0_SET */
>> +
>> +	u32		irq_first; /* The vector number that MSIs starts */
>> +	u32		num_irqs;  /* The number of vectors for MSIs */
>> +
>> +	unsigned long	*msi_map;
>> +	struct mutex	msi_map_lock; /* lock for msi_map */
>> +};
>> +
>> +static int sg2042_msi_allocate_hwirq(struct sg2042_msi_data *priv, int num_req)
>> +{
>> +	int first;
>> +
>> +	mutex_lock(&priv->msi_map_lock);
> Please use
>
>         guard(mutex)(&priv->msi_map_lock);
>
> which removes all the mutex_unlock() hackery and boils this down
Thanks, will double check.
>
>> +
>> +	first = bitmap_find_free_region(priv->msi_map, priv->num_irqs,
>> +					get_count_order(num_req));
>> +	if (first < 0) {
>> +		mutex_unlock(&priv->msi_map_lock);
>> +		return -ENOSPC;
>> +	}
>> +
>> +	mutex_unlock(&priv->msi_map_lock);
>> +
>> +	return priv->irq_first + first;
> to
>
> 	guard(mutex)(&priv->msi_map_lock);
> 	first = bitmap_find_free_region(priv->msi_map, priv->num_irqs,
> 					get_count_order(num_req));
> 	return first >= 0 ? priv->irq_first + first : -ENOSPC;
>
> See?
>
>> +}
>> +
>> +static void sg2042_msi_free_hwirq(struct sg2042_msi_data *priv,
>> +				  int hwirq, int num_req)
>> +{
>> +	int first = hwirq - priv->irq_first;
>> +
>> +	mutex_lock(&priv->msi_map_lock);
> Ditto.
>
>> +	bitmap_release_region(priv->msi_map, first, get_count_order(num_req));
>> +	mutex_unlock(&priv->msi_map_lock);
>> +}
>> +static void sg2042_msi_irq_compose_msi_msg(struct irq_data *data,
>> +					   struct msi_msg *msg)
>> +{
>> +	struct sg2042_msi_data *priv = irq_data_get_irq_chip_data(data);
>> +
>> +	msg->address_hi = upper_32_bits(priv->doorbell_addr);
>> +	msg->address_lo = lower_32_bits(priv->doorbell_addr);
>> +	msg->data = 1 << (data->hwirq - priv->irq_first);
>> +
>> +	pr_debug("%s hwirq[%d]: address_hi[%#x], address_lo[%#x], data[%#x]\n",
>> +		 __func__,
> No point in having this line break. You have 100 characters. Please fix
> this all over the place.
Got.
>
>> +		 (int)data->hwirq, msg->address_hi, msg->address_lo, msg->data);
> (int) ? Why can't you use the proper conversion specifier instead of %d?
Will double-check.
>
>> +static int sg2042_msi_middle_domain_alloc(struct irq_domain *domain,
>> +					  unsigned int virq,
>> +					  unsigned int nr_irqs, void *args)
>> +{
>> +	struct sg2042_msi_data *priv = domain->host_data;
>> +	int hwirq, err, i;
>> +
>> +	hwirq = sg2042_msi_allocate_hwirq(priv, nr_irqs);
>> +	if (hwirq < 0)
>> +		return hwirq;
>> +
>> +	for (i = 0; i < nr_irqs; i++) {
>> +		err = sg2042_msi_parent_domain_alloc(domain, virq + i, hwirq + i);
>> +		if (err)
>> +			goto err_hwirq;
>> +
>> +		pr_debug("%s: virq[%d], hwirq[%d]\n",
>> +			 __func__, virq + i, (int)hwirq + i);
> No line break required.
>
>> +		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
>> +					      &sg2042_msi_middle_irq_chip, priv);
>> +	}
>> +static int sg2042_msi_init_domains(struct sg2042_msi_data *priv,
>> +				   struct device_node *node)
>> +{
>> +	struct irq_domain *plic_domain, *middle_domain;
>> +	struct device_node *plic_node;
>> +	struct fwnode_handle *fwnode = of_node_to_fwnode(node);
> https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations
Thanks, will double-check.
>> +	if (!of_find_property(node, "interrupt-parent", NULL)) {
>> +		pr_err("Can't find interrupt-parent!\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	plic_node = of_irq_find_parent(node);
>> +	if (!plic_node) {
>> +		pr_err("Failed to find the PLIC node!\n");
>> +		return -ENXIO;
>> +	}
>> +
>> +	plic_domain = irq_find_host(plic_node);
>> +	of_node_put(plic_node);
>> +	if (!plic_domain) {
>> +		pr_err("Failed to find the PLIC domain\n");
>> +		return -ENXIO;
>> +	}
>> +
>> +	middle_domain = irq_domain_create_hierarchy(plic_domain, 0, priv->num_irqs,
>> +						    fwnode,
>> +						    &pch_msi_middle_domain_ops,
>> +						    priv);
> So now you have created a domain. How is that supposed to be used by the
> PCI layer?

Here I create the domain and attached it to the fwnode. In PCI driver, 
it can set this msi controller as its ""interrupt-parent" and find the 
domain attached as below:

static int pcie_probe(struct platform_device *pdev)
{
 ??? struct device *dev = &pdev->dev;
 ??? parent_node = of_irq_find_parent(dev->of_node);
 ??? parent_domain = irq_find_host(parent_node);
 ??? ...
}

>> +	if (!middle_domain) {
>> +		pr_err("Failed to create the MSI middle domain\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	return 0;
>> +}
>> +static int sg2042_msi_probe(struct platform_device *pdev)
>> +{
> ....
>
>> +	data->msi_map = bitmap_zalloc(data->num_irqs, GFP_KERNEL);
>> +	if (!data->msi_map)
>> +		return -ENOMEM;
>> +
>> +	return sg2042_msi_init_domains(data, pdev->dev.of_node);
> In case of error this leaks data->msi_map, no?
Thanks, I will correct this.
>> +static struct platform_driver sg2042_msi_driver = {
>> +	.driver = {
>> +		.name = "sg2042-msi",
>> +		.of_match_table = of_match_ptr(sg2042_msi_of_match),
>> +	},
>> +	.probe = sg2042_msi_probe,
>> +};
> Please see the documentation I pointed you to above and search for
> struct initializers.
>
> Thanks,
>
>          tglx


From zhangjiao2 at cmss.chinamobile.com  Tue Nov 12 23:12:01 2024
From: zhangjiao2 at cmss.chinamobile.com (zhangjiao2)
Date: Wed, 13 Nov 2024 15:12:01 +0800
Subject: [PATCH v4] pinctrl: k210: Undef K210_PC_DEFAULT
Message-ID: <20241113071201.5440-1-zhangjiao2@cmss.chinamobile.com>

From: zhang jiao <zhangjiao2 at cmss.chinamobile.com>

When the temporary macro K210_PC_DEFAULT is not needed anymore,
use its name in the #undef statement instead of
the incorrect "DEFAULT" name.

Fixes: d4c34d09ab03 ("pinctrl: Add RISC-V Canaan Kendryte K210 FPIOA driver")
Signed-off-by: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
Reviewed-by: Damien Le Moal <dlemoal at kernel.org>
---
v3->v4:
	Modify commit info and add review tag.

 drivers/pinctrl/pinctrl-k210.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
index caf20215aaba..eddb01796a83 100644
--- a/drivers/pinctrl/pinctrl-k210.c
+++ b/drivers/pinctrl/pinctrl-k210.c
@@ -181,7 +181,7 @@ static const u32 k210_pinconf_mode_id_to_mode[] = {
 	[K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
 };
 
-#undef DEFAULT
+#undef K210_PC_DEFAULT
 
 /*
  * Pin functions configuration information.
-- 
2.33.0





From unicorn_wang at outlook.com  Tue Nov 12 23:16:37 2024
From: unicorn_wang at outlook.com (Chen Wang)
Date: Wed, 13 Nov 2024 15:16:37 +0800
Subject: [PATCH 1/3] dt-bindings: interrupt-controller: Add Sophgo SG2042
 MSI
In-Reply-To: <20241112155240.GA956207-robh@kernel.org>
References: <cover.1731296803.git.unicorn_wang@outlook.com>
 <5186bb9c7feebb87136eb5e5e117fb1142dba4c2.1731296803.git.unicorn_wang@outlook.com>
 <20241112155240.GA956207-robh@kernel.org>
Message-ID: <PN1P287MB281846EC1E6448397E17CC1DFE5A2@PN1P287MB2818.INDP287.PROD.OUTLOOK.COM>


On 2024/11/12 23:52, Rob Herring wrote:
> On Mon, Nov 11, 2024 at 12:01:36PM +0800, Chen Wang wrote:
>> From: Chen Wang <unicorn_wang at outlook.com>
>>
>> Add binding for Sophgo SG2042 MSI controller.
>>
>> Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
>> ---
>>   .../sophgo,sg2042-msi.yaml                    | 78 +++++++++++++++++++
>>   1 file changed, 78 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml b/Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml
>> new file mode 100644
>> index 000000000000..9fe99b74c211
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/sophgo,sg2042-msi.yaml
>> @@ -0,0 +1,78 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/interrupt-controller/sophgo,sg2042-msi.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Sophgo SG2042 MSI Controller
>> +
>> +maintainers:
>> +  - Chen Wang <unicorn_wang at outlook.com>
>> +
>> +description:
>> +  This interrupt controller is in Sophgo SG2042 for transforming interrupts from
>> +  PCIe MSI to PLIC interrupts.
>> +
>> +allOf:
>> +  - $ref: /schemas/interrupts.yaml#
>> +  - $ref: /schemas/interrupt-controller/msi-controller.yaml#
>> +
>> +properties:
>> +  compatible:
>> +    const: sophgo,sg2042-msi
>> +
>> +  reg:
>> +    items:
>> +      - description: clear register
>> +
>> +  reg-names:
>> +    items:
>> +      - const: clr
>> +
>> +  sophgo,msi-doorbell-addr:
>> +    description:
>> +      u64 value of the MSI doorbell address
>> +    $ref: /schemas/types.yaml#/definitions/uint64
> Why not use a 'reg' entry?
>
> In any case, this should be a translatable address (i.e. honor
> #address-cells/#size-cells and ranges).
This is just a address to write MSI data, but not a register for driver 
access. So I think it seems better to configure it separately, rather 
than as other registers. This address does not need ioremap.

What do you think? I would like to hear your opinion.

Regards

Chen

>> +
>> +  sophgo,msi-base-vec:
>> +    description:
>> +      u32 value of the base of parent PLIC vector allocated
>> +      to MSI.
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    minimum: 64
>> +    maximum: 95
>> +
>> +  sophgo,msi-num-vecs:
>> +    description:
>> +      u32 value of the number of parent PLIC vectors allocated
>> +      to MSI.
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    minimum: 1
>> +    maximum: 32
> Use 'msi-ranges' for these.
Got, will fix this and thanks.
>> +
>> +  msi-controller: true
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - reg-names
>> +  - msi-controller
>> +  - sophgo,msi-doorbell-addr
>> +  - sophgo,msi-base-vec
>> +  - sophgo,msi-num-vecs
>> +
>> +additionalProperties: true
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/interrupt-controller/irq.h>
>> +    msi: msi-controller at 30000000 {
>> +      compatible = "sophgo,sg2042-msi";
>> +      reg = <0x30000000 0x4>;
>> +      reg-names = "clr";
>> +      msi-controller;
>> +      sophgo,msi-doorbell-addr = <0x00000070 0x30010300>;
>> +      sophgo,msi-base-vec = <64>;
>> +      sophgo,msi-num-vecs = <32>;
>> +      interrupt-parent = <&plic>;
>> +    };
>> -- 
>> 2.34.1
>>


From robert.paczkowski at profitix.pl  Wed Nov 13 00:50:40 2024
From: robert.paczkowski at profitix.pl (Robert Paczkowski)
Date: Wed, 13 Nov 2024 08:50:40 GMT
Subject: =?UTF-8?Q?Wsp=C3=B3=C5=82praca?=
Message-ID: <20241113084500-0.1.8.125s.0.di9d13fd8s@profitix.pl>

Dzie? dobry, 

Czy interesuje Pa?stwa pozyskanie nowych klient?w?

Zajmujemy si? profesjonalnie wsparciem firm w tym zakresie. 

Nasi partnerzy zyskuj? sta?y nap?yw nowych zlece? oraz zam?wie?, a tym samym zwi?kszaj? swoje wyniki sprzeda?y.

Czy mo?emy przedstawi? szczeg??y dotycz?ce zasad i mo?liwo?ci wsp??pracy?


Pozdrawiam
Robert Paczkowski


From ben.dooks at codethink.co.uk  Wed Nov 13 01:17:03 2024
From: ben.dooks at codethink.co.uk (Ben Dooks)
Date: Wed, 13 Nov 2024 09:17:03 +0000
Subject: [PATCH 3/3] riscv: insn: add RV_EXTRACT_FUNCT3()
In-Reply-To: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
References: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
Message-ID: <20241113091703.3133017-4-ben.dooks@codethink.co.uk>

Add extraction for the func3 field of most instructions
for use with anyone who needs it.

Note, added this for decoding of CSR accesses for
work we did looking at the RDCYCLE v RDTIME calls.

Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
---
 arch/riscv/include/asm/insn.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h
index 09fde95a5e8f..c67f44ff2066 100644
--- a/arch/riscv/include/asm/insn.h
+++ b/arch/riscv/include/asm/insn.h
@@ -299,6 +299,10 @@ static __always_inline bool riscv_insn_is_c_jalr(u32 code)
 	({typeof(x) x_ = (x); \
 	(RV_X(x_, RVG_RD_OPOFF, RVG_RD_MASK)); })
 
+#define RV_EXTRACT_FUNCT3(x) \
+	({typeof(x) x_ = (x); \
+	(RV_X(x_, RV_INSN_FUNCT3_OPOFF, RV_INSN_FUNCT3_MASK)); })
+
 #define RV_EXTRACT_UTYPE_IMM(x) \
 	({typeof(x) x_ = (x); \
 	(RV_X(x_, RV_U_IMM_31_12_OPOFF, RV_U_IMM_31_12_MASK)); })
-- 
2.37.2.352.g3c44437643



From ben.dooks at codethink.co.uk  Wed Nov 13 01:17:00 2024
From: ben.dooks at codethink.co.uk (Ben Dooks)
Date: Wed, 13 Nov 2024 09:17:00 +0000
Subject: updates for instruction trapping and ptrace
Message-ID: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>

After looking at handling the RDCYCLE as RDTIME, the following
patches are probably still useful (even if the actual in-kernel
fixup of RDCYCLE isn't).




From ben.dooks at codethink.co.uk  Wed Nov 13 01:17:02 2024
From: ben.dooks at codethink.co.uk (Ben Dooks)
Date: Wed, 13 Nov 2024 09:17:02 +0000
Subject: [PATCH 2/3] riscv: traps: make insn fetch common in unknown instruction
In-Reply-To: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
References: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
Message-ID: <20241113091703.3133017-3-ben.dooks@codethink.co.uk>

Add the trapped instruction (insn) as the second argument to
riscv_v_first_use_handler() from the trap handler so when we
add more handlers we can do the fetch of the instruction just
once.

Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
---
- fixed wording of patch from rfc
---
 arch/riscv/include/asm/vector.h |  4 ++--
 arch/riscv/kernel/traps.c       | 11 ++++++++++-
 arch/riscv/kernel/vector.c      | 11 +----------
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index be7d309cca8a..c9f0b02cd975 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -21,7 +21,7 @@
 
 extern unsigned long riscv_v_vsize;
 int riscv_v_setup_vsize(void);
-bool riscv_v_first_use_handler(struct pt_regs *regs);
+bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn);
 void kernel_vector_begin(void);
 void kernel_vector_end(void);
 void get_cpu_vector_context(void);
@@ -268,7 +268,7 @@ struct pt_regs;
 
 static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; }
 static __always_inline bool has_vector(void) { return false; }
-static inline bool riscv_v_first_use_handler(struct pt_regs *regs) { return false; }
+static inline bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn) { return false; }
 static inline bool riscv_v_vstate_query(struct pt_regs *regs) { return false; }
 static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
 #define riscv_v_vsize (0)
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 51ebfd23e007..1c3fab272fd1 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -172,11 +172,20 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
 	bool handled;
 
 	if (user_mode(regs)) {
+		u32 __user *epc = (u32 __user *)regs->epc;
+		u32 insn = (u32)regs->badaddr;
+
 		irqentry_enter_from_user_mode(regs);
 
 		local_irq_enable();
 
-		handled = riscv_v_first_use_handler(regs);
+		if (!insn) {
+			if (__get_user(insn, epc)) {
+				/* todo */
+			}
+		}
+
+		handled = riscv_v_first_use_handler(regs, insn);
 
 		local_irq_disable();
 
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 682b3feee451..b852648cb8d5 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -168,11 +168,8 @@ bool riscv_v_vstate_ctrl_user_allowed(void)
 }
 EXPORT_SYMBOL_GPL(riscv_v_vstate_ctrl_user_allowed);
 
-bool riscv_v_first_use_handler(struct pt_regs *regs)
+bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn)
 {
-	u32 __user *epc = (u32 __user *)regs->epc;
-	u32 insn = (u32)regs->badaddr;
-
 	if (!has_vector())
 		return false;
 
@@ -184,12 +181,6 @@ bool riscv_v_first_use_handler(struct pt_regs *regs)
 	if (riscv_v_vstate_query(regs))
 		return false;
 
-	/* Get the instruction */
-	if (!insn) {
-		if (__get_user(insn, epc))
-			return false;
-	}
-
 	/* Filter out non-V instructions */
 	if (!insn_is_vector(insn))
 		return false;
-- 
2.37.2.352.g3c44437643



From ben.dooks at codethink.co.uk  Wed Nov 13 01:17:01 2024
From: ben.dooks at codethink.co.uk (Ben Dooks)
Date: Wed, 13 Nov 2024 09:17:01 +0000
Subject: [PATCH 1/3] riscv: ptrace: add regs_set_register()
In-Reply-To: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
References: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
Message-ID: <20241113091703.3133017-2-ben.dooks@codethink.co.uk>

Since we have regs_get_register() and we could use the set counterpart
for things like fixing up traps, add regs_set_register() to set a pt_regs
value from offset.

Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
---
 arch/riscv/include/asm/ptrace.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
index b5b0adcc85c1..66fc1795141d 100644
--- a/arch/riscv/include/asm/ptrace.h
+++ b/arch/riscv/include/asm/ptrace.h
@@ -143,6 +143,26 @@ static inline unsigned long regs_get_register(struct pt_regs *regs,
 	return *(unsigned long *)((unsigned long)regs + offset);
 }
 
+/**
+ * regs_set_register() - set register value from its offset
+ * @regs:	pt_regs from which register value is gotten
+ * @offset:	offset of the register.
+ * @to:		value to set register to
+ *
+ * regs_set_register sets the value @to to a register whose offset from @regs.
+ * The @offset is the offset of the register in struct pt_regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this will ignore the write.
+ */
+static inline void regs_set_register(struct pt_regs *regs,
+				     unsigned int offset,
+				     unsigned long to)
+{
+	if (unlikely(offset > MAX_REG_OFFSET))
+		return;
+
+	*(unsigned long *)((unsigned long)regs + offset) = to;
+}
+
 /**
  * regs_get_kernel_argument() - get Nth function argument in kernel
  * @regs:       pt_regs of that context
-- 
2.37.2.352.g3c44437643



From ben.dooks at codethink.co.uk  Wed Nov 13 01:21:48 2024
From: ben.dooks at codethink.co.uk (Ben Dooks)
Date: Wed, 13 Nov 2024 09:21:48 +0000
Subject: [PATCH 2/3] riscv: traps: make insn fetch common in unknown
 instruction
In-Reply-To: <20241113091703.3133017-3-ben.dooks@codethink.co.uk>
References: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
 <20241113091703.3133017-3-ben.dooks@codethink.co.uk>
Message-ID: <45408e3d-5b7a-40cc-bfca-b58cf3737c9c@codethink.co.uk>

On 13/11/2024 09:17, Ben Dooks wrote:
> Add the trapped instruction (insn) as the second argument to
> riscv_v_first_use_handler() from the trap handler so when we
> add more handlers we can do the fetch of the instruction just
> once.
> 
> Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
> ---
> - fixed wording of patch from rfc
> ---
>   arch/riscv/include/asm/vector.h |  4 ++--
>   arch/riscv/kernel/traps.c       | 11 ++++++++++-
>   arch/riscv/kernel/vector.c      | 11 +----------
>   3 files changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
> index be7d309cca8a..c9f0b02cd975 100644
> --- a/arch/riscv/include/asm/vector.h
> +++ b/arch/riscv/include/asm/vector.h
> @@ -21,7 +21,7 @@
>   
>   extern unsigned long riscv_v_vsize;
>   int riscv_v_setup_vsize(void);
> -bool riscv_v_first_use_handler(struct pt_regs *regs);
> +bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn);
>   void kernel_vector_begin(void);
>   void kernel_vector_end(void);
>   void get_cpu_vector_context(void);
> @@ -268,7 +268,7 @@ struct pt_regs;
>   
>   static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; }
>   static __always_inline bool has_vector(void) { return false; }
> -static inline bool riscv_v_first_use_handler(struct pt_regs *regs) { return false; }
> +static inline bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn) { return false; }
>   static inline bool riscv_v_vstate_query(struct pt_regs *regs) { return false; }
>   static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
>   #define riscv_v_vsize (0)
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 51ebfd23e007..1c3fab272fd1 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -172,11 +172,20 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
>   	bool handled;
>   
>   	if (user_mode(regs)) {
> +		u32 __user *epc = (u32 __user *)regs->epc;
> +		u32 insn = (u32)regs->badaddr;
> +
>   		irqentry_enter_from_user_mode(regs);
>   
>   		local_irq_enable();
>   
> -		handled = riscv_v_first_use_handler(regs);
> +		if (!insn) {
> +			if (__get_user(insn, epc)) {
> +				/* todo */
> +			}

grr, of course as soon as it is sent I notice the /todo/ here

Not sure if we should print something if __get_user() fails for
what /should/ be an good instruction addrss.... should probably
at-least bail out of do_trap_insn_illegal() if not also print a
warning.

> +		}
> +
> +		handled = riscv_v_first_use_handler(regs, insn);
>   
>   		local_irq_disable();
>   
> diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
> index 682b3feee451..b852648cb8d5 100644
> --- a/arch/riscv/kernel/vector.c
> +++ b/arch/riscv/kernel/vector.c
> @@ -168,11 +168,8 @@ bool riscv_v_vstate_ctrl_user_allowed(void)
>   }
>   EXPORT_SYMBOL_GPL(riscv_v_vstate_ctrl_user_allowed);
>   
> -bool riscv_v_first_use_handler(struct pt_regs *regs)
> +bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn)
>   {
> -	u32 __user *epc = (u32 __user *)regs->epc;
> -	u32 insn = (u32)regs->badaddr;
> -
>   	if (!has_vector())
>   		return false;
>   
> @@ -184,12 +181,6 @@ bool riscv_v_first_use_handler(struct pt_regs *regs)
>   	if (riscv_v_vstate_query(regs))
>   		return false;
>   
> -	/* Get the instruction */
> -	if (!insn) {
> -		if (__get_user(insn, epc))
> -			return false;
> -	}
> -
>   	/* Filter out non-V instructions */
>   	if (!insn_is_vector(insn))
>   		return false;


-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html


From ben.dooks at codethink.co.uk  Wed Nov 13 01:31:56 2024
From: ben.dooks at codethink.co.uk (Ben Dooks)
Date: Wed, 13 Nov 2024 09:31:56 +0000
Subject: [PATCH 2/3] riscv: traps: make insn fetch common in unknown
 instruction
In-Reply-To: <45408e3d-5b7a-40cc-bfca-b58cf3737c9c@codethink.co.uk>
References: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
 <20241113091703.3133017-3-ben.dooks@codethink.co.uk>
 <45408e3d-5b7a-40cc-bfca-b58cf3737c9c@codethink.co.uk>
Message-ID: <9b7165eb-43fc-40ab-80cd-dda61e2f933d@codethink.co.uk>

On 13/11/2024 09:21, Ben Dooks wrote:
> On 13/11/2024 09:17, Ben Dooks wrote:
>> Add the trapped instruction (insn) as the second argument to
>> riscv_v_first_use_handler() from the trap handler so when we
>> add more handlers we can do the fetch of the instruction just
>> once.
>>
>> Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
>> ---
>> - fixed wording of patch from rfc
>> ---
>> ? arch/riscv/include/asm/vector.h |? 4 ++--
>> ? arch/riscv/kernel/traps.c?????? | 11 ++++++++++-
>> ? arch/riscv/kernel/vector.c????? | 11 +----------
>> ? 3 files changed, 13 insertions(+), 13 deletions(-)
>>
>> diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/ 
>> vector.h
>> index be7d309cca8a..c9f0b02cd975 100644
>> --- a/arch/riscv/include/asm/vector.h
>> +++ b/arch/riscv/include/asm/vector.h
>> @@ -21,7 +21,7 @@
>> ? extern unsigned long riscv_v_vsize;
>> ? int riscv_v_setup_vsize(void);
>> -bool riscv_v_first_use_handler(struct pt_regs *regs);
>> +bool riscv_v_first_use_handler(struct pt_regs *regs, u32 insn);
>> ? void kernel_vector_begin(void);
>> ? void kernel_vector_end(void);
>> ? void get_cpu_vector_context(void);
>> @@ -268,7 +268,7 @@ struct pt_regs;
>> ? static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; }
>> ? static __always_inline bool has_vector(void) { return false; }
>> -static inline bool riscv_v_first_use_handler(struct pt_regs *regs) 
>> { return false; }
>> +static inline bool riscv_v_first_use_handler(struct pt_regs *regs, 
>> u32 insn) { return false; }
>> ? static inline bool riscv_v_vstate_query(struct pt_regs *regs) 
>> { return false; }
>> ? static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return 
>> false; }
>> ? #define riscv_v_vsize (0)
>> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
>> index 51ebfd23e007..1c3fab272fd1 100644
>> --- a/arch/riscv/kernel/traps.c
>> +++ b/arch/riscv/kernel/traps.c
>> @@ -172,11 +172,20 @@ asmlinkage __visible __trap_section void 
>> do_trap_insn_illegal(struct pt_regs *re
>> ????? bool handled;
>> ????? if (user_mode(regs)) {
>> +??????? u32 __user *epc = (u32 __user *)regs->epc;
>> +??????? u32 insn = (u32)regs->badaddr;
>> +
>> ????????? irqentry_enter_from_user_mode(regs);
>> ????????? local_irq_enable();
>> -??????? handled = riscv_v_first_use_handler(regs);
>> +??????? if (!insn) {
>> +??????????? if (__get_user(insn, epc)) {
>> +??????????????? /* todo */
>> +??????????? }
> 
> grr, of course as soon as it is sent I notice the /todo/ here
> 
> Not sure if we should print something if __get_user() fails for
> what /should/ be an good instruction addrss.... should probably
> at-least bail out of do_trap_insn_illegal() if not also print a
> warning.
>

i think doing:

	if (___get_user(insn, epr)) {
		handled = false;
		insn = 0;
	}

then just checking for "if (insn)" before hand handlers.

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html


From james.clark at linaro.org  Wed Nov 13 02:00:36 2024
From: james.clark at linaro.org (James Clark)
Date: Wed, 13 Nov 2024 10:00:36 +0000
Subject: [PATCH v1 3/4] perf record: Skip don't fail for events that don't
 open
In-Reply-To: <CAP-5=fXuyZbn3Jiq=RQaLTqybgji50Ko8jrpsinFqo+OOPBeRw@mail.gmail.com>
References: <20241026121758.143259-1-irogers@google.com>
 <20241026121758.143259-4-irogers@google.com>
 <20241112195343.GA404636@e132581.arm.com>
 <CAP-5=fXuyZbn3Jiq=RQaLTqybgji50Ko8jrpsinFqo+OOPBeRw@mail.gmail.com>
Message-ID: <f762f404-626a-430f-b307-33c9da756ac3@linaro.org>



On 12/11/2024 10:24 pm, Ian Rogers wrote:
> On Tue, Nov 12, 2024 at 11:53?AM Leo Yan <leo.yan at arm.com> wrote:
>>
>> On Sat, Oct 26, 2024 at 05:17:57AM -0700, Ian Rogers wrote:
>>>
>>> Whilst for many tools it is an expected behavior that failure to open
>>> a perf event is a failure, ARM decided to name PMU events the same as
>>> legacy events and then failed to rename such events on a server uncore
>>> SLC PMU. As perf's default behavior when no PMU is specified is to
>>> open the event on all PMUs that advertise/"have" the event, this
>>> yielded failures when trying to make the priority of legacy and
>>> sysfs/json events uniform - something requested by RISC-V and ARM. A
>>> legacy event user on ARM hardware may find their event opened on an
>>> uncore PMU which for perf record will fail. Arnaldo suggested skipping
>>> such events which this patch implements. Rather than have the skipping
>>> conditional on running on ARM, the skipping is done on all
>>> architectures as such a fundamental behavioral difference could lead
>>> to problems with tools built/depending on perf.
>>>
>>> An example of perf record failing to open events on x86 is:
>>> ```
>>> $ perf record -e data_read,cycles,LLC-prefetch-read -a sleep 0.1
>>> Error:
>>> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_0' which will be removed.
>>> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
>>> "dmesg | grep -i perf" may provide additional information.
>>>
>>> Error:
>>> Failure to open event 'data_read' on PMU 'uncore_imc_free_running_1' which will be removed.
>>> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (data_read).
>>> "dmesg | grep -i perf" may provide additional information.
>>>
>>> Error:
>>> Failure to open event 'LLC-prefetch-read' on PMU 'cpu' which will be removed.
>>> The LLC-prefetch-read event is not supported.
>>> [ perf record: Woken up 1 times to write data ]
>>> [ perf record: Captured and wrote 2.188 MB perf.data (87 samples) ]
>>>
>>> $ perf report --stats
>>> Aggregated stats:
>>>                 TOTAL events:      17255
>>>                  MMAP events:        284  ( 1.6%)
>>>                  COMM events:       1961  (11.4%)
>>>                  EXIT events:          1  ( 0.0%)
>>>                  FORK events:       1960  (11.4%)
>>>                SAMPLE events:         87  ( 0.5%)
>>>                 MMAP2 events:      12836  (74.4%)
>>>               KSYMBOL events:         83  ( 0.5%)
>>>             BPF_EVENT events:         36  ( 0.2%)
>>>        FINISHED_ROUND events:          2  ( 0.0%)
>>>              ID_INDEX events:          1  ( 0.0%)
>>>            THREAD_MAP events:          1  ( 0.0%)
>>>               CPU_MAP events:          1  ( 0.0%)
>>>             TIME_CONV events:          1  ( 0.0%)
>>>         FINISHED_INIT events:          1  ( 0.0%)
>>> cycles stats:
>>>                SAMPLE events:         87
>>> ```
>>
>> Thanks for James reminding me.  Tested on AVA platform:
>>
>> # tree /sys/bus/event_source/devices/arm_dsu_*/events
>>    ...
>>    /sys/bus/event_source/devices/arm_dsu_9/events
>>    ??? bus_access
>>    ??? bus_cycles
>>    ??? cycles
>>    ??? l3d_cache
>>    ??? l3d_cache_allocate
>>    ??? l3d_cache_refill
>>    ??? l3d_cache_wb
>>    ??? memory_error
>>
>> # ./perf record -- sleep 0.1
>>   Error:
>>   Failure to open event 'cycles:PH' on PMU 'arm_dsu_0' which will be
>>   removed.
>>   cycles:PH: PMU Hardware doesn't support sampling/overflow-interrupts.
>>   Try 'perf stat'
>>   Error:
>>   Failure to open event 'cycles:PH' on PMU 'arm_dsu_1' which will be
>>   removed.
>>   cycles:PH: PMU Hardware doesn't support sampling/overflow-interrupts.
>>   Try 'perf stat'
>>   ...
>>   Error:
>>   Failure to open event 'cycles:PH' on PMU 'arm_dsu_15' which will be
>>   removed.
>>   cycles:PH: PMU Hardware doesn't support sampling/overflow-interrupts.
>>   Try 'perf stat'
>>   [ perf record: Woken up 1 times to write data ]
>>   [ perf record: Captured and wrote 0.008 MB perf.data (8 samples) ]
>>
>> # ./perf report --stats
>>
>>   Aggregated stats:
>>                  TOTAL events:         67
>>                   MMAP events:         40  (59.7%)
>>                   COMM events:          1  ( 1.5%)
>>                 SAMPLE events:          8  (11.9%)
>>                KSYMBOL events:          6  ( 9.0%)
>>              BPF_EVENT events:          6  ( 9.0%)
>>         FINISHED_ROUND events:          1  ( 1.5%)
>>               ID_INDEX events:          1  ( 1.5%)
>>             THREAD_MAP events:          1  ( 1.5%)
>>                CPU_MAP events:          1  ( 1.5%)
>>              TIME_CONV events:          1  ( 1.5%)
>>          FINISHED_INIT events:          1  ( 1.5%)
>>   cycles:P stats:
>>                 SAMPLE events:          8
>>
>> # ./perf stat -- sleep 0.1
>>
>>   Performance counter stats for 'sleep 0.1':
>>
>>                0.87 msec task-clock                       #    0.009 CPUs utilized
>>                   1      context-switches                 #    1.148 K/sec
>>                   0      cpu-migrations                   #    0.000 /sec
>>                  52      page-faults                      #   59.685 K/sec
>>             877,835      instructions                     #    1.14  insn per cycle
>>                                                    #    0.25  stalled cycles per insn
>>             772,102      cycles                           #  886.210 M/sec
>>             191,914      stalled-cycles-frontend          #   24.86% frontend cycles idle
>>             219,183      stalled-cycles-backend           #   28.39% backend cycles idle
>>             184,099      branches                         #  211.307 M/sec
>>               8,548      branch-misses                    #    4.64% of all branches
>>
>>         0.101623529 seconds time elapsed
>>
>>         0.001645000 seconds user
>>         0.000000000 seconds sys
>>
>> Tested-by: Leo Yan <leo.yan at arm.com>
> 
> Thanks Leo! As the Tested-by makes sense only if you've applied all 4
> patches, which your testing and James' testing shows you've both done,
> I'll add the tags to all 4 patches. I'll do likewise with Atish,
> rebase and resend the patches.
> 
> Thanks,
> Ian

Yep makes sense


From zhangchunyan at iscas.ac.cn  Wed Nov 13 01:58:30 2024
From: zhangchunyan at iscas.ac.cn (Chunyan Zhang)
Date: Wed, 13 Nov 2024 17:58:30 +0800
Subject: [PATCH V5 0/3] riscv: mm: Add soft-dirty and uffd-wp support
Message-ID: <20241113095833.1805746-1-zhangchunyan@iscas.ac.cn>

This patchset adds soft dirty and userfaultfd write protect tracking 
support for RISC-V.

As described in the patches, we are trying to utilize only one free PTE
bit(9) to support three kernel features (devmap, soft-dirty, uffd-wp).
Users cannot have them supported at the same time (have to select
one when building the kernel).

This patchset has been tested with:
1) The kselftest mm suite in which soft-dirty, madv_populate,
test_unmerge_uffd_wp, and uffd-unit-tests run and pass, and no regressions
are observed in any of the other tests.

2) CRIU:
- 'criu check --feature mem_dirty_track' returns supported;
- incremental_dumps[1] and simple_loop [2] dump and restores work fine;
- zdtm test suite can run under host mode.

This patchset applies on top of v6.12-rc7.

V5:
- Fixed typos and corrected some words in Kconfig and commit message;
- Removed pte_wrprotect() from pte_swp_mkuffd_wp(), this is a copy-paste error;
- Added Alex's Reviewed-by tag in patch 2.

V4:
- Added bit(4) descriptions into "Format of swap PTE".

V3:
- Fixed the issue reported by kernel test irobot <lkp at intel.com>.

V1 -> V2:
- Add uffd-wp supported;
- Make soft-dirty uffd-wp and devmap mutually exclusive which all use the same PTE bit;
- Add test results of CRIU in the cover-letter.

[1] https://www.criu.org/Incremental_dumps
[2] https://asciinema.org/a/232445

Chunyan Zhang (3):
  riscv: mm: Prepare for reusing PTE RSW bit(9)
  riscv: mm: Add soft-dirty page tracking support
  riscv: mm: Add uffd write-protect support

 arch/riscv/Kconfig                    |  34 ++++++-
 arch/riscv/include/asm/pgtable-64.h   |   2 +-
 arch/riscv/include/asm/pgtable-bits.h |  31 ++++++
 arch/riscv/include/asm/pgtable.h      | 133 +++++++++++++++++++++++++-
 4 files changed, 197 insertions(+), 3 deletions(-)

-- 
2.34.1



From zhangchunyan at iscas.ac.cn  Wed Nov 13 01:58:31 2024
From: zhangchunyan at iscas.ac.cn (Chunyan Zhang)
Date: Wed, 13 Nov 2024 17:58:31 +0800
Subject: [PATCH V5 1/3] riscv: mm: Prepare for reusing PTE RSW bit(9)
In-Reply-To: <20241113095833.1805746-1-zhangchunyan@iscas.ac.cn>
References: <20241113095833.1805746-1-zhangchunyan@iscas.ac.cn>
Message-ID: <20241113095833.1805746-2-zhangchunyan@iscas.ac.cn>

The PTE bit(9) on RISC-V is reserved for software, it is used by devmap
now which has to be disabled if we want to use bit(9) for other features,
since there's no more free PTE bit on RISC-V now.

So to make ARCH_HAS_PTE_DEVMAP selectable, this patch uses it as
the build condition of devmap definitions.

Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
---
 arch/riscv/include/asm/pgtable-64.h   | 2 +-
 arch/riscv/include/asm/pgtable-bits.h | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 0897dd99ab8d..babb8d2b0f0b 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -398,7 +398,7 @@ static inline struct page *pgd_page(pgd_t pgd)
 #define p4d_offset p4d_offset
 p4d_t *p4d_offset(pgd_t *pgd, unsigned long address);
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && defined(CONFIG_ARCH_HAS_PTE_DEVMAP)
 static inline int pte_devmap(pte_t pte);
 static inline pte_t pmd_pte(pmd_t pmd);
 
diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
index a8f5205cea54..5bcc73430829 100644
--- a/arch/riscv/include/asm/pgtable-bits.h
+++ b/arch/riscv/include/asm/pgtable-bits.h
@@ -19,7 +19,13 @@
 #define _PAGE_SOFT      (3 << 8)    /* Reserved for software */
 
 #define _PAGE_SPECIAL   (1 << 8)    /* RSW: 0x1 */
+
+#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
 #define _PAGE_DEVMAP    (1 << 9)    /* RSW, devmap */
+#else
+#define _PAGE_DEVMAP	0
+#endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
+
 #define _PAGE_TABLE     _PAGE_PRESENT
 
 /*
-- 
2.34.1



From zhangchunyan at iscas.ac.cn  Wed Nov 13 01:58:33 2024
From: zhangchunyan at iscas.ac.cn (Chunyan Zhang)
Date: Wed, 13 Nov 2024 17:58:33 +0800
Subject: [PATCH V5 3/3] riscv: mm: Add uffd write-protect support
In-Reply-To: <20241113095833.1805746-1-zhangchunyan@iscas.ac.cn>
References: <20241113095833.1805746-1-zhangchunyan@iscas.ac.cn>
Message-ID: <20241113095833.1805746-4-zhangchunyan@iscas.ac.cn>

Reuse PTE bit(9) to do uffd-wp tracking and make it mutually exclusive
with soft-dirty and devmap which all use this PTE bit.

Additionally for tracking the uffd-wp state as a PTE swap bit,
we use swap entry pte bit(4) which is also used by swap
soft-dirty tracking.

Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
---
 arch/riscv/Kconfig                    |  7 +++
 arch/riscv/include/asm/pgtable-bits.h | 13 ++++++
 arch/riscv/include/asm/pgtable.h      | 66 ++++++++++++++++++++++++++-
 3 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 3bccdcae9445..920071a05512 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -989,6 +989,13 @@ config RISCV_HAS_SOFT_DIRTY
 	help
 	  The PTE bit(9) is used for soft-dirty tracking.
 
+config RISCV_HAS_USERFAULTFD_WP
+	bool "userfaultfd write protection"
+	select HAVE_ARCH_USERFAULTFD_WP
+	depends on USERFAULTFD
+	help
+	  The PTE bit(9) is used for userfaultfd write-protected
+	  tracking.
 endchoice
 
 endmenu # "Kernel features"
diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
index c6d51fe9fc6f..7de16141c049 100644
--- a/arch/riscv/include/asm/pgtable-bits.h
+++ b/arch/riscv/include/asm/pgtable-bits.h
@@ -38,6 +38,19 @@
 #define _PAGE_SWP_SOFT_DIRTY	0
 #endif /* CONFIG_MEM_SOFT_DIRTY */
 
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+/*
+ * CONFIG_HAVE_ARCH_USERFAULTFD_WP is mutually exclusive with
+ * HAVE_ARCH_SOFT_DIRTY so we can use the same bit for uffd-wp
+ * and soft-dirty tracking.
+ */
+#define _PAGE_UFFD_WP		(1 << 9) /* RSW: 0x2 for uffd-wp tracking */
+#define _PAGE_SWP_UFFD_WP	_PAGE_USER
+#else
+#define _PAGE_UFFD_WP		0
+#define _PAGE_SWP_UFFD_WP	0
+#endif
+
 #define _PAGE_TABLE     _PAGE_PRESENT
 
 /*
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 1779eae5cb49..f241c444cebd 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -413,6 +413,38 @@ static inline pte_t pte_wrprotect(pte_t pte)
 	return __pte(pte_val(pte) & ~(_PAGE_WRITE));
 }
 
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+static inline int pte_uffd_wp(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_UFFD_WP;
+}
+
+static inline pte_t pte_mkuffd_wp(pte_t pte)
+{
+	return pte_wrprotect(__pte(pte_val(pte) | _PAGE_UFFD_WP));
+}
+
+static inline pte_t pte_clear_uffd_wp(pte_t pte)
+{
+	return __pte(pte_val(pte) & ~(_PAGE_UFFD_WP));
+}
+
+static inline int pte_swp_uffd_wp(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_SWP_UFFD_WP;
+}
+
+static inline pte_t pte_swp_mkuffd_wp(pte_t pte)
+{
+	return __pte(pte_val(pte) | _PAGE_SWP_UFFD_WP);
+}
+
+static inline pte_t pte_swp_clear_uffd_wp(pte_t pte)
+{
+	return __pte(pte_val(pte) & ~(_PAGE_SWP_UFFD_WP));
+}
+#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
+
 /* static inline pte_t pte_mkread(pte_t pte) */
 
 static inline pte_t pte_mkwrite_novma(pte_t pte)
@@ -789,6 +821,38 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
 	return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
 }
 
+#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
+static inline int pmd_uffd_wp(pmd_t pmd)
+{
+	return pte_uffd_wp(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_mkuffd_wp(pmd_t pmd)
+{
+	return pte_pmd(pte_mkuffd_wp(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_clear_uffd_wp(pmd_t pmd)
+{
+	return pte_pmd(pte_clear_uffd_wp(pmd_pte(pmd)));
+}
+
+static inline int pmd_swp_uffd_wp(pmd_t pmd)
+{
+	return pte_swp_uffd_wp(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_swp_mkuffd_wp(pmd_t pmd)
+{
+	return pte_pmd(pte_swp_mkuffd_wp(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_swp_clear_uffd_wp(pmd_t pmd)
+{
+	return pte_pmd(pte_swp_clear_uffd_wp(pmd_pte(pmd)));
+}
+#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
+
 #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
 static inline int pmd_soft_dirty(pmd_t pmd)
 {
@@ -913,7 +977,7 @@ extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
  * Format of swap PTE:
  *	bit            0:	_PAGE_PRESENT (zero)
  *	bit       1 to 3:       _PAGE_LEAF (zero)
- *	bit	       4:	_PAGE_SWP_SOFT_DIRTY
+ *	bit	       4:	_PAGE_SWP_SOFT_DIRTY or _PAGE_SWP_UFFD_WP
  *	bit            5:	_PAGE_PROT_NONE (zero)
  *	bit            6:	exclusive marker
  *	bits      7 to 11:	swap type
-- 
2.34.1



From zhangchunyan at iscas.ac.cn  Wed Nov 13 01:58:32 2024
From: zhangchunyan at iscas.ac.cn (Chunyan Zhang)
Date: Wed, 13 Nov 2024 17:58:32 +0800
Subject: [PATCH V5 2/3] riscv: mm: Add soft-dirty page tracking support
In-Reply-To: <20241113095833.1805746-1-zhangchunyan@iscas.ac.cn>
References: <20241113095833.1805746-1-zhangchunyan@iscas.ac.cn>
Message-ID: <20241113095833.1805746-3-zhangchunyan@iscas.ac.cn>

The PTE bit(9) is reserved for software, now used by devmap,
this patch reuses bit(9) for soft-dirty which is enabled only
if !CONFIG_ARCH_HAS_PTE_DEVMAP, in other words, soft-dirty
and devmap will be mutually exclusive on RISC-V.

To add swap PTE soft-dirty tracking, we borrow bit(4) which is
available for swap PTEs on RISC-V systems.

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Signed-off-by: Chunyan Zhang <zhangchunyan at iscas.ac.cn>
---
 arch/riscv/Kconfig                    | 27 ++++++++++-
 arch/riscv/include/asm/pgtable-bits.h | 12 +++++
 arch/riscv/include/asm/pgtable.h      | 69 ++++++++++++++++++++++++++-
 3 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index f4c570538d55..3bccdcae9445 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -40,7 +40,6 @@ config RISCV
 	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	select ARCH_HAS_PMEM_API
 	select ARCH_HAS_PREPARE_SYNC_CORE_CMD
-	select ARCH_HAS_PTE_DEVMAP if 64BIT && MMU
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_SET_DIRECT_MAP if MMU
 	select ARCH_HAS_SET_MEMORY if MMU
@@ -966,6 +965,32 @@ config RANDOMIZE_BASE
 
           If unsure, say N.
 
+choice
+	prompt "PTE RSW bit(9) usage"
+	default RISCV_HAS_PTE_DEVMAP
+	depends on MMU && 64BIT
+	help
+	  RISC-V PTE bit(9) is reserved for software, and used by more than
+	  one kernel feature which cannot be supported at the same time.
+	  So we have to select one for it.
+
+config RISCV_HAS_PTE_DEVMAP
+	bool "devmap"
+	select ARCH_HAS_PTE_DEVMAP
+	help
+	  The PTE bit(9) is used for devmap mark. ZONE_DEVICE pages need devmap
+	  PTEs support to function.
+
+	  So if you want to use ZONE_DEVICE, select this.
+
+config RISCV_HAS_SOFT_DIRTY
+	bool "soft-dirty"
+	select HAVE_ARCH_SOFT_DIRTY
+	help
+	  The PTE bit(9) is used for soft-dirty tracking.
+
+endchoice
+
 endmenu # "Kernel features"
 
 menu "Boot options"
diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
index 5bcc73430829..c6d51fe9fc6f 100644
--- a/arch/riscv/include/asm/pgtable-bits.h
+++ b/arch/riscv/include/asm/pgtable-bits.h
@@ -26,6 +26,18 @@
 #define _PAGE_DEVMAP	0
 #endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
 
+#ifdef CONFIG_MEM_SOFT_DIRTY
+#define _PAGE_SOFT_DIRTY	(1 << 9)    /* RSW: 0x2 for software dirty tracking */
+/*
+ * BIT 4 is not involved into swap entry computation, so we
+ * can borrow it for swap page soft-dirty tracking.
+ */
+#define _PAGE_SWP_SOFT_DIRTY	_PAGE_USER
+#else
+#define _PAGE_SOFT_DIRTY	0
+#define _PAGE_SWP_SOFT_DIRTY	0
+#endif /* CONFIG_MEM_SOFT_DIRTY */
+
 #define _PAGE_TABLE     _PAGE_PRESENT
 
 /*
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index e79f15293492..1779eae5cb49 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -424,7 +424,7 @@ static inline pte_t pte_mkwrite_novma(pte_t pte)
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
-	return __pte(pte_val(pte) | _PAGE_DIRTY);
+	return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
 }
 
 static inline pte_t pte_mkclean(pte_t pte)
@@ -457,6 +457,38 @@ static inline pte_t pte_mkhuge(pte_t pte)
 	return pte;
 }
 
+#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
+static inline int pte_soft_dirty(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_SOFT_DIRTY;
+}
+
+static inline pte_t pte_mksoft_dirty(pte_t pte)
+{
+	return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY);
+}
+
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
+{
+	return __pte(pte_val(pte) & ~(_PAGE_SOFT_DIRTY));
+}
+
+static inline int pte_swp_soft_dirty(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_SWP_SOFT_DIRTY;
+}
+
+static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
+{
+	return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY);
+}
+
+static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
+{
+	return __pte(pte_val(pte) & ~(_PAGE_SWP_SOFT_DIRTY));
+}
+#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
+
 #ifdef CONFIG_RISCV_ISA_SVNAPOT
 #define pte_leaf_size(pte)	(pte_napot(pte) ?				\
 					napot_cont_size(napot_cont_order(pte)) :\
@@ -757,6 +789,40 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
 	return pte_pmd(pte_mkdevmap(pmd_pte(pmd)));
 }
 
+#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
+static inline int pmd_soft_dirty(pmd_t pmd)
+{
+	return pte_soft_dirty(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
+{
+	return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
+{
+	return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd)));
+}
+
+#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
+static inline int pmd_swp_soft_dirty(pmd_t pmd)
+{
+	return pte_swp_soft_dirty(pmd_pte(pmd));
+}
+
+static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd)
+{
+	return pte_pmd(pte_swp_mksoft_dirty(pmd_pte(pmd)));
+}
+
+static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd)
+{
+	return pte_pmd(pte_swp_clear_soft_dirty(pmd_pte(pmd)));
+}
+#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
+#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
+
 static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
 				pmd_t *pmdp, pmd_t pmd)
 {
@@ -847,6 +913,7 @@ extern pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
  * Format of swap PTE:
  *	bit            0:	_PAGE_PRESENT (zero)
  *	bit       1 to 3:       _PAGE_LEAF (zero)
+ *	bit	       4:	_PAGE_SWP_SOFT_DIRTY
  *	bit            5:	_PAGE_PROT_NONE (zero)
  *	bit            6:	exclusive marker
  *	bits      7 to 11:	swap type
-- 
2.34.1



From ajones at ventanamicro.com  Wed Nov 13 02:12:51 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Wed, 13 Nov 2024 11:12:51 +0100
Subject: [PATCH 1/3] riscv: ptrace: add regs_set_register()
In-Reply-To: <20241113091703.3133017-2-ben.dooks@codethink.co.uk>
References: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
 <20241113091703.3133017-2-ben.dooks@codethink.co.uk>
Message-ID: <20241113-58aebadd1b4916382031abaa@orel>

On Wed, Nov 13, 2024 at 09:17:01AM +0000, Ben Dooks wrote:
> Since we have regs_get_register() and we could use the set counterpart
> for things like fixing up traps, add regs_set_register() to set a pt_regs
> value from offset.
> 
> Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
> ---
>  arch/riscv/include/asm/ptrace.h | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
> index b5b0adcc85c1..66fc1795141d 100644
> --- a/arch/riscv/include/asm/ptrace.h
> +++ b/arch/riscv/include/asm/ptrace.h
> @@ -143,6 +143,26 @@ static inline unsigned long regs_get_register(struct pt_regs *regs,
>  	return *(unsigned long *)((unsigned long)regs + offset);
>  }
>  
> +/**
> + * regs_set_register() - set register value from its offset

s/from/at/

> + * @regs:	pt_regs from which register value is gotten

s/gotten/set/

> + * @offset:	offset of the register.
> + * @to:		value to set register to

Can we name this 'value' instead of 'to'?

> + *
> + * regs_set_register sets the value @to to a register whose offset from @regs.
> + * The @offset is the offset of the register in struct pt_regs.
> + * If @offset is bigger than MAX_REG_OFFSET, this will ignore the write.
> + */
> +static inline void regs_set_register(struct pt_regs *regs,
> +				     unsigned int offset,
> +				     unsigned long to)
> +{
> +	if (unlikely(offset > MAX_REG_OFFSET))
> +		return;
> +
> +	*(unsigned long *)((unsigned long)regs + offset) = to;
> +}
> +
>  /**
>   * regs_get_kernel_argument() - get Nth function argument in kernel
>   * @regs:       pt_regs of that context
> -- 
> 2.37.2.352.g3c44437643
>

Thanks,
drew


From ajones at ventanamicro.com  Wed Nov 13 02:17:09 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Wed, 13 Nov 2024 11:17:09 +0100
Subject: [PATCH 3/3] riscv: insn: add RV_EXTRACT_FUNCT3()
In-Reply-To: <20241113091703.3133017-4-ben.dooks@codethink.co.uk>
References: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
 <20241113091703.3133017-4-ben.dooks@codethink.co.uk>
Message-ID: <20241113-c53841e015159bbf656643ae@orel>

On Wed, Nov 13, 2024 at 09:17:03AM +0000, Ben Dooks wrote:
> Add extraction for the func3 field of most instructions
> for use with anyone who needs it.
> 
> Note, added this for decoding of CSR accesses for
> work we did looking at the RDCYCLE v RDTIME calls.
> 
> Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
> ---
>  arch/riscv/include/asm/insn.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h
> index 09fde95a5e8f..c67f44ff2066 100644
> --- a/arch/riscv/include/asm/insn.h
> +++ b/arch/riscv/include/asm/insn.h
> @@ -299,6 +299,10 @@ static __always_inline bool riscv_insn_is_c_jalr(u32 code)
>  	({typeof(x) x_ = (x); \
>  	(RV_X(x_, RVG_RD_OPOFF, RVG_RD_MASK)); })
>  
> +#define RV_EXTRACT_FUNCT3(x) \
> +	({typeof(x) x_ = (x); \
> +	(RV_X(x_, RV_INSN_FUNCT3_OPOFF, RV_INSN_FUNCT3_MASK)); })
> +
>  #define RV_EXTRACT_UTYPE_IMM(x) \
>  	({typeof(x) x_ = (x); \
>  	(RV_X(x_, RV_U_IMM_31_12_OPOFF, RV_U_IMM_31_12_MASK)); })
> -- 
> 2.37.2.352.g3c44437643
>

It doesn't hurt to have an unused macro and there's a reasonable chance
there will be a user someday, but I'd typically wait for a user before
adding stuff. Anyway,

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>

Thanks,
drew


From ben.dooks at codethink.co.uk  Wed Nov 13 02:19:50 2024
From: ben.dooks at codethink.co.uk (Ben Dooks)
Date: Wed, 13 Nov 2024 10:19:50 +0000
Subject: [PATCH 1/3] riscv: ptrace: add regs_set_register()
In-Reply-To: <20241113-58aebadd1b4916382031abaa@orel>
References: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
 <20241113091703.3133017-2-ben.dooks@codethink.co.uk>
 <20241113-58aebadd1b4916382031abaa@orel>
Message-ID: <7278cda9-740b-4bf7-b6da-dd760121e31f@codethink.co.uk>

On 13/11/2024 10:12, Andrew Jones wrote:
> On Wed, Nov 13, 2024 at 09:17:01AM +0000, Ben Dooks wrote:
>> Since we have regs_get_register() and we could use the set counterpart
>> for things like fixing up traps, add regs_set_register() to set a pt_regs
>> value from offset.
>>
>> Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
>> ---
>>   arch/riscv/include/asm/ptrace.h | 20 ++++++++++++++++++++
>>   1 file changed, 20 insertions(+)
>>
>> diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
>> index b5b0adcc85c1..66fc1795141d 100644
>> --- a/arch/riscv/include/asm/ptrace.h
>> +++ b/arch/riscv/include/asm/ptrace.h
>> @@ -143,6 +143,26 @@ static inline unsigned long regs_get_register(struct pt_regs *regs,
>>   	return *(unsigned long *)((unsigned long)regs + offset);
>>   }
>>   
>> +/**
>> + * regs_set_register() - set register value from its offset
> 
> s/from/at/
> 
>> + * @regs:	pt_regs from which register value is gotten
> 
> s/gotten/set/
> 
>> + * @offset:	offset of the register.
>> + * @to:		value to set register to
> 
> Can we name this 'value' instead of 'to'?

Thank you, I think these are all good comments.

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html


From ben.dooks at codethink.co.uk  Wed Nov 13 02:35:07 2024
From: ben.dooks at codethink.co.uk (Ben Dooks)
Date: Wed, 13 Nov 2024 10:35:07 +0000
Subject: [PATCH 3/3] riscv: insn: add RV_EXTRACT_FUNCT3()
In-Reply-To: <20241113-c53841e015159bbf656643ae@orel>
References: <20241113091703.3133017-1-ben.dooks@codethink.co.uk>
 <20241113091703.3133017-4-ben.dooks@codethink.co.uk>
 <20241113-c53841e015159bbf656643ae@orel>
Message-ID: <133bc3d8-5196-4207-8e1b-e3da5fa82630@codethink.co.uk>

On 13/11/2024 10:17, Andrew Jones wrote:
> On Wed, Nov 13, 2024 at 09:17:03AM +0000, Ben Dooks wrote:
>> Add extraction for the func3 field of most instructions
>> for use with anyone who needs it.
>>
>> Note, added this for decoding of CSR accesses for
>> work we did looking at the RDCYCLE v RDTIME calls.
>>
>> Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
>> ---
>>   arch/riscv/include/asm/insn.h | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h
>> index 09fde95a5e8f..c67f44ff2066 100644
>> --- a/arch/riscv/include/asm/insn.h
>> +++ b/arch/riscv/include/asm/insn.h
>> @@ -299,6 +299,10 @@ static __always_inline bool riscv_insn_is_c_jalr(u32 code)
>>   	({typeof(x) x_ = (x); \
>>   	(RV_X(x_, RVG_RD_OPOFF, RVG_RD_MASK)); })
>>   
>> +#define RV_EXTRACT_FUNCT3(x) \
>> +	({typeof(x) x_ = (x); \
>> +	(RV_X(x_, RV_INSN_FUNCT3_OPOFF, RV_INSN_FUNCT3_MASK)); })
>> +
>>   #define RV_EXTRACT_UTYPE_IMM(x) \
>>   	({typeof(x) x_ = (x); \
>>   	(RV_X(x_, RV_U_IMM_31_12_OPOFF, RV_U_IMM_31_12_MASK)); })
>> -- 
>> 2.37.2.352.g3c44437643
>>
> 
> It doesn't hurt to have an unused macro and there's a reasonable chance
> there will be a user someday, but I'd typically wait for a user before
> adding stuff. Anyway,
> 
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>

I am wondering if we add a check for RDCYCLE and print a warning
even if we didn't try an fixup.

-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

https://www.codethink.co.uk/privacy.html


From zhihang.shao.iscas at gmail.com  Wed Nov 13 02:40:34 2024
From: zhihang.shao.iscas at gmail.com (Zhihang Shao)
Date: Wed, 13 Nov 2024 10:40:34 +0000
Subject: [PATCH 0/2] RISC-V CRC-T10DIF optimization with zbc extension and CRC-T10DIF selftest
Message-ID: <20241113104036.254491-1-zhihang.shao.iscas@gmail.com>

Compared to other architectures, RISC-V still lacks accerlerated implementations 
for some encryption and checksum algorithms. 
This patchset aims to add optimization for crc-t10dif algorithm with zbc extension.
To verify the correctness and measure performance of the optimization, 
the selftest is also included as part of patchset.

Zhihang Shao (2):
  lib/crct10diftest.c add selftests for crct10dif
  riscv: Optimize crct10dif with zbc extension

 arch/riscv/crypto/Kconfig               |  14 +
 arch/riscv/crypto/Makefile              |   4 +
 arch/riscv/crypto/crct10dif-riscv-zbc.c | 182 +++++++
 lib/Kconfig                             |   9 +
 lib/Makefile                            |   1 +
 lib/crct10diftest.c                     | 687 ++++++++++++++++++++++++
 6 files changed, 897 insertions(+)
 create mode 100644 arch/riscv/crypto/crct10dif-riscv-zbc.c
 create mode 100644 lib/crct10diftest.c

-- 
2.34.1



From zhihang.shao.iscas at gmail.com  Wed Nov 13 02:40:35 2024
From: zhihang.shao.iscas at gmail.com (Zhihang Shao)
Date: Wed, 13 Nov 2024 10:40:35 +0000
Subject: [PATCH 1/2] lib/crct10diftest.c add selftests for crct10dif
In-Reply-To: <20241113104036.254491-1-zhihang.shao.iscas@gmail.com>
References: <20241113104036.254491-1-zhihang.shao.iscas@gmail.com>
Message-ID: <20241113104036.254491-2-zhihang.shao.iscas@gmail.com>

Add selftests for kernel's implementation of CRC-T10DIF algorithm.
The test data includes 100 randomly generated test-cases.
The selftest file is similar to what is done in lib/crc32test.c, and is
used to verify the correctness and measure performance improvement of
the CRC-T10DIF algorithm with zbc extension optimization.

Signed-off-by: Zhihang Shao <zhihang.shao.iscas at gmail.com>
---
 lib/Kconfig         |   9 +
 lib/Makefile        |   1 +
 lib/crct10diftest.c | 687 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 697 insertions(+)
 create mode 100644 lib/crct10diftest.c

diff --git a/lib/Kconfig b/lib/Kconfig
index b38849af6f13..e0e488fd1307 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -187,6 +187,15 @@ config CRC32_SELFTEST
 	  and crc32_be over byte strings with random alignment and length
 	  and computes the total elapsed time and number of bytes processed.
 
+config CRCT10DIF_SELFTEST
+	tristate "CRCT10DIF perform self test on init"
+	depends on CRC_T10DIF
+	help
+	  This option enables the CRCT10DIF library functions to perform a
+	  self test on initialization. The self test computes crc_t10dif_update
+	  over byte strings with random alignment and length
+	  and computes the total elapsed time and number of bytes processed.
+
 choice
 	prompt "CRC32 implementation"
 	depends on CRC32
diff --git a/lib/Makefile b/lib/Makefile
index 773adf88af41..6dac65a3778c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -161,6 +161,7 @@ obj-$(CONFIG_CRC_ITU_T)	+= crc-itu-t.o
 obj-$(CONFIG_CRC32)	+= crc32.o
 obj-$(CONFIG_CRC64)     += crc64.o
 obj-$(CONFIG_CRC32_SELFTEST)	+= crc32test.o
+obj-$(CONFIG_CRCT10DIF_SELFTEST)	+= crct10diftest.o
 obj-$(CONFIG_CRC4)	+= crc4.o
 obj-$(CONFIG_CRC7)	+= crc7.o
 obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
diff --git a/lib/crct10diftest.c b/lib/crct10diftest.c
new file mode 100644
index 000000000000..9541892eb12c
--- /dev/null
+++ b/lib/crct10diftest.c
@@ -0,0 +1,687 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * CRC-T10DIF selftests
+ *
+ * Copyright (C) 2024 Institute of Software, CAS.
+ */
+#include <linux/crc-t10dif.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+
+static struct crc_test {
+	u16 crc; /* random starting crc*/
+	u16 start; /* random 6 bit offset in buf*/
+	u16 length; /* random 11 bit length of test*/
+	u16 crct10dif; /* expected crc_t10dif result*/
+} tests[] = {
+	{0xdead, 0x0009, 0x0030, 0x8419},
+	{0x37c8, 0x0014, 0x03f0, 0xf4b5},
+	{0x8f45, 0x002d, 0x03b0, 0x6937},
+	{0x4201, 0x0020, 0x0719, 0x665e},
+	{0xe102, 0x0037, 0x0599, 0xb45b},
+	{0xa65d, 0x0008, 0x024d, 0x95d3},
+	{0xadba, 0x0001, 0x0799, 0xbb14},
+	{0x4407, 0x0038, 0x06a3, 0xb401},
+	{0x5188, 0x000c, 0x03f5, 0xf00c},
+	{0x5120, 0x0025, 0x0255, 0x858b},
+	{0x6a92, 0x0006, 0x0559, 0x159a},
+	{0xfa66, 0x0032, 0x0561, 0x0916},
+	{0x40a9, 0x003a, 0x0179, 0x0eb5},
+	{0x3c82, 0x0006, 0x02f0, 0x598c},
+	{0xbe07, 0x000a, 0x0085, 0xb228},
+	{0x7942, 0x0029, 0x033b, 0x0cc4},
+	{0x1275, 0x0030, 0x041b, 0x87b3},
+	{0xb715, 0x0030, 0x03fa, 0xcda8},
+	{0x7476, 0x0013, 0x063b, 0x51e8},
+	{0xa5c5, 0x001c, 0x0245, 0x53af},
+	{0x3e97, 0x003e, 0x0575, 0xdacf},
+	{0xdf84, 0x0025, 0x0556, 0x1154},
+	{0x72ef, 0x001b, 0x079b, 0x07b3},
+	{0x6d04, 0x0016, 0x06fc, 0x8cdf},
+	{0xe206, 0x0017, 0x030e, 0xe609},
+	{0xc188, 0x0008, 0x02c3, 0x504b},
+	{0x705b, 0x003f, 0x04db, 0xcf7c},
+	{0x3c9b, 0x0021, 0x048f, 0x09f9},
+	{0x32df, 0x0004, 0x064c, 0x73fb},
+	{0x0269, 0x0022, 0x07f0, 0xa49e},
+	{0x717d, 0x000b, 0x018b, 0x2ba0},
+	{0xc261, 0x0007, 0x05fb, 0x726e},
+	{0x239f, 0x000a, 0x0582, 0xa055},
+	{0x6812, 0x0006, 0x0325, 0x6399},
+	{0x8145, 0x0001, 0x068e, 0x8a81},
+	{0xaf22, 0x001d, 0x0113, 0xeb59},
+	{0xb521, 0x001f, 0x0465, 0x0648},
+	{0x8b01, 0x0015, 0x04e4, 0xdbf6},
+	{0xf3e0, 0x002f, 0x0300, 0x01b3},
+	{0xa6f6, 0x003c, 0x02a8, 0x56f4},
+	{0x7a06, 0x002b, 0x07bc, 0x5df1},
+	{0x9071, 0x0022, 0x0286, 0x6d8a},
+	{0x8ae3, 0x0015, 0x0796, 0x4fa0},
+	{0x9432, 0x0029, 0x0406, 0xfb2d},
+	{0x3808, 0x002c, 0x00df, 0xb9b6},
+	{0xb4c1, 0x0003, 0x0788, 0x3e7e},
+	{0xbc32, 0x0008, 0x06e3, 0x9c4f},
+	{0xd384, 0x000c, 0x05be, 0x6505},
+	{0x51b7, 0x003a, 0x07a3, 0x4216},
+	{0xa85c, 0x0029, 0x03de, 0xdcfe},
+	{0x933e, 0x0034, 0x0544, 0xecac},
+	{0xcc1e, 0x000b, 0x00c5, 0x832b},
+	{0x99b7, 0x0024, 0x0730, 0x9541},
+	{0x9f67, 0x0038, 0x071a, 0x762b},
+	{0x2140, 0x003e, 0x06c1, 0xe6b5},
+	{0x0f8a, 0x003f, 0x024f, 0xfcdd},
+	{0xc9fa, 0x0032, 0x0369, 0x9192},
+	{0x5c1c, 0x0007, 0x0596, 0x074a},
+	{0xfabb, 0x001a, 0x06cb, 0xd699},
+	{0x9c25, 0x0010, 0x0300, 0x3571},
+	{0xf934, 0x0030, 0x0455, 0xd0ce},
+	{0x18e8, 0x002f, 0x0434, 0x8c42},
+	{0xd16d, 0x0036, 0x06ed, 0x247a},
+	{0x9f75, 0x003d, 0x0238, 0x2508},
+	{0xe32f, 0x0021, 0x03c6, 0x358a},
+	{0xbce8, 0x001c, 0x06a6, 0x11bd},
+	{0x9436, 0x0031, 0x067d, 0x4512},
+	{0xcd02, 0x003d, 0x0638, 0x2bef},
+	{0xdbad, 0x000d, 0x06d2, 0x4e67},
+	{0x65fd, 0x0006, 0x06be, 0xf178},
+	{0x05fc, 0x002b, 0x0062, 0x509d},
+	{0xcee8, 0x001a, 0x06e1, 0xccb1},
+	{0xe03c, 0x0027, 0x0163, 0x2633},
+	{0x6c03, 0x0009, 0x04c8, 0xfec2},
+	{0x657b, 0x0006, 0x0096, 0x1c5a},
+	{0x1cc3, 0x000e, 0x00b3, 0xd233},
+	{0x815c, 0x0005, 0x0506, 0xc241},
+	{0xaa8c, 0x0004, 0x06c3, 0x0e76},
+	{0x7970, 0x0025, 0x05fa, 0x4d7a},
+	{0x91c0, 0x001c, 0x0270, 0x40af},
+	{0x4f83, 0x0014, 0x0720, 0x9d03},
+	{0x0bdd, 0x0029, 0x03c1, 0xac55},
+	{0x372f, 0x0017, 0x03d5, 0x41d2},
+	{0x8325, 0x0009, 0x0463, 0x2add},
+	{0xf40e, 0x002a, 0x03da, 0x45ea},
+	{0x552e, 0x001e, 0x0723, 0x225a},
+	{0x41c3, 0x001d, 0x06f7, 0x1d61},
+	{0x09f9, 0x0027, 0x057f, 0x5cc0},
+	{0xfd3b, 0x0020, 0x0504, 0x8048},
+	{0xb889, 0x0005, 0x0271, 0x43e0},
+	{0xbd1c, 0x0007, 0x03aa, 0x7253},
+	{0xbad0, 0x000e, 0x04c3, 0x9855},
+	{0xc978, 0x001d, 0x0579, 0x2ab0},
+	{0x3b3b, 0x001c, 0x0545, 0x521a},
+	{0x41b9, 0x003c, 0x0082, 0x49b7},
+	{0x15a3, 0x0002, 0x0530, 0xf48a},
+	{0xeaa2, 0x0034, 0x03f8, 0x3aad},
+	{0x8af9, 0x0029, 0x02e3, 0x4b3d},
+	{0xb4b0, 0x000d, 0x0056, 0xecee},
+	{0x669b, 0x0019, 0x065f, 0x28d8},
+};
+
+static const u8 __aligned(8) test_buf[] __initconst = {
+	0x4d, 0x87, 0x5f, 0x10, 0x90, 0xd5, 0x31, 0x96,
+	0x3f, 0x5a, 0x50, 0xc7, 0x30, 0x80, 0x5f, 0x2c,
+	0x78, 0xf0, 0xa2, 0xb5, 0xfb, 0xf9, 0x83, 0x14,
+	0xe9, 0xb6, 0xaa, 0xe6, 0x39, 0x12, 0x0b, 0x87,
+	0x99, 0x6a, 0x97, 0x2a, 0x3f, 0xc8, 0xc0, 0x7e,
+	0x22, 0x10, 0x45, 0x52, 0x90, 0xa4, 0x7e, 0x08,
+	0x94, 0x21, 0xbe, 0x8f, 0x1a, 0x41, 0xa3, 0x04,
+	0xf7, 0x4d, 0xea, 0x30, 0x5f, 0xf5, 0xb7, 0xf9,
+	0x60, 0x4e, 0x23, 0x9f, 0x16, 0xe3, 0x1e, 0x38,
+	0xf3, 0x63, 0x8b, 0x84, 0x08, 0x09, 0x8c, 0x9c,
+	0x2a, 0x4a, 0x2c, 0x45, 0x8b, 0xcf, 0x49, 0x82,
+	0x1d, 0x33, 0xb3, 0x7c, 0x29, 0x6a, 0x75, 0x89,
+	0xb9, 0x98, 0x28, 0xcf, 0x7b, 0x46, 0x08, 0x6f,
+	0xaa, 0x93, 0xf3, 0xb2, 0x9c, 0x7f, 0x4e, 0xc7,
+	0xca, 0x7a, 0x0c, 0x55, 0x4a, 0x55, 0xd8, 0x67,
+	0x88, 0x8b, 0xe3, 0xb1, 0xf5, 0x59, 0x3a, 0xae,
+	0xf1, 0x63, 0x7e, 0x6d, 0xa9, 0x86, 0xdc, 0x53,
+	0x19, 0xcf, 0x05, 0xb5, 0x4e, 0x54, 0x7c, 0x18,
+	0xce, 0x88, 0x6e, 0x18, 0xdd, 0x46, 0x7f, 0x66,
+	0xd1, 0x63, 0x17, 0xc6, 0xbc, 0x52, 0x75, 0xad,
+	0xb5, 0xf3, 0x1a, 0x5e, 0x79, 0xf6, 0xb2, 0x92,
+	0xc5, 0xb7, 0x47, 0x14, 0x0b, 0xc4, 0x2c, 0xda,
+	0x4c, 0x9a, 0xf2, 0x2a, 0xe0, 0x72, 0x90, 0xb1,
+	0xd5, 0xa7, 0x78, 0x91, 0xf9, 0xed, 0x3e, 0xae,
+	0xe0, 0x59, 0x0d, 0x59, 0x4f, 0xbf, 0xeb, 0x15,
+	0x76, 0x32, 0x29, 0x82, 0xf6, 0x55, 0x5c, 0x43,
+	0xf0, 0x4e, 0x6d, 0xd0, 0xc0, 0xfd, 0x82, 0x95,
+	0xa4, 0xfa, 0x26, 0x9e, 0xe7, 0x65, 0x4c, 0xc7,
+	0xbe, 0x59, 0x20, 0x0d, 0x18, 0x0b, 0x22, 0x8f,
+	0x3d, 0x4b, 0x11, 0x34, 0xa1, 0x6d, 0x77, 0x91,
+	0xbb, 0xe4, 0x61, 0x7c, 0xe1, 0xe3, 0x11, 0x85,
+	0xdd, 0x38, 0x23, 0xc4, 0x9d, 0x70, 0x8b, 0x5b,
+	0xc9, 0xab, 0x68, 0xe2, 0xb6, 0x8b, 0x71, 0xf4,
+	0xd6, 0x82, 0x28, 0x77, 0xef, 0x9f, 0x08, 0xaa,
+	0x83, 0x6a, 0x26, 0x64, 0x4d, 0x38, 0xe9, 0x2b,
+	0x70, 0x0d, 0xef, 0x0d, 0x7d, 0x7b, 0x68, 0x46,
+	0x26, 0xd0, 0x28, 0xdd, 0x5b, 0x99, 0xd1, 0x32,
+	0x1b, 0xf9, 0xa9, 0x0a, 0x98, 0xb2, 0xb5, 0x1b,
+	0x1c, 0xdb, 0x7f, 0x69, 0x13, 0x68, 0x94, 0x83,
+	0x75, 0x84, 0x90, 0xf2, 0xff, 0xf8, 0x39, 0x25,
+	0xc9, 0x61, 0x02, 0x24, 0xfb, 0xd3, 0x56, 0x16,
+	0xcc, 0x00, 0x21, 0x64, 0xb2, 0xd6, 0x7f, 0xce,
+	0xb1, 0xfe, 0x37, 0xc5, 0x67, 0xcc, 0x48, 0xdc,
+	0x50, 0xd9, 0xcf, 0x4f, 0xd1, 0x08, 0x74, 0x9a,
+	0x69, 0x77, 0xbf, 0x64, 0x4a, 0x15, 0x7b, 0x17,
+	0x15, 0x9c, 0x7b, 0xc7, 0x72, 0xfb, 0x95, 0x23,
+	0xf9, 0xcd, 0xe8, 0x60, 0x99, 0x31, 0x3d, 0xe9,
+	0x0a, 0x0c, 0x38, 0xdb, 0x14, 0xac, 0x76, 0x7d,
+	0x23, 0x35, 0xe2, 0x6e, 0x4a, 0x5d, 0x85, 0x60,
+	0xf9, 0x00, 0x27, 0x6b, 0xfb, 0xbd, 0x8e, 0xf5,
+	0x8a, 0x77, 0x55, 0x23, 0xa8, 0x92, 0x0c, 0xb2,
+	0x9e, 0x44, 0x8d, 0xb2, 0xf0, 0x03, 0x30, 0x14,
+	0x38, 0x12, 0x82, 0x83, 0x6f, 0x07, 0xe3, 0x68,
+	0x07, 0x0a, 0xd3, 0x03, 0xc7, 0x61, 0xf8, 0x51,
+	0xd8, 0x4d, 0x74, 0x80, 0xe0, 0x80, 0x32, 0x7e,
+	0xc4, 0xc0, 0x31, 0xb5, 0xc3, 0x61, 0xc9, 0xfc,
+	0x73, 0x4b, 0x7f, 0xe2, 0x52, 0x62, 0x4a, 0x59,
+	0x6c, 0x1d, 0x5c, 0x34, 0x7e, 0x54, 0x85, 0x57,
+	0xa2, 0xfa, 0xd7, 0x82, 0x7a, 0x0a, 0x00, 0x3f,
+	0xca, 0x31, 0xf4, 0x8d, 0x92, 0xbd, 0x89, 0x05,
+	0x08, 0x08, 0xe7, 0x5a, 0x6a, 0x31, 0xb3, 0xd7,
+	0x4e, 0x10, 0x0b, 0xcd, 0x64, 0x90, 0x24, 0x06,
+	0x8a, 0xfb, 0x88, 0x05, 0x05, 0x89, 0x44, 0xcf,
+	0xba, 0x38, 0x5d, 0x4d, 0xf5, 0xe6, 0x52, 0xfd,
+	0xef, 0x3a, 0x57, 0x59, 0x6b, 0x0a, 0x30, 0xba,
+	0x1a, 0x3b, 0x87, 0x7f, 0xcc, 0xab, 0x85, 0x56,
+	0xa6, 0x0e, 0x5b, 0xac, 0x97, 0x9f, 0x7b, 0x51,
+	0xd7, 0xd8, 0x9e, 0xcc, 0xbf, 0xf1, 0xc9, 0xae,
+	0x2b, 0x20, 0x07, 0x96, 0x2b, 0x38, 0x50, 0x45,
+	0x73, 0xd7, 0xc4, 0x3f, 0x82, 0x4a, 0x96, 0x29,
+	0x58, 0xf1, 0xd5, 0xef, 0x91, 0x50, 0x40, 0x68,
+	0x29, 0xdf, 0x35, 0xe8, 0xd0, 0xfe, 0x96, 0xfb,
+	0x1f, 0x9d, 0x91, 0x4a, 0xd5, 0xe2, 0x8f, 0x49,
+	0xb9, 0x54, 0x88, 0x3c, 0x9e, 0x1e, 0x65, 0xf6,
+	0x10, 0x3a, 0xe5, 0xa1, 0x8a, 0x25, 0x09, 0xb3,
+	0x04, 0x3e, 0x9b, 0xd4, 0x3d, 0x31, 0xcf, 0x5c,
+	0xcf, 0x61, 0xa6, 0xa4, 0x43, 0x35, 0xed, 0xfc,
+	0x89, 0x76, 0x38, 0x27, 0x94, 0x9d, 0x1d, 0xa4,
+	0xd7, 0x02, 0x45, 0x62, 0x28, 0x4f, 0x15, 0x2c,
+	0x8d, 0xb1, 0x01, 0xca, 0xe2, 0xd0, 0x26, 0xb1,
+	0x31, 0xcc, 0x56, 0x74, 0x02, 0x43, 0x71, 0x8b,
+	0xb9, 0xa9, 0xb3, 0x4e, 0x47, 0xd0, 0xf2, 0x1e,
+	0xd3, 0x38, 0x80, 0xfb, 0x87, 0x96, 0x27, 0x14,
+	0x47, 0x28, 0xdf, 0x29, 0xf9, 0x05, 0xdb, 0x2a,
+	0xd2, 0x31, 0x9f, 0xd4, 0x74, 0x10, 0x5f, 0x2e,
+	0xb9, 0x12, 0x7c, 0x00, 0xe3, 0x6e, 0x1f, 0xb6,
+	0xa6, 0x9f, 0xb1, 0x2d, 0x35, 0xd8, 0x42, 0x7c,
+	0x01, 0x21, 0xa6, 0xfa, 0x26, 0x81, 0x24, 0xf8,
+	0xb2, 0xc3, 0xcc, 0x26, 0xd3, 0x2c, 0x54, 0x8d,
+	0x3e, 0xd0, 0x8d, 0x21, 0x3f, 0xac, 0xd7, 0xe5,
+	0x4c, 0x88, 0x13, 0x81, 0x61, 0x55, 0xfe, 0x62,
+	0x76, 0xa4, 0x5c, 0x9c, 0x25, 0x80, 0x95, 0xd7,
+	0x44, 0x61, 0xfd, 0x17, 0x8d, 0x52, 0xa4, 0xcc,
+	0x22, 0x32, 0xed, 0x61, 0xde, 0xc5, 0x47, 0x2a,
+	0x4d, 0x5a, 0xac, 0xae, 0xaf, 0xaa, 0x10, 0x25,
+	0x4e, 0x6c, 0xc1, 0x73, 0xed, 0x56, 0x4a, 0x31,
+	0xb8, 0x47, 0x48, 0x45, 0x99, 0xed, 0x11, 0xbc,
+	0x1f, 0xff, 0x1d, 0xfd, 0xc4, 0x64, 0x28, 0x11,
+	0xbe, 0xd4, 0xc0, 0x6d, 0x7e, 0xd0, 0x92, 0xcc,
+	0x3d, 0x54, 0x3f, 0x2a, 0xaa, 0x89, 0x5b, 0x62,
+	0xd0, 0xa3, 0xa8, 0x6a, 0x90, 0xb9, 0x26, 0xaf,
+	0xb8, 0x43, 0xad, 0x7c, 0xa8, 0xd5, 0x8e, 0x66,
+	0xa9, 0x4e, 0xd4, 0x27, 0x1e, 0x66, 0xf3, 0x5b,
+	0xba, 0x32, 0x85, 0x65, 0xbb, 0xe0, 0xc7, 0x8b,
+	0x84, 0x6f, 0xf5, 0x14, 0x29, 0x1b, 0xc4, 0xe1,
+	0x5f, 0x71, 0x5e, 0x07, 0x46, 0xec, 0x6d, 0xef,
+	0x3a, 0x41, 0x16, 0x58, 0xa8, 0x09, 0xb4, 0x62,
+	0x3b, 0x39, 0xc7, 0xf6, 0x1a, 0x8f, 0x81, 0x9e,
+	0xfe, 0x77, 0xb2, 0x27, 0x92, 0x76, 0x09, 0xf1,
+	0xe7, 0x67, 0xf8, 0x2d, 0x53, 0x66, 0x1c, 0x8d,
+	0xa7, 0x32, 0xe5, 0x4f, 0x3b, 0x99, 0xb2, 0x76,
+	0xd3, 0x79, 0x6c, 0xed, 0x08, 0xee, 0x8b, 0x07,
+	0x65, 0x3d, 0x2e, 0xf7, 0xb4, 0x37, 0xe9, 0x9b,
+	0x9e, 0xe1, 0xc9, 0xf1, 0x47, 0xe5, 0x7e, 0xef,
+	0x18, 0x64, 0x3e, 0x53, 0xfd, 0xf0, 0xca, 0xd0,
+	0x6a, 0x36, 0xbd, 0x72, 0x24, 0x48, 0x79, 0x89,
+	0x86, 0xa8, 0x81, 0x3a, 0xdf, 0x6a, 0xd5, 0x7e,
+	0x4b, 0x9e, 0x6f, 0x93, 0x84, 0xee, 0x82, 0x9c,
+	0x52, 0xc0, 0xef, 0x4f, 0xb1, 0xb9, 0x20, 0x1b,
+	0xf0, 0xdd, 0x8d, 0x14, 0x26, 0x07, 0x9e, 0xac,
+	0xaf, 0x1f, 0xe6, 0x8e, 0x89, 0xbb, 0x0c, 0xd4,
+	0x5a, 0x7c, 0x67, 0xde, 0x6a, 0xe9, 0x7a, 0xbc,
+	0xaa, 0x69, 0x0b, 0x5b, 0x23, 0x2b, 0x76, 0x13,
+	0x09, 0x03, 0x27, 0x2f, 0x0a, 0xc5, 0xdb, 0xb9,
+	0xe4, 0xc1, 0x48, 0x6d, 0x7c, 0x54, 0x42, 0xd6,
+	0xd0, 0xa9, 0xb4, 0x3a, 0x93, 0x2e, 0xf6, 0x3d,
+	0x98, 0x02, 0x98, 0xbb, 0x2d, 0x0e, 0xce, 0x36,
+	0x11, 0xf5, 0x65, 0x1c, 0xbb, 0x40, 0xd5, 0x9f,
+	0x01, 0x1d, 0x0d, 0x7e, 0x72, 0x4f, 0x54, 0x42,
+	0xf8, 0x09, 0x7d, 0x8b, 0x37, 0x73, 0xc8, 0xcf,
+	0x75, 0x60, 0x8a, 0xa3, 0x6e, 0x58, 0xd9, 0x80,
+	0x4e, 0x3f, 0x9c, 0x09, 0x7f, 0x71, 0xa8, 0x81,
+	0x8f, 0xb5, 0xff, 0x01, 0x04, 0x53, 0x43, 0xfd,
+	0x5c, 0xc0, 0x88, 0x94, 0x34, 0x51, 0x63, 0xa9,
+	0xb1, 0xee, 0x4c, 0x20, 0x46, 0x26, 0xa0, 0x94,
+	0x65, 0x3c, 0x9d, 0xe4, 0xad, 0x46, 0x65, 0x3c,
+	0xfb, 0x64, 0x3d, 0x00, 0xb8, 0x81, 0xfd, 0x14,
+	0x41, 0x85, 0xa8, 0x75, 0xd6, 0x0c, 0x1f, 0x88,
+	0xfa, 0x6b, 0xa8, 0x40, 0x91, 0x48, 0xd5, 0xf6,
+	0x84, 0x72, 0xdb, 0x31, 0xb8, 0x40, 0x6e, 0xb4,
+	0xa5, 0xab, 0xb4, 0x5d, 0x2c, 0xb1, 0x71, 0x6e,
+	0x36, 0x1a, 0xe3, 0x0d, 0x26, 0x02, 0x95, 0x20,
+	0x6e, 0x3d, 0x60, 0xff, 0x85, 0x35, 0xf6, 0x09,
+	0xa8, 0xd1, 0x3a, 0x60, 0x11, 0xa8, 0x14, 0xb6,
+	0x54, 0xc8, 0x13, 0x80, 0x79, 0x85, 0xee, 0xb0,
+	0x9f, 0xd2, 0xbd, 0xc5, 0xd4, 0x52, 0xe5, 0x42,
+	0x8f, 0x45, 0x42, 0x14, 0x7b, 0x38, 0x1d, 0x23,
+	0x09, 0x57, 0x83, 0x1a, 0x00, 0x98, 0xd1, 0x54,
+	0x60, 0xe4, 0xd4, 0xda, 0x69, 0xc3, 0x8a, 0x08,
+	0x95, 0x47, 0xcd, 0x69, 0x99, 0xb2, 0xac, 0x28,
+	0xf8, 0xee, 0x3c, 0x73, 0x26, 0x59, 0x96, 0x2f,
+	0xb0, 0x19, 0x49, 0xb0, 0xb1, 0x1a, 0x04, 0x12,
+	0xff, 0xd9, 0xec, 0x68, 0x9c, 0x76, 0x71, 0x31,
+	0xbd, 0x3e, 0x9a, 0x56, 0xf1, 0x46, 0x7e, 0xe9,
+	0x34, 0xba, 0x5c, 0x5a, 0x13, 0xf2, 0x89, 0xc3,
+	0x0b, 0xd3, 0x74, 0xbd, 0xed, 0x78, 0xcf, 0xec,
+	0x51, 0xbb, 0x55, 0xed, 0x31, 0xc6, 0x1e, 0xee,
+	0x04, 0xb9, 0x44, 0xf5, 0xff, 0xc2, 0xde, 0x34,
+	0x7c, 0x3a, 0x8e, 0x8f, 0x2c, 0x18, 0x52, 0x38,
+	0xeb, 0xc6, 0xf5, 0xd8, 0x3f, 0xc4, 0xc5, 0x90,
+	0x7f, 0x1a, 0x7e, 0xb0, 0xe0, 0x9c, 0x9e, 0xe4,
+	0x55, 0xe2, 0xda, 0x55, 0xa4, 0xb8, 0x89, 0x20,
+	0xf3, 0x17, 0xaf, 0x1f, 0x2f, 0x01, 0x57, 0x1a,
+	0xc8, 0x4c, 0xf3, 0x07, 0x10, 0xb8, 0x97, 0x8f,
+	0xd2, 0x15, 0x3f, 0xb2, 0xb2, 0xdd, 0x96, 0x07,
+	0xbf, 0x70, 0x5c, 0x63, 0x29, 0xe5, 0x83, 0x1c,
+	0xfd, 0x32, 0x3b, 0x2c, 0x34, 0x93, 0x47, 0xfc,
+	0xdf, 0x3a, 0x03, 0xf0, 0xf2, 0x9a, 0x7f, 0xc4,
+	0xb0, 0xbf, 0x76, 0x62, 0x9c, 0x0c, 0x69, 0x5c,
+	0x7d, 0xc6, 0xbf, 0xa6, 0xab, 0x43, 0xc2, 0xa8,
+	0x75, 0xfd, 0xd5, 0xa9, 0x90, 0x1c, 0xa5, 0x70,
+	0x56, 0xa8, 0x60, 0x48, 0x43, 0xdf, 0x0c, 0xf3,
+	0x9e, 0x82, 0x55, 0x3b, 0x8e, 0xbe, 0x97, 0x0b,
+	0x84, 0x56, 0xb1, 0x30, 0x99, 0x73, 0xd8, 0x0f,
+	0x71, 0xad, 0xb8, 0x01, 0xc9, 0x5e, 0x71, 0x1f,
+	0x06, 0xd1, 0x67, 0x49, 0xb1, 0x73, 0x3c, 0x4f,
+	0xf5, 0x91, 0x8a, 0x84, 0x50, 0x21, 0x8f, 0xd4,
+	0x78, 0x41, 0x04, 0x11, 0xb4, 0xdd, 0x20, 0x25,
+	0x8a, 0xd9, 0x27, 0x54, 0x37, 0x98, 0x73, 0x3d,
+	0x6a, 0xdb, 0x87, 0x1b, 0x4e, 0xc3, 0x6a, 0x44,
+	0x55, 0xf5, 0xc8, 0xa5, 0x16, 0x57, 0x79, 0x8e,
+	0x98, 0x7e, 0xa0, 0x4d, 0x5b, 0xc0, 0x72, 0xe5,
+	0x99, 0x99, 0x39, 0xd0, 0x32, 0xad, 0x0e, 0x9c,
+	0x88, 0x95, 0xb7, 0xd6, 0x58, 0x21, 0x1a, 0xad,
+	0x16, 0xe2, 0x52, 0x2d, 0x3a, 0xcc, 0xbb, 0xd2,
+	0x4a, 0x5b, 0x1f, 0xa5, 0x1c, 0x92, 0x8a, 0xb5,
+	0x2b, 0xc4, 0x86, 0x5d, 0x71, 0x94, 0xf9, 0xf9,
+	0x29, 0xb0, 0xcf, 0x81, 0xd2, 0xea, 0x2f, 0xe8,
+	0xcc, 0x81, 0x15, 0x06, 0x4d, 0xd1, 0xd9, 0x97,
+	0x2c, 0xf8, 0x3c, 0x48, 0x8a, 0xc7, 0xfe, 0xb6,
+	0x8b, 0x84, 0x13, 0xfc, 0x18, 0x0d, 0xf5, 0x41,
+	0xbd, 0xc4, 0xc2, 0x8f, 0xae, 0xf1, 0x78, 0x7b,
+	0x73, 0x8d, 0x81, 0xc0, 0x5e, 0x5a, 0x58, 0x8b,
+	0x53, 0x94, 0xd3, 0xdd, 0x5b, 0xd1, 0x93, 0xe6,
+	0x55, 0xa7, 0xe2, 0x6d, 0xb4, 0xd7, 0xae, 0x71,
+	0x9c, 0x71, 0x01, 0x4a, 0x62, 0x79, 0xc5, 0xd5,
+	0x06, 0x47, 0x96, 0x65, 0xa1, 0xee, 0xf0, 0xf4,
+	0x82, 0xc3, 0xd2, 0xde, 0x95, 0x65, 0xc4, 0xea,
+	0x0c, 0xa7, 0x58, 0xc0, 0x7e, 0x06, 0x32, 0x1a,
+	0x77, 0x33, 0x65, 0xda, 0xac, 0x2a, 0xaf, 0xb2,
+	0x71, 0x45, 0x17, 0x13, 0x33, 0x07, 0x07, 0xb6,
+	0xcb, 0xd9, 0x94, 0x60, 0x3f, 0x58, 0x4a, 0x4b,
+	0xff, 0xa2, 0x0c, 0x7e, 0xa9, 0x3e, 0x98, 0x20,
+	0x71, 0xfd, 0xfa, 0x1d, 0x28, 0xaa, 0xcf, 0x99,
+	0xef, 0xe7, 0xac, 0x23, 0xee, 0xb4, 0xd9, 0xb9,
+	0x8d, 0x6d, 0x19, 0xcc, 0xc5, 0x64, 0x18, 0xc5,
+	0x06, 0x24, 0x43, 0xaf, 0x62, 0xdb, 0xd0, 0xd3,
+	0xd9, 0xca, 0xf0, 0x01, 0x74, 0xbf, 0x9a, 0x64,
+	0xa6, 0x47, 0x87, 0x95, 0xfb, 0x60, 0x4e, 0x88,
+	0xcd, 0x68, 0x55, 0x92, 0xcc, 0x6d, 0x57, 0xd2,
+	0x91, 0x9a, 0x82, 0xf3, 0x76, 0x52, 0xc6, 0x4f,
+	0x1c, 0xb6, 0x50, 0x91, 0x75, 0xea, 0xf5, 0x1c,
+	0x31, 0x7c, 0xb1, 0x2c, 0xdc, 0xff, 0xb5, 0xa9,
+	0x67, 0x0a, 0x3b, 0x33, 0x77, 0x93, 0x06, 0x08,
+	0x2d, 0x88, 0xfb, 0xa3, 0xda, 0xc1, 0xf2, 0xf6,
+	0x77, 0x42, 0x87, 0xec, 0x2d, 0x7c, 0x08, 0x5e,
+	0xf8, 0xb9, 0x8b, 0xd4, 0xb9, 0x40, 0x7d, 0x20,
+	0x4a, 0xb9, 0x54, 0xc1, 0x4c, 0x5a, 0xc9, 0x79,
+	0xe2, 0xc4, 0x1d, 0xbc, 0x85, 0x0f, 0xb2, 0xfc,
+	0x52, 0x3a, 0xe8, 0x7f, 0xb6, 0xf1, 0xdd, 0xaf,
+	0xaa, 0x68, 0x83, 0x63, 0xa8, 0x01, 0x84, 0xf2,
+	0xba, 0xd8, 0xb3, 0x06, 0x32, 0x7c, 0x7f, 0x14,
+	0x40, 0x9c, 0xd0, 0xc5, 0xac, 0x82, 0xc1, 0xfe,
+	0xbc, 0xaa, 0x7d, 0x73, 0x9b, 0x5a, 0x22, 0x45,
+	0xc3, 0xa5, 0xa9, 0x6b, 0xa6, 0x2d, 0x5e, 0x60,
+	0x05, 0x11, 0x66, 0x37, 0x8e, 0xe6, 0x4b, 0xce,
+	0x82, 0x1b, 0x94, 0x2e, 0x9d, 0x55, 0x2c, 0x5a,
+	0xff, 0xa9, 0xcd, 0x9a, 0x04, 0xef, 0xe0, 0xc7,
+	0x94, 0x89, 0x32, 0x3b, 0xb6, 0x90, 0x9b, 0xbb,
+	0xa2, 0x02, 0xf2, 0x30, 0xe8, 0x3d, 0xfe, 0x6a,
+	0x58, 0x92, 0x99, 0xf5, 0xe8, 0xc5, 0x4f, 0xe7,
+	0x6f, 0x1c, 0x82, 0x73, 0x0b, 0x62, 0x3a, 0xa0,
+	0xeb, 0x6c, 0xdb, 0xa1, 0xfd, 0x76, 0x5c, 0x9f,
+	0x78, 0x4e, 0xcf, 0x60, 0x8b, 0xcd, 0xcb, 0xe3,
+	0x60, 0x64, 0xd8, 0x48, 0x29, 0x28, 0x2f, 0x98,
+	0x44, 0xb1, 0x0b, 0x50, 0x13, 0x45, 0xf0, 0xfe,
+	0xb2, 0xcb, 0x9f, 0xaf, 0x41, 0xfb, 0x4e, 0xba,
+	0x49, 0x1d, 0x1a, 0xd4, 0xea, 0xe5, 0xb7, 0x4a,
+	0x49, 0x90, 0x92, 0x73, 0xb8, 0xc2, 0x0b, 0xfc,
+	0x73, 0x17, 0x4c, 0x87, 0x5c, 0x3c, 0x85, 0x0e,
+	0x07, 0x25, 0xbd, 0x49, 0x20, 0x0b, 0x03, 0x6a,
+	0x28, 0x1d, 0x3e, 0x13, 0x03, 0xf6, 0x5d, 0x4c,
+	0x86, 0xf0, 0xbf, 0x3e, 0xb2, 0xcb, 0x3a, 0x25,
+	0xe2, 0x87, 0xac, 0x3e, 0xc3, 0x32, 0x4d, 0xcb,
+	0x57, 0x0a, 0x14, 0x77, 0x16, 0x17, 0xe1, 0x3e,
+	0x34, 0x20, 0x51, 0x37, 0x16, 0xaf, 0x84, 0x9c,
+	0x9f, 0x43, 0xda, 0x51, 0x0e, 0x14, 0x76, 0xf0,
+	0x9b, 0x23, 0x2f, 0x5f, 0x55, 0x7c, 0x2a, 0xac,
+	0x86, 0x3e, 0x23, 0x9c, 0x55, 0x05, 0xdb, 0x89,
+	0x25, 0x2c, 0xc1, 0x3b, 0xdb, 0x45, 0xd7, 0x7a,
+	0x88, 0xb1, 0xcb, 0x97, 0xc5, 0x42, 0x87, 0x61,
+	0x65, 0xb6, 0xc0, 0xba, 0x32, 0xea, 0x66, 0xb9,
+	0x28, 0x89, 0x55, 0x7d, 0x8e, 0x30, 0x06, 0xb3,
+	0x5d, 0xc7, 0xee, 0x38, 0x0c, 0xc5, 0xb3, 0x95,
+	0x76, 0x7e, 0x2c, 0x3c, 0xc0, 0xb3, 0x9d, 0x25,
+	0x6a, 0x5d, 0xdf, 0x9c, 0x47, 0x45, 0x55, 0x6f,
+	0xcf, 0xab, 0xec, 0x5d, 0xdb, 0xf2, 0x11, 0x38,
+	0xba, 0xff, 0x71, 0xc6, 0xc5, 0x24, 0x5b, 0x3b,
+	0xa2, 0x87, 0x77, 0x63, 0x3b, 0x14, 0x88, 0xa5,
+	0x71, 0x68, 0x41, 0xb8, 0xad, 0x97, 0x27, 0x7c,
+	0x42, 0x13, 0xda, 0x1d, 0x06, 0xeb, 0x56, 0xc0,
+	0xea, 0xc7, 0x86, 0xaf, 0xeb, 0xe2, 0xeb, 0x8d,
+	0x69, 0x62, 0xf0, 0xa4, 0x77, 0x79, 0x49, 0xe8,
+	0xe1, 0x8b, 0xa1, 0x8e, 0x22, 0xc8, 0x0b, 0x64,
+	0xdc, 0xe5, 0x81, 0xe2, 0xd0, 0xd7, 0xa2, 0xba,
+	0x9e, 0x28, 0x6a, 0x89, 0x0a, 0x55, 0x17, 0x74,
+	0xb7, 0x07, 0x18, 0x2e, 0x80, 0x62, 0x17, 0x61,
+	0xed, 0xb8, 0xf0, 0x0f, 0x80, 0xfb, 0x73, 0x5c,
+	0xe0, 0xf4, 0x3e, 0xb0, 0xcc, 0xe0, 0x6a, 0x6a,
+	0x09, 0xd4, 0xf4, 0x13, 0x29, 0x0b, 0x87, 0xe1,
+	0x12, 0xa0, 0x0f, 0x93, 0x02, 0x26, 0xf4, 0xef,
+	0xde, 0xe4, 0xfe, 0x5f, 0xdf, 0x71, 0xbb, 0xbf,
+	0x65, 0xfa, 0x6f, 0x31, 0xda, 0xda, 0x9c, 0xe3,
+	0xae, 0x90, 0xf7, 0xd8, 0x9b, 0x7e, 0xb9, 0xad,
+	0x1e, 0xc8, 0x40, 0x20, 0xef, 0x35, 0x0f, 0xcd,
+	0x19, 0x0d, 0x2c, 0xf9, 0x7e, 0xe8, 0xb8, 0xe4,
+	0xe2, 0x28, 0x15, 0xbc, 0x02, 0xb1, 0xa0, 0xb0,
+	0x41, 0x97, 0x88, 0xdc, 0x15, 0x41, 0x8a, 0x34,
+	0x0a, 0xca, 0x54, 0xf9, 0xff, 0x64, 0xc6, 0x19,
+	0x71, 0xf3, 0x12, 0xf0, 0xdb, 0xca, 0xd4, 0xbd,
+	0xf2, 0xe9, 0x79, 0xf4, 0x9b, 0x19, 0xa5, 0xdc,
+	0xb0, 0x2d, 0xb9, 0xc6, 0x6f, 0x43, 0xfa, 0x79,
+	0x0d, 0x4e, 0x72, 0x0d, 0xb2, 0x38, 0x26, 0x24,
+	0x2b, 0x38, 0x14, 0x06, 0x02, 0xe8, 0xc3, 0xf5,
+	0xd1, 0x3d, 0xe9, 0x6c, 0x56, 0x8e, 0x49, 0x07,
+	0xbc, 0x02, 0xcd, 0x2b, 0x45, 0xc7, 0xa4, 0x52,
+	0x15, 0x16, 0x5f, 0xc8, 0x4e, 0x85, 0xec, 0x7a,
+	0xbd, 0x00, 0x80, 0xc0, 0xe8, 0x44, 0xb5, 0xb9,
+	0x81, 0x9e, 0x26, 0xd7, 0x2d, 0x6f, 0xde, 0xe9,
+	0x71, 0xab, 0x14, 0xb6, 0x72, 0xb8, 0x08, 0x88,
+	0xce, 0x68, 0x50, 0x1c, 0xed, 0x3c, 0x96, 0xab,
+	0x3c, 0x17, 0x6b, 0x24, 0x5b, 0x20, 0xdd, 0xdc,
+	0xbe, 0x03, 0xb3, 0xeb, 0x72, 0x92, 0xd4, 0xe3,
+	0x3d, 0xe8, 0x99, 0xb0, 0xa0, 0xa2, 0x38, 0x6e,
+	0x0a, 0x88, 0x8b, 0xf7, 0xc4, 0x21, 0xa2, 0x00,
+	0x38, 0x0d, 0x24, 0x93, 0x2d, 0x01, 0x6f, 0xec,
+	0x05, 0x23, 0xd7, 0x77, 0xb5, 0xac, 0x5b, 0xf2,
+	0x94, 0xf4, 0xa2, 0x35, 0x96, 0xda, 0xa3, 0xa0,
+	0x62, 0x2e, 0x98, 0x26, 0x50, 0x3a, 0x26, 0x88,
+	0x48, 0x4a, 0x1c, 0x75, 0x4c, 0x8b, 0x61, 0x51,
+	0xae, 0x39, 0xc8, 0x63, 0xe5, 0x23, 0x56, 0x79,
+	0x18, 0xf8, 0xae, 0xae, 0xd3, 0x52, 0x4f, 0x35,
+	0x80, 0xe7, 0x5c, 0xd0, 0x21, 0x82, 0x59, 0x69,
+	0xcd, 0x75, 0xdf, 0x19, 0x00, 0x40, 0x6a, 0xaf,
+	0x79, 0x32, 0x12, 0x5e, 0x56, 0x68, 0xd8, 0x6e,
+	0x61, 0x86, 0x1c, 0x34, 0xd8, 0x6b, 0x69, 0x59,
+	0x52, 0xc5, 0x29, 0x74, 0x48, 0x82, 0xdd, 0x15,
+	0xf7, 0xbc, 0x2e, 0xf8, 0xfd, 0x98, 0xa7, 0x76,
+	0xca, 0xb9, 0xd5, 0x20, 0x22, 0xad, 0x8e, 0x83,
+	0x33, 0xab, 0xb7, 0x0c, 0x16, 0x20, 0x65, 0x69,
+	0xe6, 0x8e, 0xdd, 0x2e, 0x11, 0xba, 0x43, 0x08,
+	0x77, 0x71, 0x00, 0x74, 0x09, 0xa7, 0xea, 0xd3,
+	0x61, 0xbf, 0xf4, 0x83, 0x6c, 0x82, 0x06, 0xa0,
+	0x2d, 0xbd, 0xac, 0x44, 0xdd, 0x11, 0xad, 0xc3,
+	0x9f, 0x8a, 0xf1, 0xb0, 0x44, 0x34, 0xb9, 0xbb,
+	0xa5, 0xb9, 0x2f, 0xae, 0x61, 0x1a, 0x82, 0xc2,
+	0xd9, 0x76, 0x45, 0x46, 0xf8, 0x4b, 0xe6, 0x26,
+	0x08, 0x92, 0x6a, 0xe5, 0xa3, 0x17, 0xa9, 0x42,
+	0xa1, 0x9a, 0xf3, 0xe5, 0xcf, 0xac, 0xa1, 0x74,
+	0x65, 0xd0, 0x23, 0xc6, 0xea, 0xa5, 0x88, 0xc4,
+	0x1b, 0xcd, 0x0a, 0x13, 0x18, 0xf0, 0x39, 0x20,
+	0x82, 0xa3, 0x06, 0x25, 0xba, 0xaf, 0x67, 0x5b,
+	0x49, 0x5a, 0x41, 0x18, 0x06, 0xe2, 0x8d, 0x6c,
+	0xb2, 0xb0, 0x32, 0x9d, 0x55, 0xbb, 0x61, 0x70,
+	0x88, 0x6b, 0x83, 0xa1, 0x5b, 0xbd, 0xc1, 0xdd,
+	0x60, 0xc7, 0x02, 0x1b, 0x76, 0x69, 0x76, 0xc0,
+	0xc4, 0xb7, 0xd8, 0xca, 0x99, 0x65, 0x36, 0x4c,
+	0x15, 0x69, 0xe9, 0x6a, 0x24, 0x4a, 0xda, 0xac,
+	0xb5, 0x5e, 0x4d, 0x10, 0x1b, 0x0f, 0xed, 0x7b,
+	0xd6, 0xef, 0x96, 0x4d, 0x58, 0x0d, 0x0d, 0x1c,
+	0xc4, 0xe5, 0xe7, 0x5e, 0x4b, 0x1d, 0xaa, 0x60,
+	0x86, 0x93, 0xcb, 0xaa, 0xdd, 0xa5, 0x57, 0x92,
+	0x03, 0xa4, 0xa2, 0x1e, 0xb3, 0x8f, 0x9a, 0x8a,
+	0x7e, 0x30, 0xd7, 0xd6, 0x3d, 0xe4, 0xf3, 0x02,
+	0xc9, 0xda, 0x60, 0x14, 0xf7, 0x0a, 0x75, 0x7e,
+	0x9d, 0x40, 0x28, 0x7a, 0xe5, 0x7f, 0x0c, 0xe9,
+	0x24, 0xae, 0x07, 0xd7, 0x3d, 0xa1, 0x61, 0xbb,
+	0xd2, 0x38, 0x91, 0x0f, 0x1c, 0x84, 0x11, 0xe6,
+	0x5e, 0x71, 0xfa, 0x56, 0x7b, 0x6f, 0xd4, 0x18,
+	0xaf, 0xfc, 0x92, 0x95, 0x7c, 0x9e, 0x7e, 0xa0,
+	0x4c, 0x85, 0x77, 0x89, 0x27, 0xd9, 0x44, 0xf9,
+	0x11, 0xd6, 0x08, 0x2e, 0x5a, 0x1a, 0x14, 0xb9,
+	0x8b, 0x0e, 0x0f, 0x07, 0x7e, 0xe3, 0x1f, 0x2d,
+	0xdf, 0xb2, 0xc2, 0x5b, 0x50, 0x40, 0xfb, 0x9d,
+	0xc6, 0x73, 0x26, 0xed, 0x4c, 0x6b, 0xe6, 0x5d,
+	0x41, 0xee, 0x8b, 0x9b, 0x08, 0x9f, 0x54, 0x94,
+	0xae, 0x63, 0x9b, 0x2c, 0x46, 0xba, 0x59, 0x26,
+	0x6c, 0x1c, 0x81, 0xbd, 0x5c, 0x7d, 0x5a, 0x22,
+	0xf0, 0x80, 0x0f, 0x3c, 0xeb, 0xf5, 0x99, 0x2c,
+	0xe4, 0x25, 0xc8, 0xec, 0xc4, 0x1c, 0x80, 0x72,
+	0x80, 0x1b, 0x9e, 0xc6, 0xd6, 0xf8, 0xec, 0x42,
+	0x14, 0x6e, 0xff, 0x70, 0xeb, 0x59, 0x93, 0xdb,
+	0xda, 0xa2, 0x17, 0xc5, 0x98, 0xb0, 0xf2, 0x7c,
+	0xd5, 0xba, 0x68, 0x9a, 0xd6, 0xe9, 0x0c, 0x56,
+	0x04, 0xab, 0x1d, 0xda, 0xa3, 0x09, 0x1d, 0xb7,
+	0x77, 0x1c, 0x27, 0x62, 0x76, 0xba, 0x3d, 0x50,
+	0x5d, 0x54, 0x15, 0xf5, 0x05, 0x07, 0x71, 0xda,
+	0xc1, 0xd9, 0x74, 0x98, 0xc2, 0x81, 0xee, 0xc7,
+	0x2c, 0x0b, 0xa1, 0xcf, 0x15, 0xbe, 0x86, 0x8c,
+	0xdb, 0xad, 0xef, 0x51, 0x68, 0x2c, 0xa1, 0xc5,
+	0x81, 0xb6, 0xba, 0x86, 0xbe, 0x2b, 0x60, 0x7f,
+	0x04, 0xd5, 0x17, 0xc7, 0x56, 0x06, 0x8e, 0x82,
+	0x11, 0x2f, 0x51, 0x26, 0xee, 0xd7, 0xb3, 0xc9,
+	0x84, 0xa2, 0x1a, 0xec, 0xce, 0xbb, 0xb1, 0x4f,
+	0x71, 0x6b, 0xd5, 0x2f, 0x96, 0x36, 0xaf, 0x9b,
+	0x0b, 0xc6, 0x62, 0x61, 0xcc, 0xf0, 0xe3, 0xde,
+	0x1f, 0x34, 0x04, 0x0d, 0x0b, 0xb7, 0xd6, 0x8f,
+	0x59, 0xf0, 0x7c, 0x28, 0xab, 0x2d, 0x77, 0x1d,
+	0x99, 0x4d, 0x4c, 0x2f, 0x83, 0xfb, 0xca, 0x8e,
+	0xc2, 0x2c, 0xef, 0x8e, 0x1c, 0xd2, 0x6c, 0x3c,
+	0x06, 0x71, 0x49, 0x11, 0x28, 0x20, 0xa0, 0x82,
+	0x10, 0x1c, 0xaa, 0xbc, 0x4a, 0x21, 0xd9, 0xe3,
+	0x6e, 0x25, 0x12, 0xf1, 0x21, 0xdd, 0x7f, 0xe3,
+	0x09, 0x6e, 0x71, 0x26, 0x40, 0xde, 0x62, 0x46,
+	0x4f, 0xab, 0x57, 0x77, 0xcb, 0xf8, 0xf9, 0xdc,
+	0x14, 0xa3, 0x98, 0x5e, 0xc5, 0x71, 0x41, 0x33,
+	0x96, 0x54, 0x25, 0xb7, 0x31, 0xa4, 0x9a, 0x3a,
+	0x13, 0x0c, 0x60, 0x53, 0xea, 0xc2, 0x9a, 0x39,
+	0x6e, 0xf1, 0xb0, 0x39, 0xe9, 0xaa, 0x15, 0xfe,
+	0x4d, 0xad, 0x5c, 0x12, 0x1e, 0x9e, 0x46, 0xb5,
+	0xf2, 0x6b, 0x6c, 0x23, 0x0f, 0x07, 0x5d, 0x22,
+	0x13, 0xbe, 0x76, 0xfd, 0x80, 0x10, 0x36, 0xee,
+	0x01, 0xe6, 0x28, 0xeb, 0x90, 0x3d, 0xe9, 0xde,
+	0xeb, 0x45, 0xf0, 0x09, 0xe3, 0x36, 0xbe, 0xd5,
+	0xa1, 0x2b, 0xf8, 0xb1, 0x32, 0x56, 0xd3, 0x45,
+	0x14, 0x49, 0x42, 0x94, 0x59, 0x78, 0x83, 0x5b,
+	0x5e, 0xab, 0x46, 0xef, 0xe8, 0x2f, 0xcd, 0xd3,
+	0x74, 0xbd, 0xdd, 0x58, 0xf4, 0x9b, 0x2d, 0x95,
+	0xc6, 0x26, 0x46, 0xf8, 0x7c, 0x1a, 0x3d, 0x90,
+	0x63, 0x7f, 0x24, 0xbd, 0xf7, 0xa7, 0x18, 0x56,
+	0x52, 0x5e, 0x45, 0x3b, 0x8d, 0x12, 0x0e, 0x01,
+	0xcf, 0xeb, 0x59, 0xc3, 0x87, 0x87, 0x59, 0x4d,
+	0xad, 0x9f, 0x46, 0x29, 0xb9, 0x83, 0xb9, 0x1d,
+	0x03, 0xdd, 0xda, 0xfa, 0x85, 0xf2, 0x50, 0xd7,
+	0x50, 0x95, 0x12, 0xdd, 0xa7, 0x21, 0xde, 0x77,
+	0x0c, 0x38, 0x3a, 0x93, 0xbf, 0x93, 0xe1, 0x6c,
+	0x33, 0x27, 0x95, 0xec, 0xaa, 0x4e, 0x09, 0xad,
+	0x2b, 0xe3, 0xa8, 0xb0, 0xd5, 0xf8, 0x88, 0x25,
+	0x8e, 0x9a, 0x02, 0x35, 0xbb, 0xe1, 0xac, 0xc8,
+	0x19, 0xe7, 0x5b, 0xd8, 0x7a, 0x3c, 0x44, 0xad,
+	0x63, 0xd9, 0x9a, 0x0e, 0x27, 0xa3, 0xbb, 0x52,
+	0x87, 0x63, 0x03, 0x5c, 0x5c, 0x8b, 0x82, 0xea,
+	0x25, 0x84, 0x1f, 0xe1, 0x65, 0xcc, 0xa9, 0x7e,
+	0xb3, 0x04, 0x56, 0x2d, 0x41, 0x9a, 0xdb, 0xa4,
+	0x73, 0x75, 0xb2, 0x9a, 0x18, 0x6e, 0xed, 0x9f,
+	0xd1, 0xf0, 0xfc, 0x2d, 0x7b, 0x7e, 0x17, 0xa0,
+	0x02, 0x37, 0x81, 0x68, 0x03, 0x2a, 0xe6, 0xb6,
+	0x2f, 0x3d, 0xe3, 0x70, 0xd7, 0xbe, 0x14, 0x4b,
+	0x33, 0xc7, 0xe5, 0x4c, 0x35, 0xd2, 0xeb, 0x06,
+	0xc2, 0xe7, 0x34, 0x3d, 0x65, 0x4b, 0xde, 0x68,
+	0x82, 0x5f, 0xd0, 0x85, 0x8a, 0xb6, 0x3b, 0xb9,
+	0xf3, 0x1f, 0x29, 0xcb, 0xdd, 0x3d, 0x16, 0x11,
+	0x04, 0xfb, 0x5d, 0x39, 0xce, 0x48, 0x40, 0x90,
+	0x30, 0x74, 0xce, 0x95, 0xbf, 0xac, 0xfd, 0x42,
+	0x0b, 0xcd, 0xc7, 0x95, 0x84, 0x03, 0x4e, 0x77,
+	0x22, 0x77, 0x42, 0xff, 0xb5, 0x58, 0x10, 0xb9,
+	0x54, 0x6d, 0xf3, 0x22, 0xb6, 0x33, 0xb2, 0xe6,
+	0xa7, 0x80, 0x7b, 0x66, 0x2c, 0x79, 0xa8, 0x38,
+	0x46, 0x70, 0xcd, 0xca, 0x73, 0x1c, 0x42, 0x95,
+	0x93, 0x84, 0x94, 0x48, 0xdd, 0xa5, 0x02, 0x31,
+	0x12, 0xf5, 0x53, 0xc8, 0x28, 0x05, 0xae, 0xcf,
+	0x86, 0x2a, 0x35, 0xb2, 0xa3, 0xde, 0xea, 0xe9,
+	0x4e, 0xb8, 0xb4, 0xc1, 0xd4, 0xf6, 0x56, 0x67,
+	0x7a, 0xea, 0xb0, 0x57, 0x8f, 0xb2, 0x88, 0xa2,
+	0xa7, 0xdb, 0x6a, 0xcf, 0xe1, 0x19, 0x9e, 0x67,
+	0x43, 0xd3, 0x19, 0xe6, 0xb1, 0x04, 0xcf, 0xff,
+	0xbc, 0x83, 0xc0, 0x90, 0x79, 0x16, 0xf7, 0xf4,
+	0x01, 0xa7, 0x4b, 0x90, 0x59, 0xd4, 0x32, 0x00,
+	0xaf, 0x9d, 0xcf, 0x90, 0xb6, 0x6d, 0xf7, 0xf9,
+	0x41, 0x11, 0xdf, 0xf2, 0x15, 0xae, 0xf2, 0xd1,
+	0x32, 0xb2, 0x61, 0xab, 0xc9, 0x58, 0x9f, 0xca,
+	0x00, 0xeb, 0x5a, 0x59, 0xbf, 0x8d, 0x5a, 0x6e,
+	0x2a, 0x29, 0xff, 0xe0, 0x97, 0xf6, 0xd9, 0xd8,
+	0x07, 0xb8, 0xca, 0x1c, 0x66, 0xbc, 0xed, 0x98,
+	0x6f, 0x4e, 0x44, 0x38, 0xa7, 0xe3, 0x02, 0xa7,
+	0xce, 0x5c, 0x00, 0x8d, 0xe9, 0x5a, 0xfc, 0x13,
+	0x84, 0xfb, 0xf3, 0x1b, 0xf1, 0xcc, 0xf3, 0xf9,
+	0x84, 0xbd, 0x15, 0xeb, 0x7a, 0x03, 0x83, 0xe9,
+	0x51, 0xc7, 0x21, 0xf8, 0xab, 0x23, 0x9f, 0x79,
+	0x7f, 0xa0, 0x07, 0x69, 0xfa, 0x03, 0x7c, 0x7e,
+	0xfe, 0x70, 0x99, 0xef, 0x3c, 0x8c, 0xe8, 0xc1,
+	0x4a, 0xfe, 0xac, 0xc4, 0x01, 0x2f, 0xad, 0x52,
+	0xf7, 0xce, 0x4b, 0xa2, 0xf1, 0xea, 0x1b, 0x70,
+	0x8a, 0x22, 0xd9, 0x85, 0x25, 0x56, 0x03, 0x23,
+	0xc6, 0x9d, 0x13, 0x02, 0x29, 0xfb, 0xc3, 0x73,
+	0xf9, 0x6f, 0x37, 0xfa, 0x9f, 0xe4, 0x4d, 0x96,
+	0xb2, 0x98, 0x38, 0xa3, 0x82, 0x53, 0x14, 0x0d,
+	0x76, 0xed, 0x92, 0x9b, 0x43, 0x95, 0xbf, 0x09,
+	0x32, 0xd2, 0x0c, 0x5c, 0xcd, 0xcf, 0xcf, 0xc7,
+	0x3f, 0x07, 0xc1, 0xde, 0xeb, 0x0e, 0x74, 0x9e,
+	0xa6, 0xac, 0x41, 0x29, 0xff, 0x55, 0x36, 0x75,
+	0x43, 0xc8, 0x11, 0x86, 0x5d, 0xd0, 0x90, 0x90,
+	0xa2, 0x9c, 0xec, 0x6f, 0x6b, 0xbb, 0x36, 0xaa,
+	0xc2, 0xf8, 0x88, 0xae, 0x06, 0xfc, 0x4c, 0xad,
+	0xa8, 0x8d, 0xd6, 0xa8, 0xe3, 0x0c, 0x1d, 0x26,
+	0xd4, 0x2e, 0xac, 0x31, 0xfe, 0x3c, 0xc1, 0xa0,
+	0xd8, 0xad, 0x10, 0x44, 0x69, 0x46, 0xee, 0x2b,
+	0x3e, 0x77, 0xd9, 0x45, 0x73, 0x25, 0xf2, 0x1c,
+	0xb3, 0xc8, 0xc4, 0x96, 0xd4, 0xe1, 0xbc, 0xa8,
+	0x10, 0x68, 0xd9, 0x0e, 0xa5, 0x9b, 0xaf, 0x7d,
+	0x48, 0xbf, 0xc1, 0xb1, 0x05, 0xb0, 0xdd, 0x44,
+	0x27, 0xb6, 0x89, 0x9a, 0xdc, 0x7b, 0xb6, 0x8f,
+	0x43, 0x7a, 0x25, 0x17, 0x5c, 0xe1, 0xbf, 0x6c,
+	0x49, 0x98, 0x7a, 0xee, 0x33, 0x29, 0x6c, 0x7c,
+	0xe8, 0x2d, 0x2d, 0xee, 0xdd, 0x0a, 0x32, 0x04,
+	0xc1, 0xbb, 0x9f, 0x9d, 0x36, 0x55, 0x2c, 0x79,
+	0xd0, 0x51, 0x90, 0x2c, 0x32, 0x4f, 0x98, 0x7b,
+	0xe7, 0x12, 0x6a, 0x1b, 0x3c, 0xd6, 0x97, 0x24,
+	0x03, 0xc4, 0x12, 0xe1, 0xcf, 0x44, 0xe5, 0x90,
+	0xff, 0x84, 0x2d, 0x35, 0xda, 0x59, 0xae, 0xaa,
+	0xaa, 0x3e, 0xd6, 0xdc, 0x8d, 0x6e, 0x57, 0x75,
+	0x80, 0xc1, 0x90, 0xbc, 0x97, 0x27, 0xe1, 0x9b,
+	0xeb, 0xf3, 0x7c, 0xba, 0x38, 0x61, 0x4a, 0x37,
+	0xe6, 0x77, 0x6d, 0xc0, 0xd0, 0x1b, 0x6a, 0x7a,
+	0x5a, 0x40, 0x56, 0xe7, 0xae, 0xae, 0x5c, 0x2e,
+	0x6f, 0xec, 0xeb, 0x07, 0x13, 0xcc, 0xa2, 0xff,
+	0xbf, 0x1e, 0xb9, 0xf7, 0x7f, 0x04, 0x2f, 0x65,
+	0x7b, 0x9c, 0x25, 0x4c, 0xb7, 0x8f, 0xc6, 0x11,
+	0xcf, 0x1d, 0xf9, 0x7d, 0xcb, 0x55, 0xac, 0x3a,
+	0x42, 0x97, 0x41, 0x55, 0x63, 0xe3, 0x54, 0x22,
+	0x01, 0x0e, 0x1a, 0x81, 0x12, 0x49, 0xe6, 0x8d,
+	0xe5, 0x0c, 0xd9, 0x9c, 0x9b, 0xa0, 0xae, 0x6b,
+	0xbd, 0xa7, 0xe8, 0x88, 0xfc, 0x94, 0xc2, 0x3e,
+	0x2b, 0x04, 0x94, 0x8e, 0xe7, 0xe8, 0xb1, 0xe9,
+	0xf6, 0xcb, 0x6a, 0x08, 0x14, 0x50, 0x96, 0xf9,
+	0x5c, 0x6f, 0x95, 0xf8, 0x0f, 0x43, 0x63, 0xcc,
+	0xea, 0x4b, 0x54, 0xe7, 0xe0, 0x17, 0x25, 0x0b,
+	0x1b, 0xb9, 0x9a, 0x02, 0xa2, 0x4b, 0xeb, 0x98,
+	0x16, 0x55, 0xa1, 0x2a, 0xa6, 0x37, 0x23, 0x02,
+	0xa6, 0xb8, 0xfa, 0xb6, 0xfc, 0x5d, 0x82, 0xe6,
+	0xa9, 0xd7, 0xcd, 0x89, 0xee, 0xf3, 0x94, 0x09,
+	0xac, 0x2e, 0x0b, 0x4e, 0x79, 0xf7, 0xe7, 0x8f,
+	0x4c, 0x88, 0xb9, 0xf2, 0xbf, 0xdc, 0xf5, 0x65,
+	0x95, 0xef, 0x1b, 0x91, 0x4d, 0x9e, 0x77, 0xf6,
+	0x75, 0x45, 0x7f, 0x63, 0x38, 0x13, 0x6c, 0xe4,
+	0x42, 0x77, 0x33, 0xbb, 0x6e, 0x1a, 0x4b, 0xbb,
+	0xa2, 0x04, 0xad, 0x61, 0xe1, 0xa2, 0xc6, 0x76,
+	0x92, 0xe2, 0x07, 0xdf, 0x80, 0x7e, 0xd5, 0xf5,
+	0xc3, 0x54, 0x58, 0xfb, 0x67, 0xc4, 0xe0, 0xa9,
+	0x3b, 0x13, 0x65, 0xaa, 0x2d, 0xb0, 0x65, 0xcf,
+	0xb4, 0x12, 0x30, 0x95, 0xb5, 0xf6, 0x0b, 0x47,
+	0xd8, 0x12, 0x26, 0x58, 0x91, 0xfb, 0x4d, 0x54,
+	0x4f, 0xa5, 0x50, 0xb6, 0x69, 0x30, 0x60, 0xa5,
+	0x43, 0xc5, 0x4f, 0x70, 0x75, 0xb4, 0x3f, 0x29,
+	0xc6, 0x6f, 0xbf, 0x7b, 0x65, 0xca, 0xc2, 0x3e,
+	0xdd, 0xe8, 0x96, 0x6e, 0xe3, 0xe4, 0xc2, 0x32,
+	0x89, 0x12, 0xe9, 0xf3, 0x42, 0x49, 0x98, 0x85,
+	0x0e, 0xe7, 0xf5, 0x83, 0x9b, 0x34, 0xac, 0x61,
+	0xa3, 0x6b, 0xdd, 0x09, 0x36, 0x9f, 0x47, 0x13,
+	0x88, 0xdd, 0x81, 0x6b, 0xc1, 0x43, 0x9e, 0x4b,
+	0x56, 0x87, 0x3e, 0x98, 0xd0, 0xd6, 0x1e, 0xde,
+	0xbd, 0x13, 0x61, 0x58, 0x48, 0x0d, 0xb9, 0xeb,
+};
+
+static int __init crct10dif_test_init(void)
+{
+	int i;
+	int errors = 0;
+	int bytes = 0;
+	u64 nsec;
+	unsigned long flags;
+
+	static u16 crc;
+
+	for (i = 0; i < 100; i++) {
+		bytes += tests[i].length;
+		crc ^= crc_t10dif_generic(tests[i].crc, test_buf +
+		tests[i].start, tests[i].length);
+	}
+
+	local_irq_save(flags);
+
+	nsec = ktime_get_ns();
+
+	for (i = 0; i < 100; i++) {
+		if (tests[i].crct10dif != crc_t10dif_update(
+			tests[i].crc,
+			test_buf + tests[i].start,
+			tests[i].length))
+			errors++;
+	}
+
+	nsec = ktime_get_ns() - nsec;
+
+	local_irq_restore(flags);
+
+	if (errors)
+		pr_warn("crct10dif: %d self tests failed\n", errors);
+	else
+		pr_info("crct10dif: self tests passed, processed %d bytes in %lld nsec\n",
+		bytes, nsec);
+
+	return 0;
+}
+
+static void __exit crct10dif_test_exit(void)
+{
+	pr_info("CRC-T10DIF test module unloaded.\n");
+}
+
+module_init(crct10dif_test_init);
+module_exit(crct10dif_test_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CRC-T10DIF Test Module");
-- 
2.34.1



From zhihang.shao.iscas at gmail.com  Wed Nov 13 02:40:36 2024
From: zhihang.shao.iscas at gmail.com (Zhihang Shao)
Date: Wed, 13 Nov 2024 10:40:36 +0000
Subject: [PATCH 2/2] riscv: Optimize crct10dif with zbc extension
In-Reply-To: <20241113104036.254491-1-zhihang.shao.iscas@gmail.com>
References: <20241113104036.254491-1-zhihang.shao.iscas@gmail.com>
Message-ID: <20241113104036.254491-3-zhihang.shao.iscas@gmail.com>

The current CRC-T10DIF algorithm is based on table-lookup optimization.
Given the previous work on optimizing crc32 calculations with zbc
extension, it is believed that this will be equally effective for
accelerating crc-t10dif.
Therefore, this patch offers a implementation of crc-t10dif using zbc
extension. This can detect whether the current runtime environment
supports zbc feature and, if so, uses it to accelerate crc-t10dif
calculations.

This patch is tested on QEMU VM with the kernel CRC-T10DIF selftests.

Signed-off-by: Zhihang Shao <zhihang.shao.iscas at gmail.com>
---
 arch/riscv/crypto/Kconfig               |  14 ++
 arch/riscv/crypto/Makefile              |   4 +
 arch/riscv/crypto/crct10dif-riscv-zbc.c | 182 ++++++++++++++++++++++++
 lib/crct10diftest.c                     |   4 +-
 4 files changed, 202 insertions(+), 2 deletions(-)
 create mode 100644 arch/riscv/crypto/crct10dif-riscv-zbc.c

diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig
index ad58dad9a580..69751ff5573e 100644
--- a/arch/riscv/crypto/Kconfig
+++ b/arch/riscv/crypto/Kconfig
@@ -29,6 +29,20 @@ config CRYPTO_CHACHA_RISCV64
 	  Architecture: riscv64 using:
 	  - Zvkb vector crypto extension
 
+config CRYPTO_CRCT10DIF_RISCV
+       tristate "Checksum: CRCT10DIF"
+       depends on TOOLCHAIN_HAS_ZBC
+       depends on MMU
+       depends on RISCV_ALTERNATIVE
+       default y
+       help
+         CRCT10DIF checksum with Zbc extension optimized
+	 To accelerate CRCT10DIF checksum, choose Y here.
+
+         Architecture: riscv using:
+          - Zbc extension
+
+
 config CRYPTO_GHASH_RISCV64
 	tristate "Hash functions: GHASH"
 	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
diff --git a/arch/riscv/crypto/Makefile b/arch/riscv/crypto/Makefile
index 247c7bc7288c..6f849f4dc4cc 100644
--- a/arch/riscv/crypto/Makefile
+++ b/arch/riscv/crypto/Makefile
@@ -7,6 +7,9 @@ aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o \
 obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o
 chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o
 
+obj-$(CONFIG_CRYPTO_CRCT10DIF_RISCV) += crct10dif-riscv.o
+crct10dif-riscv-y := crct10dif-riscv-zbc.o
+
 obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o
 ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o
 
@@ -21,3 +24,4 @@ sm3-riscv64-y := sm3-riscv64-glue.o sm3-riscv64-zvksh-zvkb.o
 
 obj-$(CONFIG_CRYPTO_SM4_RISCV64) += sm4-riscv64.o
 sm4-riscv64-y := sm4-riscv64-glue.o sm4-riscv64-zvksed-zvkb.o
+
diff --git a/arch/riscv/crypto/crct10dif-riscv-zbc.c b/arch/riscv/crypto/crct10dif-riscv-zbc.c
new file mode 100644
index 000000000000..01571b4286f1
--- /dev/null
+++ b/arch/riscv/crypto/crct10dif-riscv-zbc.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated CRC-T10DIF implementation with RISC-V Zbc extension.
+ *
+ * Copyright (C) 2024 Institute of Software, CAS.
+ */
+
+#include <asm/alternative-macros.h>
+#include <asm/byteorder.h>
+#include <asm/hwcap.h>
+
+#include <crypto/internal/hash.h>
+
+#include <linux/byteorder/generic.h>
+#include <linux/crc-t10dif.h>
+#include <linux/minmax.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+static u16 crc_t10dif_generic_zbc(u16 crc, unsigned char const *p, size_t len);
+
+#define CRCT10DIF_POLY 0x8bb7
+
+#if __riscv_xlen == 64
+#define STEP_ORDER 3
+
+#define CRCT10DIF_POLY_QT_BE 0xf65a57f81d33a48a
+
+static inline u64 crct10dif_prep(u16 crc, unsigned long const *ptr)
+{
+	return ((u64)crc << 48) ^ (__force u64)__cpu_to_be64(*ptr);
+}
+
+#elif __riscv_xlen == 32
+#define STEP_ORDER 2
+#define CRCT10DIF_POLY_QT_BE 0xf65a57f8
+
+static inline u32 crct10dif_prep(u16 crc, unsigned long const *ptr)
+{
+	return ((u32)crc << 16) ^ (__force u32)__cpu_to_be32(*ptr);
+}
+
+#else
+#error "Unexpected __riscv_xlen"
+#endif
+
+static inline u16 crct10dif_zbc(unsigned long s)
+{
+	u16 crc;
+
+	asm volatile   (".option push\n"
+			".option arch,+zbc\n"
+			"clmulh %0, %1, %2\n"
+			"xor    %0, %0, %1\n"
+			"clmul  %0, %0, %3\n"
+			".option pop\n"
+			: "=&r" (crc)
+			: "r"(s),
+			  "r"(CRCT10DIF_POLY_QT_BE),
+			  "r"(CRCT10DIF_POLY)
+			:);
+
+	return crc;
+}
+
+#define STEP (1 << STEP_ORDER)
+#define OFFSET_MASK (STEP - 1)
+
+static inline u16 crct10dif_unaligned(u16 crc, unsigned char const *p, size_t len)
+{
+	size_t bits = len * 8;
+	unsigned long s = 0;
+	u16 crc_low = 0;
+
+	for (int i = 0; i < len; i++)
+		s = *p++ | (s << 8);
+
+	if (len < sizeof(u16)) {
+		s ^= crc >> (16 - bits);
+		crc_low = crc << bits;
+	} else {
+		s ^= (unsigned long)crc << (bits - 16);
+	}
+
+	crc = crct10dif_zbc(s);
+	crc ^= crc_low;
+
+	return crc;
+}
+
+static u16 crc_t10dif_generic_zbc(u16 crc, unsigned char const *p, size_t len)
+{
+	size_t offset, head_len, tail_len;
+	unsigned long const *p_ul;
+	unsigned long s;
+
+	offset = (unsigned long)p & OFFSET_MASK;
+	if (offset && len) {
+		head_len = min(STEP - offset, len);
+		crc = crct10dif_unaligned(crc, p, head_len);
+		p += head_len;
+		len -= head_len;
+	}
+
+	tail_len = len & OFFSET_MASK;
+	len = len >> STEP_ORDER;
+	p_ul = (unsigned long const *)p;
+
+	for (int i = 0; i < len; i++) {
+		s = crct10dif_prep(crc, p_ul);
+		crc = crct10dif_zbc(s);
+		p_ul++;
+	}
+
+	p = (unsigned char const *)p_ul;
+	if (tail_len)
+		crc = crct10dif_unaligned(crc, p, tail_len);
+
+	return crc;
+}
+
+static int crc_t10dif_init(struct shash_desc *desc)
+{
+	u16 *crc = shash_desc_ctx(desc);
+
+	*crc = 0;
+
+	return 0;
+}
+
+static int crc_t10dif_final(struct shash_desc *desc, u8 *out)
+{
+	u16 *crc = shash_desc_ctx(desc);
+
+	*(u16 *)out = *crc;
+
+	return 0;
+}
+
+static int crc_t10dif_update_zbc(struct shash_desc *desc, const u8 *data,
+				unsigned int length)
+{
+	u16 *crc = shash_desc_ctx(desc);
+
+	*crc = crc_t10dif_generic_zbc(*crc, data, length);
+
+	return 0;
+}
+
+static struct shash_alg crc_t10dif_alg = {
+	.digestsize		= CRC_T10DIF_DIGEST_SIZE,
+	.init			= crc_t10dif_init,
+	.update			= crc_t10dif_update_zbc,
+	.final			= crc_t10dif_final,
+	.descsize		= CRC_T10DIF_DIGEST_SIZE,
+
+	.base.cra_name		= "crct10dif",
+	.base.cra_driver_name	= "crct10dif-riscv-zbc",
+	.base.cra_priority	= 150,
+	.base.cra_blocksize	= CRC_T10DIF_BLOCK_SIZE,
+	.base.cra_module	= THIS_MODULE,
+};
+
+static int __init crc_t10dif_mod_init(void)
+{
+	if (riscv_isa_extension_available(NULL, ZBC))
+		return crypto_register_shash(&crc_t10dif_alg);
+
+	return -ENODEV;
+}
+
+static void __exit crc_t10dif_mod_exit(void)
+{
+	crypto_unregister_shash(&crc_t10dif_alg);
+}
+
+module_init(crc_t10dif_mod_init);
+module_exit(crc_t10dif_mod_exit);
+
+MODULE_DESCRIPTION("CRC-T10DIF using RISC-V ZBC Extension");
+MODULE_ALIAS_CRYPTO("crct10dif");
+MODULE_LICENSE("GPL");
diff --git a/lib/crct10diftest.c b/lib/crct10diftest.c
index 9541892eb12c..ac642191e6e8 100644
--- a/lib/crct10diftest.c
+++ b/lib/crct10diftest.c
@@ -666,9 +666,9 @@ static int __init crct10dif_test_init(void)
 
 	local_irq_restore(flags);
 
-	if (errors) 
+	if (errors)
 		pr_warn("crct10dif: %d self tests failed\n", errors);
-	else 
+	else
 		pr_info("crct10dif: self tests passed, processed %d bytes in %lld nsec\n",
 		bytes, nsec);
 
-- 
2.34.1



From conor at kernel.org  Wed Nov 13 03:50:44 2024
From: conor at kernel.org (Conor Dooley)
Date: Wed, 13 Nov 2024 11:50:44 +0000
Subject: [PATCH v10 0/3] Fix address translations on MPFS PCIe controller
In-Reply-To: <20241011140043.1250030-1-daire.mcnamara@microchip.com>
References: <20241011140043.1250030-1-daire.mcnamara@microchip.com>
Message-ID: <20241113-unified-humongous-cda4f06a6240@spud>

Hey folks,

On Fri, Oct 11, 2024 at 03:00:40PM +0100, daire.mcnamara at microchip.com wrote:
> From: Daire McNamara <daire.mcnamara at microchip.com>
> 
> Hi all,
> 
> On Microchip PolarFire SoC (MPFS), the PCIe controller is connected to the
> CPU via one of three Fabric Interface Connectors (FICs).  Each FIC present
> to the CPU complex as 64-bit AXI-M and 64-bit AXI-S.  To preserve
> compatibility with other PolarFire family members, the PCIe controller is
> connected to its encapsulating FIC via a 32-bit AXI-M and 32-bit AXI-S
> interface.
> 
> Each FIC is implemented in FPGA logic and can incorporate logic along its 64-bit
> AXI-M to 32-bit AXI-M chain (including address translation) and, likewise, along
> its 32-bit AXI-S to 64-bit AXI-S chain (again including address translation).
> 
> In order to reduce the potential support space for the PCIe controller in
> this environment, MPFS supports certain reference designs for these address
> translations: reference designs for cache-coherent memory accesses
> and reference designs for non-cache-coherent memory accesses. The precise
> details of these reference designs and associated customer guidelines
> recommending that customers adhere to the addressing schemes used in those
> reference designs are available from Microchip, but the implication for the
> PCIe controller address translation between CPU-space and PCIe-space are:
> 
> For outbound address translation, the PCIe controller address translation tables
> are treated as if they are 32-bit only.  Any further address translation must
> be done in FPGA fabric.
> 
> For inbound address translation, the PCIe controller is configurable for two
> cases:
> * In the case of cache-coherent designs, the base of the AXI-S side of the
>   address translation must be set to 0 and the size should be 4 GiB wide. The
>   FPGA fabric must complete any address translations based on that 0-based
>   address translation.
> * In the case of non-cache coherent designs, the base of AXI-S side of the
>   address translation must be set to 0x8000'0000 and the size shall be 2 GiB
>   wide.  The FPGA fabric must complete any address translation based on that
>   0x80000000 base.
> 
> So, for example, in the non-cache-coherent case, with a device tree property
> that maps an inbound range from 0x10'0000'0000 in PCIe space to 0x10'0000'0000
> in CPU space, the PCIe rootport will translate a PCIe address of 0x10'0000'0000
> to an intermediate 32-bit AXI-S address of 0x8000'0000 and the FIC is
> responsible for translating that intermediate 32-bit AXI-S address of
> 0x8000'0000 to a 64-bit AXI-S address of 0x10'0000'0000.
> 
> And similarly, for example, in the cache-coherent case, with a device tree
> property that maps an inbound range from 0x10'0000'0000 in PCIe space to
> 0x10'0000'0000 in CPU space, the PCIe rootport will translate a PCIe address
> of 0x10'0000'0000 to an intermediate 32-bit AXI-S address of 0x0000'0000 and
> the FIC is responsible for translating that intermediate 32-bit AXI-S address
> of 0x0000'0000 to a 64-bit AXI-S address of 0x10'0000'0000.
> 
> See https://lore.kernel.org/all/20220902142202.2437658-1-daire.mcnamara at microchip.com/T/
> for backstory.
> 
> Changes since v9:
> - Dropped plda_setup_inbound_address_translation() from StarFive driver

Since I had some success bumping the other series for this driver, any
chance of some attention here?
AFAIK, Daire's addressed what's been pointed out by reviewers and
exempted the StarFive driver from overwriting the firmware-set values
with once calculated from DT as they requested.

Cheers,
Conor.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241113/fda9ca62/attachment.sig>

From ebiggers at kernel.org  Wed Nov 13 05:46:55 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed, 13 Nov 2024 08:46:55 -0500
Subject: [PATCH 1/2] lib/crct10diftest.c add selftests for crct10dif
In-Reply-To: <20241113104036.254491-2-zhihang.shao.iscas@gmail.com>
References: <20241113104036.254491-1-zhihang.shao.iscas@gmail.com>
 <20241113104036.254491-2-zhihang.shao.iscas@gmail.com>
Message-ID: <20241113134655.GA794@quark.localdomain>

On Wed, Nov 13, 2024 at 10:40:35AM +0000, Zhihang Shao wrote:
> Add selftests for kernel's implementation of CRC-T10DIF algorithm.
> The test data includes 100 randomly generated test-cases.
> The selftest file is similar to what is done in lib/crc32test.c, and is
> used to verify the correctness and measure performance improvement of
> the CRC-T10DIF algorithm with zbc extension optimization.
> 
> Signed-off-by: Zhihang Shao <zhihang.shao.iscas at gmail.com>
> ---
>  lib/Kconfig         |   9 +
>  lib/Makefile        |   1 +
>  lib/crct10diftest.c | 687 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 697 insertions(+)
>  create mode 100644 lib/crct10diftest.c

crc_t10dif_update() goes through the crypto API, so for now you should be able
to just use the crypto self-tests instead, i.e. boot a kernel with
CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y.

I am planning to fix the crct10dif library to be optimized directly (without
going through the crypto API), like what I am doing for crc32.  At that point a
crct10dif library test will be needed, and I'll add one then.

There are also several issues with the existing crc32 test which you're copying,
and which I'd like to address when adding a new test.  For example, the test
does not cover short lengths, and it runs the tests with IRQs disabled which
makes optimized code not used on many architectures.

- Eric


From palmer at dabbelt.com  Wed Nov 13 07:11:51 2024
From: palmer at dabbelt.com (Palmer Dabbelt)
Date: Wed, 13 Nov 2024 07:11:51 -0800 (PST)
Subject: [PATCH] RISC-V: Enable Zicbom in usermode
In-Reply-To: <20241025-puritan-sank-b8a828ef5872@spud>
Message-ID: <mhng-cee266c4-3485-423a-b769-aae7ae034a1a@palmer-ri-x1c9>

On Fri, 25 Oct 2024 03:16:44 PDT (-0700), Conor Dooley wrote:
> On Fri, Oct 25, 2024 at 05:15:27PM +0800, Yunhui Cui wrote:
>> Like Zicboz, by enabling the corresponding bits of senvcfg,
>> the instructions cbo.clean, cbo.flush, and cbo.inval can be
>> executed normally in user mode.
>> 
>> Signed-off-by: Yunhui Cui <cuiyunhui at bytedance.com>
>> ---
>>  arch/riscv/kernel/cpufeature.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
>> index 1992ea64786e..bc850518ab41 100644
>> --- a/arch/riscv/kernel/cpufeature.c
>> +++ b/arch/riscv/kernel/cpufeature.c
>> @@ -924,7 +924,7 @@ unsigned long riscv_get_elf_hwcap(void)
>>  void __init riscv_user_isa_enable(void)
>>  {
>>  	if (riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOZ))
>> -		current->thread.envcfg |= ENVCFG_CBZE;
>> +		current->thread.envcfg |= ENVCFG_CBIE | ENVCFG_CBCFE | ENVCFG_CBZE;
>
> I believe we previously decided that userspace should not be allowed to

Ya, we didn't want to expose this because it opens up a can of worms.  
Is there a use case for this?  It's not like this is entirely impossible 
to do, it just requires a bit of thought (and should probably be gated 
behind some per-process disabling).

> use zicbom, but that not withstanding - this is wrong. It should be
> checking for Zicbom, not Zicboz.


From patchwork-bot+linux-riscv at kernel.org  Wed Nov 13 07:12:55 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 13 Nov 2024 15:12:55 +0000
Subject: [PATCH v6 00/13] Zacas/Zabha support and qspinlocks
In-Reply-To: <20241103145153.105097-1-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
Message-ID: <173151077551.1250875.2817493635093268101.git-patchwork-notify@kernel.org>

Hello:

This series was applied to riscv/linux.git (for-next)
by Palmer Dabbelt <palmer at rivosinc.com>:

On Sun,  3 Nov 2024 15:51:40 +0100 you wrote:
> This implements [cmp]xchgXX() macros using Zacas and Zabha extensions
> and finally uses those newly introduced macros to add support for
> qspinlocks: note that this implementation of qspinlocks satisfies the
> forward progress guarantee.
> 
> It also uses Ziccrse to provide the qspinlock implementation.
> 
> [...]

Here is the summary with links:
  - [v6,01/13] riscv: Move cpufeature.h macros into their own header
    https://git.kernel.org/riscv/c/010e12aa4925
  - [v6,02/13] riscv: Do not fail to build on byte/halfword operations with Zawrs
    https://git.kernel.org/riscv/c/af042c457db0
  - [v6,03/13] riscv: Implement cmpxchg32/64() using Zacas
    https://git.kernel.org/riscv/c/38acdee32d23
  - [v6,04/13] dt-bindings: riscv: Add Zabha ISA extension description
    https://git.kernel.org/riscv/c/51624ddcf59d
  - [v6,05/13] riscv: Implement cmpxchg8/16() using Zabha
    https://git.kernel.org/riscv/c/1658ef4314b3
  - [v6,06/13] riscv: Improve zacas fully-ordered cmpxchg()
    https://git.kernel.org/riscv/c/6116e22ef33a
  - [v6,07/13] riscv: Implement arch_cmpxchg128() using Zacas
    https://git.kernel.org/riscv/c/f7bd2be7663c
  - [v6,08/13] riscv: Implement xchg8/16() using Zabha
    https://git.kernel.org/riscv/c/97ddab7fbea8
  - [v6,09/13] asm-generic: ticket-lock: Reuse arch_spinlock_t of qspinlock
    https://git.kernel.org/riscv/c/cbe82e140bb7
  - [v6,10/13] asm-generic: ticket-lock: Add separate ticket-lock.h
    https://git.kernel.org/riscv/c/22c33321e260
  - [v6,11/13] riscv: Add ISA extension parsing for Ziccrse
    https://git.kernel.org/riscv/c/2d36fe89d872
  - [v6,12/13] dt-bindings: riscv: Add Ziccrse ISA extension description
    https://git.kernel.org/riscv/c/447b2afbcde1
  - [v6,13/13] riscv: Add qspinlock support
    https://git.kernel.org/riscv/c/ab83647fadae

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Nov 13 07:12:56 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 13 Nov 2024 15:12:56 +0000
Subject: [PATCH v5 00/13] Zacas/Zabha support and qspinlocks
In-Reply-To: <20240818063538.6651-1-alexghiti@rivosinc.com>
References: <20240818063538.6651-1-alexghiti@rivosinc.com>
Message-ID: <173151077674.1250875.11061543352254749516.git-patchwork-notify@kernel.org>

Hello:

This series was applied to riscv/linux.git (for-next)
by Palmer Dabbelt <palmer at rivosinc.com>:

On Sun, 18 Aug 2024 08:35:25 +0200 you wrote:
> This implements [cmp]xchgXX() macros using Zacas and Zabha extensions
> and finally uses those newly introduced macros to add support for
> qspinlocks: note that this implementation of qspinlocks satisfies the
> forward progress guarantee.
> 
> It also uses Ziccrse to provide the qspinlock implementation.
> 
> [...]

Here is the summary with links:
  - [v5,01/13] riscv: Move cpufeature.h macros into their own header
    https://git.kernel.org/riscv/c/010e12aa4925
  - [v5,02/13] riscv: Do not fail to build on byte/halfword operations with Zawrs
    https://git.kernel.org/riscv/c/af042c457db0
  - [v5,03/13] riscv: Implement cmpxchg32/64() using Zacas
    https://git.kernel.org/riscv/c/38acdee32d23
  - [v5,04/13] dt-bindings: riscv: Add Zabha ISA extension description
    (no matching commit)
  - [v5,05/13] riscv: Implement cmpxchg8/16() using Zabha
    (no matching commit)
  - [v5,06/13] riscv: Improve zacas fully-ordered cmpxchg()
    (no matching commit)
  - [v5,07/13] riscv: Implement arch_cmpxchg128() using Zacas
    https://git.kernel.org/riscv/c/f7bd2be7663c
  - [v5,08/13] riscv: Implement xchg8/16() using Zabha
    https://git.kernel.org/riscv/c/97ddab7fbea8
  - [v5,09/13] asm-generic: ticket-lock: Reuse arch_spinlock_t of qspinlock
    https://git.kernel.org/riscv/c/cbe82e140bb7
  - [v5,10/13] asm-generic: ticket-lock: Add separate ticket-lock.h
    https://git.kernel.org/riscv/c/22c33321e260
  - [v5,11/13] riscv: Add ISA extension parsing for Ziccrse
    (no matching commit)
  - [v5,12/13] dt-bindings: riscv: Add Ziccrse ISA extension description
    https://git.kernel.org/riscv/c/447b2afbcde1
  - [v5,13/13] riscv: Add qspinlock support
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+linux-riscv at kernel.org  Wed Nov 13 07:12:58 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 13 Nov 2024 15:12:58 +0000
Subject: [PATCH for-next v2] riscv: Fix default misaligned access trap
In-Reply-To: <20241108-fix_handle_misaligned_load-v2-1-91d547ce64db@rivosinc.com>
References: <20241108-fix_handle_misaligned_load-v2-1-91d547ce64db@rivosinc.com>
Message-ID: <173151077824.1250875.1331896085573525028.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (for-next)
by Palmer Dabbelt <palmer at rivosinc.com>:

On Fri, 08 Nov 2024 15:47:36 -0800 you wrote:
> Commit d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses
> supported") removed the default handlers for handle_misaligned_load()
> and handle_misaligned_store(). When the kernel is compiled without
> RISCV_SCALAR_MISALIGNED, these handlers are never defined, causing
> compilation errors.
> 
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> Fixes: d1703dc7bc8e ("RISC-V: Detect unaligned vector accesses supported")
> 
> [...]

Here is the summary with links:
  - [for-next,v2] riscv: Fix default misaligned access trap
    https://git.kernel.org/riscv/c/0eb512779d64

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From tglx at linutronix.de  Wed Nov 13 07:31:44 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Wed, 13 Nov 2024 16:31:44 +0100
Subject: [PATCH 2/3] irqchip: Add the Sophgo SG2042 MSI interrupt
 controller
In-Reply-To: <PN1P287MB28185C9DA26A773775BDC4C6FE5A2@PN1P287MB2818.INDP287.PROD.OUTLOOK.COM>
References: <cover.1731296803.git.unicorn_wang@outlook.com>
 <8076fe2af9f2b007a42c986ed193ba50ff674bfa.1731296803.git.unicorn_wang@outlook.com>
 <87cyizmzhf.ffs@tglx>
 <PN1P287MB28185C9DA26A773775BDC4C6FE5A2@PN1P287MB2818.INDP287.PROD.OUTLOOK.COM>
Message-ID: <87v7wrkv4v.ffs@tglx>

On Wed, Nov 13 2024 at 14:43, Chen Wang wrote:
> On 2024/11/13 14:14, Thomas Gleixner wrote:
>>> +
>>> +	middle_domain = irq_domain_create_hierarchy(plic_domain, 0, priv->num_irqs,
>>> +						    fwnode,
>>> +						    &pch_msi_middle_domain_ops,
>>> +						    priv);
>> So now you have created a domain. How is that supposed to be used by the
>> PCI layer?
>
> Here I create the domain and attached it to the fwnode. In PCI driver, 
> it can set this msi controller as its ""interrupt-parent" and find the 
> domain attached as below:
>
> static int pcie_probe(struct platform_device *pdev)
> {
>  ??? struct device *dev = &pdev->dev;
>  ??? parent_node = of_irq_find_parent(dev->of_node);
>  ??? parent_domain = irq_find_host(parent_node);
>  ??? ...
> }

I assume you then want to create a global PCI/MSI domain via
pci_msi_create_irq_domain(), right?

That's not the preferred way to do that. Any new implementation should
use the MSI parent model, where each PCI device creates it's own per
device MSI domain with the MSI interrupt controller as parent
domain.

There is a library with helper functions, irq-msi-lib.[ch]. See
gicv2m_allocate_domains() or pch_msi_init_domains() for reference.

Thanks

        tglx


From emil.renner.berthing at canonical.com  Wed Nov 13 07:31:26 2024
From: emil.renner.berthing at canonical.com (Emil Renner Berthing)
Date: Wed, 13 Nov 2024 07:31:26 -0800
Subject: [PATCH] riscv: defconfig: enable pinctrl and dwmac support for TH1520
In-Reply-To: <20241110054405.667779-1-drew@pdp7.com>
References: <20241110054405.667779-1-drew@pdp7.com>
Message-ID: <CAJM55Z9o0JyJnw6C3=eGmgduK92M3nthKSLCB3-N5QD0YkLwyQ@mail.gmail.com>

Drew Fustini wrote:
> Enable pinctrl and ethernet dwmac driver for the TH1520 SoC boards like
> the BeagleV Ahead and the Sipeed LicheePi 4A.
>
> Signed-off-by: Drew Fustini <drew at pdp7.com>
> ---
> Note: the th1520 pinctrl driver and thead dwmac ethernet driver have
> been applied by their respective subsystems and are in linux-next.
> I've successfully tested next on both the ahead and lpi4a boards.
> This patch is based on next-20241108.
>
>  arch/riscv/configs/defconfig | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
> index b4a37345703e..99a11142c03c 100644
> --- a/arch/riscv/configs/defconfig
> +++ b/arch/riscv/configs/defconfig
> @@ -167,6 +167,7 @@ CONFIG_PINCTRL_SOPHGO_CV1800B=y
>  CONFIG_PINCTRL_SOPHGO_CV1812H=y
>  CONFIG_PINCTRL_SOPHGO_SG2000=y
>  CONFIG_PINCTRL_SOPHGO_SG2002=y
> +CONFIG_PINCTRL_TH1520=y
>  CONFIG_GPIO_DWAPB=y
>  CONFIG_GPIO_SIFIVE=y
>  CONFIG_POWER_RESET_GPIO_RESTART=y
> @@ -242,6 +243,7 @@ CONFIG_RTC_DRV_SUN6I=y
>  CONFIG_DMADEVICES=y
>  CONFIG_DMA_SUN6I=m
>  CONFIG_DW_AXI_DMAC=y
> +CONFIG_DWMAC_THEAD=y

The network driver doesn't seem like something that's essential to boot the
board. I'd suggest just enabling it as a module.

/Emil

>  CONFIG_VIRTIO_PCI=y
>  CONFIG_VIRTIO_BALLOON=y
>  CONFIG_VIRTIO_INPUT=y
> --
> 2.34.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From nick.hu at sifive.com  Wed Nov 13 08:13:38 2024
From: nick.hu at sifive.com (Nick Hu)
Date: Thu, 14 Nov 2024 00:13:38 +0800
Subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack
 memory via FWFT sbi call
In-Reply-To: <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com> <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
Message-ID: <CAKddAkCCVjNHUinPWtOiK8Ki_ZkdoUCawfv1-+0B69J_1aJv5Q@mail.gmail.com>

Hi Deepak

On Tue, Nov 12, 2024 at 5:08?AM Deepak Gupta <debug at rivosinc.com> wrote:
>
> Kernel will have to perform shadow stack operations on user shadow stack.
> Like during signal delivery and sigreturn, shadow stack token must be
> created and validated respectively. Thus shadow stack access for kernel
> must be enabled.
>
> In future when kernel shadow stacks are enabled for linux kernel, it must
> be enabled as early as possible for better coverage and prevent imbalance
> between regular stack and shadow stack. After `relocate_enable_mmu` has
> been done, this is as early as possible it can enabled.
>
> Signed-off-by: Deepak Gupta <debug at rivosinc.com>
> ---
>  arch/riscv/kernel/asm-offsets.c |  4 ++++
>  arch/riscv/kernel/head.S        | 12 ++++++++++++
>  2 files changed, 16 insertions(+)
>
> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> index 766bd33f10cb..a22ab8a41672 100644
> --- a/arch/riscv/kernel/asm-offsets.c
> +++ b/arch/riscv/kernel/asm-offsets.c
> @@ -517,4 +517,8 @@ void asm_offsets(void)
>         DEFINE(FREGS_A6,            offsetof(struct ftrace_regs, a6));
>         DEFINE(FREGS_A7,            offsetof(struct ftrace_regs, a7));
>  #endif
> +       DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
> +       DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
> +       DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
> +       DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);
>  }
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 356d5397b2a2..6244408ca917 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -164,6 +164,12 @@ secondary_start_sbi:
>         call relocate_enable_mmu
>  #endif
>         call .Lsetup_trap_vector
> +       li a7, SBI_EXT_FWFT
> +       li a6, SBI_EXT_FWFT_SET
> +       li a0, SBI_FWFT_SHADOW_STACK
> +       li a1, 1 /* enable supervisor to access shadow stack access */
> +       li a2, SBI_FWFT_SET_FLAG_LOCK
> +       ecall
>         scs_load_current
>         call smp_callin
>  #endif /* CONFIG_SMP */
> @@ -320,6 +326,12 @@ SYM_CODE_START(_start_kernel)
>         la tp, init_task
>         la sp, init_thread_union + THREAD_SIZE
>         addi sp, sp, -PT_SIZE_ON_STACK
> +       li a7, SBI_EXT_FWFT
> +       li a6, SBI_EXT_FWFT_SET
> +       li a0, SBI_FWFT_SHADOW_STACK
> +       li a1, 1 /* enable supervisor to access shadow stack access */
> +       li a2, SBI_FWFT_SET_FLAG_LOCK
> +       ecall
>         scs_load_current
>
>  #ifdef CONFIG_KASAN
>
> --
> 2.45.0
>
Should we clear the SBI_FWFT_SET_FLAG_LOCK before the cpu hotplug
otherwise the menvcfg.sse won't be set by the fwft set sbi call when
the hotplug cpu back to kernel?

Regards,
Nick
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From alex at ghiti.fr  Wed Nov 13 08:15:20 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Wed, 13 Nov 2024 17:15:20 +0100
Subject: [PATCH RFC 1/3] dt-bindings: riscv: Add Svukte entry
In-Reply-To: <20240920-dev-maxh-svukte-rebase-v1-1-7864a88a62bd@sifive.com>
References: <20240920-dev-maxh-svukte-rebase-v1-0-7864a88a62bd@sifive.com>
 <20240920-dev-maxh-svukte-rebase-v1-1-7864a88a62bd@sifive.com>
Message-ID: <eb8f399b-fa09-47fd-8102-9b65b0839dd5@ghiti.fr>

Hi Max,

On 20/09/2024 09:39, Max Hsu wrote:
> Add an entry for the Svukte extension to the riscv,isa-extensions
> property.
>
> Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
> Signed-off-by: Max Hsu <max.hsu at sifive.com>
> ---
>   Documentation/devicetree/bindings/riscv/extensions.yaml | 7 +++++++
>   1 file changed, 7 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
> index a06dbc6b4928958704855c8993291b036e3d1a63..df96aea5e53a70b0cb8905332464a42a264e56e6 100644
> --- a/Documentation/devicetree/bindings/riscv/extensions.yaml
> +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
> @@ -171,6 +171,13 @@ properties:
>               memory types as ratified in the 20191213 version of the privileged
>               ISA specification.
>   
> +        - const: svukte
> +          description:
> +            The standard Svukte supervisor-level extensions for making user-mode


s/extensions/extension


> +            accesses to supervisor memory raise page faults in constant time,
> +            mitigating attacks that attempt to discover the supervisor
> +            software's address-space layout, as PR#1564 of riscv-isa-manual.
> +
>           - const: zacas
>             description: |
>               The Zacas extension for Atomic Compare-and-Swap (CAS) instructions
>

You'll need a new version for the proper commit sha1 once it gets 
ratified anyway, so with the typo fixed, you can add:

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From ajones at ventanamicro.com  Wed Nov 13 09:37:13 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Wed, 13 Nov 2024 18:37:13 +0100
Subject: [External] Re: [PATCH] RISC-V: Enable Zicbom in usermode
In-Reply-To: <CAEEQ3wmn9W8A5y37aFisQqd=8Ke7Lt6nY6am99j0O2cNbsVj-A@mail.gmail.com>
References: <20241025091527.57825-1-cuiyunhui@bytedance.com>
 <20241025-puritan-sank-b8a828ef5872@spud>
 <3CCBB0AB-169D-4677-9A44-53E4148908D5@jrtc27.com>
 <CAEEQ3wmn9W8A5y37aFisQqd=8Ke7Lt6nY6am99j0O2cNbsVj-A@mail.gmail.com>
Message-ID: <20241113-ec9f91d62f4845df79bb21f3@orel>

On Thu, Oct 31, 2024 at 04:29:49PM +0800, yunhui cui wrote:
> Hi Jessica,
> 
> On Sat, Oct 26, 2024 at 12:32?AM Jessica Clarke <jrtc27 at jrtc27.com> wrote:
> >
> > On 25 Oct 2024, at 11:16, Conor Dooley <conor at kernel.org> wrote:
> > > On Fri, Oct 25, 2024 at 05:15:27PM +0800, Yunhui Cui wrote:
> > >> Like Zicboz, by enabling the corresponding bits of senvcfg,
> > >> the instructions cbo.clean, cbo.flush, and cbo.inval can be
> > >> executed normally in user mode.
> > >>
> > >> Signed-off-by: Yunhui Cui <cuiyunhui at bytedance.com>
> > >> ---
> > >> arch/riscv/kernel/cpufeature.c | 2 +-
> > >> 1 file changed, 1 insertion(+), 1 deletion(-)
> > >>
> > >> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> > >> index 1992ea64786e..bc850518ab41 100644
> > >> --- a/arch/riscv/kernel/cpufeature.c
> > >> +++ b/arch/riscv/kernel/cpufeature.c
> > >> @@ -924,7 +924,7 @@ unsigned long riscv_get_elf_hwcap(void)
> > >> void __init riscv_user_isa_enable(void)
> > >> {
> > >> if (riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOZ))
> > >> - current->thread.envcfg |= ENVCFG_CBZE;
> > >> + current->thread.envcfg |= ENVCFG_CBIE | ENVCFG_CBCFE | ENVCFG_CBZE;
> > >
> > > I believe we previously decided that userspace should not be allowed to
> > > use zicbom, but that not withstanding - this is wrong. It should be
> > > checking for Zicbom, not Zicboz.
> >
> > Allowing clean/flush is safe but has the same problems as fence.i with
> > regards to migrating between harts. Allowing invalidate, unless mapped
> > to flush, is not safe in general unless the kernel does a lot of
> > flushing to avoid userspace accessing data it shouldn?t be able to see.
> >
> > Also, ENVCFG_CBIE is a mask for a multi-bit field, which happens to
> > have the same value as ENVCFG_CBIE_INV (i.e. really is making cbo.inval
> > be an invalidate). I note that the KVM code, which this likely copied
> > from(?), makes the same mistake, but there that is the intended
> > behaviour, if misleading about what the field really is.
> >
> > So, with suitable caveats, allowing clean/flush could be a reasonable
> > thing to do (maybe useful for userspace drivers so long as they pin
> > themselves to a specific hart?), but invalidate should only ever be
> > allowed if mapped to flush.
> >
> > Jess
> >
> Yes. The original intention is to enable clean/flush/invalid. So
> ENVCFG_CBIE | ENVCFG_CBCFE is added. When one core initiates an
> invalidation, other cores will also invalidate the corresponding cache
> line. So do we not need to worry about this problem? Moreover,
> invalidation is not found in the logic of disabling preemption in the
> kernel. Or perhaps binding cores belongs to the user-space's own
> logic. Can this patch be fixed as RISCV_ISA_EXT_ZICBOM and then a v2
> be sent?

Jessica points out that CBIE should only be set if it's 0b01 but it's
currently 0b11, so just changing RISCV_ISA_EXT_ZICBOM is insufficient
for v2.

Is there a use case for usermode to have an invalidate without a clean?
If so, then is that use case not present on Arm platforms or is there a
workaround for Arm platforms? Because Arm's 'DC IVAC' is only allowed for
EL1 and higher. To be consistent with Arm we can add cbo.flush and
cbo.clean (CBCFE) since Arm does allow exposing 'DC CIVAC' and 'DC CVAC'
to EL0. Since it looks like CBIE=0b01 would just make cbo.inval an alias
of cbo.flush, then I'm not sure it makes sense to set it, in fact it may
just confuse things.

Thanks,
drew


From quic_obabatun at quicinc.com  Wed Nov 13 10:02:49 2024
From: quic_obabatun at quicinc.com (Oreoluwa Babatunde)
Date: Wed, 13 Nov 2024 10:02:49 -0800
Subject: [PATCH] dma-mapping: Save base/size instead of pointer to shared
 DMA pool
In-Reply-To: <f8cef6845a6141f0277e31a71fe153612daae776.1731436631.git.geert+renesas@glider.be>
References: <f8cef6845a6141f0277e31a71fe153612daae776.1731436631.git.geert+renesas@glider.be>
Message-ID: <6a8ba993-9413-40ad-8c91-0cf268798585@quicinc.com>


On 11/12/2024 10:39 AM, Geert Uytterhoeven wrote:
> On RZ/Five, which is non-coherent, and uses CONFIG_DMA_GLOBAL_POOL=y:
>
>     Oops - store (or AMO) access fault [#1]
>     CPU: 0 UID: 0 PID: 1 Comm: swapper Not tainted 6.12.0-rc1-00015-g8a6e02d0c00e #201
>     Hardware name: Renesas SMARC EVK based on r9a07g043f01 (DT)
>     epc : __memset+0x60/0x100
>      ra : __dma_alloc_from_coherent+0x150/0x17a
>     epc : ffffffff8062d2bc ra : ffffffff80053a94 sp : ffffffc60000ba20
>      gp : ffffffff812e9938 tp : ffffffd601920000 t0 : ffffffc6000d0000
>      t1 : 0000000000000000 t2 : ffffffffe9600000 s0 : ffffffc60000baa0
>      s1 : ffffffc6000d0000 a0 : ffffffc6000d0000 a1 : 0000000000000000
>      a2 : 0000000000001000 a3 : ffffffc6000d1000 a4 : 0000000000000000
>      a5 : 0000000000000000 a6 : ffffffd601adacc0 a7 : ffffffd601a841a8
>      s2 : ffffffd6018573c0 s3 : 0000000000001000 s4 : ffffffd6019541e0
>      s5 : 0000000200000022 s6 : ffffffd6018f8410 s7 : ffffffd6018573e8
>      s8 : 0000000000000001 s9 : 0000000000000001 s10: 0000000000000010
>      s11: 0000000000000000 t3 : 0000000000000000 t4 : ffffffffdefe62d1
>      t5 : 000000001cd6a3a9 t6 : ffffffd601b2aad6
>     status: 0000000200000120 badaddr: ffffffc6000d0000 cause: 0000000000000007
>     [<ffffffff8062d2bc>] __memset+0x60/0x100
>     [<ffffffff80053e1a>] dma_alloc_from_global_coherent+0x1c/0x28
>     [<ffffffff80053056>] dma_direct_alloc+0x98/0x112
>     [<ffffffff8005238c>] dma_alloc_attrs+0x78/0x86
>     [<ffffffff8035fdb4>] rz_dmac_probe+0x3f6/0x50a
>     [<ffffffff803a0694>] platform_probe+0x4c/0x8a
>
> If CONFIG_DMA_GLOBAL_POOL=y, the reserved_mem structure passed to
> rmem_dma_setup() is saved for later use, by saving the passed pointer.
> However, when dma_init_reserved_memory() is called later, the pointer
> has become stale, causing a crash.
>
> E.g. in the RZ/Five case, the referenced memory now contains the
> reserved_mem structure for the "mmode_resv0 at 30000" node (with base
> 0x30000 and size 0x10000), instead of the correct "pma_resv0 at 58000000"
> node (with base 0x58000000 and size 0x8000000).
>
> Fix this by saving the needed reserved_mem structure's contents instead.
>
> Fixes: 8a6e02d0c00e7b62 ("of: reserved_mem: Restructure how the reserved memory regions are processed")
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Oreoluwa Babatunde <quic_obabatun at quicinc.com>
> ---
>  kernel/dma/coherent.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
> index ff5683a57f77126d..3b2bdca9f1d4b027 100644
> --- a/kernel/dma/coherent.c
> +++ b/kernel/dma/coherent.c
> @@ -330,7 +330,8 @@ int dma_init_global_coherent(phys_addr_t phys_addr, size_t size)
>  #include <linux/of_reserved_mem.h>
>  
>  #ifdef CONFIG_DMA_GLOBAL_POOL
> -static struct reserved_mem *dma_reserved_default_memory __initdata;
> +static phys_addr_t dma_reserved_default_memory_base __initdata;
> +static phys_addr_t dma_reserved_default_memory_size __initdata;
>  #endif
>  
>  static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
> @@ -376,9 +377,10 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
>  
>  #ifdef CONFIG_DMA_GLOBAL_POOL
>  	if (of_get_flat_dt_prop(node, "linux,dma-default", NULL)) {
> -		WARN(dma_reserved_default_memory,
> +		WARN(dma_reserved_default_memory_size,
>  		     "Reserved memory: region for default DMA coherent area is redefined\n");
> -		dma_reserved_default_memory = rmem;
> +		dma_reserved_default_memory_base = rmem->base;
> +		dma_reserved_default_memory_size = rmem->size;
>  	}
>  #endif
>  
> @@ -391,10 +393,10 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem)
>  #ifdef CONFIG_DMA_GLOBAL_POOL
>  static int __init dma_init_reserved_memory(void)
>  {
> -	if (!dma_reserved_default_memory)
> +	if (!dma_reserved_default_memory_size)
>  		return -ENOMEM;
> -	return dma_init_global_coherent(dma_reserved_default_memory->base,
> -					dma_reserved_default_memory->size);
> +	return dma_init_global_coherent(dma_reserved_default_memory_base,
> +					dma_reserved_default_memory_size);
>  }
>  core_initcall(dma_init_reserved_memory);
>  #endif /* CONFIG_DMA_GLOBAL_POOL */
Hi Geert,

Thanks for providing a fix!

I also looked around more to see if there are more places that
could store a stale reference to rmem but I didn't see any others,
so I think we are good!

I have given my "reviewed-by" tag as well.

Thank you!
Oreoluwa


From dave at stgolabs.net  Wed Nov 13 10:33:21 2024
From: dave at stgolabs.net (Davidlohr Bueso)
Date: Wed, 13 Nov 2024 10:33:21 -0800
Subject: [PATCH] riscv/futex: Optimize atomic cmpxchg
Message-ID: <20241113183321.491113-1-dave@stgolabs.net>

Remove redundant release/acquire barriers, optimizing the lr/sc sequence
to provide conditional RCsc synchronization, per the RVWMO.

Signed-off-by: Davidlohr Bueso <dave at stgolabs.net>
---
 arch/riscv/include/asm/futex.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
index fc8130f995c1..72be100afa23 100644
--- a/arch/riscv/include/asm/futex.h
+++ b/arch/riscv/include/asm/futex.h
@@ -85,7 +85,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 
 	__enable_user_access();
 	__asm__ __volatile__ (
-	"1:	lr.w.aqrl %[v],%[u]			\n"
+	"1:	lr.w %[v],%[u]			        \n"
 	"	bne %[v],%z[ov],3f			\n"
 	"2:	sc.w.aqrl %[t],%z[nv],%[u]		\n"
 	"	bnez %[t],1b				\n"
-- 
2.39.5



From drew at pdp7.com  Wed Nov 13 10:43:36 2024
From: drew at pdp7.com (Drew Fustini)
Date: Wed, 13 Nov 2024 10:43:36 -0800
Subject: [PATCH v2] riscv: defconfig: enable pinctrl and dwmac support for TH1520
Message-ID: <20241113184333.829716-1-drew@pdp7.com>

Enable pinctrl and ethernet dwmac driver for the TH1520 SoC boards like
the BeagleV Ahead and the Sipeed LicheePi 4A.

Signed-off-by: Drew Fustini <drew at pdp7.com>
---
Changes in v2:
 - Switch CONFIG_DWMAC_THEAD from built-in to module


 arch/riscv/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index b4a37345703e..d26e670404b6 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -167,6 +167,7 @@ CONFIG_PINCTRL_SOPHGO_CV1800B=y
 CONFIG_PINCTRL_SOPHGO_CV1812H=y
 CONFIG_PINCTRL_SOPHGO_SG2000=y
 CONFIG_PINCTRL_SOPHGO_SG2002=y
+CONFIG_PINCTRL_TH1520=y
 CONFIG_GPIO_DWAPB=y
 CONFIG_GPIO_SIFIVE=y
 CONFIG_POWER_RESET_GPIO_RESTART=y
@@ -242,6 +243,7 @@ CONFIG_RTC_DRV_SUN6I=y
 CONFIG_DMADEVICES=y
 CONFIG_DMA_SUN6I=m
 CONFIG_DW_AXI_DMAC=y
+CONFIG_DWMAC_THEAD=m
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_INPUT=y
-- 
2.34.1



From parri.andrea at gmail.com  Wed Nov 13 11:15:05 2024
From: parri.andrea at gmail.com (Andrea Parri)
Date: Wed, 13 Nov 2024 21:15:05 +0200
Subject: [PATCH] riscv/futex: Optimize atomic cmpxchg
In-Reply-To: <20241113183321.491113-1-dave@stgolabs.net>
References: <20241113183321.491113-1-dave@stgolabs.net>
Message-ID: <ZzT6uRDpkuEu5GH-@andrea>

On Wed, Nov 13, 2024 at 10:33:21AM -0800, Davidlohr Bueso wrote:
> Remove redundant release/acquire barriers, optimizing the lr/sc sequence
> to provide conditional RCsc synchronization, per the RVWMO.
> 
> Signed-off-by: Davidlohr Bueso <dave at stgolabs.net>
> ---
>  arch/riscv/include/asm/futex.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
> index fc8130f995c1..72be100afa23 100644
> --- a/arch/riscv/include/asm/futex.h
> +++ b/arch/riscv/include/asm/futex.h
> @@ -85,7 +85,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
>  
>  	__enable_user_access();
>  	__asm__ __volatile__ (
> -	"1:	lr.w.aqrl %[v],%[u]			\n"
> +	"1:	lr.w %[v],%[u]			        \n"
>  	"	bne %[v],%z[ov],3f			\n"
>  	"2:	sc.w.aqrl %[t],%z[nv],%[u]		\n"
>  	"	bnez %[t],1b				\n"

atomic_cmpxchg() uses yet another scheme, but this does also look good
to me: FWIW,

Reviewed-by: Andrea Parri <parri.andrea at gmail.com>

  Andrea


From unicorn_wang at outlook.com  Wed Nov 13 16:20:24 2024
From: unicorn_wang at outlook.com (Chen Wang)
Date: Thu, 14 Nov 2024 08:20:24 +0800
Subject: [PATCH 2/3] irqchip: Add the Sophgo SG2042 MSI interrupt
 controller
In-Reply-To: <87v7wrkv4v.ffs@tglx>
References: <cover.1731296803.git.unicorn_wang@outlook.com>
 <8076fe2af9f2b007a42c986ed193ba50ff674bfa.1731296803.git.unicorn_wang@outlook.com>
 <87cyizmzhf.ffs@tglx>
 <PN1P287MB28185C9DA26A773775BDC4C6FE5A2@PN1P287MB2818.INDP287.PROD.OUTLOOK.COM>
 <87v7wrkv4v.ffs@tglx>
Message-ID: <MA0P287MB2822B7CFC338C7AED1F0A549FE5B2@MA0P287MB2822.INDP287.PROD.OUTLOOK.COM>


On 2024/11/13 23:31, Thomas Gleixner wrote:
> On Wed, Nov 13 2024 at 14:43, Chen Wang wrote:
>> On 2024/11/13 14:14, Thomas Gleixner wrote:
>>>> +
>>>> +	middle_domain = irq_domain_create_hierarchy(plic_domain, 0, priv->num_irqs,
>>>> +						    fwnode,
>>>> +						    &pch_msi_middle_domain_ops,
>>>> +						    priv);
>>> So now you have created a domain. How is that supposed to be used by the
>>> PCI layer?
>> Here I create the domain and attached it to the fwnode. In PCI driver,
>> it can set this msi controller as its ""interrupt-parent" and find the
>> domain attached as below:
>>
>> static int pcie_probe(struct platform_device *pdev)
>> {
>>   ??? struct device *dev = &pdev->dev;
>>   ??? parent_node = of_irq_find_parent(dev->of_node);
>>   ??? parent_domain = irq_find_host(parent_node);
>>   ??? ...
>> }
> I assume you then want to create a global PCI/MSI domain via
> pci_msi_create_irq_domain(), right?
Yes, I am writing another pcie driver, which will call 
pci_msi_create_irq_domain() to create a child domain of this middle_domain.
>
> That's not the preferred way to do that. Any new implementation should
> use the MSI parent model, where each PCI device creates it's own per
> device MSI domain with the MSI interrupt controller as parent
> domain.
>
> There is a library with helper functions, irq-msi-lib.[ch]. See
> gicv2m_allocate_domains() or pch_msi_init_domains() for reference.

Thanks, I will check this out.

Regards,

Chen

>
> Thanks
>
>          tglx


From debug at rivosinc.com  Wed Nov 13 17:06:50 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Wed, 13 Nov 2024 17:06:50 -0800
Subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack
 memory via FWFT sbi call
In-Reply-To: <CAKddAkCCVjNHUinPWtOiK8Ki_ZkdoUCawfv1-+0B69J_1aJv5Q@mail.gmail.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
 <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
 <CAKddAkCCVjNHUinPWtOiK8Ki_ZkdoUCawfv1-+0B69J_1aJv5Q@mail.gmail.com>
Message-ID: <ZzVNKvCu4MOs7O5z@debug.ba.rivosinc.com>

On Thu, Nov 14, 2024 at 12:13:38AM +0800, Nick Hu wrote:
>Hi Deepak
>
>On Tue, Nov 12, 2024 at 5:08?AM Deepak Gupta <debug at rivosinc.com> wrote:
>>
>> Kernel will have to perform shadow stack operations on user shadow stack.
>> Like during signal delivery and sigreturn, shadow stack token must be
>> created and validated respectively. Thus shadow stack access for kernel
>> must be enabled.
>>
>> In future when kernel shadow stacks are enabled for linux kernel, it must
>> be enabled as early as possible for better coverage and prevent imbalance
>> between regular stack and shadow stack. After `relocate_enable_mmu` has
>> been done, this is as early as possible it can enabled.
>>
>> Signed-off-by: Deepak Gupta <debug at rivosinc.com>
>> ---
>>  arch/riscv/kernel/asm-offsets.c |  4 ++++
>>  arch/riscv/kernel/head.S        | 12 ++++++++++++
>>  2 files changed, 16 insertions(+)
>>
>> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
>> index 766bd33f10cb..a22ab8a41672 100644
>> --- a/arch/riscv/kernel/asm-offsets.c
>> +++ b/arch/riscv/kernel/asm-offsets.c
>> @@ -517,4 +517,8 @@ void asm_offsets(void)
>>         DEFINE(FREGS_A6,            offsetof(struct ftrace_regs, a6));
>>         DEFINE(FREGS_A7,            offsetof(struct ftrace_regs, a7));
>>  #endif
>> +       DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
>> +       DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
>> +       DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
>> +       DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);
>>  }
>> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
>> index 356d5397b2a2..6244408ca917 100644
>> --- a/arch/riscv/kernel/head.S
>> +++ b/arch/riscv/kernel/head.S
>> @@ -164,6 +164,12 @@ secondary_start_sbi:
>>         call relocate_enable_mmu
>>  #endif
>>         call .Lsetup_trap_vector
>> +       li a7, SBI_EXT_FWFT
>> +       li a6, SBI_EXT_FWFT_SET
>> +       li a0, SBI_FWFT_SHADOW_STACK
>> +       li a1, 1 /* enable supervisor to access shadow stack access */
>> +       li a2, SBI_FWFT_SET_FLAG_LOCK
>> +       ecall
>>         scs_load_current
>>         call smp_callin
>>  #endif /* CONFIG_SMP */
>> @@ -320,6 +326,12 @@ SYM_CODE_START(_start_kernel)
>>         la tp, init_task
>>         la sp, init_thread_union + THREAD_SIZE
>>         addi sp, sp, -PT_SIZE_ON_STACK
>> +       li a7, SBI_EXT_FWFT
>> +       li a6, SBI_EXT_FWFT_SET
>> +       li a0, SBI_FWFT_SHADOW_STACK
>> +       li a1, 1 /* enable supervisor to access shadow stack access */
>> +       li a2, SBI_FWFT_SET_FLAG_LOCK
>> +       ecall
>>         scs_load_current
>>
>>  #ifdef CONFIG_KASAN
>>
>> --
>> 2.45.0
>>
>Should we clear the SBI_FWFT_SET_FLAG_LOCK before the cpu hotplug
>otherwise the menvcfg.sse won't be set by the fwft set sbi call when
>the hotplug cpu back to kernel?

Hmm...

An incoming hotplug CPU has no features setup on it.
I see that `sbi_cpu_start` will supply `secondary_start_sbi` as start
up code for incoming CPU. `secondary_start_sbi` is in head.S which converges
in `.Lsecondary_start_common`. And thus hotplugged CPU should be
issuing shadow stack set FWFT sbi as well.

Am I missing something ?

>
>Regards,
>Nick
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv


From nick.hu at sifive.com  Wed Nov 13 17:20:14 2024
From: nick.hu at sifive.com (Nick Hu)
Date: Thu, 14 Nov 2024 09:20:14 +0800
Subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack
 memory via FWFT sbi call
In-Reply-To: <ZzVNKvCu4MOs7O5z@debug.ba.rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
 <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
 <CAKddAkCCVjNHUinPWtOiK8Ki_ZkdoUCawfv1-+0B69J_1aJv5Q@mail.gmail.com> <ZzVNKvCu4MOs7O5z@debug.ba.rivosinc.com>
Message-ID: <CAKddAkDbGYeONaksq6fzLzx47BHZo3Ar7Sog3MOgf7Y+Birovw@mail.gmail.com>

Hi Deepak

On Thu, Nov 14, 2024 at 9:06?AM Deepak Gupta <debug at rivosinc.com> wrote:
>
> On Thu, Nov 14, 2024 at 12:13:38AM +0800, Nick Hu wrote:
> >Hi Deepak
> >
> >On Tue, Nov 12, 2024 at 5:08?AM Deepak Gupta <debug at rivosinc.com> wrote:
> >>
> >> Kernel will have to perform shadow stack operations on user shadow stack.
> >> Like during signal delivery and sigreturn, shadow stack token must be
> >> created and validated respectively. Thus shadow stack access for kernel
> >> must be enabled.
> >>
> >> In future when kernel shadow stacks are enabled for linux kernel, it must
> >> be enabled as early as possible for better coverage and prevent imbalance
> >> between regular stack and shadow stack. After `relocate_enable_mmu` has
> >> been done, this is as early as possible it can enabled.
> >>
> >> Signed-off-by: Deepak Gupta <debug at rivosinc.com>
> >> ---
> >>  arch/riscv/kernel/asm-offsets.c |  4 ++++
> >>  arch/riscv/kernel/head.S        | 12 ++++++++++++
> >>  2 files changed, 16 insertions(+)
> >>
> >> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> >> index 766bd33f10cb..a22ab8a41672 100644
> >> --- a/arch/riscv/kernel/asm-offsets.c
> >> +++ b/arch/riscv/kernel/asm-offsets.c
> >> @@ -517,4 +517,8 @@ void asm_offsets(void)
> >>         DEFINE(FREGS_A6,            offsetof(struct ftrace_regs, a6));
> >>         DEFINE(FREGS_A7,            offsetof(struct ftrace_regs, a7));
> >>  #endif
> >> +       DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
> >> +       DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
> >> +       DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
> >> +       DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);
> >>  }
> >> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> >> index 356d5397b2a2..6244408ca917 100644
> >> --- a/arch/riscv/kernel/head.S
> >> +++ b/arch/riscv/kernel/head.S
> >> @@ -164,6 +164,12 @@ secondary_start_sbi:
> >>         call relocate_enable_mmu
> >>  #endif
> >>         call .Lsetup_trap_vector
> >> +       li a7, SBI_EXT_FWFT
> >> +       li a6, SBI_EXT_FWFT_SET
> >> +       li a0, SBI_FWFT_SHADOW_STACK
> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
> >> +       ecall
> >>         scs_load_current
> >>         call smp_callin
> >>  #endif /* CONFIG_SMP */
> >> @@ -320,6 +326,12 @@ SYM_CODE_START(_start_kernel)
> >>         la tp, init_task
> >>         la sp, init_thread_union + THREAD_SIZE
> >>         addi sp, sp, -PT_SIZE_ON_STACK
> >> +       li a7, SBI_EXT_FWFT
> >> +       li a6, SBI_EXT_FWFT_SET
> >> +       li a0, SBI_FWFT_SHADOW_STACK
> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
> >> +       ecall
> >>         scs_load_current
> >>
> >>  #ifdef CONFIG_KASAN
> >>
> >> --
> >> 2.45.0
> >>
> >Should we clear the SBI_FWFT_SET_FLAG_LOCK before the cpu hotplug
> >otherwise the menvcfg.sse won't be set by the fwft set sbi call when
> >the hotplug cpu back to kernel?
>
> Hmm...
>
> An incoming hotplug CPU has no features setup on it.
> I see that `sbi_cpu_start` will supply `secondary_start_sbi` as start
> up code for incoming CPU. `secondary_start_sbi` is in head.S which converges
> in `.Lsecondary_start_common`. And thus hotplugged CPU should be
> issuing shadow stack set FWFT sbi as well.
>
> Am I missing something ?
>
This is the correct flow. However the opensbi will deny it due to the
SBI_FWFT_SET_FLAG_LOCK already being set.
So the menvcfg.sse will not set by this flow.

if (conf->flags & SBI_FWFT_SET_FLAG_LOCK)
                return SBI_EDENIED;

Regards,
Nick
> >
> >Regards,
> >Nick
> >>
> >> _______________________________________________
> >> linux-riscv mailing list
> >> linux-riscv at lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/linux-riscv


From debug at rivosinc.com  Wed Nov 13 17:25:00 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Wed, 13 Nov 2024 17:25:00 -0800
Subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack
 memory via FWFT sbi call
In-Reply-To: <CAKddAkDbGYeONaksq6fzLzx47BHZo3Ar7Sog3MOgf7Y+Birovw@mail.gmail.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
 <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
 <CAKddAkCCVjNHUinPWtOiK8Ki_ZkdoUCawfv1-+0B69J_1aJv5Q@mail.gmail.com>
 <ZzVNKvCu4MOs7O5z@debug.ba.rivosinc.com>
 <CAKddAkDbGYeONaksq6fzLzx47BHZo3Ar7Sog3MOgf7Y+Birovw@mail.gmail.com>
Message-ID: <ZzVRbCZP9N4Os8Bj@debug.ba.rivosinc.com>

On Thu, Nov 14, 2024 at 09:20:14AM +0800, Nick Hu wrote:
>Hi Deepak
>
>On Thu, Nov 14, 2024 at 9:06?AM Deepak Gupta <debug at rivosinc.com> wrote:
>>
>> On Thu, Nov 14, 2024 at 12:13:38AM +0800, Nick Hu wrote:
>> >Hi Deepak
>> >
>> >On Tue, Nov 12, 2024 at 5:08?AM Deepak Gupta <debug at rivosinc.com> wrote:
>> >>
>> >> Kernel will have to perform shadow stack operations on user shadow stack.
>> >> Like during signal delivery and sigreturn, shadow stack token must be
>> >> created and validated respectively. Thus shadow stack access for kernel
>> >> must be enabled.
>> >>
>> >> In future when kernel shadow stacks are enabled for linux kernel, it must
>> >> be enabled as early as possible for better coverage and prevent imbalance
>> >> between regular stack and shadow stack. After `relocate_enable_mmu` has
>> >> been done, this is as early as possible it can enabled.
>> >>
>> >> Signed-off-by: Deepak Gupta <debug at rivosinc.com>
>> >> ---
>> >>  arch/riscv/kernel/asm-offsets.c |  4 ++++
>> >>  arch/riscv/kernel/head.S        | 12 ++++++++++++
>> >>  2 files changed, 16 insertions(+)
>> >>
>> >> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
>> >> index 766bd33f10cb..a22ab8a41672 100644
>> >> --- a/arch/riscv/kernel/asm-offsets.c
>> >> +++ b/arch/riscv/kernel/asm-offsets.c
>> >> @@ -517,4 +517,8 @@ void asm_offsets(void)
>> >>         DEFINE(FREGS_A6,            offsetof(struct ftrace_regs, a6));
>> >>         DEFINE(FREGS_A7,            offsetof(struct ftrace_regs, a7));
>> >>  #endif
>> >> +       DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
>> >> +       DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
>> >> +       DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
>> >> +       DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);
>> >>  }
>> >> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
>> >> index 356d5397b2a2..6244408ca917 100644
>> >> --- a/arch/riscv/kernel/head.S
>> >> +++ b/arch/riscv/kernel/head.S
>> >> @@ -164,6 +164,12 @@ secondary_start_sbi:
>> >>         call relocate_enable_mmu
>> >>  #endif
>> >>         call .Lsetup_trap_vector
>> >> +       li a7, SBI_EXT_FWFT
>> >> +       li a6, SBI_EXT_FWFT_SET
>> >> +       li a0, SBI_FWFT_SHADOW_STACK
>> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
>> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
>> >> +       ecall
>> >>         scs_load_current
>> >>         call smp_callin
>> >>  #endif /* CONFIG_SMP */
>> >> @@ -320,6 +326,12 @@ SYM_CODE_START(_start_kernel)
>> >>         la tp, init_task
>> >>         la sp, init_thread_union + THREAD_SIZE
>> >>         addi sp, sp, -PT_SIZE_ON_STACK
>> >> +       li a7, SBI_EXT_FWFT
>> >> +       li a6, SBI_EXT_FWFT_SET
>> >> +       li a0, SBI_FWFT_SHADOW_STACK
>> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
>> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
>> >> +       ecall
>> >>         scs_load_current
>> >>
>> >>  #ifdef CONFIG_KASAN
>> >>
>> >> --
>> >> 2.45.0
>> >>
>> >Should we clear the SBI_FWFT_SET_FLAG_LOCK before the cpu hotplug
>> >otherwise the menvcfg.sse won't be set by the fwft set sbi call when
>> >the hotplug cpu back to kernel?
>>
>> Hmm...
>>
>> An incoming hotplug CPU has no features setup on it.
>> I see that `sbi_cpu_start` will supply `secondary_start_sbi` as start
>> up code for incoming CPU. `secondary_start_sbi` is in head.S which converges
>> in `.Lsecondary_start_common`. And thus hotplugged CPU should be
>> issuing shadow stack set FWFT sbi as well.
>>
>> Am I missing something ?
>>
>This is the correct flow. However the opensbi will deny it due to the
>SBI_FWFT_SET_FLAG_LOCK already being set.
>So the menvcfg.sse will not set by this flow.
>
>if (conf->flags & SBI_FWFT_SET_FLAG_LOCK)
>                return SBI_EDENIED;
>

hmm... Why?

`conf` is pointing to per-hart state in firmware.

On this incoming cpu, opensbi (or equivalent) firmware must have
ensured that this per-hart state doesn't have lock set.

Am I missing something?

>Regards,
>Nick
>> >
>> >Regards,
>> >Nick
>> >>
>> >> _______________________________________________
>> >> linux-riscv mailing list
>> >> linux-riscv at lists.infradead.org
>> >> http://lists.infradead.org/mailman/listinfo/linux-riscv


From charlie at rivosinc.com  Wed Nov 13 18:21:06 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:06 -0800
Subject: [PATCH v11 00/14] riscv: Add support for xtheadvector
Message-ID: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>

xtheadvector is a custom extension that is based upon riscv vector
version 0.7.1 [1]. All of the vector routines have been modified to
support this alternative vector version based upon whether xtheadvector
was determined to be supported at boot.

vlenb is not supported on the existing xtheadvector hardware, so a
devicetree property thead,vlenb is added to provide the vlenb to Linux.

There is a new hwprobe key RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 that is
used to request which thead vendor extensions are supported on the
current platform. This allows future vendors to allocate hwprobe keys
for their vendor.

Support for xtheadvector is also added to the vector kselftests.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>

[1] https://github.com/T-head-Semi/thead-extension-spec/blob/95358cb2cca9489361c61d335e03d3134b14133f/xtheadvector.adoc

---
This series is a continuation of a different series that was fragmented
into two other series in an attempt to get part of it merged in the 6.10
merge window. The split-off series did not get merged due to a NAK on
the series that added the generic riscv,vlenb devicetree entry. This
series has converted riscv,vlenb to thead,vlenb to remedy this issue.

The original series is titled "riscv: Support vendor extensions and
xtheadvector" [3].

I have tested this with an Allwinner Nezha board. I used SkiffOS [1] to
manage building the image, but upgraded the U-Boot version to Samuel
Holland's more up-to-date version [2] and changed out the device tree
used by U-Boot with the device trees that are present in upstream linux
and this series. Thank you Samuel for all of the work you did to make
this task possible.

[1] https://github.com/skiffos/SkiffOS/tree/master/configs/allwinner/nezha
[2] https://github.com/smaeul/u-boot/commit/2e89b706f5c956a70c989cd31665f1429e9a0b48
[3] https://lore.kernel.org/all/20240503-dev-charlie-support_thead_vector_6_9-v6-0-cb7624e65d82 at rivosinc.com/
[4] https://lore.kernel.org/lkml/20240719-support_vendor_extensions-v3-4-0af7587bbec0 at rivosinc.com/T/

---
Changes in v11:
- Fix an issue where the mitigation was not being properly skipped when
  requested
- Fix vstate_discard issue
- Fix issue when -1 was passed into
  __riscv_isa_vendor_extension_available()
- Remove some artifacts from being placed in the test directory
- Link to v10: https://lore.kernel.org/r/20240911-xtheadvector-v10-0-8d3930091246 at rivosinc.com

Changes in v10:
- In DT probing disable vector with new function to clear vendor
  extension bits for xtheadvector
- Add ghostwrite mitigations for c9xx CPUs. This disables xtheadvector
  unless mitigations=off is set as a kernel boot arg
- Link to v9: https://lore.kernel.org/r/20240806-xtheadvector-v9-0-62a56d2da5d0 at rivosinc.com

Changes in v9:
- Rebase onto palmer's for-next
- Fix sparse error in arch/riscv/kernel/vendor_extensions/thead.c
- Fix maybe-uninitialized warning in arch/riscv/include/asm/vendor_extensions/vendor_hwprobe.h
- Wrap some long lines
- Link to v8: https://lore.kernel.org/r/20240724-xtheadvector-v8-0-cf043168e137 at rivosinc.com

Changes in v8:
- Rebase onto palmer's for-next
- Link to v7: https://lore.kernel.org/r/20240724-xtheadvector-v7-0-b741910ada3e at rivosinc.com

Changes in v7:
- Add defs for has_xtheadvector_no_alternatives() and has_xtheadvector()
  when vector disabled. (Palmer)
- Link to v6: https://lore.kernel.org/r/20240722-xtheadvector-v6-0-c9af0130fa00 at rivosinc.com

Changes in v6:
- Fix return type of is_vector_supported()/is_xthead_supported() to be bool
- Link to v5: https://lore.kernel.org/r/20240719-xtheadvector-v5-0-4b485fc7d55f at rivosinc.com

Changes in v5:
- Rebase on for-next
- Link to v4: https://lore.kernel.org/r/20240702-xtheadvector-v4-0-2bad6820db11 at rivosinc.com

Changes in v4:
- Replace inline asm with C (Samuel)
- Rename VCSRs to CSRs (Samuel)
- Replace .insn directives with .4byte directives
- Link to v3: https://lore.kernel.org/r/20240619-xtheadvector-v3-0-bff39eb9668e at rivosinc.com

Changes in v3:
- Add back Heiko's signed-off-by (Conor)
- Mark RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 as a bitmask
- Link to v2: https://lore.kernel.org/r/20240610-xtheadvector-v2-0-97a48613ad64 at rivosinc.com

Changes in v2:
- Removed extraneous references to "riscv,vlenb" (Jess)
- Moved declaration of "thead,vlenb" into cpus.yaml and added
  restriction that it's only applicable to thead cores (Conor)
- Check CONFIG_RISCV_ISA_XTHEADVECTOR instead of CONFIG_RISCV_ISA_V for
  thead,vlenb (Jess)
- Fix naming of hwprobe variables (Evan)
- Link to v1: https://lore.kernel.org/r/20240609-xtheadvector-v1-0-3fe591d7f109 at rivosinc.com

---
Charlie Jenkins (13):
      dt-bindings: riscv: Add xtheadvector ISA extension description
      dt-bindings: cpus: add a thead vlen register length property
      riscv: dts: allwinner: Add xtheadvector to the D1/D1s devicetree
      riscv: Add thead and xtheadvector as a vendor extension
      riscv: vector: Use vlenb from DT for thead
      riscv: csr: Add CSR encodings for CSR_VXRM/CSR_VXSAT
      riscv: Add xtheadvector instruction definitions
      riscv: vector: Support xtheadvector save/restore
      riscv: hwprobe: Add thead vendor extension probing
      riscv: hwprobe: Document thead vendor extensions and xtheadvector extension
      selftests: riscv: Fix vector tests
      selftests: riscv: Support xtheadvector in vector tests
      riscv: Add ghostwrite vulnerability

Heiko Stuebner (1):
      RISC-V: define the elements of the VCSR vector CSR

 Documentation/arch/riscv/hwprobe.rst               |  10 +
 Documentation/devicetree/bindings/riscv/cpus.yaml  |  19 ++
 .../devicetree/bindings/riscv/extensions.yaml      |  10 +
 arch/riscv/Kconfig.errata                          |  11 +
 arch/riscv/Kconfig.vendor                          |  26 ++
 arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi      |   3 +-
 arch/riscv/errata/thead/errata.c                   |  28 ++
 arch/riscv/include/asm/bugs.h                      |  22 ++
 arch/riscv/include/asm/cpufeature.h                |   2 +
 arch/riscv/include/asm/csr.h                       |  15 +
 arch/riscv/include/asm/errata_list.h               |   3 +-
 arch/riscv/include/asm/hwprobe.h                   |   3 +-
 arch/riscv/include/asm/switch_to.h                 |   2 +-
 arch/riscv/include/asm/vector.h                    | 222 +++++++++++----
 arch/riscv/include/asm/vendor_extensions/thead.h   |  47 ++++
 .../include/asm/vendor_extensions/thead_hwprobe.h  |  19 ++
 .../include/asm/vendor_extensions/vendor_hwprobe.h |  37 +++
 arch/riscv/include/uapi/asm/hwprobe.h              |   3 +-
 arch/riscv/include/uapi/asm/vendor/thead.h         |   3 +
 arch/riscv/kernel/Makefile                         |   2 +
 arch/riscv/kernel/bugs.c                           |  60 ++++
 arch/riscv/kernel/cpufeature.c                     |  59 +++-
 arch/riscv/kernel/kernel_mode_vector.c             |   8 +-
 arch/riscv/kernel/process.c                        |   4 +-
 arch/riscv/kernel/signal.c                         |   6 +-
 arch/riscv/kernel/sys_hwprobe.c                    |   5 +
 arch/riscv/kernel/vector.c                         |  24 +-
 arch/riscv/kernel/vendor_extensions.c              |  10 +
 arch/riscv/kernel/vendor_extensions/Makefile       |   2 +
 arch/riscv/kernel/vendor_extensions/thead.c        |  29 ++
 .../riscv/kernel/vendor_extensions/thead_hwprobe.c |  19 ++
 drivers/base/cpu.c                                 |   3 +
 include/linux/cpu.h                                |   1 +
 tools/testing/selftests/riscv/vector/.gitignore    |   3 +-
 tools/testing/selftests/riscv/vector/Makefile      |  17 +-
 .../selftests/riscv/vector/v_exec_initval_nolibc.c |  94 +++++++
 tools/testing/selftests/riscv/vector/v_helpers.c   |  68 +++++
 tools/testing/selftests/riscv/vector/v_helpers.h   |   8 +
 tools/testing/selftests/riscv/vector/v_initval.c   |  22 ++
 .../selftests/riscv/vector/v_initval_nolibc.c      |  68 -----
 .../selftests/riscv/vector/vstate_exec_nolibc.c    |  20 +-
 .../testing/selftests/riscv/vector/vstate_prctl.c  | 305 +++++++++++++--------
 42 files changed, 1051 insertions(+), 271 deletions(-)
---
base-commit: 0eb512779d642b21ced83778287a0f7a3ca8f2a1
change-id: 20240530-xtheadvector-833d3d17b423
-- 
- Charlie



From charlie at rivosinc.com  Wed Nov 13 18:21:07 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:07 -0800
Subject: [PATCH v11 01/14] dt-bindings: riscv: Add xtheadvector ISA
 extension description
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-1-236c22791ef9@rivosinc.com>

The xtheadvector ISA extension is described on the T-Head extension spec
Github page [1] at commit 95358cb2cca9.

Link: https://github.com/T-head-Semi/thead-extension-spec/blob/95358cb2cca9489361c61d335e03d3134b14133f/xtheadvector.adoc [1]

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 Documentation/devicetree/bindings/riscv/extensions.yaml | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
index af7e5237b2c0..b49278e2f2aa 100644
--- a/Documentation/devicetree/bindings/riscv/extensions.yaml
+++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
@@ -593,6 +593,10 @@ properties:
             latency, as ratified in commit 56ed795 ("Update
             riscv-crypto-spec-vector.adoc") of riscv-crypto.
 
+        # vendor extensions, each extension sorted alphanumerically under the
+        # vendor they belong to. Vendors are sorted alphanumerically as well.
+
+        # Andes
         - const: xandespmu
           description:
             The Andes Technology performance monitor extension for counter overflow
@@ -600,6 +604,12 @@ properties:
             Registers in the AX45MP datasheet.
             https://www.andestech.com/wp-content/uploads/AX45MP-1C-Rev.-5.0.0-Datasheet.pdf
 
+        # T-HEAD
+        - const: xtheadvector
+          description:
+            The T-HEAD specific 0.7.1 vector implementation as written in
+            https://github.com/T-head-Semi/thead-extension-spec/blob/95358cb2cca9489361c61d335e03d3134b14133f/xtheadvector.adoc.
+
     allOf:
       # Zcb depends on Zca
       - if:

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:08 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:08 -0800
Subject: [PATCH v11 02/14] dt-bindings: cpus: add a thead vlen register
 length property
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-2-236c22791ef9@rivosinc.com>

Add a property analogous to the vlenb CSR so that software can detect
the vector length of each CPU prior to it being brought online.
Currently software has to assume that the vector length read from the
boot CPU applies to all possible CPUs. On T-Head CPUs implementing
pre-ratification vector, reading the th.vlenb CSR may produce an illegal
instruction trap, so this property is required on such systems.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 Documentation/devicetree/bindings/riscv/cpus.yaml | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml
index 8edc8261241a..c0cf6cf56749 100644
--- a/Documentation/devicetree/bindings/riscv/cpus.yaml
+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
@@ -26,6 +26,18 @@ description: |
 allOf:
   - $ref: /schemas/cpu.yaml#
   - $ref: extensions.yaml
+  - if:
+      not:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - thead,c906
+                - thead,c910
+                - thead,c920
+    then:
+      properties:
+        thead,vlenb: false
 
 properties:
   compatible:
@@ -95,6 +107,13 @@ properties:
     description:
       The blocksize in bytes for the Zicboz cache operations.
 
+  thead,vlenb:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      VLEN/8, the vector register length in bytes. This property is required on
+      thead systems where the vector register length is not identical on all harts, or
+      the vlenb CSR is not available.
+
   # RISC-V has multiple properties for cache op block sizes as the sizes
   # differ between individual CBO extensions
   cache-op-block-size: false

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:09 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:09 -0800
Subject: [PATCH v11 03/14] riscv: dts: allwinner: Add xtheadvector to the
 D1/D1s devicetree
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-3-236c22791ef9@rivosinc.com>

The D1/D1s SoCs support xtheadvector so it can be included in the
devicetree. Also include vlenb for the cpu.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
index 64c3c2e6cbe0..6367112e614a 100644
--- a/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi
@@ -27,7 +27,8 @@ cpu0: cpu at 0 {
 			riscv,isa = "rv64imafdc";
 			riscv,isa-base = "rv64i";
 			riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
-					       "zifencei", "zihpm";
+					       "zifencei", "zihpm", "xtheadvector";
+			thead,vlenb = <128>;
 			#cooling-cells = <2>;
 
 			cpu0_intc: interrupt-controller {

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:10 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:10 -0800
Subject: [PATCH v11 04/14] riscv: Add thead and xtheadvector as a vendor
 extension
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-4-236c22791ef9@rivosinc.com>

Add support to the kernel for THead vendor extensions with the target of
the new extension xtheadvector.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 arch/riscv/Kconfig.vendor                        | 13 +++++++++++++
 arch/riscv/include/asm/vendor_extensions/thead.h | 16 ++++++++++++++++
 arch/riscv/kernel/cpufeature.c                   |  1 +
 arch/riscv/kernel/vendor_extensions.c            | 10 ++++++++++
 arch/riscv/kernel/vendor_extensions/Makefile     |  1 +
 arch/riscv/kernel/vendor_extensions/thead.c      | 18 ++++++++++++++++++
 6 files changed, 59 insertions(+)

diff --git a/arch/riscv/Kconfig.vendor b/arch/riscv/Kconfig.vendor
index 6f1cdd32ed29..9897442bd44f 100644
--- a/arch/riscv/Kconfig.vendor
+++ b/arch/riscv/Kconfig.vendor
@@ -16,4 +16,17 @@ config RISCV_ISA_VENDOR_EXT_ANDES
 	  If you don't know what to do here, say Y.
 endmenu
 
+menu "T-Head"
+config RISCV_ISA_VENDOR_EXT_THEAD
+	bool "T-Head vendor extension support"
+	select RISCV_ISA_VENDOR_EXT
+	default y
+	help
+	  Say N here to disable detection of and support for all T-Head vendor
+	  extensions. Without this option enabled, T-Head vendor extensions will
+	  not be detected at boot and their presence not reported to userspace.
+
+	  If you don't know what to do here, say Y.
+endmenu
+
 endmenu
diff --git a/arch/riscv/include/asm/vendor_extensions/thead.h b/arch/riscv/include/asm/vendor_extensions/thead.h
new file mode 100644
index 000000000000..48421d1553ad
--- /dev/null
+++ b/arch/riscv/include/asm/vendor_extensions/thead.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RISCV_VENDOR_EXTENSIONS_THEAD_H
+#define _ASM_RISCV_VENDOR_EXTENSIONS_THEAD_H
+
+#include <asm/vendor_extensions.h>
+
+#include <linux/types.h>
+
+/*
+ * Extension keys must be strictly less than RISCV_ISA_VENDOR_EXT_MAX.
+ */
+#define RISCV_ISA_VENDOR_EXT_XTHEADVECTOR		0
+
+extern struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_thead;
+
+#endif
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index eb904ca64ad0..d752291d829b 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -25,6 +25,7 @@
 #include <asm/sbi.h>
 #include <asm/vector.h>
 #include <asm/vendor_extensions.h>
+#include <asm/vendor_extensions/thead.h>
 
 #define NUM_ALPHA_EXTS ('z' - 'a' + 1)
 
diff --git a/arch/riscv/kernel/vendor_extensions.c b/arch/riscv/kernel/vendor_extensions.c
index a8126d118341..a31ff84740eb 100644
--- a/arch/riscv/kernel/vendor_extensions.c
+++ b/arch/riscv/kernel/vendor_extensions.c
@@ -6,6 +6,7 @@
 #include <asm/vendorid_list.h>
 #include <asm/vendor_extensions.h>
 #include <asm/vendor_extensions/andes.h>
+#include <asm/vendor_extensions/thead.h>
 
 #include <linux/array_size.h>
 #include <linux/types.h>
@@ -14,6 +15,9 @@ struct riscv_isa_vendor_ext_data_list *riscv_isa_vendor_ext_list[] = {
 #ifdef CONFIG_RISCV_ISA_VENDOR_EXT_ANDES
 	&riscv_isa_vendor_ext_list_andes,
 #endif
+#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_THEAD
+	&riscv_isa_vendor_ext_list_thead,
+#endif
 };
 
 const size_t riscv_isa_vendor_ext_list_size = ARRAY_SIZE(riscv_isa_vendor_ext_list);
@@ -41,6 +45,12 @@ bool __riscv_isa_vendor_extension_available(int cpu, unsigned long vendor, unsig
 		cpu_bmap = riscv_isa_vendor_ext_list_andes.per_hart_isa_bitmap;
 		break;
 	#endif
+	#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_THEAD
+	case THEAD_VENDOR_ID:
+		bmap = &riscv_isa_vendor_ext_list_thead.all_harts_isa_bitmap;
+		cpu_bmap = riscv_isa_vendor_ext_list_thead.per_hart_isa_bitmap;
+		break;
+	#endif
 	default:
 		return false;
 	}
diff --git a/arch/riscv/kernel/vendor_extensions/Makefile b/arch/riscv/kernel/vendor_extensions/Makefile
index 6a61aed944f1..353522cb3bf0 100644
--- a/arch/riscv/kernel/vendor_extensions/Makefile
+++ b/arch/riscv/kernel/vendor_extensions/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 obj-$(CONFIG_RISCV_ISA_VENDOR_EXT_ANDES)	+= andes.o
+obj-$(CONFIG_RISCV_ISA_VENDOR_EXT_THEAD)	+= thead.o
diff --git a/arch/riscv/kernel/vendor_extensions/thead.c b/arch/riscv/kernel/vendor_extensions/thead.c
new file mode 100644
index 000000000000..0f27baf8d245
--- /dev/null
+++ b/arch/riscv/kernel/vendor_extensions/thead.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <asm/cpufeature.h>
+#include <asm/vendor_extensions.h>
+#include <asm/vendor_extensions/thead.h>
+
+#include <linux/array_size.h>
+#include <linux/types.h>
+
+/* All T-Head vendor extensions supported in Linux */
+static const struct riscv_isa_ext_data riscv_isa_vendor_ext_thead[] = {
+	__RISCV_ISA_EXT_DATA(xtheadvector, RISCV_ISA_VENDOR_EXT_XTHEADVECTOR),
+};
+
+struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_thead = {
+	.ext_data_count = ARRAY_SIZE(riscv_isa_vendor_ext_thead),
+	.ext_data = riscv_isa_vendor_ext_thead,
+};

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:11 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:11 -0800
Subject: [PATCH v11 05/14] riscv: vector: Use vlenb from DT for thead
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-5-236c22791ef9@rivosinc.com>

If thead,vlenb is provided in the device tree, prefer that over reading
the vlenb csr.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 arch/riscv/Kconfig.vendor                        | 13 +++++++
 arch/riscv/include/asm/cpufeature.h              |  2 +
 arch/riscv/include/asm/vendor_extensions/thead.h |  6 +++
 arch/riscv/kernel/cpufeature.c                   | 48 ++++++++++++++++++++++++
 arch/riscv/kernel/vector.c                       | 12 +++++-
 arch/riscv/kernel/vendor_extensions/thead.c      | 11 ++++++
 6 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/Kconfig.vendor b/arch/riscv/Kconfig.vendor
index 9897442bd44f..b096548fe0ff 100644
--- a/arch/riscv/Kconfig.vendor
+++ b/arch/riscv/Kconfig.vendor
@@ -26,6 +26,19 @@ config RISCV_ISA_VENDOR_EXT_THEAD
 	  extensions. Without this option enabled, T-Head vendor extensions will
 	  not be detected at boot and their presence not reported to userspace.
 
+	  If you don't know what to do here, say Y.
+
+config RISCV_ISA_XTHEADVECTOR
+	bool "xtheadvector extension support"
+	depends on RISCV_ISA_VENDOR_EXT_THEAD
+	depends on RISCV_ISA_V
+	depends on FPU
+	default y
+	help
+	  Say N here if you want to disable all xtheadvector related procedures
+	  in the kernel. This will disable vector for any T-Head board that
+	  contains xtheadvector rather than the standard vector.
+
 	  If you don't know what to do here, say Y.
 endmenu
 
diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h
index 4bd054c54c21..569140d6e639 100644
--- a/arch/riscv/include/asm/cpufeature.h
+++ b/arch/riscv/include/asm/cpufeature.h
@@ -34,6 +34,8 @@ DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
 /* Per-cpu ISA extensions. */
 extern struct riscv_isainfo hart_isa[NR_CPUS];
 
+extern u32 thead_vlenb_of;
+
 void __init riscv_user_isa_enable(void);
 
 #define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) {	\
diff --git a/arch/riscv/include/asm/vendor_extensions/thead.h b/arch/riscv/include/asm/vendor_extensions/thead.h
index 48421d1553ad..93fcbf46c87e 100644
--- a/arch/riscv/include/asm/vendor_extensions/thead.h
+++ b/arch/riscv/include/asm/vendor_extensions/thead.h
@@ -13,4 +13,10 @@
 
 extern struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_thead;
 
+#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_THEAD
+void disable_xtheadvector(void);
+#else
+static inline void disable_xtheadvector(void) { }
+#endif
+
 #endif
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index d752291d829b..7d9e8bbfaef2 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -39,6 +39,8 @@ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
 /* Per-cpu ISA extensions. */
 struct riscv_isainfo hart_isa[NR_CPUS];
 
+u32 thead_vlenb_of;
+
 /**
  * riscv_isa_extension_base() - Get base extension word
  *
@@ -779,6 +781,46 @@ static void __init riscv_fill_vendor_ext_list(int cpu)
 	}
 }
 
+static int has_thead_homogeneous_vlenb(void)
+{
+	int cpu;
+	u32 prev_vlenb = 0;
+	u32 vlenb;
+
+	/* Ignore thead,vlenb property if xtheavector is not enabled in the kernel */
+	if (!IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR))
+		return 0;
+
+	for_each_possible_cpu(cpu) {
+		struct device_node *cpu_node;
+
+		cpu_node = of_cpu_device_node_get(cpu);
+		if (!cpu_node) {
+			pr_warn("Unable to find cpu node\n");
+			return -ENOENT;
+		}
+
+		if (of_property_read_u32(cpu_node, "thead,vlenb", &vlenb)) {
+			of_node_put(cpu_node);
+
+			if (prev_vlenb)
+				return -ENOENT;
+			continue;
+		}
+
+		if (prev_vlenb && vlenb != prev_vlenb) {
+			of_node_put(cpu_node);
+			return -ENOENT;
+		}
+
+		prev_vlenb = vlenb;
+		of_node_put(cpu_node);
+	}
+
+	thead_vlenb_of = vlenb;
+	return 0;
+}
+
 static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
 {
 	unsigned int cpu;
@@ -832,6 +874,12 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
 		riscv_fill_vendor_ext_list(cpu);
 	}
 
+	if (riscv_isa_vendor_extension_available(THEAD_VENDOR_ID, XTHEADVECTOR) &&
+	    has_thead_homogeneous_vlenb() < 0) {
+		pr_warn("Unsupported heterogeneous vlenb detected, vector extension disabled.\n");
+		disable_xtheadvector();
+	}
+
 	if (bitmap_empty(riscv_isa, RISCV_ISA_EXT_MAX))
 		return -ENOENT;
 
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 821818886fab..3877a0454239 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -33,7 +33,17 @@ int riscv_v_setup_vsize(void)
 {
 	unsigned long this_vsize;
 
-	/* There are 32 vector registers with vlenb length. */
+	/*
+	 * There are 32 vector registers with vlenb length.
+	 *
+	 * If the thead,vlenb property was provided by the firmware, use that
+	 * instead of probing the CSRs.
+	 */
+	if (thead_vlenb_of) {
+		riscv_v_vsize = thead_vlenb_of * 32;
+		return 0;
+	}
+
 	riscv_v_enable();
 	this_vsize = csr_read(CSR_VLENB) * 32;
 	riscv_v_disable();
diff --git a/arch/riscv/kernel/vendor_extensions/thead.c b/arch/riscv/kernel/vendor_extensions/thead.c
index 0f27baf8d245..519dbf70710a 100644
--- a/arch/riscv/kernel/vendor_extensions/thead.c
+++ b/arch/riscv/kernel/vendor_extensions/thead.c
@@ -5,6 +5,7 @@
 #include <asm/vendor_extensions/thead.h>
 
 #include <linux/array_size.h>
+#include <linux/cpumask.h>
 #include <linux/types.h>
 
 /* All T-Head vendor extensions supported in Linux */
@@ -16,3 +17,13 @@ struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_thead = {
 	.ext_data_count = ARRAY_SIZE(riscv_isa_vendor_ext_thead),
 	.ext_data = riscv_isa_vendor_ext_thead,
 };
+
+void disable_xtheadvector(void)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		clear_bit(RISCV_ISA_VENDOR_EXT_XTHEADVECTOR, riscv_isa_vendor_ext_list_thead.per_hart_isa_bitmap[cpu].isa);
+
+	clear_bit(RISCV_ISA_VENDOR_EXT_XTHEADVECTOR, riscv_isa_vendor_ext_list_thead.all_harts_isa_bitmap.isa);
+}

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:12 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:12 -0800
Subject: [PATCH v11 06/14] RISC-V: define the elements of the VCSR vector
 CSR
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-6-236c22791ef9@rivosinc.com>

From: Heiko Stuebner <heiko at sntech.de>

The VCSR CSR contains two elements VXRM[2:1] and VXSAT[0].

Define constants for those to access the elements in a readable way.

Acked-by: Guo Ren <guoren at kernel.org>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner at vrull.eu>
Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 arch/riscv/include/asm/csr.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index fe5d4eb9adea..db1d26dfaef9 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -314,6 +314,10 @@
 #define CSR_STIMECMP		0x14D
 #define CSR_STIMECMPH		0x15D
 
+#define VCSR_VXRM_MASK			3
+#define VCSR_VXRM_SHIFT			1
+#define VCSR_VXSAT_MASK			1
+
 /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
 #define CSR_SISELECT		0x150
 #define CSR_SIREG		0x151

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:13 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:13 -0800
Subject: [PATCH v11 07/14] riscv: csr: Add CSR encodings for
 CSR_VXRM/CSR_VXSAT
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-7-236c22791ef9@rivosinc.com>

The VXRM vector csr for xtheadvector has an encoding of 0xa and VXSAT
has an encoding of 0x9.

Co-developed-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 arch/riscv/include/asm/csr.h | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index db1d26dfaef9..2155f5afffd6 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -314,9 +314,14 @@
 #define CSR_STIMECMP		0x14D
 #define CSR_STIMECMPH		0x15D
 
-#define VCSR_VXRM_MASK			3
-#define VCSR_VXRM_SHIFT			1
-#define VCSR_VXSAT_MASK			1
+/* xtheadvector symbolic CSR names */
+#define CSR_VXSAT		0x9
+#define CSR_VXRM		0xa
+
+/* xtheadvector CSR masks */
+#define CSR_VXRM_MASK		3
+#define CSR_VXRM_SHIFT		1
+#define CSR_VXSAT_MASK		1
 
 /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
 #define CSR_SISELECT		0x150

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:14 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:14 -0800
Subject: [PATCH v11 08/14] riscv: Add xtheadvector instruction definitions
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-8-236c22791ef9@rivosinc.com>

xtheadvector uses different encodings than standard vector for
vsetvli and vector loads/stores. Write the instruction formats to be
used in assembly code.

Co-developed-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 arch/riscv/include/asm/vendor_extensions/thead.h | 25 ++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/riscv/include/asm/vendor_extensions/thead.h b/arch/riscv/include/asm/vendor_extensions/thead.h
index 93fcbf46c87e..e85c75b3b340 100644
--- a/arch/riscv/include/asm/vendor_extensions/thead.h
+++ b/arch/riscv/include/asm/vendor_extensions/thead.h
@@ -19,4 +19,29 @@ void disable_xtheadvector(void);
 static inline void disable_xtheadvector(void) { }
 #endif
 
+/* Extension specific helpers */
+
+/*
+ * Vector 0.7.1 as used for example on T-Head Xuantie cores, uses an older
+ * encoding for vsetvli (ta, ma vs. d1), so provide an instruction for
+ * vsetvli	t4, x0, e8, m8, d1
+ */
+#define THEAD_VSETVLI_T4X0E8M8D1	".long	0x00307ed7\n\t"
+
+/*
+ * While in theory, the vector-0.7.1 vsb.v and vlb.v result in the same
+ * encoding as the standard vse8.v and vle8.v, compilers seem to optimize
+ * the call resulting in a different encoding and then using a value for
+ * the "mop" field that is not part of vector-0.7.1
+ * So encode specific variants for vstate_save and _restore.
+ */
+#define THEAD_VSB_V_V0T0		".long	0x02028027\n\t"
+#define THEAD_VSB_V_V8T0		".long	0x02028427\n\t"
+#define THEAD_VSB_V_V16T0		".long	0x02028827\n\t"
+#define THEAD_VSB_V_V24T0		".long	0x02028c27\n\t"
+#define THEAD_VLB_V_V0T0		".long	0x012028007\n\t"
+#define THEAD_VLB_V_V8T0		".long	0x012028407\n\t"
+#define THEAD_VLB_V_V16T0		".long	0x012028807\n\t"
+#define THEAD_VLB_V_V24T0		".long	0x012028c07\n\t"
+
 #endif

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:16 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:16 -0800
Subject: [PATCH v11 10/14] riscv: hwprobe: Add thead vendor extension
 probing
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-10-236c22791ef9@rivosinc.com>

Add a new hwprobe key "RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0" which
allows userspace to probe for the new RISCV_ISA_VENDOR_EXT_XTHEADVECTOR
vendor extension.

This new key will allow userspace code to probe for which thead vendor
extensions are supported. This API is modeled to be consistent with
RISCV_HWPROBE_KEY_IMA_EXT_0. The bitmask returned will have each bit
corresponding to a supported thead vendor extension of the cpumask set.
Just like RISCV_HWPROBE_KEY_IMA_EXT_0, this allows a userspace program
to determine all of the supported thead vendor extensions in one call.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Reviewed-by: Evan Green <evan at rivosinc.com>
---
 arch/riscv/include/asm/hwprobe.h                   |  3 +-
 .../include/asm/vendor_extensions/thead_hwprobe.h  | 19 +++++++++++
 .../include/asm/vendor_extensions/vendor_hwprobe.h | 37 ++++++++++++++++++++++
 arch/riscv/include/uapi/asm/hwprobe.h              |  3 +-
 arch/riscv/include/uapi/asm/vendor/thead.h         |  3 ++
 arch/riscv/kernel/sys_hwprobe.c                    |  5 +++
 arch/riscv/kernel/vendor_extensions/Makefile       |  1 +
 .../riscv/kernel/vendor_extensions/thead_hwprobe.c | 19 +++++++++++
 8 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/hwprobe.h b/arch/riscv/include/asm/hwprobe.h
index 1ce1df6d0ff3..fb2c27a6e5f6 100644
--- a/arch/riscv/include/asm/hwprobe.h
+++ b/arch/riscv/include/asm/hwprobe.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
- * Copyright 2023 Rivos, Inc
+ * Copyright 2023-2024 Rivos, Inc
  */
 
 #ifndef _ASM_HWPROBE_H
@@ -21,6 +21,7 @@ static inline bool hwprobe_key_is_bitmask(__s64 key)
 	case RISCV_HWPROBE_KEY_BASE_BEHAVIOR:
 	case RISCV_HWPROBE_KEY_IMA_EXT_0:
 	case RISCV_HWPROBE_KEY_CPUPERF_0:
+	case RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0:
 		return true;
 	}
 
diff --git a/arch/riscv/include/asm/vendor_extensions/thead_hwprobe.h b/arch/riscv/include/asm/vendor_extensions/thead_hwprobe.h
new file mode 100644
index 000000000000..65a9c5612466
--- /dev/null
+++ b/arch/riscv/include/asm/vendor_extensions/thead_hwprobe.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RISCV_VENDOR_EXTENSIONS_THEAD_HWPROBE_H
+#define _ASM_RISCV_VENDOR_EXTENSIONS_THEAD_HWPROBE_H
+
+#include <linux/cpumask.h>
+
+#include <uapi/asm/hwprobe.h>
+
+#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_THEAD
+void hwprobe_isa_vendor_ext_thead_0(struct riscv_hwprobe *pair, const struct cpumask *cpus);
+#else
+static inline void hwprobe_isa_vendor_ext_thead_0(struct riscv_hwprobe *pair,
+						  const struct cpumask *cpus)
+{
+	pair->value = 0;
+}
+#endif
+
+#endif
diff --git a/arch/riscv/include/asm/vendor_extensions/vendor_hwprobe.h b/arch/riscv/include/asm/vendor_extensions/vendor_hwprobe.h
new file mode 100644
index 000000000000..6b9293e984a9
--- /dev/null
+++ b/arch/riscv/include/asm/vendor_extensions/vendor_hwprobe.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2024 Rivos, Inc
+ */
+
+#ifndef _ASM_RISCV_SYS_HWPROBE_H
+#define _ASM_RISCV_SYS_HWPROBE_H
+
+#include <asm/cpufeature.h>
+
+#define VENDOR_EXT_KEY(ext)								\
+	do {										\
+		if (__riscv_isa_extension_available(isainfo->isa, RISCV_ISA_VENDOR_EXT_##ext)) \
+			pair->value |= RISCV_HWPROBE_VENDOR_EXT_##ext;			\
+		else									\
+			missing |= RISCV_HWPROBE_VENDOR_EXT_##ext;			\
+	} while (false)
+
+/*
+ * Loop through and record extensions that 1) anyone has, and 2) anyone
+ * doesn't have.
+ *
+ * _extension_checks is an arbitrary C block to set the values of pair->value
+ * and missing. It should be filled with VENDOR_EXT_KEY expressions.
+ */
+#define VENDOR_EXTENSION_SUPPORTED(pair, cpus, per_hart_vendor_bitmap, _extension_checks)	\
+	do {											\
+		int cpu;									\
+		u64 missing = 0;								\
+		for_each_cpu(cpu, (cpus)) {							\
+			struct riscv_isavendorinfo *isainfo = &(per_hart_vendor_bitmap)[cpu];	\
+			_extension_checks							\
+		}										\
+		(pair)->value &= ~missing;							\
+	} while (false)										\
+
+#endif /* _ASM_RISCV_SYS_HWPROBE_H */
diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
index 3af142b99f77..c3c1cc951cb9 100644
--- a/arch/riscv/include/uapi/asm/hwprobe.h
+++ b/arch/riscv/include/uapi/asm/hwprobe.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 /*
- * Copyright 2023 Rivos, Inc
+ * Copyright 2023-2024 Rivos, Inc
  */
 
 #ifndef _UAPI_ASM_HWPROBE_H
@@ -94,6 +94,7 @@ struct riscv_hwprobe {
 #define		RISCV_HWPROBE_MISALIGNED_VECTOR_SLOW		2
 #define		RISCV_HWPROBE_MISALIGNED_VECTOR_FAST		3
 #define		RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED	4
+#define RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0	11
 /* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
 
 /* Flags */
diff --git a/arch/riscv/include/uapi/asm/vendor/thead.h b/arch/riscv/include/uapi/asm/vendor/thead.h
new file mode 100644
index 000000000000..43790ebe5faf
--- /dev/null
+++ b/arch/riscv/include/uapi/asm/vendor/thead.h
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+
+#define		RISCV_HWPROBE_VENDOR_EXT_XTHEADVECTOR	(1 << 0)
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index 9050f3246264..13eff75d78a8 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -15,6 +15,7 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/vector.h>
+#include <asm/vendor_extensions/thead_hwprobe.h>
 #include <vdso/vsyscall.h>
 
 
@@ -286,6 +287,10 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
 		pair->value = riscv_timebase;
 		break;
 
+	case RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0:
+		hwprobe_isa_vendor_ext_thead_0(pair, cpus);
+		break;
+
 	/*
 	 * For forward compatibility, unknown keys don't fail the whole
 	 * call, but get their element key set to -1 and value set to 0
diff --git a/arch/riscv/kernel/vendor_extensions/Makefile b/arch/riscv/kernel/vendor_extensions/Makefile
index 353522cb3bf0..866414c81a9f 100644
--- a/arch/riscv/kernel/vendor_extensions/Makefile
+++ b/arch/riscv/kernel/vendor_extensions/Makefile
@@ -2,3 +2,4 @@
 
 obj-$(CONFIG_RISCV_ISA_VENDOR_EXT_ANDES)	+= andes.o
 obj-$(CONFIG_RISCV_ISA_VENDOR_EXT_THEAD)	+= thead.o
+obj-$(CONFIG_RISCV_ISA_VENDOR_EXT_THEAD)	+= thead_hwprobe.o
diff --git a/arch/riscv/kernel/vendor_extensions/thead_hwprobe.c b/arch/riscv/kernel/vendor_extensions/thead_hwprobe.c
new file mode 100644
index 000000000000..2eba34011786
--- /dev/null
+++ b/arch/riscv/kernel/vendor_extensions/thead_hwprobe.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <asm/vendor_extensions/thead.h>
+#include <asm/vendor_extensions/thead_hwprobe.h>
+#include <asm/vendor_extensions/vendor_hwprobe.h>
+
+#include <linux/cpumask.h>
+#include <linux/types.h>
+
+#include <uapi/asm/hwprobe.h>
+#include <uapi/asm/vendor/thead.h>
+
+void hwprobe_isa_vendor_ext_thead_0(struct riscv_hwprobe *pair, const struct cpumask *cpus)
+{
+	VENDOR_EXTENSION_SUPPORTED(pair, cpus,
+				   riscv_isa_vendor_ext_list_thead.per_hart_isa_bitmap, {
+		VENDOR_EXT_KEY(XTHEADVECTOR);
+	});
+}

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:15 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:15 -0800
Subject: [PATCH v11 09/14] riscv: vector: Support xtheadvector save/restore
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-9-236c22791ef9@rivosinc.com>

Use alternatives to add support for xtheadvector vector save/restore
routines.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
---
 arch/riscv/include/asm/csr.h           |   6 +
 arch/riscv/include/asm/switch_to.h     |   2 +-
 arch/riscv/include/asm/vector.h        | 222 +++++++++++++++++++++++++--------
 arch/riscv/kernel/cpufeature.c         |   6 +-
 arch/riscv/kernel/kernel_mode_vector.c |   8 +-
 arch/riscv/kernel/process.c            |   4 +-
 arch/riscv/kernel/signal.c             |   6 +-
 arch/riscv/kernel/vector.c             |  12 +-
 8 files changed, 198 insertions(+), 68 deletions(-)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 2155f5afffd6..ee23d0366cb2 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -30,6 +30,12 @@
 #define SR_VS_CLEAN	_AC(0x00000400, UL)
 #define SR_VS_DIRTY	_AC(0x00000600, UL)
 
+#define SR_VS_THEAD		_AC(0x01800000, UL) /* xtheadvector Status */
+#define SR_VS_OFF_THEAD		_AC(0x00000000, UL)
+#define SR_VS_INITIAL_THEAD	_AC(0x00800000, UL)
+#define SR_VS_CLEAN_THEAD	_AC(0x01000000, UL)
+#define SR_VS_DIRTY_THEAD	_AC(0x01800000, UL)
+
 #define SR_XS		_AC(0x00018000, UL) /* Extension Status */
 #define SR_XS_OFF	_AC(0x00000000, UL)
 #define SR_XS_INITIAL	_AC(0x00008000, UL)
diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
index 94e33216b2d9..0e71eb82f920 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -117,7 +117,7 @@ do {							\
 	__set_prev_cpu(__prev->thread);			\
 	if (has_fpu())					\
 		__switch_to_fpu(__prev, __next);	\
-	if (has_vector())					\
+	if (has_vector() || has_xtheadvector())		\
 		__switch_to_vector(__prev, __next);	\
 	if (switch_to_should_flush_icache(__next))	\
 		local_flush_icache_all();		\
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index c7c023afbacd..e8a83f55be2b 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -18,6 +18,27 @@
 #include <asm/cpufeature.h>
 #include <asm/csr.h>
 #include <asm/asm.h>
+#include <asm/vendorid_list.h>
+#include <asm/vendor_extensions.h>
+#include <asm/vendor_extensions/thead.h>
+
+#define __riscv_v_vstate_or(_val, TYPE) ({				\
+	typeof(_val) _res = _val;					\
+	if (has_xtheadvector()) \
+		_res = (_res & ~SR_VS_THEAD) | SR_VS_##TYPE##_THEAD;	\
+	else								\
+		_res = (_res & ~SR_VS) | SR_VS_##TYPE;			\
+	_res;								\
+})
+
+#define __riscv_v_vstate_check(_val, TYPE) ({				\
+	bool _res;							\
+	if (has_xtheadvector()) \
+		_res = ((_val) & SR_VS_THEAD) == SR_VS_##TYPE##_THEAD;	\
+	else								\
+		_res = ((_val) & SR_VS) == SR_VS_##TYPE;		\
+	_res;								\
+})
 
 extern unsigned long riscv_v_vsize;
 int riscv_v_setup_vsize(void);
@@ -41,39 +62,62 @@ static __always_inline bool has_vector(void)
 	return riscv_has_extension_unlikely(RISCV_ISA_EXT_ZVE32X);
 }
 
+static __always_inline bool has_xtheadvector_no_alternatives(void)
+{
+	if (IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR))
+		return riscv_isa_vendor_extension_available(THEAD_VENDOR_ID, XTHEADVECTOR);
+	else
+		return false;
+}
+
+static __always_inline bool has_xtheadvector(void)
+{
+	if (IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR))
+		return riscv_has_vendor_extension_unlikely(THEAD_VENDOR_ID,
+							   RISCV_ISA_VENDOR_EXT_XTHEADVECTOR);
+	else
+		return false;
+}
+
 static inline void __riscv_v_vstate_clean(struct pt_regs *regs)
 {
-	regs->status = (regs->status & ~SR_VS) | SR_VS_CLEAN;
+	regs->status = __riscv_v_vstate_or(regs->status, CLEAN);
 }
 
 static inline void __riscv_v_vstate_dirty(struct pt_regs *regs)
 {
-	regs->status = (regs->status & ~SR_VS) | SR_VS_DIRTY;
+	regs->status = __riscv_v_vstate_or(regs->status, DIRTY);
 }
 
 static inline void riscv_v_vstate_off(struct pt_regs *regs)
 {
-	regs->status = (regs->status & ~SR_VS) | SR_VS_OFF;
+	regs->status = __riscv_v_vstate_or(regs->status, OFF);
 }
 
 static inline void riscv_v_vstate_on(struct pt_regs *regs)
 {
-	regs->status = (regs->status & ~SR_VS) | SR_VS_INITIAL;
+	regs->status = __riscv_v_vstate_or(regs->status, INITIAL);
 }
 
 static inline bool riscv_v_vstate_query(struct pt_regs *regs)
 {
-	return (regs->status & SR_VS) != 0;
+	return !__riscv_v_vstate_check(regs->status, OFF);
 }
 
 static __always_inline void riscv_v_enable(void)
 {
-	csr_set(CSR_SSTATUS, SR_VS);
+	if (has_xtheadvector())
+		csr_set(CSR_SSTATUS, SR_VS_THEAD);
+	else
+		csr_set(CSR_SSTATUS, SR_VS);
 }
 
 static __always_inline void riscv_v_disable(void)
 {
-	csr_clear(CSR_SSTATUS, SR_VS);
+	if (has_xtheadvector())
+		csr_clear(CSR_SSTATUS, SR_VS_THEAD);
+	else
+		csr_clear(CSR_SSTATUS, SR_VS);
 }
 
 static __always_inline void __vstate_csr_save(struct __riscv_v_ext_state *dest)
@@ -82,10 +126,36 @@ static __always_inline void __vstate_csr_save(struct __riscv_v_ext_state *dest)
 		"csrr	%0, " __stringify(CSR_VSTART) "\n\t"
 		"csrr	%1, " __stringify(CSR_VTYPE) "\n\t"
 		"csrr	%2, " __stringify(CSR_VL) "\n\t"
-		"csrr	%3, " __stringify(CSR_VCSR) "\n\t"
-		"csrr	%4, " __stringify(CSR_VLENB) "\n\t"
 		: "=r" (dest->vstart), "=r" (dest->vtype), "=r" (dest->vl),
-		  "=r" (dest->vcsr), "=r" (dest->vlenb) : :);
+		"=r" (dest->vcsr) : :);
+
+	if (has_xtheadvector()) {
+		unsigned long status;
+
+		/*
+		 * CSR_VCSR is defined as
+		 * [2:1] - vxrm[1:0]
+		 * [0] - vxsat
+		 * The earlier vector spec implemented by T-Head uses separate
+		 * registers for the same bit-elements, so just combine those
+		 * into the existing output field.
+		 *
+		 * Additionally T-Head cores need FS to be enabled when accessing
+		 * the VXRM and VXSAT CSRs, otherwise ending in illegal instructions.
+		 * Though the cores do not implement the VXRM and VXSAT fields in the
+		 * FCSR CSR that vector-0.7.1 specifies.
+		 */
+		status = csr_read_set(CSR_STATUS, SR_FS_DIRTY);
+		dest->vcsr = csr_read(CSR_VXSAT) | csr_read(CSR_VXRM) << CSR_VXRM_SHIFT;
+
+		dest->vlenb = riscv_v_vsize / 32;
+
+		if ((status & SR_FS) != SR_FS_DIRTY)
+			csr_write(CSR_STATUS, status);
+	} else {
+		dest->vcsr = csr_read(CSR_VCSR);
+		dest->vlenb = csr_read(CSR_VLENB);
+	}
 }
 
 static __always_inline void __vstate_csr_restore(struct __riscv_v_ext_state *src)
@@ -96,9 +166,25 @@ static __always_inline void __vstate_csr_restore(struct __riscv_v_ext_state *src
 		"vsetvl	 x0, %2, %1\n\t"
 		".option pop\n\t"
 		"csrw	" __stringify(CSR_VSTART) ", %0\n\t"
-		"csrw	" __stringify(CSR_VCSR) ", %3\n\t"
-		: : "r" (src->vstart), "r" (src->vtype), "r" (src->vl),
-		    "r" (src->vcsr) :);
+		: : "r" (src->vstart), "r" (src->vtype), "r" (src->vl));
+
+	if (has_xtheadvector()) {
+		unsigned long status = csr_read(CSR_SSTATUS);
+
+		/*
+		 * Similar to __vstate_csr_save above, restore values for the
+		 * separate VXRM and VXSAT CSRs from the vcsr variable.
+		 */
+		status = csr_read_set(CSR_STATUS, SR_FS_DIRTY);
+
+		csr_write(CSR_VXRM, (src->vcsr >> CSR_VXRM_SHIFT) & CSR_VXRM_MASK);
+		csr_write(CSR_VXSAT, src->vcsr & CSR_VXSAT_MASK);
+
+		if ((status & SR_FS) != SR_FS_DIRTY)
+			csr_write(CSR_STATUS, status);
+	} else {
+		csr_write(CSR_VCSR, src->vcsr);
+	}
 }
 
 static inline void __riscv_v_vstate_save(struct __riscv_v_ext_state *save_to,
@@ -108,19 +194,33 @@ static inline void __riscv_v_vstate_save(struct __riscv_v_ext_state *save_to,
 
 	riscv_v_enable();
 	__vstate_csr_save(save_to);
-	asm volatile (
-		".option push\n\t"
-		".option arch, +zve32x\n\t"
-		"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
-		"vse8.v		v0, (%1)\n\t"
-		"add		%1, %1, %0\n\t"
-		"vse8.v		v8, (%1)\n\t"
-		"add		%1, %1, %0\n\t"
-		"vse8.v		v16, (%1)\n\t"
-		"add		%1, %1, %0\n\t"
-		"vse8.v		v24, (%1)\n\t"
-		".option pop\n\t"
-		: "=&r" (vl) : "r" (datap) : "memory");
+	if (has_xtheadvector()) {
+		asm volatile (
+			"mv t0, %0\n\t"
+			THEAD_VSETVLI_T4X0E8M8D1
+			THEAD_VSB_V_V0T0
+			"add		t0, t0, t4\n\t"
+			THEAD_VSB_V_V0T0
+			"add		t0, t0, t4\n\t"
+			THEAD_VSB_V_V0T0
+			"add		t0, t0, t4\n\t"
+			THEAD_VSB_V_V0T0
+			: : "r" (datap) : "memory", "t0", "t4");
+	} else {
+		asm volatile (
+			".option push\n\t"
+			".option arch, +zve32x\n\t"
+			"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
+			"vse8.v		v0, (%1)\n\t"
+			"add		%1, %1, %0\n\t"
+			"vse8.v		v8, (%1)\n\t"
+			"add		%1, %1, %0\n\t"
+			"vse8.v		v16, (%1)\n\t"
+			"add		%1, %1, %0\n\t"
+			"vse8.v		v24, (%1)\n\t"
+			".option pop\n\t"
+			: "=&r" (vl) : "r" (datap) : "memory");
+	}
 	riscv_v_disable();
 }
 
@@ -130,19 +230,33 @@ static inline void __riscv_v_vstate_restore(struct __riscv_v_ext_state *restore_
 	unsigned long vl;
 
 	riscv_v_enable();
-	asm volatile (
-		".option push\n\t"
-		".option arch, +zve32x\n\t"
-		"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
-		"vle8.v		v0, (%1)\n\t"
-		"add		%1, %1, %0\n\t"
-		"vle8.v		v8, (%1)\n\t"
-		"add		%1, %1, %0\n\t"
-		"vle8.v		v16, (%1)\n\t"
-		"add		%1, %1, %0\n\t"
-		"vle8.v		v24, (%1)\n\t"
-		".option pop\n\t"
-		: "=&r" (vl) : "r" (datap) : "memory");
+	if (has_xtheadvector()) {
+		asm volatile (
+			"mv t0, %0\n\t"
+			THEAD_VSETVLI_T4X0E8M8D1
+			THEAD_VLB_V_V0T0
+			"add		t0, t0, t4\n\t"
+			THEAD_VLB_V_V0T0
+			"add		t0, t0, t4\n\t"
+			THEAD_VLB_V_V0T0
+			"add		t0, t0, t4\n\t"
+			THEAD_VLB_V_V0T0
+			: : "r" (datap) : "memory", "t0", "t4");
+	} else {
+		asm volatile (
+			".option push\n\t"
+			".option arch, +zve32x\n\t"
+			"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
+			"vle8.v		v0, (%1)\n\t"
+			"add		%1, %1, %0\n\t"
+			"vle8.v		v8, (%1)\n\t"
+			"add		%1, %1, %0\n\t"
+			"vle8.v		v16, (%1)\n\t"
+			"add		%1, %1, %0\n\t"
+			"vle8.v		v24, (%1)\n\t"
+			".option pop\n\t"
+			: "=&r" (vl) : "r" (datap) : "memory");
+	}
 	__vstate_csr_restore(restore_from);
 	riscv_v_disable();
 }
@@ -152,33 +266,41 @@ static inline void __riscv_v_vstate_discard(void)
 	unsigned long vl, vtype_inval = 1UL << (BITS_PER_LONG - 1);
 
 	riscv_v_enable();
+	if (has_xtheadvector())
+		asm volatile (THEAD_VSETVLI_T4X0E8M8D1 : : : "t4");
+	else
+		asm volatile (
+			".option push\n\t"
+			".option arch, +zve32x\n\t"
+			"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
+			".option pop\n\t": "=&r" (vl));
+
 	asm volatile (
 		".option push\n\t"
 		".option arch, +zve32x\n\t"
-		"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
 		"vmv.v.i	v0, -1\n\t"
 		"vmv.v.i	v8, -1\n\t"
 		"vmv.v.i	v16, -1\n\t"
 		"vmv.v.i	v24, -1\n\t"
 		"vsetvl		%0, x0, %1\n\t"
 		".option pop\n\t"
-		: "=&r" (vl) : "r" (vtype_inval) : "memory");
+		: "=&r" (vl) : "r" (vtype_inval));
+
 	riscv_v_disable();
 }
 
 static inline void riscv_v_vstate_discard(struct pt_regs *regs)
 {
-	if ((regs->status & SR_VS) == SR_VS_OFF)
-		return;
-
-	__riscv_v_vstate_discard();
-	__riscv_v_vstate_dirty(regs);
+	if (riscv_v_vstate_query(regs)) {
+		__riscv_v_vstate_discard();
+		__riscv_v_vstate_dirty(regs);
+	}
 }
 
 static inline void riscv_v_vstate_save(struct __riscv_v_ext_state *vstate,
 				       struct pt_regs *regs)
 {
-	if ((regs->status & SR_VS) == SR_VS_DIRTY) {
+	if (__riscv_v_vstate_check(regs->status, DIRTY)) {
 		__riscv_v_vstate_save(vstate, vstate->datap);
 		__riscv_v_vstate_clean(regs);
 	}
@@ -187,7 +309,7 @@ static inline void riscv_v_vstate_save(struct __riscv_v_ext_state *vstate,
 static inline void riscv_v_vstate_restore(struct __riscv_v_ext_state *vstate,
 					  struct pt_regs *regs)
 {
-	if ((regs->status & SR_VS) != SR_VS_OFF) {
+	if (riscv_v_vstate_query(regs)) {
 		__riscv_v_vstate_restore(vstate, vstate->datap);
 		__riscv_v_vstate_clean(regs);
 	}
@@ -196,7 +318,7 @@ static inline void riscv_v_vstate_restore(struct __riscv_v_ext_state *vstate,
 static inline void riscv_v_vstate_set_restore(struct task_struct *task,
 					      struct pt_regs *regs)
 {
-	if ((regs->status & SR_VS) != SR_VS_OFF) {
+	if (riscv_v_vstate_query(regs)) {
 		set_tsk_thread_flag(task, TIF_RISCV_V_DEFER_RESTORE);
 		riscv_v_vstate_on(regs);
 	}
@@ -270,6 +392,8 @@ struct pt_regs;
 static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; }
 static __always_inline bool has_vector(void) { return false; }
 static __always_inline bool insn_is_vector(u32 insn_buf) { return false; }
+static __always_inline bool has_xtheadvector_no_alternatives(void) { return false; }
+static __always_inline bool has_xtheadvector(void) { return false; }
 static inline bool riscv_v_first_use_handler(struct pt_regs *regs) { return false; }
 static inline bool riscv_v_vstate_query(struct pt_regs *regs) { return false; }
 static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 7d9e8bbfaef2..ba6976132638 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -874,8 +874,7 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
 		riscv_fill_vendor_ext_list(cpu);
 	}
 
-	if (riscv_isa_vendor_extension_available(THEAD_VENDOR_ID, XTHEADVECTOR) &&
-	    has_thead_homogeneous_vlenb() < 0) {
+	if (has_xtheadvector_no_alternatives() && has_thead_homogeneous_vlenb() < 0) {
 		pr_warn("Unsupported heterogeneous vlenb detected, vector extension disabled.\n");
 		disable_xtheadvector();
 	}
@@ -932,7 +931,8 @@ void __init riscv_fill_hwcap(void)
 		elf_hwcap &= ~COMPAT_HWCAP_ISA_F;
 	}
 
-	if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ZVE32X)) {
+	if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ZVE32X) ||
+	    has_xtheadvector_no_alternatives()) {
 		/*
 		 * This cannot fail when called on the boot hart
 		 */
diff --git a/arch/riscv/kernel/kernel_mode_vector.c b/arch/riscv/kernel/kernel_mode_vector.c
index 6afe80c7f03a..99972a48e86b 100644
--- a/arch/riscv/kernel/kernel_mode_vector.c
+++ b/arch/riscv/kernel/kernel_mode_vector.c
@@ -143,7 +143,7 @@ static int riscv_v_start_kernel_context(bool *is_nested)
 
 	/* Transfer the ownership of V from user to kernel, then save */
 	riscv_v_start(RISCV_PREEMPT_V | RISCV_PREEMPT_V_DIRTY);
-	if ((task_pt_regs(current)->status & SR_VS) == SR_VS_DIRTY) {
+	if (__riscv_v_vstate_check(task_pt_regs(current)->status, DIRTY)) {
 		uvstate = &current->thread.vstate;
 		__riscv_v_vstate_save(uvstate, uvstate->datap);
 	}
@@ -160,7 +160,7 @@ asmlinkage void riscv_v_context_nesting_start(struct pt_regs *regs)
 		return;
 
 	depth = riscv_v_ctx_get_depth();
-	if (depth == 0 && (regs->status & SR_VS) == SR_VS_DIRTY)
+	if (depth == 0 && __riscv_v_vstate_check(regs->status, DIRTY))
 		riscv_preempt_v_set_dirty();
 
 	riscv_v_ctx_depth_inc();
@@ -208,7 +208,7 @@ void kernel_vector_begin(void)
 {
 	bool nested = false;
 
-	if (WARN_ON(!has_vector()))
+	if (WARN_ON(!(has_vector() || has_xtheadvector())))
 		return;
 
 	BUG_ON(!may_use_simd());
@@ -236,7 +236,7 @@ EXPORT_SYMBOL_GPL(kernel_vector_begin);
  */
 void kernel_vector_end(void)
 {
-	if (WARN_ON(!has_vector()))
+	if (WARN_ON(!(has_vector() || has_xtheadvector())))
 		return;
 
 	riscv_v_disable();
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 58b6482c2bf6..6534264dfce2 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -190,7 +190,7 @@ void flush_thread(void)
 void arch_release_task_struct(struct task_struct *tsk)
 {
 	/* Free the vector context of datap. */
-	if (has_vector())
+	if (has_vector() || has_xtheadvector())
 		riscv_v_thread_free(tsk);
 }
 
@@ -240,7 +240,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
 		p->thread.s[0] = 0;
 	}
 	p->thread.riscv_v_flags = 0;
-	if (has_vector())
+	if (has_vector() || has_xtheadvector())
 		riscv_v_thread_alloc(p);
 	p->thread.ra = (unsigned long)ret_from_fork;
 	p->thread.sp = (unsigned long)childregs; /* kernel sp */
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index dcd282419456..94e905eea1de 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -189,7 +189,7 @@ static long restore_sigcontext(struct pt_regs *regs,
 
 			return 0;
 		case RISCV_V_MAGIC:
-			if (!has_vector() || !riscv_v_vstate_query(regs) ||
+			if (!(has_vector() || has_xtheadvector()) || !riscv_v_vstate_query(regs) ||
 			    size != riscv_v_sc_size)
 				return -EINVAL;
 
@@ -211,7 +211,7 @@ static size_t get_rt_frame_size(bool cal_all)
 
 	frame_size = sizeof(*frame);
 
-	if (has_vector()) {
+	if (has_vector() || has_xtheadvector()) {
 		if (cal_all || riscv_v_vstate_query(task_pt_regs(current)))
 			total_context_size += riscv_v_sc_size;
 	}
@@ -284,7 +284,7 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
 	if (has_fpu())
 		err |= save_fp_state(regs, &sc->sc_fpregs);
 	/* Save the vector state. */
-	if (has_vector() && riscv_v_vstate_query(regs))
+	if ((has_vector() || has_xtheadvector()) && riscv_v_vstate_query(regs))
 		err |= save_v_state(regs, (void __user **)&sc_ext_ptr);
 	/* Write zero to fp-reserved space and check it on restore_sigcontext */
 	err |= __put_user(0, &sc->sc_extdesc.reserved);
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 3877a0454239..61ded78fcaec 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -63,7 +63,7 @@ int riscv_v_setup_vsize(void)
 
 void __init riscv_v_setup_ctx_cache(void)
 {
-	if (!has_vector())
+	if (!(has_vector() || has_xtheadvector()))
 		return;
 
 	riscv_v_user_cachep = kmem_cache_create_usercopy("riscv_vector_ctx",
@@ -183,7 +183,7 @@ bool riscv_v_first_use_handler(struct pt_regs *regs)
 	u32 __user *epc = (u32 __user *)regs->epc;
 	u32 insn = (u32)regs->badaddr;
 
-	if (!has_vector())
+	if (!(has_vector() || has_xtheadvector()))
 		return false;
 
 	/* Do not handle if V is not supported, or disabled */
@@ -226,7 +226,7 @@ void riscv_v_vstate_ctrl_init(struct task_struct *tsk)
 	bool inherit;
 	int cur, next;
 
-	if (!has_vector())
+	if (!(has_vector() || has_xtheadvector()))
 		return;
 
 	next = riscv_v_ctrl_get_next(tsk);
@@ -248,7 +248,7 @@ void riscv_v_vstate_ctrl_init(struct task_struct *tsk)
 
 long riscv_v_vstate_ctrl_get_current(void)
 {
-	if (!has_vector())
+	if (!(has_vector() || has_xtheadvector()))
 		return -EINVAL;
 
 	return current->thread.vstate_ctrl & PR_RISCV_V_VSTATE_CTRL_MASK;
@@ -259,7 +259,7 @@ long riscv_v_vstate_ctrl_set_current(unsigned long arg)
 	bool inherit;
 	int cur, next;
 
-	if (!has_vector())
+	if (!(has_vector() || has_xtheadvector()))
 		return -EINVAL;
 
 	if (arg & ~PR_RISCV_V_VSTATE_CTRL_MASK)
@@ -309,7 +309,7 @@ static struct ctl_table riscv_v_default_vstate_table[] = {
 
 static int __init riscv_v_sysctl_init(void)
 {
-	if (has_vector())
+	if (has_vector() || has_xtheadvector())
 		if (!register_sysctl("abi", riscv_v_default_vstate_table))
 			return -EINVAL;
 	return 0;

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:17 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:17 -0800
Subject: [PATCH v11 11/14] riscv: hwprobe: Document thead vendor extensions
 and xtheadvector extension
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-11-236c22791ef9@rivosinc.com>

Document support for thead vendor extensions using the key
RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 and xtheadvector extension using
the key RISCV_HWPROBE_VENDOR_EXT_XTHEADVECTOR.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
Reviewed-by: Evan Green <evan at rivosinc.com>
---
 Documentation/arch/riscv/hwprobe.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
index 955fbcd19ce9..f273ea15a8e8 100644
--- a/Documentation/arch/riscv/hwprobe.rst
+++ b/Documentation/arch/riscv/hwprobe.rst
@@ -293,3 +293,13 @@ The following keys are defined:
 
   * :c:macro:`RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED`: Misaligned vector accesses are
     not supported at all and will generate a misaligned address fault.
+
+* :c:macro:`RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0`: A bitmask containing the
+  thead vendor extensions that are compatible with the
+  :c:macro:`RISCV_HWPROBE_BASE_BEHAVIOR_IMA`: base system behavior.
+
+  * T-HEAD
+
+    * :c:macro:`RISCV_HWPROBE_VENDOR_EXT_XTHEADVECTOR`: The xtheadvector vendor
+        extension is supported in the T-Head ISA extensions spec starting from
+	commit a18c801634 ("Add T-Head VECTOR vendor extension. ").

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:19 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:19 -0800
Subject: [PATCH v11 13/14] selftests: riscv: Support xtheadvector in vector
 tests
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-13-236c22791ef9@rivosinc.com>

Extend existing vector tests to be compatible with the xtheadvector
instructions.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 .../selftests/riscv/vector/v_exec_initval_nolibc.c | 23 ++++--
 tools/testing/selftests/riscv/vector/v_helpers.c   | 17 ++++-
 tools/testing/selftests/riscv/vector/v_helpers.h   |  4 +-
 tools/testing/selftests/riscv/vector/v_initval.c   | 12 ++-
 .../selftests/riscv/vector/vstate_exec_nolibc.c    | 20 +++--
 .../testing/selftests/riscv/vector/vstate_prctl.c  | 89 ++++++++++++++--------
 6 files changed, 113 insertions(+), 52 deletions(-)

diff --git a/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c b/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c
index 4a39cab29c34..35c0812e32de 100644
--- a/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c
+++ b/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c
@@ -18,13 +18,22 @@ int main(int argc, char **argv)
 	unsigned long vl;
 	int first = 1;
 
-	asm volatile (
-		".option push\n\t"
-		".option arch, +v\n\t"
-		"vsetvli	%[vl], x0, e8, m1, ta, ma\n\t"
-		".option pop\n\t"
-		: [vl] "=r" (vl)
-	);
+	if (argc > 2 && strcmp(argv[2], "x"))
+		asm volatile (
+			// 0 | zimm[10:0] | rs1 | 1 1 1 | rd |1010111| vsetvli
+			// vsetvli	t4, x0, e8, m1, d1
+			".4byte		0b00000000000000000111111011010111\n\t"
+			"mv		%[vl], t4\n\t"
+			: [vl] "=r" (vl) : : "t4"
+		);
+	else
+		asm volatile (
+			".option push\n\t"
+			".option arch, +v\n\t"
+			"vsetvli	%[vl], x0, e8, m1, ta, ma\n\t"
+			".option pop\n\t"
+			: [vl] "=r" (vl)
+		);
 
 #define CHECK_VECTOR_REGISTER(register) ({					\
 	for (int i = 0; i < vl; i++) {						\
diff --git a/tools/testing/selftests/riscv/vector/v_helpers.c b/tools/testing/selftests/riscv/vector/v_helpers.c
index d50f4dfbf9e5..01a8799dcb78 100644
--- a/tools/testing/selftests/riscv/vector/v_helpers.c
+++ b/tools/testing/selftests/riscv/vector/v_helpers.c
@@ -1,12 +1,22 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
 #include "../hwprobe/hwprobe.h"
+#include <asm/vendor/thead.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/wait.h>
 
+bool is_xtheadvector_supported(void)
+{
+	struct riscv_hwprobe pair;
+
+	pair.key = RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0;
+	riscv_hwprobe(&pair, 1, 0, NULL, 0);
+	return pair.value & RISCV_HWPROBE_VENDOR_EXT_XTHEADVECTOR;
+}
+
 bool is_vector_supported(void)
 {
 	struct riscv_hwprobe pair;
@@ -16,9 +26,9 @@ bool is_vector_supported(void)
 	return pair.value & RISCV_HWPROBE_EXT_ZVE32X;
 }
 
-int launch_test(char *next_program, int test_inherit)
+int launch_test(char *next_program, int test_inherit, int xtheadvector)
 {
-	char *exec_argv[3], *exec_envp[1];
+	char *exec_argv[4], *exec_envp[1];
 	int rc, pid, status;
 
 	pid = fork();
@@ -30,7 +40,8 @@ int launch_test(char *next_program, int test_inherit)
 	if (!pid) {
 		exec_argv[0] = next_program;
 		exec_argv[1] = test_inherit != 0 ? "x" : NULL;
-		exec_argv[2] = NULL;
+		exec_argv[2] = xtheadvector != 0 ? "x" : NULL;
+		exec_argv[3] = NULL;
 		exec_envp[0] = NULL;
 		/* launch the program again to check inherit */
 		rc = execve(next_program, exec_argv, exec_envp);
diff --git a/tools/testing/selftests/riscv/vector/v_helpers.h b/tools/testing/selftests/riscv/vector/v_helpers.h
index faeeeb625b6e..763cddfe26da 100644
--- a/tools/testing/selftests/riscv/vector/v_helpers.h
+++ b/tools/testing/selftests/riscv/vector/v_helpers.h
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 #include <stdbool.h>
 
+bool is_xtheadvector_supported(void);
+
 bool is_vector_supported(void);
 
-int launch_test(char *next_program, int test_inherit);
+int launch_test(char *next_program, int test_inherit, int xtheadvector);
diff --git a/tools/testing/selftests/riscv/vector/v_initval.c b/tools/testing/selftests/riscv/vector/v_initval.c
index f38b5797fa31..be9e1d18ad29 100644
--- a/tools/testing/selftests/riscv/vector/v_initval.c
+++ b/tools/testing/selftests/riscv/vector/v_initval.c
@@ -7,10 +7,16 @@
 
 TEST(v_initval)
 {
-	if (!is_vector_supported())
-		SKIP(return, "Vector not supported");
+	int xtheadvector = 0;
 
-	ASSERT_EQ(0, launch_test(NEXT_PROGRAM, 0));
+	if (!is_vector_supported()) {
+		if (is_xtheadvector_supported())
+			xtheadvector = 1;
+		else
+			SKIP(return, "Vector not supported");
+	}
+
+	ASSERT_EQ(0, launch_test(NEXT_PROGRAM, 0, xtheadvector));
 }
 
 TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c b/tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c
index 1f9969bed235..7b7d6f21acb4 100644
--- a/tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c
+++ b/tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c
@@ -6,13 +6,16 @@
 
 int main(int argc, char **argv)
 {
-	int rc, pid, status, test_inherit = 0;
+	int rc, pid, status, test_inherit = 0, xtheadvector = 0;
 	long ctrl, ctrl_c;
 	char *exec_argv[2], *exec_envp[2];
 
-	if (argc > 1)
+	if (argc > 1 && strcmp(argv[1], "x"))
 		test_inherit = 1;
 
+	if (argc > 2 && strcmp(argv[2], "x"))
+		xtheadvector = 1;
+
 	ctrl = my_syscall1(__NR_prctl, PR_RISCV_V_GET_CONTROL);
 	if (ctrl < 0) {
 		puts("PR_RISCV_V_GET_CONTROL is not supported\n");
@@ -53,11 +56,14 @@ int main(int argc, char **argv)
 				puts("child's vstate_ctrl not equal to parent's\n");
 				exit(-1);
 			}
-			asm volatile (".option push\n\t"
-				      ".option arch, +v\n\t"
-				      "vsetvli x0, x0, e32, m8, ta, ma\n\t"
-				      ".option pop\n\t"
-				      );
+			if (xtheadvector)
+				asm volatile (".4byte	0x00007ed7");
+			else
+				asm volatile (".option push\n\t"
+					".option arch, +v\n\t"
+					"vsetvli x0, x0, e32, m8, ta, ma\n\t"
+					".option pop\n\t"
+					);
 			exit(ctrl);
 		}
 	}
diff --git a/tools/testing/selftests/riscv/vector/vstate_prctl.c b/tools/testing/selftests/riscv/vector/vstate_prctl.c
index 2fc86924bf42..62fbb17a0556 100644
--- a/tools/testing/selftests/riscv/vector/vstate_prctl.c
+++ b/tools/testing/selftests/riscv/vector/vstate_prctl.c
@@ -11,7 +11,7 @@
 
 #define NEXT_PROGRAM "./vstate_exec_nolibc"
 
-int test_and_compare_child(long provided, long expected, int inherit)
+int test_and_compare_child(long provided, long expected, int inherit, int xtheadvector)
 {
 	int rc;
 
@@ -21,7 +21,7 @@ int test_and_compare_child(long provided, long expected, int inherit)
 		       provided, rc);
 		return -1;
 	}
-	rc = launch_test(NEXT_PROGRAM, inherit);
+	rc = launch_test(NEXT_PROGRAM, inherit, xtheadvector);
 	if (rc != expected) {
 		printf("Test failed, check %d != %ld\n", rc, expected);
 		return -2;
@@ -36,7 +36,7 @@ TEST(get_control_no_v)
 {
 	long rc;
 
-	if (is_vector_supported())
+	if (is_vector_supported() || is_xtheadvector_supported())
 		SKIP(return, "Test expects vector to be not supported");
 
 	rc = prctl(PR_RISCV_V_GET_CONTROL);
@@ -50,7 +50,7 @@ TEST(set_control_no_v)
 {
 	long rc;
 
-	if (is_vector_supported())
+	if (is_vector_supported() || is_xtheadvector_supported())
 		SKIP(return, "Test expects vector to be not supported");
 
 	rc = prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON);
@@ -65,12 +65,12 @@ TEST(vstate_on_current)
 	long flag;
 	long rc;
 
-	if (!is_vector_supported())
+	if (!is_vector_supported() && !is_xtheadvector_supported())
 		SKIP(return, "Vector not supported");
 
 	flag = PR_RISCV_V_VSTATE_CTRL_ON;
 	rc = prctl(PR_RISCV_V_SET_CONTROL, flag);
-	EXPECT_EQ(0, rc) TH_LOG("Enabling V for current should always success");
+	EXPECT_EQ(0, rc) TH_LOG("Enabling V for current should always succeed");
 }
 
 TEST(vstate_off_eperm)
@@ -78,7 +78,7 @@ TEST(vstate_off_eperm)
 	long flag;
 	long rc;
 
-	if (!is_vector_supported())
+	if (!is_vector_supported() && !is_xtheadvector_supported())
 		SKIP(return, "Vector not supported");
 
 	flag = PR_RISCV_V_VSTATE_CTRL_OFF;
@@ -92,89 +92,116 @@ TEST(vstate_off_eperm)
 TEST(vstate_on_no_nesting)
 {
 	long flag;
+	int xtheadvector = 0;
 
-	if (!is_vector_supported())
-		SKIP(return, "Vector not supported");
+	if (!is_vector_supported()) {
+		if (is_xtheadvector_supported())
+			xtheadvector = 1;
+		else
+			SKIP(return, "Vector not supported");
+	}
 
 	/* Turn on next's vector explicitly and test */
 	flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
 
-	EXPECT_EQ(0,
-		  test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_ON, 0));
+	EXPECT_EQ(0, test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_ON, 0, xtheadvector));
 }
 
 TEST(vstate_off_nesting)
 {
 	long flag;
+	int xtheadvector = 0;
 
-	if (!is_vector_supported())
-		SKIP(return, "Vector not supported");
+	if (!is_vector_supported()) {
+		if (is_xtheadvector_supported())
+			xtheadvector = 1;
+		else
+			SKIP(return, "Vector not supported");
+	}
 
 	/* Turn off next's vector explicitly and test */
 	flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
 
-	EXPECT_EQ(0,
-		  test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_OFF, 1));
+	EXPECT_EQ(0, test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_OFF, 1, xtheadvector));
 }
 
 TEST(vstate_on_inherit_no_nesting)
 {
 	long flag, expected;
+	int xtheadvector = 0;
 
-	if (!is_vector_supported())
-		SKIP(return, "Vector not supported");
+	if (!is_vector_supported()) {
+		if (is_xtheadvector_supported())
+			xtheadvector = 1;
+		else
+			SKIP(return, "Vector not supported");
+	}
 
 	/* Turn on next's vector explicitly and test no inherit */
 	flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
 	flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
 	expected = flag | PR_RISCV_V_VSTATE_CTRL_ON;
 
-	EXPECT_EQ(0, test_and_compare_child(flag, expected, 0));
+	EXPECT_EQ(0, test_and_compare_child(flag, expected, 0, xtheadvector));
 }
 
 TEST(vstate_on_inherit)
 {
 	long flag, expected;
+	int xtheadvector = 0;
 
-	if (!is_vector_supported())
-		SKIP(return, "Vector not supported");
+	if (!is_vector_supported()) {
+		if (is_xtheadvector_supported())
+			xtheadvector = 1;
+		else
+			SKIP(return, "Vector not supported");
+	}
 
 	/* Turn on next's vector explicitly and test inherit */
 	flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
 	flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
 	expected = flag | PR_RISCV_V_VSTATE_CTRL_ON;
 
-	EXPECT_EQ(0, test_and_compare_child(flag, expected, 1));
+	EXPECT_EQ(0, test_and_compare_child(flag, expected, 1, xtheadvector));
 }
 
 TEST(vstate_off_inherit_no_nesting)
 {
 	long flag, expected;
+	int xtheadvector = 0;
 
-	if (!is_vector_supported())
-		SKIP(return, "Vector not supported");
-
+	if (!is_vector_supported()) {
+		if (is_xtheadvector_supported())
+			xtheadvector = 1;
+		else
+			SKIP(return, "Vector not supported");
+	}
 	/* Turn off next's vector explicitly and test no inherit */
 	flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
 	flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
 	expected = flag | PR_RISCV_V_VSTATE_CTRL_OFF;
 
-	EXPECT_EQ(0, test_and_compare_child(flag, expected, 0));
+	EXPECT_EQ(0, test_and_compare_child(flag, expected, 0, xtheadvector));
 }
 
 TEST(vstate_off_inherit)
 {
 	long flag, expected;
+	int xtheadvector = 0;
 
-	if (!is_vector_supported())
-		SKIP(return, "Vector not supported");
+	if (!is_vector_supported()) {
+		if (is_xtheadvector_supported())
+			xtheadvector = 1;
+		else
+			SKIP(return, "Vector not supported");
+	}
 
 	/* Turn off next's vector explicitly and test inherit */
 	flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
 	flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
 	expected = flag | PR_RISCV_V_VSTATE_CTRL_OFF;
 
-	EXPECT_EQ(0, test_and_compare_child(flag, expected, 1));
+	EXPECT_EQ(0, test_and_compare_child(flag, expected, 1, xtheadvector));
 }
 
 /* arguments should fail with EINVAL */
@@ -182,7 +209,7 @@ TEST(inval_set_control_1)
 {
 	int rc;
 
-	if (!is_vector_supported())
+	if (!is_vector_supported() && !is_xtheadvector_supported())
 		SKIP(return, "Vector not supported");
 
 	rc = prctl(PR_RISCV_V_SET_CONTROL, 0xff0);
@@ -195,7 +222,7 @@ TEST(inval_set_control_2)
 {
 	int rc;
 
-	if (!is_vector_supported())
+	if (!is_vector_supported() && !is_xtheadvector_supported())
 		SKIP(return, "Vector not supported");
 
 	rc = prctl(PR_RISCV_V_SET_CONTROL, 0x3);
@@ -208,7 +235,7 @@ TEST(inval_set_control_3)
 {
 	int rc;
 
-	if (!is_vector_supported())
+	if (!is_vector_supported() && !is_xtheadvector_supported())
 		SKIP(return, "Vector not supported");
 
 	rc = prctl(PR_RISCV_V_SET_CONTROL, 0xc);

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:20 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:20 -0800
Subject: [PATCH v11 14/14] riscv: Add ghostwrite vulnerability
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-14-236c22791ef9@rivosinc.com>

Follow the patterns of the other architectures that use
GENERIC_CPU_VULNERABILITIES for riscv to introduce the ghostwrite
vulnerability and mitigation. The mitigation is to disable all vector
which is accomplished by clearing the bit from the cpufeature field.

Ghostwrite only affects thead c9xx CPUs that impelment xtheadvector, so
the vulerability will only be mitigated on these CPUs.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 arch/riscv/Kconfig.errata            | 11 +++++++
 arch/riscv/errata/thead/errata.c     | 28 +++++++++++++++++
 arch/riscv/include/asm/bugs.h        | 22 +++++++++++++
 arch/riscv/include/asm/errata_list.h |  3 +-
 arch/riscv/kernel/Makefile           |  2 ++
 arch/riscv/kernel/bugs.c             | 60 ++++++++++++++++++++++++++++++++++++
 arch/riscv/kernel/cpufeature.c       | 10 +++++-
 drivers/base/cpu.c                   |  3 ++
 include/linux/cpu.h                  |  1 +
 9 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 2acc7d876e1f..e318119d570d 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -119,4 +119,15 @@ config ERRATA_THEAD_PMU
 
 	  If you don't know what to do here, say "Y".
 
+config ERRATA_THEAD_GHOSTWRITE
+	bool "Apply T-Head Ghostwrite errata"
+	depends on ERRATA_THEAD && RISCV_ISA_XTHEADVECTOR
+	default y
+	help
+	  The T-Head C9xx cores have a vulnerability in the xtheadvector
+	  instruction set. When this errata is enabled, the CPUs will be probed
+	  to determine if they are vulnerable and disable xtheadvector.
+
+	  If you don't know what to do here, say "Y".
+
 endmenu # "CPU errata selection"
diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c
index f5120e07c318..5cc008ab41a8 100644
--- a/arch/riscv/errata/thead/errata.c
+++ b/arch/riscv/errata/thead/errata.c
@@ -10,6 +10,7 @@
 #include <linux/string.h>
 #include <linux/uaccess.h>
 #include <asm/alternative.h>
+#include <asm/bugs.h>
 #include <asm/cacheflush.h>
 #include <asm/cpufeature.h>
 #include <asm/dma-noncoherent.h>
@@ -142,6 +143,31 @@ static bool errata_probe_pmu(unsigned int stage,
 	return true;
 }
 
+static bool errata_probe_ghostwrite(unsigned int stage,
+				    unsigned long arch_id, unsigned long impid)
+{
+	if (!IS_ENABLED(CONFIG_ERRATA_THEAD_GHOSTWRITE))
+		return false;
+
+	/*
+	 * target-c9xx cores report arch_id and impid as 0
+	 *
+	 * While ghostwrite may not affect all c9xx cores that implement
+	 * xtheadvector, there is no futher granularity than c9xx. Assume
+	 * vulnerable for this entire class of processors when xtheadvector is
+	 * enabled.
+	 */
+	if (arch_id != 0 || impid != 0)
+		return false;
+
+	if (stage != RISCV_ALTERNATIVES_EARLY_BOOT)
+		return false;
+
+	ghostwrite_set_vulnerable();
+
+	return true;
+}
+
 static u32 thead_errata_probe(unsigned int stage,
 			      unsigned long archid, unsigned long impid)
 {
@@ -155,6 +181,8 @@ static u32 thead_errata_probe(unsigned int stage,
 	if (errata_probe_pmu(stage, archid, impid))
 		cpu_req_errata |= BIT(ERRATA_THEAD_PMU);
 
+	errata_probe_ghostwrite(stage, archid, impid);
+
 	return cpu_req_errata;
 }
 
diff --git a/arch/riscv/include/asm/bugs.h b/arch/riscv/include/asm/bugs.h
new file mode 100644
index 000000000000..17ca0a947730
--- /dev/null
+++ b/arch/riscv/include/asm/bugs.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Interface for managing mitigations for riscv vulnerabilities.
+ *
+ * Copyright (C) 2024 Rivos Inc.
+ */
+
+#ifndef __ASM_BUGS_H
+#define __ASM_BUGS_H
+
+/* Watch out, ordering is important here. */
+enum mitigation_state {
+	UNAFFECTED,
+	MITIGATED,
+	VULNERABLE,
+};
+
+void ghostwrite_set_vulnerable(void);
+bool ghostwrite_enable_mitigation(void);
+enum mitigation_state ghostwrite_get_state(void);
+
+#endif /* __ASM_BUGS_H */
diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index 7c8a71a526a3..6e426ed7919a 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -25,7 +25,8 @@
 #ifdef CONFIG_ERRATA_THEAD
 #define	ERRATA_THEAD_MAE 0
 #define	ERRATA_THEAD_PMU 1
-#define	ERRATA_THEAD_NUMBER 2
+#define	ERRATA_THEAD_GHOSTWRITE 2
+#define	ERRATA_THEAD_NUMBER 3
 #endif
 
 #ifdef __ASSEMBLY__
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 30db92672ada..d73f04c6c563 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -118,3 +118,5 @@ obj-$(CONFIG_COMPAT)		+= compat_vdso/
 obj-$(CONFIG_64BIT)		+= pi/
 obj-$(CONFIG_ACPI)		+= acpi.o
 obj-$(CONFIG_ACPI_NUMA)	+= acpi_numa.o
+
+obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += bugs.o
diff --git a/arch/riscv/kernel/bugs.c b/arch/riscv/kernel/bugs.c
new file mode 100644
index 000000000000..3655fe7d678c
--- /dev/null
+++ b/arch/riscv/kernel/bugs.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 Rivos Inc.
+ */
+
+#include <linux/cpu.h>
+#include <linux/device.h>
+#include <linux/sprintf.h>
+
+#include <asm/bugs.h>
+#include <asm/vendor_extensions/thead.h>
+
+static enum mitigation_state ghostwrite_state;
+
+void ghostwrite_set_vulnerable(void)
+{
+	ghostwrite_state = VULNERABLE;
+}
+
+/*
+ * Vendor extension alternatives will use the value set at the time of boot
+ * alternative patching, thus this must be called before boot alternatives are
+ * patched (and after extension probing) to be effective.
+ *
+ * Returns true if mitgated, false otherwise.
+ */
+bool ghostwrite_enable_mitigation(void)
+{
+	if (IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR) &&
+	    ghostwrite_state == VULNERABLE && !cpu_mitigations_off()) {
+		disable_xtheadvector();
+		ghostwrite_state = MITIGATED;
+		return true;
+	}
+
+	return false;
+}
+
+enum mitigation_state ghostwrite_get_state(void)
+{
+	return ghostwrite_state;
+}
+
+ssize_t cpu_show_ghostwrite(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	if (IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR)) {
+		switch (ghostwrite_state) {
+		case UNAFFECTED:
+			return sprintf(buf, "Not affected\n");
+		case MITIGATED:
+			return sprintf(buf, "Mitigation: xtheadvector disabled\n");
+		case VULNERABLE:
+			fallthrough;
+		default:
+			return sprintf(buf, "Vulnerable\n");
+		}
+	} else {
+		return sprintf(buf, "Not affected\n");
+	}
+}
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index ba6976132638..35670c96b383 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -17,6 +17,7 @@
 #include <linux/of.h>
 #include <asm/acpi.h>
 #include <asm/alternative.h>
+#include <asm/bugs.h>
 #include <asm/cacheflush.h>
 #include <asm/cpufeature.h>
 #include <asm/hwcap.h>
@@ -824,6 +825,7 @@ static int has_thead_homogeneous_vlenb(void)
 static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
 {
 	unsigned int cpu;
+	bool mitigated;
 
 	for_each_possible_cpu(cpu) {
 		unsigned long this_hwcap = 0;
@@ -874,7 +876,13 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
 		riscv_fill_vendor_ext_list(cpu);
 	}
 
-	if (has_xtheadvector_no_alternatives() && has_thead_homogeneous_vlenb() < 0) {
+	/*
+	 * Execute ghostwrite mitigation immediately after detecting extensions
+	 * to disable xtheadvector if necessary.
+	 */
+	mitigated = ghostwrite_enable_mitigation();
+
+	if (!mitigated && has_xtheadvector_no_alternatives() && has_thead_homogeneous_vlenb() < 0) {
 		pr_warn("Unsupported heterogeneous vlenb detected, vector extension disabled.\n");
 		disable_xtheadvector();
 	}
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index fdaa24bb641a..a7e511849875 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -599,6 +599,7 @@ CPU_SHOW_VULN_FALLBACK(retbleed);
 CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow);
 CPU_SHOW_VULN_FALLBACK(gds);
 CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling);
+CPU_SHOW_VULN_FALLBACK(ghostwrite);
 
 static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
 static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
@@ -614,6 +615,7 @@ static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL);
 static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL);
 static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL);
 static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL);
+static DEVICE_ATTR(ghostwrite, 0444, cpu_show_ghostwrite, NULL);
 
 static struct attribute *cpu_root_vulnerabilities_attrs[] = {
 	&dev_attr_meltdown.attr,
@@ -630,6 +632,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = {
 	&dev_attr_spec_rstack_overflow.attr,
 	&dev_attr_gather_data_sampling.attr,
 	&dev_attr_reg_file_data_sampling.attr,
+	&dev_attr_ghostwrite.attr,
 	NULL
 };
 
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index bdcec1732445..6a0a8f1c7c90 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -77,6 +77,7 @@ extern ssize_t cpu_show_gds(struct device *dev,
 			    struct device_attribute *attr, char *buf);
 extern ssize_t cpu_show_reg_file_data_sampling(struct device *dev,
 					       struct device_attribute *attr, char *buf);
+extern ssize_t cpu_show_ghostwrite(struct device *dev, struct device_attribute *attr, char *buf);
 
 extern __printf(4, 5)
 struct device *cpu_device_create(struct device *parent, void *drvdata,

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:21:18 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:21:18 -0800
Subject: [PATCH v11 12/14] selftests: riscv: Fix vector tests
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <20241113-xtheadvector-v11-12-236c22791ef9@rivosinc.com>

Overhaul the riscv vector tests to use kselftest_harness to help the
test cases correctly report the results and decouple the individual test
cases from each other. With this refactoring, only run the test cases if
vector is reported and properly report the test case as skipped
otherwise. The v_initval_nolibc test was previously not checking if
vector was supported and used a function (malloc) which invalidates
the state of the vector registers.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 tools/testing/selftests/riscv/vector/.gitignore    |   3 +-
 tools/testing/selftests/riscv/vector/Makefile      |  17 +-
 .../selftests/riscv/vector/v_exec_initval_nolibc.c |  85 +++++++
 tools/testing/selftests/riscv/vector/v_helpers.c   |  57 +++++
 tools/testing/selftests/riscv/vector/v_helpers.h   |   6 +
 tools/testing/selftests/riscv/vector/v_initval.c   |  16 ++
 .../selftests/riscv/vector/v_initval_nolibc.c      |  68 -----
 .../testing/selftests/riscv/vector/vstate_prctl.c  | 278 ++++++++++++---------
 8 files changed, 337 insertions(+), 193 deletions(-)

diff --git a/tools/testing/selftests/riscv/vector/.gitignore b/tools/testing/selftests/riscv/vector/.gitignore
index 9ae7964491d5..7d9c87cd0649 100644
--- a/tools/testing/selftests/riscv/vector/.gitignore
+++ b/tools/testing/selftests/riscv/vector/.gitignore
@@ -1,3 +1,4 @@
 vstate_exec_nolibc
 vstate_prctl
-v_initval_nolibc
+v_initval
+v_exec_initval_nolibc
diff --git a/tools/testing/selftests/riscv/vector/Makefile b/tools/testing/selftests/riscv/vector/Makefile
index bfff0ff4f3be..6f7497f4e7b3 100644
--- a/tools/testing/selftests/riscv/vector/Makefile
+++ b/tools/testing/selftests/riscv/vector/Makefile
@@ -2,18 +2,27 @@
 # Copyright (C) 2021 ARM Limited
 # Originally tools/testing/arm64/abi/Makefile
 
-TEST_GEN_PROGS := vstate_prctl v_initval_nolibc
-TEST_GEN_PROGS_EXTENDED := vstate_exec_nolibc
+TEST_GEN_PROGS := v_initval vstate_prctl
+TEST_GEN_PROGS_EXTENDED := vstate_exec_nolibc v_exec_initval_nolibc
 
 include ../../lib.mk
 
-$(OUTPUT)/vstate_prctl: vstate_prctl.c ../hwprobe/sys_hwprobe.S
+$(OUTPUT)/sys_hwprobe.o: ../hwprobe/sys_hwprobe.S
+	$(CC) -static -c -o$@ $(CFLAGS) $^
+
+$(OUTPUT)/v_helpers.o: v_helpers.c
+	$(CC) -static -c -o$@ $(CFLAGS) $^
+
+$(OUTPUT)/vstate_prctl: vstate_prctl.c $(OUTPUT)/sys_hwprobe.o $(OUTPUT)/v_helpers.o
 	$(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^
 
 $(OUTPUT)/vstate_exec_nolibc: vstate_exec_nolibc.c
 	$(CC) -nostdlib -static -include ../../../../include/nolibc/nolibc.h \
 		-Wall $(CFLAGS) $(LDFLAGS) $^ -o $@ -lgcc
 
-$(OUTPUT)/v_initval_nolibc: v_initval_nolibc.c
+$(OUTPUT)/v_initval: v_initval.c $(OUTPUT)/sys_hwprobe.o $(OUTPUT)/v_helpers.o
+	$(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^
+
+$(OUTPUT)/v_exec_initval_nolibc: v_exec_initval_nolibc.c
 	$(CC) -nostdlib -static -include ../../../../include/nolibc/nolibc.h \
 		-Wall $(CFLAGS) $(LDFLAGS) $^ -o $@ -lgcc
diff --git a/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c b/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c
new file mode 100644
index 000000000000..4a39cab29c34
--- /dev/null
+++ b/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Get values of vector registers as soon as the program starts to test if
+ * is properly cleaning the values before starting a new program. Vector
+ * registers are caller saved, so no function calls may happen before reading
+ * the values. To further ensure consistency, this file is compiled without
+ * libc and without auto-vectorization.
+ *
+ * To be "clean" all values must be either all ones or all zeroes.
+ */
+
+#define __stringify_1(x...)	#x
+#define __stringify(x...)	__stringify_1(x)
+
+int main(int argc, char **argv)
+{
+	char prev_value = 0, value;
+	unsigned long vl;
+	int first = 1;
+
+	asm volatile (
+		".option push\n\t"
+		".option arch, +v\n\t"
+		"vsetvli	%[vl], x0, e8, m1, ta, ma\n\t"
+		".option pop\n\t"
+		: [vl] "=r" (vl)
+	);
+
+#define CHECK_VECTOR_REGISTER(register) ({					\
+	for (int i = 0; i < vl; i++) {						\
+		asm volatile (							\
+			".option push\n\t"					\
+			".option arch, +v\n\t"					\
+			"vmv.x.s %0, " __stringify(register) "\n\t"		\
+			"vsrl.vi " __stringify(register) ", " __stringify(register) ", 8\n\t" \
+			".option pop\n\t"					\
+			: "=r" (value));					\
+		if (first) {							\
+			first = 0;						\
+		} else if (value != prev_value || !(value == 0x00 || value == 0xff)) { \
+			printf("Register " __stringify(register)		\
+				" values not clean! value: %u\n", value);	\
+			exit(-1);						\
+		}								\
+		prev_value = value;						\
+	}									\
+})
+
+	CHECK_VECTOR_REGISTER(v0);
+	CHECK_VECTOR_REGISTER(v1);
+	CHECK_VECTOR_REGISTER(v2);
+	CHECK_VECTOR_REGISTER(v3);
+	CHECK_VECTOR_REGISTER(v4);
+	CHECK_VECTOR_REGISTER(v5);
+	CHECK_VECTOR_REGISTER(v6);
+	CHECK_VECTOR_REGISTER(v7);
+	CHECK_VECTOR_REGISTER(v8);
+	CHECK_VECTOR_REGISTER(v9);
+	CHECK_VECTOR_REGISTER(v10);
+	CHECK_VECTOR_REGISTER(v11);
+	CHECK_VECTOR_REGISTER(v12);
+	CHECK_VECTOR_REGISTER(v13);
+	CHECK_VECTOR_REGISTER(v14);
+	CHECK_VECTOR_REGISTER(v15);
+	CHECK_VECTOR_REGISTER(v16);
+	CHECK_VECTOR_REGISTER(v17);
+	CHECK_VECTOR_REGISTER(v18);
+	CHECK_VECTOR_REGISTER(v19);
+	CHECK_VECTOR_REGISTER(v20);
+	CHECK_VECTOR_REGISTER(v21);
+	CHECK_VECTOR_REGISTER(v22);
+	CHECK_VECTOR_REGISTER(v23);
+	CHECK_VECTOR_REGISTER(v24);
+	CHECK_VECTOR_REGISTER(v25);
+	CHECK_VECTOR_REGISTER(v26);
+	CHECK_VECTOR_REGISTER(v27);
+	CHECK_VECTOR_REGISTER(v28);
+	CHECK_VECTOR_REGISTER(v29);
+	CHECK_VECTOR_REGISTER(v30);
+	CHECK_VECTOR_REGISTER(v31);
+
+#undef CHECK_VECTOR_REGISTER
+
+	return 0;
+}
diff --git a/tools/testing/selftests/riscv/vector/v_helpers.c b/tools/testing/selftests/riscv/vector/v_helpers.c
new file mode 100644
index 000000000000..d50f4dfbf9e5
--- /dev/null
+++ b/tools/testing/selftests/riscv/vector/v_helpers.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "../hwprobe/hwprobe.h"
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+bool is_vector_supported(void)
+{
+	struct riscv_hwprobe pair;
+
+	pair.key = RISCV_HWPROBE_KEY_IMA_EXT_0;
+	riscv_hwprobe(&pair, 1, 0, NULL, 0);
+	return pair.value & RISCV_HWPROBE_EXT_ZVE32X;
+}
+
+int launch_test(char *next_program, int test_inherit)
+{
+	char *exec_argv[3], *exec_envp[1];
+	int rc, pid, status;
+
+	pid = fork();
+	if (pid < 0) {
+		printf("fork failed %d", pid);
+		return -1;
+	}
+
+	if (!pid) {
+		exec_argv[0] = next_program;
+		exec_argv[1] = test_inherit != 0 ? "x" : NULL;
+		exec_argv[2] = NULL;
+		exec_envp[0] = NULL;
+		/* launch the program again to check inherit */
+		rc = execve(next_program, exec_argv, exec_envp);
+		if (rc) {
+			perror("execve");
+			printf("child execve failed %d\n", rc);
+			exit(-1);
+		}
+	}
+
+	rc = waitpid(-1, &status, 0);
+	if (rc < 0) {
+		printf("waitpid failed\n");
+		return -3;
+	}
+
+	if ((WIFEXITED(status) && WEXITSTATUS(status) == -1) ||
+	    WIFSIGNALED(status)) {
+		printf("child exited abnormally\n");
+		return -4;
+	}
+
+	return WEXITSTATUS(status);
+}
diff --git a/tools/testing/selftests/riscv/vector/v_helpers.h b/tools/testing/selftests/riscv/vector/v_helpers.h
new file mode 100644
index 000000000000..faeeeb625b6e
--- /dev/null
+++ b/tools/testing/selftests/riscv/vector/v_helpers.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <stdbool.h>
+
+bool is_vector_supported(void);
+
+int launch_test(char *next_program, int test_inherit);
diff --git a/tools/testing/selftests/riscv/vector/v_initval.c b/tools/testing/selftests/riscv/vector/v_initval.c
new file mode 100644
index 000000000000..f38b5797fa31
--- /dev/null
+++ b/tools/testing/selftests/riscv/vector/v_initval.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "../../kselftest_harness.h"
+#include "v_helpers.h"
+
+#define NEXT_PROGRAM "./v_exec_initval_nolibc"
+
+TEST(v_initval)
+{
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
+
+	ASSERT_EQ(0, launch_test(NEXT_PROGRAM, 0));
+}
+
+TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/riscv/vector/v_initval_nolibc.c b/tools/testing/selftests/riscv/vector/v_initval_nolibc.c
deleted file mode 100644
index 1dd94197da30..000000000000
--- a/tools/testing/selftests/riscv/vector/v_initval_nolibc.c
+++ /dev/null
@@ -1,68 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-#include "../../kselftest.h"
-#define MAX_VSIZE	(8192 * 32)
-
-void dump(char *ptr, int size)
-{
-	int i = 0;
-
-	for (i = 0; i < size; i++) {
-		if (i != 0) {
-			if (i % 16 == 0)
-				printf("\n");
-			else if (i % 8 == 0)
-				printf("  ");
-		}
-		printf("%02x ", ptr[i]);
-	}
-	printf("\n");
-}
-
-int main(void)
-{
-	int i;
-	unsigned long vl;
-	char *datap, *tmp;
-
-	datap = malloc(MAX_VSIZE);
-	if (!datap) {
-		ksft_test_result_fail("fail to allocate memory for size = %d\n", MAX_VSIZE);
-		exit(-1);
-	}
-
-	tmp = datap;
-	asm volatile (
-		".option push\n\t"
-		".option arch, +v\n\t"
-		"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
-		"vse8.v		v0, (%2)\n\t"
-		"add		%1, %2, %0\n\t"
-		"vse8.v		v8, (%1)\n\t"
-		"add		%1, %1, %0\n\t"
-		"vse8.v		v16, (%1)\n\t"
-		"add		%1, %1, %0\n\t"
-		"vse8.v		v24, (%1)\n\t"
-		".option pop\n\t"
-		: "=&r" (vl), "=r" (tmp) : "r" (datap) : "memory");
-
-	ksft_print_msg("vl = %lu\n", vl);
-
-	if (datap[0] != 0x00 && datap[0] != 0xff) {
-		ksft_test_result_fail("v-regesters are not properly initialized\n");
-		dump(datap, vl * 4);
-		exit(-1);
-	}
-
-	for (i = 1; i < vl * 4; i++) {
-		if (datap[i] != datap[0]) {
-			ksft_test_result_fail("detect stale values on v-regesters\n");
-			dump(datap, vl * 4);
-			exit(-2);
-		}
-	}
-
-	free(datap);
-	ksft_exit_pass();
-	return 0;
-}
diff --git a/tools/testing/selftests/riscv/vector/vstate_prctl.c b/tools/testing/selftests/riscv/vector/vstate_prctl.c
index 895177f6bf4c..2fc86924bf42 100644
--- a/tools/testing/selftests/riscv/vector/vstate_prctl.c
+++ b/tools/testing/selftests/riscv/vector/vstate_prctl.c
@@ -3,50 +3,13 @@
 #include <unistd.h>
 #include <errno.h>
 #include <sys/wait.h>
+#include <sys/types.h>
+#include <stdlib.h>
 
-#include "../hwprobe/hwprobe.h"
-#include "../../kselftest.h"
+#include "../../kselftest_harness.h"
+#include "v_helpers.h"
 
 #define NEXT_PROGRAM "./vstate_exec_nolibc"
-static int launch_test(int test_inherit)
-{
-	char *exec_argv[3], *exec_envp[1];
-	int rc, pid, status;
-
-	pid = fork();
-	if (pid < 0) {
-		ksft_test_result_fail("fork failed %d", pid);
-		return -1;
-	}
-
-	if (!pid) {
-		exec_argv[0] = NEXT_PROGRAM;
-		exec_argv[1] = test_inherit != 0 ? "x" : NULL;
-		exec_argv[2] = NULL;
-		exec_envp[0] = NULL;
-		/* launch the program again to check inherit */
-		rc = execve(NEXT_PROGRAM, exec_argv, exec_envp);
-		if (rc) {
-			perror("execve");
-			ksft_test_result_fail("child execve failed %d\n", rc);
-			exit(-1);
-		}
-	}
-
-	rc = waitpid(-1, &status, 0);
-	if (rc < 0) {
-		ksft_test_result_fail("waitpid failed\n");
-		return -3;
-	}
-
-	if ((WIFEXITED(status) && WEXITSTATUS(status) == -1) ||
-	    WIFSIGNALED(status)) {
-		ksft_test_result_fail("child exited abnormally\n");
-		return -4;
-	}
-
-	return WEXITSTATUS(status);
-}
 
 int test_and_compare_child(long provided, long expected, int inherit)
 {
@@ -54,128 +17,203 @@ int test_and_compare_child(long provided, long expected, int inherit)
 
 	rc = prctl(PR_RISCV_V_SET_CONTROL, provided);
 	if (rc != 0) {
-		ksft_test_result_fail("prctl with provided arg %lx failed with code %d\n",
-				      provided, rc);
+		printf("prctl with provided arg %lx failed with code %d\n",
+		       provided, rc);
 		return -1;
 	}
-	rc = launch_test(inherit);
+	rc = launch_test(NEXT_PROGRAM, inherit);
 	if (rc != expected) {
-		ksft_test_result_fail("Test failed, check %d != %ld\n", rc,
-				      expected);
+		printf("Test failed, check %d != %ld\n", rc, expected);
 		return -2;
 	}
 	return 0;
 }
 
-#define PR_RISCV_V_VSTATE_CTRL_CUR_SHIFT	0
-#define PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT	2
+#define PR_RISCV_V_VSTATE_CTRL_CUR_SHIFT 0
+#define PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT 2
 
-int main(void)
+TEST(get_control_no_v)
 {
-	struct riscv_hwprobe pair;
-	long flag, expected;
 	long rc;
 
-	pair.key = RISCV_HWPROBE_KEY_IMA_EXT_0;
-	rc = riscv_hwprobe(&pair, 1, 0, NULL, 0);
-	if (rc < 0) {
-		ksft_test_result_fail("hwprobe() failed with %ld\n", rc);
-		return -1;
-	}
+	if (is_vector_supported())
+		SKIP(return, "Test expects vector to be not supported");
 
-	if (pair.key != RISCV_HWPROBE_KEY_IMA_EXT_0) {
-		ksft_test_result_fail("hwprobe cannot probe RISCV_HWPROBE_KEY_IMA_EXT_0\n");
-		return -2;
-	}
+	rc = prctl(PR_RISCV_V_GET_CONTROL);
+	EXPECT_EQ(-1, rc)
+	TH_LOG("GET_CONTROL should fail on kernel/hw without ZVE32X");
+	EXPECT_EQ(EINVAL, errno)
+	TH_LOG("GET_CONTROL should fail on kernel/hw without ZVE32X");
+}
 
-	if (!(pair.value & RISCV_HWPROBE_EXT_ZVE32X)) {
-		rc = prctl(PR_RISCV_V_GET_CONTROL);
-		if (rc != -1 || errno != EINVAL) {
-			ksft_test_result_fail("GET_CONTROL should fail on kernel/hw without ZVE32X\n");
-			return -3;
-		}
-
-		rc = prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON);
-		if (rc != -1 || errno != EINVAL) {
-			ksft_test_result_fail("SET_CONTROL should fail on kernel/hw without ZVE32X\n");
-			return -4;
-		}
-
-		ksft_test_result_skip("Vector not supported\n");
-		return 0;
-	}
+TEST(set_control_no_v)
+{
+	long rc;
+
+	if (is_vector_supported())
+		SKIP(return, "Test expects vector to be not supported");
+
+	rc = prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON);
+	EXPECT_EQ(-1, rc)
+	TH_LOG("SET_CONTROL should fail on kernel/hw without ZVE32X");
+	EXPECT_EQ(EINVAL, errno)
+	TH_LOG("SET_CONTROL should fail on kernel/hw without ZVE32X");
+}
+
+TEST(vstate_on_current)
+{
+	long flag;
+	long rc;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
 
 	flag = PR_RISCV_V_VSTATE_CTRL_ON;
 	rc = prctl(PR_RISCV_V_SET_CONTROL, flag);
-	if (rc != 0) {
-		ksft_test_result_fail("Enabling V for current should always success\n");
-		return -5;
-	}
+	EXPECT_EQ(0, rc) TH_LOG("Enabling V for current should always success");
+}
+
+TEST(vstate_off_eperm)
+{
+	long flag;
+	long rc;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
 
 	flag = PR_RISCV_V_VSTATE_CTRL_OFF;
 	rc = prctl(PR_RISCV_V_SET_CONTROL, flag);
-	if (rc != -1 || errno != EPERM) {
-		ksft_test_result_fail("Disabling current's V alive must fail with EPERM(%d)\n",
-				      errno);
-		return -5;
-	}
+	EXPECT_EQ(EPERM, errno)
+	TH_LOG("Disabling V in current thread with V enabled must fail with EPERM(%d)", errno);
+	EXPECT_EQ(-1, rc)
+	TH_LOG("Disabling V in current thread with V enabled must fail with EPERM(%d)", errno);
+}
+
+TEST(vstate_on_no_nesting)
+{
+	long flag;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
 
 	/* Turn on next's vector explicitly and test */
 	flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
-	if (test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_ON, 0))
-		return -6;
+
+	EXPECT_EQ(0,
+		  test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_ON, 0));
+}
+
+TEST(vstate_off_nesting)
+{
+	long flag;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
 
 	/* Turn off next's vector explicitly and test */
 	flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
-	if (test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_OFF, 0))
-		return -7;
+
+	EXPECT_EQ(0,
+		  test_and_compare_child(flag, PR_RISCV_V_VSTATE_CTRL_OFF, 1));
+}
+
+TEST(vstate_on_inherit_no_nesting)
+{
+	long flag, expected;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
+
+	/* Turn on next's vector explicitly and test no inherit */
+	flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
+	flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
+	expected = flag | PR_RISCV_V_VSTATE_CTRL_ON;
+
+	EXPECT_EQ(0, test_and_compare_child(flag, expected, 0));
+}
+
+TEST(vstate_on_inherit)
+{
+	long flag, expected;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
 
 	/* Turn on next's vector explicitly and test inherit */
 	flag = PR_RISCV_V_VSTATE_CTRL_ON << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
 	flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
 	expected = flag | PR_RISCV_V_VSTATE_CTRL_ON;
-	if (test_and_compare_child(flag, expected, 0))
-		return -8;
 
-	if (test_and_compare_child(flag, expected, 1))
-		return -9;
+	EXPECT_EQ(0, test_and_compare_child(flag, expected, 1));
+}
+
+TEST(vstate_off_inherit_no_nesting)
+{
+	long flag, expected;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
+
+	/* Turn off next's vector explicitly and test no inherit */
+	flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
+	flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
+	expected = flag | PR_RISCV_V_VSTATE_CTRL_OFF;
+
+	EXPECT_EQ(0, test_and_compare_child(flag, expected, 0));
+}
+
+TEST(vstate_off_inherit)
+{
+	long flag, expected;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
 
 	/* Turn off next's vector explicitly and test inherit */
 	flag = PR_RISCV_V_VSTATE_CTRL_OFF << PR_RISCV_V_VSTATE_CTRL_NEXT_SHIFT;
 	flag |= PR_RISCV_V_VSTATE_CTRL_INHERIT;
 	expected = flag | PR_RISCV_V_VSTATE_CTRL_OFF;
-	if (test_and_compare_child(flag, expected, 0))
-		return -10;
 
-	if (test_and_compare_child(flag, expected, 1))
-		return -11;
+	EXPECT_EQ(0, test_and_compare_child(flag, expected, 1));
+}
+
+/* arguments should fail with EINVAL */
+TEST(inval_set_control_1)
+{
+	int rc;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
 
-	/* arguments should fail with EINVAL */
 	rc = prctl(PR_RISCV_V_SET_CONTROL, 0xff0);
-	if (rc != -1 || errno != EINVAL) {
-		ksft_test_result_fail("Undefined control argument should return EINVAL\n");
-		return -12;
-	}
+	EXPECT_EQ(-1, rc);
+	EXPECT_EQ(EINVAL, errno);
+}
+
+/* arguments should fail with EINVAL */
+TEST(inval_set_control_2)
+{
+	int rc;
+
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
 
 	rc = prctl(PR_RISCV_V_SET_CONTROL, 0x3);
-	if (rc != -1 || errno != EINVAL) {
-		ksft_test_result_fail("Undefined control argument should return EINVAL\n");
-		return -12;
-	}
+	EXPECT_EQ(-1, rc);
+	EXPECT_EQ(EINVAL, errno);
+}
 
-	rc = prctl(PR_RISCV_V_SET_CONTROL, 0xc);
-	if (rc != -1 || errno != EINVAL) {
-		ksft_test_result_fail("Undefined control argument should return EINVAL\n");
-		return -12;
-	}
+/* arguments should fail with EINVAL */
+TEST(inval_set_control_3)
+{
+	int rc;
 
-	rc = prctl(PR_RISCV_V_SET_CONTROL, 0xc);
-	if (rc != -1 || errno != EINVAL) {
-		ksft_test_result_fail("Undefined control argument should return EINVAL\n");
-		return -12;
-	}
+	if (!is_vector_supported())
+		SKIP(return, "Vector not supported");
 
-	ksft_test_result_pass("tests for riscv_v_vstate_ctrl pass\n");
-	ksft_exit_pass();
-	return 0;
+	rc = prctl(PR_RISCV_V_SET_CONTROL, 0xc);
+	EXPECT_EQ(-1, rc);
+	EXPECT_EQ(EINVAL, errno);
 }
+
+TEST_HARNESS_MAIN

-- 
2.34.1



From charlie at rivosinc.com  Wed Nov 13 18:24:45 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:24:45 -0800
Subject: [PATCH v10 05/14] riscv: vector: Use vlenb from DT for thead
In-Reply-To: <tencent_2EF88DF37C4B82B2DA0B8E49B85C312E2108@qq.com>
References: <20240911-xtheadvector-v10-0-8d3930091246@rivosinc.com>
 <20240911-xtheadvector-v10-5-8d3930091246@rivosinc.com>
 <tencent_2EF88DF37C4B82B2DA0B8E49B85C312E2108@qq.com>
Message-ID: <ZzVfbS8-NizjKkst@ghost>

On Sun, Nov 10, 2024 at 03:34:54AM +0800, Yangyu Chen wrote:
> Hi Charlie,
> 
> I have tested this patchset with ghostwrite rebased to linux commit da4373fbcf ("Merge tag 'thermal-6.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm") [1] on my D1 Nezha board, with defconfig + CONFIG_ERRATA_THEAD_GHOSTWRITE=n, I got this message during boot:
> 
> [    0.027584] Kernel panic - not syncing: __kmem_cache_create_args: Failed to create slab 'riscv_vector_ctx'. Error -22
> [    0.038057] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.0-rc6-00310-gb276cf69df24-dirty #11
> [    0.047240] Hardware name: Allwinner D1 Nezha (DT)
> [    0.052007] Call Trace:
> [    0.054434] [<ffffffff80007172>] dump_backtrace+0x1c/0x24
> [    0.059806] [<ffffffff809f6834>] show_stack+0x2c/0x38
> [    0.064833] [<ffffffff80a040f0>] dump_stack_lvl+0x52/0x74
> [    0.070206] [<ffffffff80a04126>] dump_stack+0x14/0x1c
> [    0.075233] [<ffffffff809f6db6>] panic+0x10c/0x300
> [    0.080000] [<ffffffff8017b5a0>] __kmem_cache_create_args+0x24a/0x2b6
> [    0.086413] [<ffffffff80c04c68>] riscv_v_setup_ctx_cache+0x56/0x84
> [    0.092566] [<ffffffff80c04288>] arch_task_cache_init+0x10/0x1c
> [    0.098460] [<ffffffff80c07d02>] fork_init+0x68/0x1a8
> [    0.103486] [<ffffffff80c00ed2>] start_kernel+0x77e/0x822
> [    0.108870] ---[ end Kernel panic - not syncing: __kmem_cache_create_args: Failed to create slab 'riscv_vector_ctx'. Error -22 ]---
> 
> [1] https://github.com/cyyself/linux/tree/xtheadvector_20241110
> 
> On 9/12/24 13:55, Charlie Jenkins wrote:
> >  diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
> > index 682b3feee451..9775d6a9c8ee 100644
> > --- a/arch/riscv/kernel/vector.c
> > +++ b/arch/riscv/kernel/vector.c
> > @@ -33,7 +33,17 @@ int riscv_v_setup_vsize(void)
> >  {
> >  	unsigned long this_vsize;
> >  -	/* There are 32 vector registers with vlenb length. */
> > +	/*
> > +	 * There are 32 vector registers with vlenb length.
> > +	 *
> > +	 * If the thead,vlenb property was provided by the firmware, use that
> > +	 * instead of probing the CSRs.
> > +	 */
> > +	if (thead_vlenb_of) {
> > +		this_vsize = thead_vlenb_of * 32;
> 
> Then, I patched here which replaces "this_vsize" with "riscv_v_vsize". The kernel boots normally and I can see ?xtheadvector" in /proc/cpuinfo.
> 
> However, when I try to run the "v_exec_initval_nolibc" test, the kernel panics with these outputs:
> 
> [  978.788878] Oops - illegal instruction [#1]
> [  978.788897] Modules linked in:
> [  978.788908] CPU: 0 UID: 1000 PID: 461 Comm: v_exec_initval_ Not tainted 6.12.0-rc6-00310-gb276cf69df24-dirty #12
> [  978.788924] Hardware name: Allwinner D1 Nezha (DT)
> [  978.788929] epc : do_trap_ecall_u+0x56/0x20a
> [  978.788956]  ra : _new_vmalloc_restore_context_a0+0xc2/0xce
> [  978.788974] epc : ffffffff80a04afe ra : ffffffff80a0e742 sp : ffffffc6003fbeb0
> [  978.788983]  gp : ffffffff81717080 tp : ffffffd60723b300 t0 : ffffffff81001268
> [  978.788991]  t1 : ffffffff80a04aa8 t2 : ffffffff810012a8 s0 : ffffffc6003fbee0
> [  978.789000]  s1 : ffffffc6003fbee0 a0 : ffffffc6003fbee0 a1 : 000000000000005d
> [  978.789007]  a2 : 0000000000000000 a3 : ffffffffffffffda a4 : 0000000000000003
> [  978.789015]  a5 : 0000000000000000 a6 : 0000000002adb5fe a7 : 000000000000005d
> [  978.789022]  s2 : 00000000000108a8 s3 : 0000000000000000 s4 : 0000000000000008
> [  978.789030]  s5 : 0000003fb42ab780 s6 : 0000002adb5fe420 s7 : 0000002adb5fb9e0
> [  978.789038]  s8 : 0000002adb5fe440 s9 : 0000002adb5fe420 s10: 0000002adb572ad4
> [  978.789046]  s11: 0000002adb572ad0 t3 : 0000003fb43c5e3c t4 : 622f7273752f3d5f
> [  978.789053]  t5 : 0000002adb5fd5a1 t6 : 0000000002adb5ff
> [  978.789060] status: 8000000201800100 badaddr: 000000005e0fb057 cause: 0000000000000002
> [  978.789069] [<ffffffff80a04afe>] do_trap_ecall_u+0x56/0x20a
> [  978.789086] [<ffffffff80a0e742>] _new_vmalloc_restore_context_a0+0xc2/0xce
> [  978.789113] Code: a073 1007 006f 1a60 7057 0c30 57fd 17fe 77d7 0c30 (b057) 5e0f
> [  978.789123] ---[ end trace 0000000000000000 ]---
> [  978.789131] Kernel panic - not syncing: Fatal exception in interrupt
> [  978.937158] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
> 
> Is something wrong with my setup?

Thanks for reporting this! I just sent out a new version with the fix.
Something went wrong with the __riscv_v_vstate_discard() and was
triggering this failure. I have tested that this new version is able to
pass the testcase.

https://lore.kernel.org/linux-riscv/20241113-xtheadvector-v11-0-236c22791ef9 at rivosinc.com/T/#t

- Charlie

> 
> Thanks,
> Yangyu Chen
> 
> > +		return 0;
> > +	}
> > +
> >  	riscv_v_enable();
> >  	this_vsize = csr_read(CSR_VLENB) * 32;
> >  	riscv_v_disable();
> > diff --git a/arch/riscv/kernel/vendor_extensions/thead.c b/arch/riscv/kernel/vendor_extensions/thead.c
> > index 0f27baf8d245..519dbf70710a 100644
> > --- a/arch/riscv/kernel/vendor_extensions/thead.c
> > +++ b/arch/riscv/kernel/vendor_extensions/thead.c
> > @@ -5,6 +5,7 @@
> >  #include <asm/vendor_extensions/thead.h>
> >    #include <linux/array_size.h>
> > +#include <linux/cpumask.h>
> >  #include <linux/types.h>
> >    /* All T-Head vendor extensions supported in Linux */
> > @@ -16,3 +17,13 @@ struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_thead = {
> >  	.ext_data_count = ARRAY_SIZE(riscv_isa_vendor_ext_thead),
> >  	.ext_data = riscv_isa_vendor_ext_thead,
> >  };
> > +
> > +void disable_xtheadvector(void)
> > +{
> > +	int cpu;
> > +
> > +	for_each_possible_cpu(cpu)
> > +		clear_bit(RISCV_ISA_VENDOR_EXT_XTHEADVECTOR, riscv_isa_vendor_ext_list_thead.per_hart_isa_bitmap[cpu].isa);
> > +
> > +	clear_bit(RISCV_ISA_VENDOR_EXT_XTHEADVECTOR, riscv_isa_vendor_ext_list_thead.all_harts_isa_bitmap.isa);
> > +}
> 


From charlie at rivosinc.com  Wed Nov 13 18:44:53 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 18:44:53 -0800
Subject: [PATCH v10 00/14] riscv: Add support for xtheadvector
In-Reply-To: <CH0PR20MB393254369E401BF068005C7FCE752@CH0PR20MB3932.namprd20.prod.outlook.com>
References: <20240911-xtheadvector-v10-0-8d3930091246@rivosinc.com>
 <CH0PR20MB393254369E401BF068005C7FCE752@CH0PR20MB3932.namprd20.prod.outlook.com>
Message-ID: <ZzVkJd1lGy0TsjlW@ghost>

On Mon, Sep 30, 2024 at 12:07:23AM +0800, Aoba K wrote:
> 
> On 2024/9/12 13:55, Charlie Jenkins wrote:
> > xtheadvector is a custom extension that is based upon riscv vector
> > version 0.7.1 [1]. All of the vector routines have been modified to
> > support this alternative vector version based upon whether xtheadvector
> > was determined to be supported at boot.
> > 
> > vlenb is not supported on the existing xtheadvector hardware, so a
> > devicetree property thead,vlenb is added to provide the vlenb to Linux.
> > 
> > There is a new hwprobe key RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 that is
> > used to request which thead vendor extensions are supported on the
> > current platform. This allows future vendors to allocate hwprobe keys
> > for their vendor.
> > 
> > Support for xtheadvector is also added to the vector kselftests.
> > 
> > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > 
> > [1] https://github.com/T-head-Semi/thead-extension-spec/blob/95358cb2cca9489361c61d335e03d3134b14133f/xtheadvector.adoc
> > 
> > ---
> > This series is a continuation of a different series that was fragmented
> > into two other series in an attempt to get part of it merged in the 6.10
> > merge window. The split-off series did not get merged due to a NAK on
> > the series that added the generic riscv,vlenb devicetree entry. This
> > series has converted riscv,vlenb to thead,vlenb to remedy this issue.
> > 
> > The original series is titled "riscv: Support vendor extensions and
> > xtheadvector" [3].
> > 
> > The series titled "riscv: Extend cpufeature.c to detect vendor
> > extensions" is still under development and this series is based on that
> > series! [4]
> > 
> > I have tested this with an Allwinner Nezha board. I used SkiffOS [1] to
> > manage building the image, but upgraded the U-Boot version to Samuel
> > Holland's more up-to-date version [2] and changed out the device tree
> > used by U-Boot with the device trees that are present in upstream linux
> > and this series. Thank you Samuel for all of the work you did to make
> > this task possible.
> > 
> > [1] https://github.com/skiffos/SkiffOS/tree/master/configs/allwinner/nezha
> > [2] https://github.com/smaeul/u-boot/commit/2e89b706f5c956a70c989cd31665f1429e9a0b48
> > [3] https://lore.kernel.org/all/20240503-dev-charlie-support_thead_vector_6_9-v6-0-cb7624e65d82 at rivosinc.com/
> > [4] https://lore.kernel.org/lkml/20240719-support_vendor_extensions-v3-4-0af7587bbec0 at rivosinc.com/T/
> > 
> > ---
> > Changes in v10:
> > - In DT probing disable vector with new function to clear vendor
> >    extension bits for xtheadvector
> > - Add ghostwrite mitigations for c9xx CPUs. This disables xtheadvector
> >    unless mitigations=off is set as a kernel boot arg
> > - Link to v9: https://lore.kernel.org/r/20240806-xtheadvector-v9-0-62a56d2da5d0 at rivosinc.com
> > 
> > Changes in v9:
> > - Rebase onto palmer's for-next
> > - Fix sparse error in arch/riscv/kernel/vendor_extensions/thead.c
> > - Fix maybe-uninitialized warning in arch/riscv/include/asm/vendor_extensions/vendor_hwprobe.h
> > - Wrap some long lines
> > - Link to v8: https://lore.kernel.org/r/20240724-xtheadvector-v8-0-cf043168e137 at rivosinc.com
> > 
> > Changes in v8:
> > - Rebase onto palmer's for-next
> > - Link to v7: https://lore.kernel.org/r/20240724-xtheadvector-v7-0-b741910ada3e at rivosinc.com
> > 
> > Changes in v7:
> > - Add defs for has_xtheadvector_no_alternatives() and has_xtheadvector()
> >    when vector disabled. (Palmer)
> > - Link to v6: https://lore.kernel.org/r/20240722-xtheadvector-v6-0-c9af0130fa00 at rivosinc.com
> > 
> > Changes in v6:
> > - Fix return type of is_vector_supported()/is_xthead_supported() to be bool
> > - Link to v5: https://lore.kernel.org/r/20240719-xtheadvector-v5-0-4b485fc7d55f at rivosinc.com
> > 
> > Changes in v5:
> > - Rebase on for-next
> > - Link to v4: https://lore.kernel.org/r/20240702-xtheadvector-v4-0-2bad6820db11 at rivosinc.com
> > 
> > Changes in v4:
> > - Replace inline asm with C (Samuel)
> > - Rename VCSRs to CSRs (Samuel)
> > - Replace .insn directives with .4byte directives
> > - Link to v3: https://lore.kernel.org/r/20240619-xtheadvector-v3-0-bff39eb9668e at rivosinc.com
> > 
> > Changes in v3:
> > - Add back Heiko's signed-off-by (Conor)
> > - Mark RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 as a bitmask
> > - Link to v2: https://lore.kernel.org/r/20240610-xtheadvector-v2-0-97a48613ad64 at rivosinc.com
> > 
> > Changes in v2:
> > - Removed extraneous references to "riscv,vlenb" (Jess)
> > - Moved declaration of "thead,vlenb" into cpus.yaml and added
> >    restriction that it's only applicable to thead cores (Conor)
> > - Check CONFIG_RISCV_ISA_XTHEADVECTOR instead of CONFIG_RISCV_ISA_V for
> >    thead,vlenb (Jess)
> > - Fix naming of hwprobe variables (Evan)
> > - Link to v1: https://lore.kernel.org/r/20240609-xtheadvector-v1-0-3fe591d7f109 at rivosinc.com
> > 
> > ---
> > Charlie Jenkins (13):
> >        dt-bindings: riscv: Add xtheadvector ISA extension description
> >        dt-bindings: cpus: add a thead vlen register length property
> >        riscv: dts: allwinner: Add xtheadvector to the D1/D1s devicetree
> >        riscv: Add thead and xtheadvector as a vendor extension
> >        riscv: vector: Use vlenb from DT for thead
> >        riscv: csr: Add CSR encodings for CSR_VXRM/CSR_VXSAT
> >        riscv: Add xtheadvector instruction definitions
> >        riscv: vector: Support xtheadvector save/restore
> >        riscv: hwprobe: Add thead vendor extension probing
> >        riscv: hwprobe: Document thead vendor extensions and xtheadvector extension
> >        selftests: riscv: Fix vector tests
> >        selftests: riscv: Support xtheadvector in vector tests
> >        riscv: Add ghostwrite vulnerability
> > 
> > Heiko Stuebner (1):
> >        RISC-V: define the elements of the VCSR vector CSR
> > 
> >   Documentation/arch/riscv/hwprobe.rst               |  10 +
> >   Documentation/devicetree/bindings/riscv/cpus.yaml  |  19 ++
> >   .../devicetree/bindings/riscv/extensions.yaml      |  10 +
> >   arch/riscv/Kconfig.errata                          |  11 +
> >   arch/riscv/Kconfig.vendor                          |  26 ++
> >   arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi      |   3 +-
> >   arch/riscv/errata/thead/errata.c                   |  28 ++
> >   arch/riscv/include/asm/bugs.h                      |  22 ++
> >   arch/riscv/include/asm/cpufeature.h                |   2 +
> >   arch/riscv/include/asm/csr.h                       |  15 +
> >   arch/riscv/include/asm/errata_list.h               |   3 +-
> >   arch/riscv/include/asm/hwprobe.h                   |   3 +-
> >   arch/riscv/include/asm/switch_to.h                 |   2 +-
> >   arch/riscv/include/asm/vector.h                    | 225 +++++++++++----
> >   arch/riscv/include/asm/vendor_extensions/thead.h   |  48 ++++
> >   .../include/asm/vendor_extensions/thead_hwprobe.h  |  19 ++
> >   .../include/asm/vendor_extensions/vendor_hwprobe.h |  37 +++
> >   arch/riscv/include/uapi/asm/hwprobe.h              |   3 +-
> >   arch/riscv/include/uapi/asm/vendor/thead.h         |   3 +
> >   arch/riscv/kernel/Makefile                         |   2 +
> >   arch/riscv/kernel/bugs.c                           |  55 ++++
> >   arch/riscv/kernel/cpufeature.c                     |  58 +++-
> >   arch/riscv/kernel/kernel_mode_vector.c             |   8 +-
> >   arch/riscv/kernel/process.c                        |   4 +-
> >   arch/riscv/kernel/signal.c                         |   6 +-
> >   arch/riscv/kernel/sys_hwprobe.c                    |   5 +
> >   arch/riscv/kernel/vector.c                         |  24 +-
> >   arch/riscv/kernel/vendor_extensions.c              |  10 +
> >   arch/riscv/kernel/vendor_extensions/Makefile       |   2 +
> >   arch/riscv/kernel/vendor_extensions/thead.c        |  29 ++
> >   .../riscv/kernel/vendor_extensions/thead_hwprobe.c |  19 ++
> >   drivers/base/cpu.c                                 |   3 +
> >   include/linux/cpu.h                                |   1 +
> >   tools/testing/selftests/riscv/vector/.gitignore    |   3 +-
> >   tools/testing/selftests/riscv/vector/Makefile      |  17 +-
> >   .../selftests/riscv/vector/v_exec_initval_nolibc.c |  94 +++++++
> >   tools/testing/selftests/riscv/vector/v_helpers.c   |  68 +++++
> >   tools/testing/selftests/riscv/vector/v_helpers.h   |   8 +
> >   tools/testing/selftests/riscv/vector/v_initval.c   |  22 ++
> >   .../selftests/riscv/vector/v_initval_nolibc.c      |  68 -----
> >   .../selftests/riscv/vector/vstate_exec_nolibc.c    |  20 +-
> >   .../testing/selftests/riscv/vector/vstate_prctl.c  | 305 +++++++++++++--------
> >   42 files changed, 1048 insertions(+), 272 deletions(-)
> > ---
> > base-commit: 0e3f3649d44bf1b388a7613ade14c29cbdedf075
> > change-id: 20240530-xtheadvector-833d3d17b423
> 
> 
> Hello Charlie,
> 
> 
> Apologize for the last email, when dealing with pastebin it deleted the last
> version...
> 
> tl,dr for the last email: Patches not boot on Sipeed Lichee RV Dock (with
> same D1 SoC).
> 
> Logs here:
> 
> https://fars.ee/XFzR
> 
> (the board resets without kernel panic)

Apologies, this thread slipped by me. This looks to be the same issue as was experienced here [1] and fixed here [2].

[1] https://lore.kernel.org/linux-riscv/ZoydV7vad5JWIcZb at ghost/
[2] https://lore.kernel.org/linux-riscv/20240820034850.3189912-1-apatel at ventanamicro.com/

Since you are on 6.11-rc2 that patch is probably not in your tree, as it
was merged in 6.11-rc4 unfortunately. Can you try updating your kernel
to include that patch?

- Charlie


> 
> 
> Cheers,
> 
> Aoba K


From cyy at cyyself.name  Wed Nov 13 18:44:37 2024
From: cyy at cyyself.name (Yangyu Chen)
Date: Thu, 14 Nov 2024 10:44:37 +0800
Subject: [PATCH v11 10/14] riscv: hwprobe: Add thead vendor extension
 probing
In-Reply-To: <20241113-xtheadvector-v11-10-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
 <20241113-xtheadvector-v11-10-236c22791ef9@rivosinc.com>
Message-ID: <tencent_5B500856E30E1FB920B6B68D6315EE70CC06@qq.com>



On 11/14/24 10:21, Charlie Jenkins wrote:
> Add a new hwprobe key "RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0" which
> allows userspace to probe for the new RISCV_ISA_VENDOR_EXT_XTHEADVECTOR
> vendor extension.
> 

Hi Charlie,

How about changing the name of the key from 
"RISCV_ISA_VENDOR_EXT_XTHEADVECTOR" to "RISCV_HWPROBE_KEY_VENDOR_EXT_0" 
and use marchid to identify what the vendor is, each vendor will have 
its own bit definition in this value. So we can avoid adding so many 
hwprobe keys for each vendor in the future.

I proposed a commit here: 
https://github.com/cyyself/linux/commit/36390645d85d1ac75dd71172f167719df4297f59

> This new key will allow userspace code to probe for which thead vendor
> extensions are supported. This API is modeled to be consistent with
> RISCV_HWPROBE_KEY_IMA_EXT_0. The bitmask returned will have each bit
> corresponding to a supported thead vendor extension of the cpumask set.
> Just like RISCV_HWPROBE_KEY_IMA_EXT_0, this allows a userspace program
> to determine all of the supported thead vendor extensions in one call.
> 
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> Reviewed-by: Evan Green <evan at rivosinc.com>
> ---
>   arch/riscv/include/asm/hwprobe.h                   |  3 +-
>   .../include/asm/vendor_extensions/thead_hwprobe.h  | 19 +++++++++++
>   .../include/asm/vendor_extensions/vendor_hwprobe.h | 37 ++++++++++++++++++++++
>   arch/riscv/include/uapi/asm/hwprobe.h              |  3 +-
>   arch/riscv/include/uapi/asm/vendor/thead.h         |  3 ++
>   arch/riscv/kernel/sys_hwprobe.c                    |  5 +++
>   arch/riscv/kernel/vendor_extensions/Makefile       |  1 +
>   .../riscv/kernel/vendor_extensions/thead_hwprobe.c | 19 +++++++++++
>   8 files changed, 88 insertions(+), 2 deletions(-)
> 



From unicorn_wang at outlook.com  Wed Nov 13 18:51:23 2024
From: unicorn_wang at outlook.com (Chen Wang)
Date: Thu, 14 Nov 2024 10:51:23 +0800
Subject: [PATCH 1/5] dt-bindings: pci: Add Sophgo SG2042 PCIe host
In-Reply-To: <20241112155913.GA973575-robh@kernel.org>
References: <cover.1731303328.git.unicorn_wang@outlook.com>
 <1edbed1276a459a144f0cb0815859a1eb40bfcbf.1731303328.git.unicorn_wang@outlook.com>
 <20241112155913.GA973575-robh@kernel.org>
Message-ID: <MA0P287MB2822642BE6F4B448410A28FAFE5B2@MA0P287MB2822.INDP287.PROD.OUTLOOK.COM>


On 2024/11/12 23:59, Rob Herring wrote:
> On Mon, Nov 11, 2024 at 01:59:37PM +0800, Chen Wang wrote:
>> From: Chen Wang <unicorn_wang at outlook.com>
>>
>> Add binding for Sophgo SG2042 PCIe host controller.
>>
>> Signed-off-by: Chen Wang <unicorn_wang at outlook.com>
>> ---
>>   .../bindings/pci/sophgo,sg2042-pcie-host.yaml | 88 +++++++++++++++++++
>>   1 file changed, 88 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml b/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
>> new file mode 100644
>> index 000000000000..d4d2232f354f
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/sophgo,sg2042-pcie-host.yaml
>> @@ -0,0 +1,88 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/pci/sophgo,sg2042-pcie-host.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Sophgo SG2042 PCIe Host (Cadence PCIe Wrapper)
>> +
>> +description: |+
> Don't need '|+'
Got, thanks.
>
>> +  Sophgo SG2042 PCIe host controller is based on the Cadence PCIe core.
>> +  It shares common features with the PCIe core and inherits common properties
>> +  defined in Documentation/devicetree/bindings/pci/cdns-pcie-host.yaml.
> That's clear from the $ref. No need to say that in prose.
Got, thanks.
>
>> +
>> +maintainers:
>> +  - Chen Wang <unicorn_wang at outlook.com>
>> +
>> +properties:
>> +  compatible:
>> +    const: sophgo,sg2042-pcie-host
>> +
>> +  reg:
>> +    maxItems: 2
>> +
>> +  reg-names:
>> +    items:
>> +      - const: reg
>> +      - const: cfg
>> +
>> +  sophgo,syscon-pcie-ctrl:
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    description: Phandle to the SYSCON entry
> Please describe what you need to access.
>
>> +
>> +  sophgo,link-id:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    description: Cadence IP link ID.
> Is this an index or related to the syscon? Nak for the former, use
> linux,pci-domain. For the latter, add an arg to sophgo,syscon-pcie-ctrl.
Let me give you some background info.

SG2042 uses Cadence IP, every IP is composed of 2 cores(called link0 & 
link1 as Cadence's term). The Cadence IP has two modes of operation, 
selected by a strap pin.

In the single-link mode, the Cadence PCIe core instance associated with 
Link0 is connected to all the lanes and the Cadence PCIe core instance 
associated with Link1 is inactive.

In the dual-link mode, the Cadence PCIe core instance associated with 
Link0 is connected to the lower half of the lanes and the Cadence PCIe 
core instance associated with Link1 is connected to the upper half of 
the lanes.

SG2042 contains 2 Cadence IPs and configures the Cores as below:

```
 ? ? ? ? ? ? ? ?+-- Core(Link0) <---> pcie_rc0 ? +-----------------+
Cadence IP 1 --+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| cdns_pcie0_ctrl |
 ? ? ? ? ? ? ? ?+-- Core(Link1) <---> disabled ? +-----------------+
 ? ? ? ? ? ? ? ?+-- Core(Link0) <---> pcie_rc1 ? +-----------------+
Cadence IP 2 --+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| cdns_pcie1_ctrl |
 ? ? ? ? ? ? ? ?+-- Core(Link1) <---> pcie_rc2 ? +-----------------+
```


pcie_rcX is pcie node ("sophgo,sg2042-pcie-host") defined in DTS.
cdns_pcie0_ctrl is syscon node ("sophgo,sg2042-pcie-ctrl") defined in DTS

cdns_pcieX_ctrl contains some registers shared by pcie_rcX, even two 
RC(Link)s may share different bits of the same register. For 
example?cdns_pcie1_ctrl contains registers shared by link0 & link1 for 
Cadence IP 2.

So we defined "sophgo,link-id" to flag which core(link) the rc maps to, 
with this we can know what registers(bits) we should use.

That's why I don't use "linux,pci-domain" and also it's not proper to 
define it as arg to "sophgo,syscon-pcie-ctrl".


>> +
>> +  sophgo,internal-msi:
>> +    $ref: /schemas/types.yaml#/definitions/flag
>> +    description: Identifies whether the PCIE node uses internal MSI controller.
> Wouldn't 'msi-parent' work for this purpose?
I will check it out, thanks.
>
>> +
>> +  vendor-id:
>> +    const: 0x1f1c
>> +
>> +  device-id:
>> +    const: 0x2042
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  interrupt-names:
>> +    const: msi
>> +
>> +allOf:
>> +  - $ref: cdns-pcie-host.yaml#
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - reg-names
>> +  - sophgo,syscon-pcie-ctrl
>> +  - sophgo,link-id
>> +  - vendor-id
>> +  - device-id
>> +  - ranges
> ranges is already required in the common schemas.
Got.
>> +
>> +additionalProperties: true
>> +
>> +examples:
>> +  - |
>> +    pcie at 62000000 {
>> +      compatible = "sophgo,sg2042-pcie-host";
>> +      device_type = "pci";
>> +      reg = <0x62000000  0x00800000>,
>> +            <0x48000000  0x00001000>;
>> +      reg-names = "reg", "cfg";
>> +      #address-cells = <3>;
>> +      #size-cells = <2>;
>> +      ranges = <0x81000000 0 0x00000000 0xde000000 0 0x00010000>,
>> +               <0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>;
>> +      bus-range = <0x80 0xbf>;
>> +      vendor-id = <0x1f1c>;
>> +      device-id = <0x2042>;
>> +      cdns,no-bar-match-nbits = <48>;
>> +      sophgo,link-id = <0>;
>> +      sophgo,syscon-pcie-ctrl = <&cdns_pcie1_ctrl>;
>> +      sophgo,internal-msi;
>> +      interrupt-parent = <&intc>;
>> +    };
>> -- 
>> 2.34.1
>>


From charlie at rivosinc.com  Wed Nov 13 19:02:26 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 19:02:26 -0800
Subject: [PATCH v11 10/14] riscv: hwprobe: Add thead vendor extension
 probing
In-Reply-To: <tencent_5B500856E30E1FB920B6B68D6315EE70CC06@qq.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
 <20241113-xtheadvector-v11-10-236c22791ef9@rivosinc.com>
 <tencent_5B500856E30E1FB920B6B68D6315EE70CC06@qq.com>
Message-ID: <ZzVoQi6D0U30p9sg@ghost>

On Thu, Nov 14, 2024 at 10:44:37AM +0800, Yangyu Chen wrote:
> 
> 
> On 11/14/24 10:21, Charlie Jenkins wrote:
> > Add a new hwprobe key "RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0" which
> > allows userspace to probe for the new RISCV_ISA_VENDOR_EXT_XTHEADVECTOR
> > vendor extension.
> > 
> 
> Hi Charlie,
> 
> How about changing the name of the key from
> "RISCV_ISA_VENDOR_EXT_XTHEADVECTOR" to "RISCV_HWPROBE_KEY_VENDOR_EXT_0" and
> use marchid to identify what the vendor is, each vendor will have its own
> bit definition in this value. So we can avoid adding so many hwprobe keys
> for each vendor in the future.
> 
> I proposed a commit here: https://github.com/cyyself/linux/commit/36390645d85d1ac75dd71172f167719df4297f59

I actually originally had this in one of my first versions of this
series but was convinced by Conor to change it. The problem with it was
that tying vendor extensions to mvendorid means that it is enforced by
the kernel that vendors cannot share vendor extensions. It is possible
for vendor A to purchase IP that contains a vendor extension from vendor
B. This vendor extension should work on platforms created by vendor A
and vendor B. However, vendor A and vendor B have different mvendorids,
so the kernel can't support this if it is tied to mvendorid.  It could
be solved by duplicating every extension that vendors have, but then
userspace software would have to keep in mind the mvendorid they are
running on and check the different extensions for the different vendors
even though the implementation of the extension is the same.

The original conversation where Conor and I agreed that it was better to
have vendor extensions not rely on mvendorid:

https://lore.kernel.org/linux-riscv/20240416-husband-flavored-96c1dad58b6e at wendy/

> 
> > This new key will allow userspace code to probe for which thead vendor
> > extensions are supported. This API is modeled to be consistent with
> > RISCV_HWPROBE_KEY_IMA_EXT_0. The bitmask returned will have each bit
> > corresponding to a supported thead vendor extension of the cpumask set.
> > Just like RISCV_HWPROBE_KEY_IMA_EXT_0, this allows a userspace program
> > to determine all of the supported thead vendor extensions in one call.
> > 
> > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > Reviewed-by: Evan Green <evan at rivosinc.com>
> > ---
> >   arch/riscv/include/asm/hwprobe.h                   |  3 +-
> >   .../include/asm/vendor_extensions/thead_hwprobe.h  | 19 +++++++++++
> >   .../include/asm/vendor_extensions/vendor_hwprobe.h | 37 ++++++++++++++++++++++
> >   arch/riscv/include/uapi/asm/hwprobe.h              |  3 +-
> >   arch/riscv/include/uapi/asm/vendor/thead.h         |  3 ++
> >   arch/riscv/kernel/sys_hwprobe.c                    |  5 +++
> >   arch/riscv/kernel/vendor_extensions/Makefile       |  1 +
> >   .../riscv/kernel/vendor_extensions/thead_hwprobe.c | 19 +++++++++++
> >   8 files changed, 88 insertions(+), 2 deletions(-)
> > 
> 


From cyy at cyyself.name  Wed Nov 13 19:26:47 2024
From: cyy at cyyself.name (Yangyu Chen)
Date: Thu, 14 Nov 2024 11:26:47 +0800
Subject: [PATCH v11 10/14] riscv: hwprobe: Add thead vendor extension
 probing
In-Reply-To: <ZzVoQi6D0U30p9sg@ghost>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
 <20241113-xtheadvector-v11-10-236c22791ef9@rivosinc.com>
 <tencent_5B500856E30E1FB920B6B68D6315EE70CC06@qq.com>
 <ZzVoQi6D0U30p9sg@ghost>
Message-ID: <tencent_6A95637042401AD5F8BE05C7B4F11CAD7009@qq.com>



On 11/14/24 11:02, Charlie Jenkins wrote:
> On Thu, Nov 14, 2024 at 10:44:37AM +0800, Yangyu Chen wrote:
>>
>>
>> On 11/14/24 10:21, Charlie Jenkins wrote:
>>> Add a new hwprobe key "RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0" which
>>> allows userspace to probe for the new RISCV_ISA_VENDOR_EXT_XTHEADVECTOR
>>> vendor extension.
>>>
>>
>> Hi Charlie,
>>
>> How about changing the name of the key from
>> "RISCV_ISA_VENDOR_EXT_XTHEADVECTOR" to "RISCV_HWPROBE_KEY_VENDOR_EXT_0" and
>> use marchid to identify what the vendor is, each vendor will have its own
>> bit definition in this value. So we can avoid adding so many hwprobe keys
>> for each vendor in the future.
>>
>> I proposed a commit here: https://github.com/cyyself/linux/commit/36390645d85d1ac75dd71172f167719df4297f59
> 
> I actually originally had this in one of my first versions of this
> series but was convinced by Conor to change it. The problem with it was
> that tying vendor extensions to mvendorid means that it is enforced by
> the kernel that vendors cannot share vendor extensions. It is possible
> for vendor A to purchase IP that contains a vendor extension from vendor
> B. This vendor extension should work on platforms created by vendor A
> and vendor B. However, vendor A and vendor B have different mvendorids,
> so the kernel can't support this if it is tied to mvendorid.  It could
> be solved by duplicating every extension that vendors have, but then
> userspace software would have to keep in mind the mvendorid they are
> running on and check the different extensions for the different vendors
> even though the implementation of the extension is the same.
> 
> The original conversation where Conor and I agreed that it was better to
> have vendor extensions not rely on mvendorid:
> 
> https://lore.kernel.org/linux-riscv/20240416-husband-flavored-96c1dad58b6e at wendy/
> 

Thanks for your explanation. I will strongly agree with Conor's opinion 
if the feature bitmask does not exist in RISC-V C-ABI.

However, as the feature mask defined in RISC-V C-ABI[1] uses the design 
depending on marchid currently, should we reconsider this key for its 
use case? The current target_clones and taget_version implemented in 
GCC[2] and LLVM[3] also use the bitmask defined in C-ABI. I think if we 
use this key depending on marchid, to make a key shared with all vendors 
will make this cleaner.

[1] 
https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc#function-multi-version
[2] 
https://github.com/gcc-mirror/gcc/blob/8564d0948c72df0a66d7eb47e15c6ab43e9b25ce/gcc/config/riscv/riscv.cc#L13016
[3] 
https://github.com/llvm/llvm-project/blob/f407dff50cdcbcfee9dd92397d3792627c3ac708/clang/lib/CodeGen/CGBuiltin.cpp#L14627

>>
>>> This new key will allow userspace code to probe for which thead vendor
>>> extensions are supported. This API is modeled to be consistent with
>>> RISCV_HWPROBE_KEY_IMA_EXT_0. The bitmask returned will have each bit
>>> corresponding to a supported thead vendor extension of the cpumask set.
>>> Just like RISCV_HWPROBE_KEY_IMA_EXT_0, this allows a userspace program
>>> to determine all of the supported thead vendor extensions in one call.
>>>
>>> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
>>> Reviewed-by: Evan Green <evan at rivosinc.com>
>>> ---
>>>    arch/riscv/include/asm/hwprobe.h                   |  3 +-
>>>    .../include/asm/vendor_extensions/thead_hwprobe.h  | 19 +++++++++++
>>>    .../include/asm/vendor_extensions/vendor_hwprobe.h | 37 ++++++++++++++++++++++
>>>    arch/riscv/include/uapi/asm/hwprobe.h              |  3 +-
>>>    arch/riscv/include/uapi/asm/vendor/thead.h         |  3 ++
>>>    arch/riscv/kernel/sys_hwprobe.c                    |  5 +++
>>>    arch/riscv/kernel/vendor_extensions/Makefile       |  1 +
>>>    .../riscv/kernel/vendor_extensions/thead_hwprobe.c | 19 +++++++++++
>>>    8 files changed, 88 insertions(+), 2 deletions(-)
>>>
>>




From charlie at rivosinc.com  Wed Nov 13 20:46:12 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 20:46:12 -0800
Subject: [PATCH v11 10/14] riscv: hwprobe: Add thead vendor extension
 probing
In-Reply-To: <tencent_6A95637042401AD5F8BE05C7B4F11CAD7009@qq.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
 <20241113-xtheadvector-v11-10-236c22791ef9@rivosinc.com>
 <tencent_5B500856E30E1FB920B6B68D6315EE70CC06@qq.com>
 <ZzVoQi6D0U30p9sg@ghost>
 <tencent_6A95637042401AD5F8BE05C7B4F11CAD7009@qq.com>
Message-ID: <ZzWAlJm1ShgsZr4m@ghost>

On Thu, Nov 14, 2024 at 11:26:47AM +0800, Yangyu Chen wrote:
> 
> 
> On 11/14/24 11:02, Charlie Jenkins wrote:
> > On Thu, Nov 14, 2024 at 10:44:37AM +0800, Yangyu Chen wrote:
> > > 
> > > 
> > > On 11/14/24 10:21, Charlie Jenkins wrote:
> > > > Add a new hwprobe key "RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0" which
> > > > allows userspace to probe for the new RISCV_ISA_VENDOR_EXT_XTHEADVECTOR
> > > > vendor extension.
> > > > 
> > > 
> > > Hi Charlie,
> > > 
> > > How about changing the name of the key from
> > > "RISCV_ISA_VENDOR_EXT_XTHEADVECTOR" to "RISCV_HWPROBE_KEY_VENDOR_EXT_0" and
> > > use marchid to identify what the vendor is, each vendor will have its own
> > > bit definition in this value. So we can avoid adding so many hwprobe keys
> > > for each vendor in the future.
> > > 
> > > I proposed a commit here: https://github.com/cyyself/linux/commit/36390645d85d1ac75dd71172f167719df4297f59
> > 
> > I actually originally had this in one of my first versions of this
> > series but was convinced by Conor to change it. The problem with it was
> > that tying vendor extensions to mvendorid means that it is enforced by
> > the kernel that vendors cannot share vendor extensions. It is possible
> > for vendor A to purchase IP that contains a vendor extension from vendor
> > B. This vendor extension should work on platforms created by vendor A
> > and vendor B. However, vendor A and vendor B have different mvendorids,
> > so the kernel can't support this if it is tied to mvendorid.  It could
> > be solved by duplicating every extension that vendors have, but then
> > userspace software would have to keep in mind the mvendorid they are
> > running on and check the different extensions for the different vendors
> > even though the implementation of the extension is the same.
> > 
> > The original conversation where Conor and I agreed that it was better to
> > have vendor extensions not rely on mvendorid:
> > 
> > https://lore.kernel.org/linux-riscv/20240416-husband-flavored-96c1dad58b6e at wendy/
> > 
> 
> Thanks for your explanation. I will strongly agree with Conor's opinion if
> the feature bitmask does not exist in RISC-V C-ABI.
> 
> However, as the feature mask defined in RISC-V C-ABI[1] uses the design
> depending on marchid currently, should we reconsider this key for its use
> case? The current target_clones and taget_version implemented in GCC[2] and
> LLVM[3] also use the bitmask defined in C-ABI. I think if we use this key
> depending on marchid, to make a key shared with all vendors will make this
> cleaner.

Changing this will break linux userspace API. It is a non-workable
solution for the kernel to associate extensions with marchid/mvendorid
for the reasons provided. I fail to see why this ABI would require the
kernel to behave in this manner. The ABI provides the marchid to be used
by function multi-versioning and applications are free to use the
marchid to change which function they want to compile. However, if they
want to know if an extension is supported, then they need to use
hwprobe. If they want to check if xtheadvector is supported, then they
call hwprobe with the xtheadvector key. This is true no matter what the
mvendorid of the system is. This does not add any complexity, "clean"
code can equally be written following this scheme or following a scheme
that relies on mvendorid. Ditching the reliance on mvendorid in the
kernel allows the kernel to be as generic as possible, and allow
whatever ABIs or hardware that exist to have a resiliant way of
communicating with the kernel.

- CHarlie

> 
> [1] https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc#function-multi-version
> [2] https://github.com/gcc-mirror/gcc/blob/8564d0948c72df0a66d7eb47e15c6ab43e9b25ce/gcc/config/riscv/riscv.cc#L13016
> [3] https://github.com/llvm/llvm-project/blob/f407dff50cdcbcfee9dd92397d3792627c3ac708/clang/lib/CodeGen/CGBuiltin.cpp#L14627
> 
> > > 
> > > > This new key will allow userspace code to probe for which thead vendor
> > > > extensions are supported. This API is modeled to be consistent with
> > > > RISCV_HWPROBE_KEY_IMA_EXT_0. The bitmask returned will have each bit
> > > > corresponding to a supported thead vendor extension of the cpumask set.
> > > > Just like RISCV_HWPROBE_KEY_IMA_EXT_0, this allows a userspace program
> > > > to determine all of the supported thead vendor extensions in one call.
> > > > 
> > > > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > > > Reviewed-by: Evan Green <evan at rivosinc.com>
> > > > ---
> > > >    arch/riscv/include/asm/hwprobe.h                   |  3 +-
> > > >    .../include/asm/vendor_extensions/thead_hwprobe.h  | 19 +++++++++++
> > > >    .../include/asm/vendor_extensions/vendor_hwprobe.h | 37 ++++++++++++++++++++++
> > > >    arch/riscv/include/uapi/asm/hwprobe.h              |  3 +-
> > > >    arch/riscv/include/uapi/asm/vendor/thead.h         |  3 ++
> > > >    arch/riscv/kernel/sys_hwprobe.c                    |  5 +++
> > > >    arch/riscv/kernel/vendor_extensions/Makefile       |  1 +
> > > >    .../riscv/kernel/vendor_extensions/thead_hwprobe.c | 19 +++++++++++
> > > >    8 files changed, 88 insertions(+), 2 deletions(-)
> > > > 
> > > 
> 
> 


From hch at lst.de  Wed Nov 13 21:43:31 2024
From: hch at lst.de (Christoph Hellwig)
Date: Thu, 14 Nov 2024 06:43:31 +0100
Subject: [PATCH] dma-mapping: Save base/size instead of pointer to
 shared DMA pool
In-Reply-To: <f8cef6845a6141f0277e31a71fe153612daae776.1731436631.git.geert+renesas@glider.be>
References: <f8cef6845a6141f0277e31a71fe153612daae776.1731436631.git.geert+renesas@glider.be>
Message-ID: <20241114054331.GA10817@lst.de>

Thanks Geert,

I've applied the patch to the dma-mapping for-next tree.



From nick.hu at sifive.com  Wed Nov 13 22:17:30 2024
From: nick.hu at sifive.com (Nick Hu)
Date: Thu, 14 Nov 2024 14:17:30 +0800
Subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack
 memory via FWFT sbi call
In-Reply-To: <ZzVRbCZP9N4Os8Bj@debug.ba.rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
 <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
 <CAKddAkCCVjNHUinPWtOiK8Ki_ZkdoUCawfv1-+0B69J_1aJv5Q@mail.gmail.com>
 <ZzVNKvCu4MOs7O5z@debug.ba.rivosinc.com> <CAKddAkDbGYeONaksq6fzLzx47BHZo3Ar7Sog3MOgf7Y+Birovw@mail.gmail.com>
 <ZzVRbCZP9N4Os8Bj@debug.ba.rivosinc.com>
Message-ID: <CAKddAkBCByf570PXfz798FtBbeGQWe2LJpdzxkE+jv3Zd3ZV1w@mail.gmail.com>

Hi Deepak

On Thu, Nov 14, 2024 at 9:25?AM Deepak Gupta <debug at rivosinc.com> wrote:
>
> On Thu, Nov 14, 2024 at 09:20:14AM +0800, Nick Hu wrote:
> >Hi Deepak
> >
> >On Thu, Nov 14, 2024 at 9:06?AM Deepak Gupta <debug at rivosinc.com> wrote:
> >>
> >> On Thu, Nov 14, 2024 at 12:13:38AM +0800, Nick Hu wrote:
> >> >Hi Deepak
> >> >
> >> >On Tue, Nov 12, 2024 at 5:08?AM Deepak Gupta <debug at rivosinc.com> wrote:
> >> >>
> >> >> Kernel will have to perform shadow stack operations on user shadow stack.
> >> >> Like during signal delivery and sigreturn, shadow stack token must be
> >> >> created and validated respectively. Thus shadow stack access for kernel
> >> >> must be enabled.
> >> >>
> >> >> In future when kernel shadow stacks are enabled for linux kernel, it must
> >> >> be enabled as early as possible for better coverage and prevent imbalance
> >> >> between regular stack and shadow stack. After `relocate_enable_mmu` has
> >> >> been done, this is as early as possible it can enabled.
> >> >>
> >> >> Signed-off-by: Deepak Gupta <debug at rivosinc.com>
> >> >> ---
> >> >>  arch/riscv/kernel/asm-offsets.c |  4 ++++
> >> >>  arch/riscv/kernel/head.S        | 12 ++++++++++++
> >> >>  2 files changed, 16 insertions(+)
> >> >>
> >> >> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> >> >> index 766bd33f10cb..a22ab8a41672 100644
> >> >> --- a/arch/riscv/kernel/asm-offsets.c
> >> >> +++ b/arch/riscv/kernel/asm-offsets.c
> >> >> @@ -517,4 +517,8 @@ void asm_offsets(void)
> >> >>         DEFINE(FREGS_A6,            offsetof(struct ftrace_regs, a6));
> >> >>         DEFINE(FREGS_A7,            offsetof(struct ftrace_regs, a7));
> >> >>  #endif
> >> >> +       DEFINE(SBI_EXT_FWFT, SBI_EXT_FWFT);
> >> >> +       DEFINE(SBI_EXT_FWFT_SET, SBI_EXT_FWFT_SET);
> >> >> +       DEFINE(SBI_FWFT_SHADOW_STACK, SBI_FWFT_SHADOW_STACK);
> >> >> +       DEFINE(SBI_FWFT_SET_FLAG_LOCK, SBI_FWFT_SET_FLAG_LOCK);
> >> >>  }
> >> >> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> >> >> index 356d5397b2a2..6244408ca917 100644
> >> >> --- a/arch/riscv/kernel/head.S
> >> >> +++ b/arch/riscv/kernel/head.S
> >> >> @@ -164,6 +164,12 @@ secondary_start_sbi:
> >> >>         call relocate_enable_mmu
> >> >>  #endif
> >> >>         call .Lsetup_trap_vector
> >> >> +       li a7, SBI_EXT_FWFT
> >> >> +       li a6, SBI_EXT_FWFT_SET
> >> >> +       li a0, SBI_FWFT_SHADOW_STACK
> >> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
> >> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
> >> >> +       ecall
> >> >>         scs_load_current
> >> >>         call smp_callin
> >> >>  #endif /* CONFIG_SMP */
> >> >> @@ -320,6 +326,12 @@ SYM_CODE_START(_start_kernel)
> >> >>         la tp, init_task
> >> >>         la sp, init_thread_union + THREAD_SIZE
> >> >>         addi sp, sp, -PT_SIZE_ON_STACK
> >> >> +       li a7, SBI_EXT_FWFT
> >> >> +       li a6, SBI_EXT_FWFT_SET
> >> >> +       li a0, SBI_FWFT_SHADOW_STACK
> >> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
> >> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
> >> >> +       ecall
> >> >>         scs_load_current
> >> >>
> >> >>  #ifdef CONFIG_KASAN
> >> >>
> >> >> --
> >> >> 2.45.0
> >> >>
> >> >Should we clear the SBI_FWFT_SET_FLAG_LOCK before the cpu hotplug
> >> >otherwise the menvcfg.sse won't be set by the fwft set sbi call when
> >> >the hotplug cpu back to kernel?
> >>
> >> Hmm...
> >>
> >> An incoming hotplug CPU has no features setup on it.
> >> I see that `sbi_cpu_start` will supply `secondary_start_sbi` as start
> >> up code for incoming CPU. `secondary_start_sbi` is in head.S which converges
> >> in `.Lsecondary_start_common`. And thus hotplugged CPU should be
> >> issuing shadow stack set FWFT sbi as well.
> >>
> >> Am I missing something ?
> >>
> >This is the correct flow. However the opensbi will deny it due to the
> >SBI_FWFT_SET_FLAG_LOCK already being set.
> >So the menvcfg.sse will not set by this flow.
> >
> >if (conf->flags & SBI_FWFT_SET_FLAG_LOCK)
> >                return SBI_EDENIED;
> >
>
> hmm... Why?
>
> `conf` is pointing to per-hart state in firmware.
>
> On this incoming cpu, opensbi (or equivalent) firmware must have
> ensured that this per-hart state doesn't have lock set.
>
> Am I missing something?
>
Current OpenSBI doesn't clear the lock in the warm init of the hotplug path.
It seems like we need a patch to address it.

Regards,
Nick
> >Regards,
> >Nick
> >> >
> >> >Regards,
> >> >Nick
> >> >>
> >> >> _______________________________________________
> >> >> linux-riscv mailing list
> >> >> linux-riscv at lists.infradead.org
> >> >> http://lists.infradead.org/mailman/listinfo/linux-riscv


From mikisabate at gmail.com  Wed Nov 13 22:37:20 2024
From: mikisabate at gmail.com (=?utf-8?Q?Miquel_Sabat=C3=A9_Sol=C3=A0?=)
Date: Thu, 14 Nov 2024 07:37:20 +0100
Subject: [RESEND PATCH v2] riscv: hwprobe: export Zicntr and Zihpm
 extensions
In-Reply-To: <66f1cc93.050a0220.bf7a0.30f3@mx.google.com> ("Miquel
 =?utf-8?Q?Sabat=C3=A9=09Sol=C3=A0=22's?= message of "Mon, 23 Sep 2024
 22:16:17 +0200")
References: <20240913051324.8176-1-mikisabate@gmail.com>
	<66f1cc93.050a0220.bf7a0.30f3@mx.google.com>
Message-ID: <67359aa2.050a0220.cc412.2c60@mx.google.com>

On dl., de set. 23 2024, Miquel Sabat? Sol? wrote:

> On dv., de set. 13 2024, Miquel Sabat? Sol? wrote:
>
>> Export Zicntr and Zihpm ISA extensions through the hwprobe syscall.
>>
>> Signed-off-by: Miquel Sabat? Sol? <mikisabate at gmail.com>
>> Acked-by: Jesse Taube <jesse at rivosinc.com>
>> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
>> ---
>> This is a resend because I sent v2 as a reply to the original thread and
>> it most probably was lost by most people. Fortunately Conor picked it up
>> and gave it a review.
>>
>> I am resending this so it can be properly applied. Thank you for your time and
>> sorry for the inconvenience.
>>
>> Changes since v1 [1]: the EXT_KEY instructions have been written in order.
>>
>> [1] https://lore.kernel.org/linux-riscv/20240817075629.262318-1-mikisabate at gmail.com/
>>
>>  Documentation/arch/riscv/hwprobe.rst  | 6 ++++++
>>  arch/riscv/include/uapi/asm/hwprobe.h | 2 ++
>>  arch/riscv/kernel/sys_hwprobe.c       | 2 ++
>>  3 files changed, 10 insertions(+)
>>
>> diff --git a/Documentation/arch/riscv/hwprobe.rst b/Documentation/arch/riscv/hwprobe.rst
>> index 3db60a0911df..cfd2929d0562 100644
>> --- a/Documentation/arch/riscv/hwprobe.rst
>> +++ b/Documentation/arch/riscv/hwprobe.rst
>> @@ -183,6 +183,9 @@ The following keys are defined:
>>         defined in the Atomic Compare-and-Swap (CAS) instructions manual starting
>>         from commit 5059e0ca641c ("update to ratified").
>>
>> +  * :c:macro:`RISCV_HWPROBE_EXT_ZICNTR`: The Zicntr extension version 2.0
>> +       is supported as defined in the RISC-V ISA manual.
>> +
>>    * :c:macro:`RISCV_HWPROBE_EXT_ZICOND`: The Zicond extension is supported as
>>         defined in the RISC-V Integer Conditional (Zicond) operations extension
>>         manual starting from commit 95cf1f9 ("Add changes requested by Ved
>> @@ -192,6 +195,9 @@ The following keys are defined:
>>         supported as defined in the RISC-V ISA manual starting from commit
>>         d8ab5c78c207 ("Zihintpause is ratified").
>>
>> +  * :c:macro:`RISCV_HWPROBE_EXT_ZIHPM`: The Zihpm extension version 2.0
>> +       is supported as defined in the RISC-V ISA manual.
>> +
>>    * :c:macro:`RISCV_HWPROBE_EXT_ZVE32X`: The Vector sub-extension Zve32x is
>>      supported, as defined by version 1.0 of the RISC-V Vector extension manual.
>>
>> diff --git a/arch/riscv/include/uapi/asm/hwprobe.h b/arch/riscv/include/uapi/asm/hwprobe.h
>> index b706c8e47b02..098a815b3fd4 100644
>> --- a/arch/riscv/include/uapi/asm/hwprobe.h
>> +++ b/arch/riscv/include/uapi/asm/hwprobe.h
>> @@ -72,6 +72,8 @@ struct riscv_hwprobe {
>>  #define		RISCV_HWPROBE_EXT_ZCF		(1ULL << 46)
>>  #define		RISCV_HWPROBE_EXT_ZCMOP		(1ULL << 47)
>>  #define		RISCV_HWPROBE_EXT_ZAWRS		(1ULL << 48)
>> +#define		RISCV_HWPROBE_EXT_ZICNTR	(1ULL << 49)
>> +#define		RISCV_HWPROBE_EXT_ZIHPM		(1ULL << 50)
>>  #define RISCV_HWPROBE_KEY_CPUPERF_0	5
>>  #define		RISCV_HWPROBE_MISALIGNED_UNKNOWN	(0 << 0)
>>  #define		RISCV_HWPROBE_MISALIGNED_EMULATED	(1 << 0)
>> diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
>> index 8d1b5c35d2a7..910b41b6a7ab 100644
>> --- a/arch/riscv/kernel/sys_hwprobe.c
>> +++ b/arch/riscv/kernel/sys_hwprobe.c
>> @@ -107,9 +107,11 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
>>  		EXT_KEY(ZCB);
>>  		EXT_KEY(ZCMOP);
>>  		EXT_KEY(ZICBOZ);
>> +		EXT_KEY(ZICNTR);
>>  		EXT_KEY(ZICOND);
>>  		EXT_KEY(ZIHINTNTL);
>>  		EXT_KEY(ZIHINTPAUSE);
>> +		EXT_KEY(ZIHPM);
>>  		EXT_KEY(ZIMOP);
>>  		EXT_KEY(ZKND);
>>  		EXT_KEY(ZKNE);
>
> Hello,
>
> Gently ping :) Can we get this merged for 6.12?
>
> Thanks!
> Miquel

Hello,

Gently ping :)

This will certainly not be included for 6.12, but is there a chance to
get it for 6.13?

Thanks,
Miquel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 861 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241114/63173647/attachment.sig>

From dlan at gentoo.org  Wed Nov 13 22:49:43 2024
From: dlan at gentoo.org (Yixun Lan)
Date: Thu, 14 Nov 2024 14:49:43 +0800
Subject: [PATCH v3 2/2] i2c: spacemit: add support for SpacemiT K1 SoC
In-Reply-To: <20241112-k1-i2c-master-v3-2-5005b70dc208@gmail.com>
References: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
 <20241112-k1-i2c-master-v3-2-5005b70dc208@gmail.com>
Message-ID: <20241114064943-GYA998060@gentoo>

On 11:07 Tue 12 Nov     , Troy Mitchell wrote:
> From: Troy Mitchell <troymitchell988 at gmail.com>
> 
> This patch introduces basic I2C support for the SpacemiT K1 SoC,
> utilizing interrupts for transfers.
> 
> The driver has been tested using i2c-tools on a Bananapi-F3 board,
> and basic I2C read/write operations have been confirmed to work.
> 
> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
> ---
>  drivers/i2c/busses/Kconfig  |  19 ++
>  drivers/i2c/busses/Makefile |   1 +
>  drivers/i2c/busses/i2c-k1.c | 656 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 676 insertions(+)
> 
> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
> index 6b3ba7e5723a..91630f55667f 100644
> --- a/drivers/i2c/busses/Kconfig
> +++ b/drivers/i2c/busses/Kconfig
> @@ -779,6 +779,25 @@ config I2C_JZ4780
>  
>  	 If you don't know what to do here, say N.
>  
> +config I2C_K1
> +	tristate "Spacemit K1 I2C adapter"
> +	depends on ARCH_SPACEMIT || COMPILE_TEST
> +	depends on OF
> +	help
> +	  This option enables support for the I2C interface on the Spacemit K1
> +	  platform.
> +
> +	  If you enable this configuration, the kernel will include support for
> +	  the I2C adapter specific to the Spacemit K1 platform. This driver ca
> +	  be used to manage I2C bus transactions, which are necessary for
> +	  interfacing with I2C peripherals such as sensors, EEPROMs, and other
> +	  devices.
> +
> +	  This driver can also be compiled as a module. If you choose to build
> +	  it as a module, the resulting kernel module will be named `i2c-k1`.
> +	  Loading this module will enable the I2C functionality for the K1
> +	  platform dynamically, without requiring a rebuild of the kernel.
> +
>  config I2C_KEBA
>  	tristate "KEBA I2C controller support"
>  	depends on HAS_IOMEM
> diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
> index ecc07c50f2a0..9744b0e58598 100644
> --- a/drivers/i2c/busses/Makefile
> +++ b/drivers/i2c/busses/Makefile
> @@ -76,6 +76,7 @@ obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
>  obj-$(CONFIG_I2C_IMX_LPI2C)	+= i2c-imx-lpi2c.o
>  obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
>  obj-$(CONFIG_I2C_JZ4780)	+= i2c-jz4780.o
> +obj-$(CONFIG_I2C_K1)		+= i2c-k1.o
>  obj-$(CONFIG_I2C_KEBA)		+= i2c-keba.o
>  obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
>  obj-$(CONFIG_I2C_LPC2K)		+= i2c-lpc2k.o
> diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c
> new file mode 100644
> index 000000000000..12bb71625e0a
> --- /dev/null
> +++ b/drivers/i2c/busses/i2c-k1.c
> @@ -0,0 +1,656 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2024 Troy Mitchell <troymitchell988 at gmail.com>
> + */
> +
> + #include <linux/clk.h>
> + #include <linux/i2c.h>
> + #include <linux/iopoll.h>
> + #include <linux/module.h>
> + #include <linux/of_address.h>
> + #include <linux/platform_device.h>
> +
> +/* spacemit i2c registers */
> +#define ICR          0x0		/* Control Register */
> +#define ISR          0x4		/* Status Register */
> +#define ISAR         0x8		/* Slave Address Register */
> +#define IDBR         0xc		/* Data Buffer Register */
> +#define ILCR         0x10		/* Load Count Register */
> +#define IWCR         0x14		/* Wait Count Register */
> +#define IRST_CYC     0x18		/* Bus reset cycle counter */
> +#define IBMR         0x1c		/* Bus monitor register */
> +#define IWFIFO       0x20		/* Write FIFO Register */
> +#define IWFIFO_WPTR  0x24		/* Write FIFO Write Pointer Register */
> +#define IWFIFO_RPTR  0x28		/* Write FIFO Read Pointer Register */
> +#define IRFIFO       0x2c		/* Read FIFO Register */
> +#define IRFIFO_WPTR  0x30		/* Read FIFO Write Pointer Register */
> +#define IRFIFO_RPTR  0x34		/* Read FIFO Read Pointer Register */
> +
> +/* register ICR fields */
> +#define CR_START        BIT(0)		/* start bit */
> +#define CR_STOP         BIT(1)		/* stop bit */
> +#define CR_ACKNAK       BIT(2)		/* send ACK(0) or NAK(1) */
> +#define CR_TB           BIT(3)		/* transfer byte bit */
> +#define CR_TXBEGIN      BIT(4)		/* transaction begin */
> +#define CR_FIFOEN       BIT(5)		/* enable FIFO mode */
> +#define CR_GPIOEN       BIT(6)		/* enable GPIO mode for SCL in HS */
> +#define CR_DMAEN        BIT(7)		/* enable DMA for TX and RX FIFOs */
> +#define CR_MODE_FAST    BIT(8)		/* bus mode (master operation) */
> +#define CR_MODE_HIGH    BIT(9)		/* bus mode (master operation) */
> +#define CR_UR           BIT(10)		/* unit reset */
> +#define CR_RSTREQ       BIT(11)		/* i2c bus reset request */
> +#define CR_MA           BIT(12)		/* master abort */
> +#define CR_SCLE         BIT(13)		/* master clock enable */
> +#define CR_IUE          BIT(14)		/* unit enable */
> +#define CR_HS_STRETCH   BIT(16)		/* I2C hs stretch */
> +#define CR_ALDIE        BIT(18)		/* enable arbitration interrupt */
> +#define CR_DTEIE        BIT(19)		/* enable tx interrupts */
> +#define CR_DRFIE        BIT(20)		/* enable rx interrupts */
> +#define CR_GCD          BIT(21)		/* general call disable */
> +#define CR_BEIE         BIT(22)		/* enable bus error ints */
> +#define CR_SADIE        BIT(23)		/* slave address detected int enable */
> +#define CR_SSDIE        BIT(24)		/* slave STOP detected int enable */
> +#define CR_MSDIE        BIT(25)		/* master STOP detected int enable */
> +#define CR_MSDE         BIT(26)		/* master STOP detected enable */
> +#define CR_TXDONEIE     BIT(27)		/* transaction done int enable */
> +#define CR_TXEIE        BIT(28)		/* transmit FIFO empty int enable */
> +#define CR_RXHFIE       BIT(29)		/* receive FIFO half-full int enable */
> +#define CR_RXFIE        BIT(30)		/* receive FIFO full int enable */
> +#define CR_RXOVIE       BIT(31)		/* receive FIFO overrun int enable */
> +
> +/* register ISR fields */
> +#define SR_RWM          BIT(13)		/* read/write mode */
> +#define SR_ACKNAK       BIT(14)		/* ACK/NACK status */
> +#define SR_UB           BIT(15)		/* unit busy */
> +#define SR_IBB          BIT(16)		/* i2c bus busy */
> +#define SR_EBB          BIT(17)		/* early bus busy */
> +#define SR_ALD          BIT(18)		/* arbitration loss detected */
> +#define SR_ITE          BIT(19)		/* tx buffer empty */
> +#define SR_IRF          BIT(20)		/* rx buffer full */
> +#define SR_GCAD         BIT(21)		/* general call address detected */
> +#define SR_BED          BIT(22)		/* bus error no ACK/NAK */
> +#define SR_SAD          BIT(23)		/* slave address detected */
> +#define SR_SSD          BIT(24)		/* slave stop detected */
> +#define SR_MSD          BIT(26)		/* master stop detected */
> +#define SR_TXDONE       BIT(27)		/* transaction done */
> +#define SR_TXE          BIT(28)		/* tx FIFO empty */
> +#define SR_RXHF         BIT(29)		/* rx FIFO half-full */
> +#define SR_RXF          BIT(30)		/* rx FIFO full */
> +#define SR_RXOV         BIT(31)		/* RX FIFO overrun */
> +
> +/* register ILCR fields */
> +#define LCR_SLV         0x000001FF	/* SLV: bit[8:0] */
> +#define LCR_FLV         0x0003FE00	/* FLV: bit[17:9] */
> +#define LCR_HLVH        0x07FC0000	/* HLVH: bit[26:18] */
> +#define LCR_HLVL        0xF8000000	/* HLVL: bit[31:27] */
> +
> +/* register IWCR fields */
> +#define WCR_COUNT       0x0000001F	/* COUNT: bit[4:0] */
> +#define WCR_COUNT1      0x000003E0	/* HS_COUNT1: bit[9:5] */
> +#define WCR_COUNT2      0x00007C00	/* HS_COUNT2: bit[14:10] */
> +
> +/* register IBMR fields */
> +#define BMR_SDA         BIT(0)		/* SDA line level */
> +#define BMR_SCL         BIT(1)		/* SCL line level */
> +
> +/* register IWFIFO fields */
> +#define WFIFO_DATA_MSK      0x000000FF  /* data: bit[7:0] */
> +#define WFIFO_CTRL_MSK      0x000003E0  /* control: bit[11:8] */
> +#define WFIFO_CTRL_START    BIT(8)      /* start bit */
> +#define WFIFO_CTRL_STOP     BIT(9)      /* stop bit */
> +#define WFIFO_CTRL_ACKNAK   BIT(10)     /* send ACK(0) or NAK(1) */
> +#define WFIFO_CTRL_TB       BIT(11)     /* transfer byte bit */
> +
> +/* status register init value */
> +#define I2C_INT_STATUS_MASK    0xfffc0000  /* SR bits[31:18] */
> +#define I2C_INT_CTRL_MASK      (CR_ALDIE | CR_DTEIE | CR_DRFIE | \
> +				CR_BEIE | CR_TXDONEIE | CR_TXEIE | \
> +				CR_RXHFIE | CR_RXFIE | CR_RXOVIE | \
> +				CR_MSDIE)
> +
> +/* i2c bus recover timeout: us */
> +#define I2C_BUS_RECOVER_TIMEOUT		(100000)
> +
> +#define I2C_FAST_MODE_FREQ		(400000)
> +
> +enum spacemit_i2c_state {
> +	STATE_IDLE,
> +	STATE_START,
> +	STATE_READ,
> +	STATE_WRITE,
> +};
> +
> +enum spacemit_i2c_dir {
> +	DIR_WRITE,
> +	DIR_READ
> +};
> +
> +/* i2c-spacemit driver's main struct */
> +struct spacemit_i2c_dev {
> +	struct device *dev;
> +	struct i2c_adapter adapt;
> +
> +	/* hardware resources */
> +	void __iomem *base;
> +	int irq;
> +
> +	struct i2c_msg *msgs;
> +	int msg_num;
> +	struct i2c_msg *cur_msg;
> +
> +	/* index of the current message being processed */
> +	int msg_idx;
> +	u8 *msg_buf;
> +	/* the number of unprocessed bytes remaining in each message  */
> +	size_t unprocessed;
> +
> +	enum spacemit_i2c_state state;
> +	enum spacemit_i2c_dir dir;
> +	struct completion complete;
> +	u32 status;
> +	u32 err;
> +};
> +
> +static void spacemit_i2c_enable(struct spacemit_i2c_dev *i2c)
> +{
> +	u32 val;
> +
> +	val = readl(i2c->base + ICR);
> +	writel(val | CR_IUE, i2c->base + ICR);
> +}
> +
> +static void spacemit_i2c_disable(struct spacemit_i2c_dev *i2c)
> +{
> +	u32 val;
> +
> +	val = readl(i2c->base + ICR);
> +	val &= ~CR_IUE;
> +	writel(val, i2c->base + ICR);
> +}
> +
> +static void spacemit_i2c_reset(struct spacemit_i2c_dev *i2c)
> +{
> +	writel(CR_UR, i2c->base + ICR);
> +	udelay(5);
> +	writel(0, i2c->base + ICR);
> +}
> +
> +static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c);
> +
> +static void spacemit_i2c_bus_reset(struct spacemit_i2c_dev *i2c)
> +{
> +	u32 status;
> +
> +	/* if bus is locked, reset unit. 0: locked */
> +	status = readl(i2c->base + IBMR);
> +	if ((status & BMR_SDA) && (status & BMR_SCL))
> +		return;
> +
> +	spacemit_i2c_reset(i2c);
> +	usleep_range(10, 20);
> +
> +	/* check scl status again */
> +	status = readl(i2c->base + IBMR);
> +	if (!(status & BMR_SCL))
> +		dev_warn_ratelimited(i2c->dev, "unit reset failed\n");
> +}
> +
> +static int spacemit_i2c_recover_bus_busy(struct spacemit_i2c_dev *i2c)
> +{
> +	int ret = 0;
> +	u32 val;
> +
> +	val = readl(i2c->base + ISR);
> +	if (likely(!(val & (SR_UB | SR_IBB))))
> +		return 0;
> +
> +	ret = readl_poll_timeout(i2c->base + ISR, val, !(val & (SR_UB | SR_IBB)),
> +				 1500, I2C_BUS_RECOVER_TIMEOUT);
> +	if (unlikely(ret)) {
> +		spacemit_i2c_reset(i2c);
> +		ret = -EAGAIN;
> +	}
> +
> +	return ret;
> +}
> +
> +static void spacemit_i2c_check_bus_release(struct spacemit_i2c_dev *i2c)
> +{
> +	/* in case bus is not released after transfer completes */
> +	if (unlikely(readl(i2c->base + ISR) & SR_EBB)) {
> +		spacemit_i2c_bus_reset(i2c);
> +		usleep_range(90, 150);
> +	}
> +}
> +
> +static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c)
> +{
> +	u32 val = 0;
> +
> +	/*
> +	 * Unmask interrupt bits for all xfer mode:
> +	 * bus error, arbitration loss detected.
> +	 * For transaction complete signal, we use master stop
> +	 * interrupt, so we don't need to unmask CR_TXDONEIE.
> +	 */
> +	val |= CR_BEIE | CR_ALDIE;
> +
> +	/*
> +	 * Unmask interrupt bits for interrupt xfer mode:
> +	 * DBR rx full.
> +	 * For tx empty interrupt CR_DTEIE, we only
> +	 * need to enable when trigger byte transfer to start
> +	 * data sending.
> +	 */
> +	val |= CR_DRFIE;
> +
> +	/* set speed bits: default fast mode */
> +	val |= CR_MODE_FAST;
> +
> +	/* disable response to general call */
> +	val |= CR_GCD;
> +
> +	/* enable SCL clock output */
> +	val |= CR_SCLE;
> +
> +	/* enable master stop detected */
> +	val |= CR_MSDE | CR_MSDIE;
> +
> +	writel(val, i2c->base + ICR);
> +}
> +
> +static inline void
> +spacemit_i2c_clear_int_status(struct spacemit_i2c_dev *i2c, u32 mask)
> +{
> +	writel(mask & I2C_INT_STATUS_MASK, i2c->base + ISR);
> +}
> +
> +static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c)
> +{
> +	u32 slave_addr_rw, val;
> +
> +	i2c->dir = i2c->cur_msg->flags & I2C_M_RD;
> +	i2c->state = STATE_START;
> +
> +	if (i2c->cur_msg->flags & I2C_M_RD)
> +		slave_addr_rw = ((i2c->cur_msg->addr & 0x7f) << 1) | 1;
> +	else
> +		slave_addr_rw = (i2c->cur_msg->addr & 0x7f) << 1;
> +
> +	writel(slave_addr_rw, i2c->base + IDBR);
> +
> +	val = readl(i2c->base + ICR);
> +
> +	/* send start pulse */
> +	val &= ~CR_STOP;
> +	val |= CR_START | CR_TB | CR_DTEIE;
> +	writel(val, i2c->base + ICR);
> +}
> +
> +static void spacemit_i2c_stop(struct spacemit_i2c_dev *i2c)
> +{
> +	u32 val;
> +
> +	val = readl(i2c->base + ICR);
> +
> +	val |= CR_STOP | CR_ALDIE | CR_TB;
> +
> +	if (i2c->dir == DIR_READ)
> +		val |= CR_ACKNAK;
> +
> +	writel(val, i2c->base + ICR);
> +}
> +
> +static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
> +{
> +	unsigned long time_left;
> +
> +	for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) {
> +		i2c->cur_msg = i2c->msgs + i2c->msg_idx;
> +		i2c->msg_buf = i2c->cur_msg->buf;
> +		i2c->err = 0;
> +		i2c->status = 0;
> +		i2c->unprocessed = i2c->cur_msg->len;
> +
> +		reinit_completion(&i2c->complete);
> +
> +		spacemit_i2c_start(i2c);
> +
> +		time_left = wait_for_completion_timeout(&i2c->complete,
> +							i2c->adapt.timeout);
> +		if (unlikely(time_left == 0)) {
> +			dev_alert(i2c->dev, "msg completion timeout\n");
> +			spacemit_i2c_bus_reset(i2c);
> +			spacemit_i2c_reset(i2c);
> +			return -ETIMEDOUT;
> +		}
> +
> +		if (unlikely(i2c->err))
> +			return spacemit_i2c_handle_err(i2c);
> +	}
> +
> +	return 0;
> +}
> +
> +static int spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c)
> +{
> +	if (i2c->dir == DIR_READ) {
> +		if (i2c->unprocessed == 1 && i2c->msg_idx == i2c->msg_num - 1)
> +			return 1;
> +	} else if (i2c->dir == DIR_WRITE) {
> +		if (!i2c->unprocessed && i2c->msg_idx == i2c->msg_num - 1)
> +			return 1;
> +	}
> +
> +	return 0;
> +}
> +
> +static void spacemit_i2c_handle_write(struct spacemit_i2c_dev *i2c)
> +{
> +	/* if transfer completes, ISR will handle it */
> +	if (i2c->status & SR_MSD)
> +		return;
> +
> +	if (i2c->unprocessed) {
> +		writel(*i2c->msg_buf++, i2c->base + IDBR);
> +		i2c->unprocessed--;
> +		return;
> +	}
> +
> +	/* STATE_IDLE avoids trigger next byte */
> +	i2c->state = STATE_IDLE;
> +	complete(&i2c->complete);
> +}
> +
> +static void spacemit_i2c_handle_read(struct spacemit_i2c_dev *i2c)
> +{
> +	if (i2c->unprocessed) {
> +		*i2c->msg_buf++ = readl(i2c->base + IDBR);
> +		i2c->unprocessed--;
> +	}
> +
> +	/* if transfer completes, ISR will handle it */
> +	if (i2c->status & (SR_MSD | SR_ACKNAK))
> +		return;
> +
> +	/* it has to append stop bit in icr that read last byte */
> +	if (i2c->unprocessed)
> +		return;
> +
> +	/* STATE_IDLE avoids trigger next byte */
> +	i2c->state = STATE_IDLE;
> +	complete(&i2c->complete);
> +}
> +
> +static void spacemit_i2c_handle_start(struct spacemit_i2c_dev *i2c)
> +{
> +	if (i2c->dir == DIR_READ) {
> +		i2c->state = STATE_READ;
> +		return;
> +	}
> +
> +	if (i2c->dir == DIR_WRITE) {
> +		i2c->state = STATE_WRITE;
> +		spacemit_i2c_handle_write(i2c);
> +	}
> +}
> +
> +static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c)
> +{
> +	if (!i2c->err)
> +		return 0;
> +
> +	dev_dbg(i2c->dev, "i2c error status: 0x%08x\n",	i2c->status);
> +
> +	if (i2c->err & (SR_BED | SR_ALD))
> +		spacemit_i2c_reset(i2c);
> +
> +	if (i2c->err & (SR_RXOV | SR_ALD))
> +		return -EAGAIN;
> +
> +	return (i2c->status & SR_ACKNAK) ? -ENXIO : -EIO;
> +}
> +
> +static void spacemit_i2c_err_check(struct spacemit_i2c_dev *i2c)
> +{
> +	u32 val;
> +	/*
> +	 * send transaction complete signal:
> +	 * error happens, detect master stop
> +	 */
> +	if (likely(i2c->err || (i2c->status & SR_MSD))) {
> +		/*
> +		 * Here the transaction is already done, we don't need any
> +		 * other interrupt signals from now, in case any interrupt
> +		 * happens before spacemit_i2c_xfer to disable irq and i2c unit,
> +		 * we mask all the interrupt signals and clear the interrupt
> +		 * status.
> +		 */
> +		val = readl(i2c->base + ICR);
> +		val &= ~I2C_INT_CTRL_MASK;
> +		writel(val, i2c->base + ICR);
> +
> +		spacemit_i2c_clear_int_status(i2c, I2C_INT_STATUS_MASK);
> +
> +		i2c->state = STATE_IDLE;
> +		complete(&i2c->complete);
> +	}
> +}
> +
> +static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
> +{
> +	struct spacemit_i2c_dev *i2c = devid;
> +	u32 status, val;
> +
> +	status = readl(i2c->base + ISR);
> +	if (!status)
> +		return IRQ_HANDLED;
> +
> +	i2c->status = status;
> +
> +	i2c->err = status & (SR_BED | SR_RXOV | SR_ALD);
> +
> +	spacemit_i2c_clear_int_status(i2c, status);
> +
> +	if (unlikely(i2c->err))
> +		goto err_out;
> +
> +	val = readl(i2c->base + ICR);
> +
> +	val &= ~(CR_TB | CR_ACKNAK | CR_STOP | CR_START);
> +	writel(val, i2c->base + ICR);
> +
> +	switch (i2c->state) {
> +	case STATE_START:
> +		spacemit_i2c_handle_start(i2c);
> +		break;
> +	case STATE_READ:
> +		spacemit_i2c_handle_read(i2c);
> +		break;
> +	case STATE_WRITE:
> +		spacemit_i2c_handle_write(i2c);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	if (i2c->state != STATE_IDLE) {
> +		if (spacemit_i2c_is_last_msg(i2c)) {
> +			/* trigger next byte with stop */
> +			spacemit_i2c_stop(i2c);
> +		} else {
> +			/* trigger next byte */
> +			val |= CR_ALDIE | CR_TB;
> +			writel(val, i2c->base + ICR);
> +		}
> +	}
> +
> +err_out:
> +	spacemit_i2c_err_check(i2c);
> +	return IRQ_HANDLED;
> +}
> +
> +static void spacemit_i2c_calc_timeout(struct spacemit_i2c_dev *i2c)
> +{
> +	unsigned long timeout;
> +	int idx = 0, cnt = 0, freq;
> +
> +	while (idx < i2c->msg_num) {
> +		cnt += (i2c->msgs + idx)->len + 1;
> +		idx++;
> +	}
> +
> +	freq = I2C_FAST_MODE_FREQ;
so this will set frequency to fast mode (400K), this contradict with PATCH[1/2] which
says default clock-frequency is 100000, either you need to change the code? or
update the dt-binding?

> +	/*
> +	 * multiply by 9 because each byte in I2C transmission requires
> +	 * 9 clock cycles: 8 bits of data plus 1 ACK/NACK bit.
> +	 */
> +	timeout = cnt * 9 * USEC_PER_SEC / freq;
> +
> +	i2c->adapt.timeout = usecs_to_jiffies(timeout + USEC_PER_SEC / 2) / i2c->msg_num;
> +}
> +
> +static inline int spacemit_i2c_xfer_core(struct spacemit_i2c_dev *i2c)
drop inline? IMO, it isn't worth here for long function

> +{
> +	int ret = 0;
no need to initilize to 0
> +
> +	spacemit_i2c_reset(i2c);
> +
> +	spacemit_i2c_calc_timeout(i2c);
> +
> +	spacemit_i2c_init(i2c);
> +
> +	spacemit_i2c_enable(i2c);
> +	enable_irq(i2c->irq);
> +
> +	/* i2c wait for bus busy */
> +	ret = spacemit_i2c_recover_bus_busy(i2c);
> +	if (unlikely(ret))
> +		return ret;
> +
> +	ret = spacemit_i2c_xfer_msg(i2c);
> +	if (unlikely(ret < 0)) {
> +		dev_dbg(i2c->dev, "i2c transfer error\n");
> +		/* timeout error should not be overridden, and the transfer
> +		 * error will be confirmed by err handle function latter,
> +		 * the reset should be invalid argument error.
> +		 */
> +		if (ret != -ETIMEDOUT)
> +			ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static int
> +spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg msgs[], int num)
no need to wrap the line, it makes the code a little bit weird..

current policy increase to 100characters, the old 80-column is not enforced
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bdc48fa11e46f867ea4d75fa59ee87a7f48be144

> +{
> +	struct spacemit_i2c_dev *i2c = i2c_get_adapdata(adapt);
> +	int ret;
> +
> +	i2c->msgs = msgs;
> +	i2c->msg_num = num;
> +
> +	ret = spacemit_i2c_xfer_core(i2c);
> +	if (likely(!ret))
> +		spacemit_i2c_check_bus_release(i2c);
> +
> +	disable_irq(i2c->irq);
> +
> +	spacemit_i2c_disable(i2c);
> +
> +	if (unlikely((ret == -ETIMEDOUT || ret == -EAGAIN)))
> +		dev_alert(i2c->dev, "i2c transfer failed, ret %d err 0x%x\n", ret, i2c->err);
> +
> +	return ret < 0 ? ret : num;
> +}
> +
> +static u32 spacemit_i2c_func(struct i2c_adapter *adap)
> +{
> +	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
> +}
> +
> +static const struct i2c_algorithm spacemit_i2c_algo = {
> +	.xfer = spacemit_i2c_xfer,
> +	.functionality = spacemit_i2c_func,
> +};
> +
> +static int spacemit_i2c_probe(struct platform_device *pdev)
> +{
> +	struct spacemit_i2c_dev *i2c;
> +	struct device_node *of_node = pdev->dev.of_node;
> +	struct clk *clk;
> +	int ret = 0;
> +
> +	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
> +	if (!i2c)
> +		return -ENOMEM;
> +
> +	i2c->dev = &pdev->dev;
> +
> +	i2c->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(i2c->base))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(i2c->base), "failed to do ioremap");
> +
> +	i2c->irq = platform_get_irq(pdev, 0);
> +	if (i2c->irq < 0)
> +		return dev_err_probe(&pdev->dev, i2c->irq, "failed to get irq resource");
> +
> +	ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
> +			       IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(i2c->dev), i2c);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret, "failed to request irq");
> +
> +	disable_irq(i2c->irq);
> +
> +	clk = devm_clk_get_enabled(&pdev->dev, NULL);
> +	if (IS_ERR(clk))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk), "failed to enable clock");
> +
I'd suggest also to handle pin request here, since pinctrl driver is merged

https://lore.kernel.org/all/CACRpkdYnaJsKKfcdhHeMGTTp86M+wNODzZx2e=OYbxQ4Jc4Rjw at mail.gmail.com/

> +	i2c_set_adapdata(&i2c->adapt, i2c);
> +	i2c->adapt.owner = THIS_MODULE;
> +	i2c->adapt.algo = &spacemit_i2c_algo;
> +	i2c->adapt.dev.parent = i2c->dev;
> +	i2c->adapt.nr = pdev->id;
> +
> +	i2c->adapt.dev.of_node = of_node;
> +	i2c->adapt.algo_data = i2c;
> +
> +	strscpy(i2c->adapt.name, "spacemit-i2c-adapter", sizeof(i2c->adapt.name));
> +
> +	init_completion(&i2c->complete);
> +
> +	ret = i2c_add_numbered_adapter(&i2c->adapt);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret, "failed to add i2c adapter");
> +
> +	platform_set_drvdata(pdev, i2c);
> +
> +	return 0;
> +}
> +
> +static void spacemit_i2c_remove(struct platform_device *pdev)
> +{
> +	struct spacemit_i2c_dev *i2c = platform_get_drvdata(pdev);
> +
> +	i2c_del_adapter(&i2c->adapt);
> +}
> +
> +static const struct of_device_id spacemit_i2c_of_match[] = {
> +	{ .compatible = "spacemit,k1-i2c", },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, spacemit_i2c_of_match);
> +
> +static struct platform_driver spacemit_i2c_driver = {
> +	.probe = spacemit_i2c_probe,
> +	.remove = spacemit_i2c_remove,
> +	.driver = {
> +		.name = "i2c-k1",
> +		.of_match_table = spacemit_i2c_of_match,
> +	},
> +};
> +module_platform_driver(spacemit_i2c_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("I2C bus driver for SpacemiT K1 SoC");
> 
> -- 
> 2.34.1
> 

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55


From cyy at cyyself.name  Wed Nov 13 22:54:17 2024
From: cyy at cyyself.name (Yangyu Chen)
Date: Thu, 14 Nov 2024 14:54:17 +0800
Subject: [PATCH v11 10/14] riscv: hwprobe: Add thead vendor extension
 probing
In-Reply-To: <ZzWAlJm1ShgsZr4m@ghost>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
 <20241113-xtheadvector-v11-10-236c22791ef9@rivosinc.com>
 <tencent_5B500856E30E1FB920B6B68D6315EE70CC06@qq.com>
 <ZzVoQi6D0U30p9sg@ghost>
 <tencent_6A95637042401AD5F8BE05C7B4F11CAD7009@qq.com>
 <ZzWAlJm1ShgsZr4m@ghost>
Message-ID: <tencent_9BB243901B8FF9FC0457B51D1CFF714B6209@qq.com>



On 11/14/24 12:46, Charlie Jenkins wrote:
> On Thu, Nov 14, 2024 at 11:26:47AM +0800, Yangyu Chen wrote:
>>
>>
>> On 11/14/24 11:02, Charlie Jenkins wrote:
>>> On Thu, Nov 14, 2024 at 10:44:37AM +0800, Yangyu Chen wrote:
>>>>
>>>>
>>>> On 11/14/24 10:21, Charlie Jenkins wrote:
>>>>> Add a new hwprobe key "RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0" which
>>>>> allows userspace to probe for the new RISCV_ISA_VENDOR_EXT_XTHEADVECTOR
>>>>> vendor extension.
>>>>>
>>>>
>>>> Hi Charlie,
>>>>
>>>> How about changing the name of the key from
>>>> "RISCV_ISA_VENDOR_EXT_XTHEADVECTOR" to "RISCV_HWPROBE_KEY_VENDOR_EXT_0" and
>>>> use marchid to identify what the vendor is, each vendor will have its own
>>>> bit definition in this value. So we can avoid adding so many hwprobe keys
>>>> for each vendor in the future.
>>>>
>>>> I proposed a commit here: https://github.com/cyyself/linux/commit/36390645d85d1ac75dd71172f167719df4297f59
>>>
>>> I actually originally had this in one of my first versions of this
>>> series but was convinced by Conor to change it. The problem with it was
>>> that tying vendor extensions to mvendorid means that it is enforced by
>>> the kernel that vendors cannot share vendor extensions. It is possible
>>> for vendor A to purchase IP that contains a vendor extension from vendor
>>> B. This vendor extension should work on platforms created by vendor A
>>> and vendor B. However, vendor A and vendor B have different mvendorids,
>>> so the kernel can't support this if it is tied to mvendorid.  It could
>>> be solved by duplicating every extension that vendors have, but then
>>> userspace software would have to keep in mind the mvendorid they are
>>> running on and check the different extensions for the different vendors
>>> even though the implementation of the extension is the same.
>>>
>>> The original conversation where Conor and I agreed that it was better to
>>> have vendor extensions not rely on mvendorid:
>>>
>>> https://lore.kernel.org/linux-riscv/20240416-husband-flavored-96c1dad58b6e at wendy/
>>>
>>
>> Thanks for your explanation. I will strongly agree with Conor's opinion if
>> the feature bitmask does not exist in RISC-V C-ABI.
>>
>> However, as the feature mask defined in RISC-V C-ABI[1] uses the design
>> depending on marchid currently, should we reconsider this key for its use
>> case? The current target_clones and taget_version implemented in GCC[2] and
>> LLVM[3] also use the bitmask defined in C-ABI. I think if we use this key
>> depending on marchid, to make a key shared with all vendors will make this
>> cleaner.
> 
> Changing this will break linux userspace API. It is a non-workable
> solution for the kernel to associate extensions with marchid/mvendorid
> for the reasons provided. I fail to see why this ABI would require the
> kernel to behave in this manner. The ABI provides the marchid to be used
> by function multi-versioning and applications are free to use the
> marchid to change which function they want to compile. However, if they
> want to know if an extension is supported, then they need to use
> hwprobe. If they want to check if xtheadvector is supported, then they> call hwprobe with the xtheadvector key. This is true no matter what the
> mvendorid of the system is.

A userspace software can use either c-api defined feature masks or 
directly use hwprobe syscall. If they use c-api defined feature masks as 
GCC or LLVM did for compiler generated IFUNC resolver, the bitmask is 
guarded by mvendorid. So my point at that time was that if the C-API 
defined way became mainstream, why should we keep this key only for 
T-Head to increase the maintenance overhead?

This has been discussed here before in RISC-V C-API: 
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/74#issuecomment-2128844747

But now (from the last email), you convinced me. So, I would like to 
make the c-api change: 
https://github.com/riscv-non-isa/riscv-c-api-doc/issues/96

> This does not add any complexity, "clean"
> code can equally be written following this scheme or following a scheme
> that relies on mvendorid. Ditching the reliance on mvendorid in the
> kernel allows the kernel to be as generic as possible, and allow
> whatever ABIs or hardware that exist to have a resiliant way of
> communicating with the kernel.
> 

OK. I'm just concerned about when these vendors will add the hwprobe key 
for their own extension, which may introduce a potential merge conflict 
in the kernel tree. It can also be a disaster if the hardware vendor 
ships their kernel with these under-review patches for their products 
with hwprobe key conflict with mainline kernel.

But we can avoid this now by adding each key for each vendor to avoid 
potential conflict in the future. This can be a separate patch for 
future work, so there is nothing to change here.

Thanks,
Yangyu Chen

> - CHarlie
> 
>>
>> [1] https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc#function-multi-version
>> [2] https://github.com/gcc-mirror/gcc/blob/8564d0948c72df0a66d7eb47e15c6ab43e9b25ce/gcc/config/riscv/riscv.cc#L13016
>> [3] https://github.com/llvm/llvm-project/blob/f407dff50cdcbcfee9dd92397d3792627c3ac708/clang/lib/CodeGen/CGBuiltin.cpp#L14627
>>
>>>>
>>>>> This new key will allow userspace code to probe for which thead vendor
>>>>> extensions are supported. This API is modeled to be consistent with
>>>>> RISCV_HWPROBE_KEY_IMA_EXT_0. The bitmask returned will have each bit
>>>>> corresponding to a supported thead vendor extension of the cpumask set.
>>>>> Just like RISCV_HWPROBE_KEY_IMA_EXT_0, this allows a userspace program
>>>>> to determine all of the supported thead vendor extensions in one call.
>>>>>
>>>>> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
>>>>> Reviewed-by: Evan Green <evan at rivosinc.com>
>>>>> ---
>>>>>     arch/riscv/include/asm/hwprobe.h                   |  3 +-
>>>>>     .../include/asm/vendor_extensions/thead_hwprobe.h  | 19 +++++++++++
>>>>>     .../include/asm/vendor_extensions/vendor_hwprobe.h | 37 ++++++++++++++++++++++
>>>>>     arch/riscv/include/uapi/asm/hwprobe.h              |  3 +-
>>>>>     arch/riscv/include/uapi/asm/vendor/thead.h         |  3 ++
>>>>>     arch/riscv/kernel/sys_hwprobe.c                    |  5 +++
>>>>>     arch/riscv/kernel/vendor_extensions/Makefile       |  1 +
>>>>>     .../riscv/kernel/vendor_extensions/thead_hwprobe.c | 19 +++++++++++
>>>>>     8 files changed, 88 insertions(+), 2 deletions(-)
>>>>>
>>>>
>>
>>




From zhangchunyan at iscas.ac.cn  Wed Nov 13 23:04:49 2024
From: zhangchunyan at iscas.ac.cn (Chunyan Zhang)
Date: Thu, 14 Nov 2024 15:04:49 +0800
Subject: [PATCH 2/2] riscv: Optimize crct10dif with zbc extension
In-Reply-To: <20241113104036.254491-3-zhihang.shao.iscas@gmail.com>
References: <20241113104036.254491-1-zhihang.shao.iscas@gmail.com> <20241113104036.254491-3-zhihang.shao.iscas@gmail.com>
Message-ID: <CAOsKWHCK-W72sx94WnVTeAm7mbG2XAgqD9LiLdRDNEfJQ-Ex=w@mail.gmail.com>

On Wed, 13 Nov 2024 at 19:06, Zhihang Shao <zhihang.shao.iscas at gmail.com> wrote:
>
> The current CRC-T10DIF algorithm is based on table-lookup optimization.
> Given the previous work on optimizing crc32 calculations with zbc
> extension, it is believed that this will be equally effective for
> accelerating crc-t10dif.
> Therefore, this patch offers a implementation of crc-t10dif using zbc
> extension. This can detect whether the current runtime environment
> supports zbc feature and, if so, uses it to accelerate crc-t10dif
> calculations.
>
> This patch is tested on QEMU VM with the kernel CRC-T10DIF selftests.
>
> Signed-off-by: Zhihang Shao <zhihang.shao.iscas at gmail.com>
> ---
>  arch/riscv/crypto/Kconfig               |  14 ++
>  arch/riscv/crypto/Makefile              |   4 +
>  arch/riscv/crypto/crct10dif-riscv-zbc.c | 182 ++++++++++++++++++++++++
>  lib/crct10diftest.c                     |   4 +-
>  4 files changed, 202 insertions(+), 2 deletions(-)
>  create mode 100644 arch/riscv/crypto/crct10dif-riscv-zbc.c
>
> diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig
> index ad58dad9a580..69751ff5573e 100644
> --- a/arch/riscv/crypto/Kconfig
> +++ b/arch/riscv/crypto/Kconfig
> @@ -29,6 +29,20 @@ config CRYPTO_CHACHA_RISCV64
>           Architecture: riscv64 using:
>           - Zvkb vector crypto extension
>
> +config CRYPTO_CRCT10DIF_RISCV
> +       tristate "Checksum: CRCT10DIF"
> +       depends on TOOLCHAIN_HAS_ZBC
> +       depends on MMU
> +       depends on RISCV_ALTERNATIVE
> +       default y
> +       help
> +         CRCT10DIF checksum with Zbc extension optimized
> +        To accelerate CRCT10DIF checksum, choose Y here.

This line should be aligned with two characters.

> +
> +         Architecture: riscv using:
> +          - Zbc extension

Same here.

> +
> +

More than one redundant empty line should be removed.

>  config CRYPTO_GHASH_RISCV64
>         tristate "Hash functions: GHASH"
>         depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
> diff --git a/arch/riscv/crypto/Makefile b/arch/riscv/crypto/Makefile
> index 247c7bc7288c..6f849f4dc4cc 100644
> --- a/arch/riscv/crypto/Makefile
> +++ b/arch/riscv/crypto/Makefile
> @@ -7,6 +7,9 @@ aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o \
>  obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o
>  chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o
>
> +obj-$(CONFIG_CRYPTO_CRCT10DIF_RISCV) += crct10dif-riscv.o
> +crct10dif-riscv-y := crct10dif-riscv-zbc.o
> +
>  obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o
>  ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o
>
> @@ -21,3 +24,4 @@ sm3-riscv64-y := sm3-riscv64-glue.o sm3-riscv64-zvksh-zvkb.o
>
>  obj-$(CONFIG_CRYPTO_SM4_RISCV64) += sm4-riscv64.o
>  sm4-riscv64-y := sm4-riscv64-glue.o sm4-riscv64-zvksed-zvkb.o
> +
> diff --git a/arch/riscv/crypto/crct10dif-riscv-zbc.c b/arch/riscv/crypto/crct10dif-riscv-zbc.c
> new file mode 100644
> index 000000000000..01571b4286f1
> --- /dev/null
> +++ b/arch/riscv/crypto/crct10dif-riscv-zbc.c
> @@ -0,0 +1,182 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Accelerated CRC-T10DIF implementation with RISC-V Zbc extension.
> + *
> + * Copyright (C) 2024 Institute of Software, CAS.
> + */
> +
> +#include <asm/alternative-macros.h>
> +#include <asm/byteorder.h>
> +#include <asm/hwcap.h>
> +
> +#include <crypto/internal/hash.h>
> +
> +#include <linux/byteorder/generic.h>
> +#include <linux/crc-t10dif.h>
> +#include <linux/minmax.h>
> +#include <linux/module.h>
> +#include <linux/types.h>
> +
> +static u16 crc_t10dif_generic_zbc(u16 crc, unsigned char const *p, size_t len);
> +
> +#define CRCT10DIF_POLY 0x8bb7
> +
> +#if __riscv_xlen == 64
> +#define STEP_ORDER 3
> +
> +#define CRCT10DIF_POLY_QT_BE 0xf65a57f81d33a48a
> +
> +static inline u64 crct10dif_prep(u16 crc, unsigned long const *ptr)
> +{
> +       return ((u64)crc << 48) ^ (__force u64)__cpu_to_be64(*ptr);
> +}
> +
> +#elif __riscv_xlen == 32
> +#define STEP_ORDER 2
> +#define CRCT10DIF_POLY_QT_BE 0xf65a57f8
> +
> +static inline u32 crct10dif_prep(u16 crc, unsigned long const *ptr)
> +{
> +       return ((u32)crc << 16) ^ (__force u32)__cpu_to_be32(*ptr);
> +}
> +
> +#else
> +#error "Unexpected __riscv_xlen"
> +#endif
> +
> +static inline u16 crct10dif_zbc(unsigned long s)
> +{
> +       u16 crc;
> +
> +       asm volatile   (".option push\n"
> +                       ".option arch,+zbc\n"
> +                       "clmulh %0, %1, %2\n"
> +                       "xor    %0, %0, %1\n"
> +                       "clmul  %0, %0, %3\n"
> +                       ".option pop\n"
> +                       : "=&r" (crc)
> +                       : "r"(s),
> +                         "r"(CRCT10DIF_POLY_QT_BE),
> +                         "r"(CRCT10DIF_POLY)
> +                       :);
> +
> +       return crc;
> +}
> +
> +#define STEP (1 << STEP_ORDER)
> +#define OFFSET_MASK (STEP - 1)
> +
> +static inline u16 crct10dif_unaligned(u16 crc, unsigned char const *p, size_t len)
> +{
> +       size_t bits = len * 8;
> +       unsigned long s = 0;
> +       u16 crc_low = 0;
> +
> +       for (int i = 0; i < len; i++)
> +               s = *p++ | (s << 8);
> +
> +       if (len < sizeof(u16)) {
> +               s ^= crc >> (16 - bits);
> +               crc_low = crc << bits;
> +       } else {
> +               s ^= (unsigned long)crc << (bits - 16);
> +       }
> +
> +       crc = crct10dif_zbc(s);
> +       crc ^= crc_low;
> +
> +       return crc;
> +}
> +
> +static u16 crc_t10dif_generic_zbc(u16 crc, unsigned char const *p, size_t len)
> +{
> +       size_t offset, head_len, tail_len;
> +       unsigned long const *p_ul;
> +       unsigned long s;
> +
> +       offset = (unsigned long)p & OFFSET_MASK;
> +       if (offset && len) {
> +               head_len = min(STEP - offset, len);
> +               crc = crct10dif_unaligned(crc, p, head_len);
> +               p += head_len;
> +               len -= head_len;
> +       }
> +
> +       tail_len = len & OFFSET_MASK;
> +       len = len >> STEP_ORDER;
> +       p_ul = (unsigned long const *)p;
> +
> +       for (int i = 0; i < len; i++) {
> +               s = crct10dif_prep(crc, p_ul);
> +               crc = crct10dif_zbc(s);
> +               p_ul++;
> +       }
> +
> +       p = (unsigned char const *)p_ul;
> +       if (tail_len)
> +               crc = crct10dif_unaligned(crc, p, tail_len);
> +
> +       return crc;
> +}
> +
> +static int crc_t10dif_init(struct shash_desc *desc)
> +{
> +       u16 *crc = shash_desc_ctx(desc);
> +
> +       *crc = 0;
> +
> +       return 0;
> +}
> +
> +static int crc_t10dif_final(struct shash_desc *desc, u8 *out)
> +{
> +       u16 *crc = shash_desc_ctx(desc);
> +
> +       *(u16 *)out = *crc;
> +
> +       return 0;
> +}
> +
> +static int crc_t10dif_update_zbc(struct shash_desc *desc, const u8 *data,
> +                               unsigned int length)
> +{
> +       u16 *crc = shash_desc_ctx(desc);
> +
> +       *crc = crc_t10dif_generic_zbc(*crc, data, length);
> +
> +       return 0;
> +}
> +
> +static struct shash_alg crc_t10dif_alg = {
> +       .digestsize             = CRC_T10DIF_DIGEST_SIZE,
> +       .init                   = crc_t10dif_init,
> +       .update                 = crc_t10dif_update_zbc,
> +       .final                  = crc_t10dif_final,
> +       .descsize               = CRC_T10DIF_DIGEST_SIZE,
> +
> +       .base.cra_name          = "crct10dif",
> +       .base.cra_driver_name   = "crct10dif-riscv-zbc",
> +       .base.cra_priority      = 150,
> +       .base.cra_blocksize     = CRC_T10DIF_BLOCK_SIZE,
> +       .base.cra_module        = THIS_MODULE,
> +};
> +
> +static int __init crc_t10dif_mod_init(void)
> +{
> +       if (riscv_isa_extension_available(NULL, ZBC))
> +               return crypto_register_shash(&crc_t10dif_alg);
> +
> +       return -ENODEV;
> +}
> +
> +static void __exit crc_t10dif_mod_exit(void)
> +{
> +       crypto_unregister_shash(&crc_t10dif_alg);
> +}
> +
> +module_init(crc_t10dif_mod_init);
> +module_exit(crc_t10dif_mod_exit);
> +
> +MODULE_DESCRIPTION("CRC-T10DIF using RISC-V ZBC Extension");
> +MODULE_ALIAS_CRYPTO("crct10dif");
> +MODULE_LICENSE("GPL");
> diff --git a/lib/crct10diftest.c b/lib/crct10diftest.c
> index 9541892eb12c..ac642191e6e8 100644
> --- a/lib/crct10diftest.c
> +++ b/lib/crct10diftest.c
> @@ -666,9 +666,9 @@ static int __init crct10dif_test_init(void)
>
>         local_irq_restore(flags);
>
> -       if (errors)
> +       if (errors)

This change should be removed from this patch.

>                 pr_warn("crct10dif: %d self tests failed\n", errors);
> -       else
> +       else

Same here.

>                 pr_info("crct10dif: self tests passed, processed %d bytes in %lld nsec\n",
>                 bytes, nsec);
>
> --
> 2.34.1
>
>



From dlan at gentoo.org  Wed Nov 13 23:06:01 2024
From: dlan at gentoo.org (Yixun Lan)
Date: Thu, 14 Nov 2024 15:06:01 +0800
Subject: [PATCH v3 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <20241112-aged-trailing-cffda6af0944@spud>
References: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
 <20241112-k1-i2c-master-v3-1-5005b70dc208@gmail.com>
 <20241112-aged-trailing-cffda6af0944@spud>
Message-ID: <20241114070601-GYA1001363@gentoo>

On 18:03 Tue 12 Nov     , Conor Dooley wrote:
> On Tue, Nov 12, 2024 at 11:07:39AM +0800, Troy Mitchell wrote:
> > From: Troy Mitchell <troymitchell988 at gmail.com>
> > 
> > The I2C of K1 supports fast-speed-mode and high-speed-mode,
> > and supports FIFO transmission.
> > 
> > Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
> > ---
> >  .../devicetree/bindings/i2c/spacemit,k1-i2c.yaml   | 52 ++++++++++++++++++++++
> >  1 file changed, 52 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> > new file mode 100644
> > index 000000000000..e8cce360bf03
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> > @@ -0,0 +1,52 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: I2C controller embedded in SpacemiT's K1 SoC
> > +
> > +maintainers:
> > +  - Troy Mitchell <troymitchell988 at gmail.com>
> > +
> > +properties:
> > +  compatible:
> > +    const: spacemit,k1-i2c
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 1
> > +
> > +  clock-frequency:
> > +    description:
> > +      Desired I2C bus clock frequency in Hz.
> > +      K1 supports standard, fast, high-speed modes, from 1 to 3300000.
while we are here, I'd suggest rephrase the sentence above to align it better with the doc

K1 support three different modes which running different frequencies
standard speed mode: up to 100000 (100Hz)
fast speed mode    : up to 400000 (400Hz)
high speed mode    : up to 3300000 (3.3Mhz)

> > +    default: 100000
> > +    minimum: 1
> > +    maximum: 3300000
> 
> It's sufficient to define just default and max btw, the min is set in
> i2c-controller.yaml (in dt-schema itself). Don't respin for that alone.
+1, the minimum settings isn't really useful, clearly not apply in the practical case

> 
> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - clocks
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    i2c at d4010800 {
> > +        compatible = "spacemit,k1-i2c";
> > +        reg = <0xd4010800 0x38>;
> > +        interrupt-parent = <&plic>;
> > +        interrupts = <36>;
> > +        clocks = <&ccu 90>;
> > +        clock-frequency = <100000>;
> > +    };
> > +
> > +...
> > 
> > -- 
> > 2.34.1
> > 



-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55


From charlie at rivosinc.com  Wed Nov 13 23:23:24 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 13 Nov 2024 23:23:24 -0800
Subject: [PATCH v11 10/14] riscv: hwprobe: Add thead vendor extension
 probing
In-Reply-To: <tencent_9BB243901B8FF9FC0457B51D1CFF714B6209@qq.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
 <20241113-xtheadvector-v11-10-236c22791ef9@rivosinc.com>
 <tencent_5B500856E30E1FB920B6B68D6315EE70CC06@qq.com>
 <ZzVoQi6D0U30p9sg@ghost>
 <tencent_6A95637042401AD5F8BE05C7B4F11CAD7009@qq.com>
 <ZzWAlJm1ShgsZr4m@ghost>
 <tencent_9BB243901B8FF9FC0457B51D1CFF714B6209@qq.com>
Message-ID: <ZzWlbCiRuDKzilms@ghost>

On Thu, Nov 14, 2024 at 02:54:17PM +0800, Yangyu Chen wrote:
> 
> 
> On 11/14/24 12:46, Charlie Jenkins wrote:
> > On Thu, Nov 14, 2024 at 11:26:47AM +0800, Yangyu Chen wrote:
> > > 
> > > 
> > > On 11/14/24 11:02, Charlie Jenkins wrote:
> > > > On Thu, Nov 14, 2024 at 10:44:37AM +0800, Yangyu Chen wrote:
> > > > > 
> > > > > 
> > > > > On 11/14/24 10:21, Charlie Jenkins wrote:
> > > > > > Add a new hwprobe key "RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0" which
> > > > > > allows userspace to probe for the new RISCV_ISA_VENDOR_EXT_XTHEADVECTOR
> > > > > > vendor extension.
> > > > > > 
> > > > > 
> > > > > Hi Charlie,
> > > > > 
> > > > > How about changing the name of the key from
> > > > > "RISCV_ISA_VENDOR_EXT_XTHEADVECTOR" to "RISCV_HWPROBE_KEY_VENDOR_EXT_0" and
> > > > > use marchid to identify what the vendor is, each vendor will have its own
> > > > > bit definition in this value. So we can avoid adding so many hwprobe keys
> > > > > for each vendor in the future.
> > > > > 
> > > > > I proposed a commit here: https://github.com/cyyself/linux/commit/36390645d85d1ac75dd71172f167719df4297f59
> > > > 
> > > > I actually originally had this in one of my first versions of this
> > > > series but was convinced by Conor to change it. The problem with it was
> > > > that tying vendor extensions to mvendorid means that it is enforced by
> > > > the kernel that vendors cannot share vendor extensions. It is possible
> > > > for vendor A to purchase IP that contains a vendor extension from vendor
> > > > B. This vendor extension should work on platforms created by vendor A
> > > > and vendor B. However, vendor A and vendor B have different mvendorids,
> > > > so the kernel can't support this if it is tied to mvendorid.  It could
> > > > be solved by duplicating every extension that vendors have, but then
> > > > userspace software would have to keep in mind the mvendorid they are
> > > > running on and check the different extensions for the different vendors
> > > > even though the implementation of the extension is the same.
> > > > 
> > > > The original conversation where Conor and I agreed that it was better to
> > > > have vendor extensions not rely on mvendorid:
> > > > 
> > > > https://lore.kernel.org/linux-riscv/20240416-husband-flavored-96c1dad58b6e at wendy/
> > > > 
> > > 
> > > Thanks for your explanation. I will strongly agree with Conor's opinion if
> > > the feature bitmask does not exist in RISC-V C-ABI.
> > > 
> > > However, as the feature mask defined in RISC-V C-ABI[1] uses the design
> > > depending on marchid currently, should we reconsider this key for its use
> > > case? The current target_clones and taget_version implemented in GCC[2] and
> > > LLVM[3] also use the bitmask defined in C-ABI. I think if we use this key
> > > depending on marchid, to make a key shared with all vendors will make this
> > > cleaner.
> > 
> > Changing this will break linux userspace API. It is a non-workable
> > solution for the kernel to associate extensions with marchid/mvendorid
> > for the reasons provided. I fail to see why this ABI would require the
> > kernel to behave in this manner. The ABI provides the marchid to be used
> > by function multi-versioning and applications are free to use the
> > marchid to change which function they want to compile. However, if they
> > want to know if an extension is supported, then they need to use
> > hwprobe. If they want to check if xtheadvector is supported, then they> call hwprobe with the xtheadvector key. This is true no matter what the
> > mvendorid of the system is.
> 
> A userspace software can use either c-api defined feature masks or directly
> use hwprobe syscall. If they use c-api defined feature masks as GCC or LLVM
> did for compiler generated IFUNC resolver, the bitmask is guarded by
> mvendorid. So my point at that time was that if the C-API defined way became
> mainstream, why should we keep this key only for T-Head to increase the
> maintenance overhead?

Yes that makes sense. I was thinking that the Andes PMU extension had a
hwprobe key, but I realized that it does not. This patch has been on the
lists for so long I lost track! I was trying to design this to be
forward-thinking, I believe that it makes more sense this way, but I am
interested in the opinion of the c-api maintainers.

> 
> This has been discussed here before in RISC-V C-API: https://github.com/riscv-non-isa/riscv-c-api-doc/pull/74#issuecomment-2128844747
> 
> But now (from the last email), you convinced me. So, I would like to make
> the c-api change: https://github.com/riscv-non-isa/riscv-c-api-doc/issues/96
> 

Thank you for opening that!

> > This does not add any complexity, "clean"
> > code can equally be written following this scheme or following a scheme
> > that relies on mvendorid. Ditching the reliance on mvendorid in the
> > kernel allows the kernel to be as generic as possible, and allow
> > whatever ABIs or hardware that exist to have a resiliant way of
> > communicating with the kernel.
> > 
> 
> OK. I'm just concerned about when these vendors will add the hwprobe key for
> their own extension, which may introduce a potential merge conflict in the
> kernel tree. It can also be a disaster if the hardware vendor ships their
> kernel with these under-review patches for their products with hwprobe key
> conflict with mainline kernel.
> 
> But we can avoid this now by adding each key for each vendor to avoid
> potential conflict in the future. This can be a separate patch for future
> work, so there is nothing to change here.

Yes that is unfortunately the downside of hwprobe that it is a
centralized source of these keys, and that can be exacerbated by this
scheme were vendor keys are not completely isolated from each other.
That would be very unfortunate if a vendor ships a kernel and binaries
that has different keys than the mainline kernel. Hopefully vendors
don't do that, but it should be manageable for vendors to submit their own
keys.

Thank you for bringing this up, it is an important issue! A main goal of
this series was to get vendor extensions in a state that would be able
to grow into a future when there are lots of vendors.

> 
> Thanks,
> Yangyu Chen
> 
> > - CHarlie
> > 
> > > 
> > > [1] https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc#function-multi-version
> > > [2] https://github.com/gcc-mirror/gcc/blob/8564d0948c72df0a66d7eb47e15c6ab43e9b25ce/gcc/config/riscv/riscv.cc#L13016
> > > [3] https://github.com/llvm/llvm-project/blob/f407dff50cdcbcfee9dd92397d3792627c3ac708/clang/lib/CodeGen/CGBuiltin.cpp#L14627
> > > 
> > > > > 
> > > > > > This new key will allow userspace code to probe for which thead vendor
> > > > > > extensions are supported. This API is modeled to be consistent with
> > > > > > RISCV_HWPROBE_KEY_IMA_EXT_0. The bitmask returned will have each bit
> > > > > > corresponding to a supported thead vendor extension of the cpumask set.
> > > > > > Just like RISCV_HWPROBE_KEY_IMA_EXT_0, this allows a userspace program
> > > > > > to determine all of the supported thead vendor extensions in one call.
> > > > > > 
> > > > > > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > > > > > Reviewed-by: Evan Green <evan at rivosinc.com>
> > > > > > ---
> > > > > >     arch/riscv/include/asm/hwprobe.h                   |  3 +-
> > > > > >     .../include/asm/vendor_extensions/thead_hwprobe.h  | 19 +++++++++++
> > > > > >     .../include/asm/vendor_extensions/vendor_hwprobe.h | 37 ++++++++++++++++++++++
> > > > > >     arch/riscv/include/uapi/asm/hwprobe.h              |  3 +-
> > > > > >     arch/riscv/include/uapi/asm/vendor/thead.h         |  3 ++
> > > > > >     arch/riscv/kernel/sys_hwprobe.c                    |  5 +++
> > > > > >     arch/riscv/kernel/vendor_extensions/Makefile       |  1 +
> > > > > >     .../riscv/kernel/vendor_extensions/thead_hwprobe.c | 19 +++++++++++
> > > > > >     8 files changed, 88 insertions(+), 2 deletions(-)
> > > > > > 
> > > > > 
> > > 
> > > 
> 
> 


From prabhakar.csengg at gmail.com  Thu Nov 14 01:37:20 2024
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Thu, 14 Nov 2024 09:37:20 +0000
Subject: [PATCH] dma-mapping: Save base/size instead of pointer to shared
 DMA pool
In-Reply-To: <f8cef6845a6141f0277e31a71fe153612daae776.1731436631.git.geert+renesas@glider.be>
References: <f8cef6845a6141f0277e31a71fe153612daae776.1731436631.git.geert+renesas@glider.be>
Message-ID: <CA+V-a8sdSBFin=edpj+p5k4KZU4aen+k0acJVTD35YxTbE1qYQ@mail.gmail.com>

On Tue, Nov 12, 2024 at 6:41?PM Geert Uytterhoeven
<geert+renesas at glider.be> wrote:
>
> On RZ/Five, which is non-coherent, and uses CONFIG_DMA_GLOBAL_POOL=y:
>
>     Oops - store (or AMO) access fault [#1]
>     CPU: 0 UID: 0 PID: 1 Comm: swapper Not tainted 6.12.0-rc1-00015-g8a6e02d0c00e #201
>     Hardware name: Renesas SMARC EVK based on r9a07g043f01 (DT)
>     epc : __memset+0x60/0x100
>      ra : __dma_alloc_from_coherent+0x150/0x17a
>     epc : ffffffff8062d2bc ra : ffffffff80053a94 sp : ffffffc60000ba20
>      gp : ffffffff812e9938 tp : ffffffd601920000 t0 : ffffffc6000d0000
>      t1 : 0000000000000000 t2 : ffffffffe9600000 s0 : ffffffc60000baa0
>      s1 : ffffffc6000d0000 a0 : ffffffc6000d0000 a1 : 0000000000000000
>      a2 : 0000000000001000 a3 : ffffffc6000d1000 a4 : 0000000000000000
>      a5 : 0000000000000000 a6 : ffffffd601adacc0 a7 : ffffffd601a841a8
>      s2 : ffffffd6018573c0 s3 : 0000000000001000 s4 : ffffffd6019541e0
>      s5 : 0000000200000022 s6 : ffffffd6018f8410 s7 : ffffffd6018573e8
>      s8 : 0000000000000001 s9 : 0000000000000001 s10: 0000000000000010
>      s11: 0000000000000000 t3 : 0000000000000000 t4 : ffffffffdefe62d1
>      t5 : 000000001cd6a3a9 t6 : ffffffd601b2aad6
>     status: 0000000200000120 badaddr: ffffffc6000d0000 cause: 0000000000000007
>     [<ffffffff8062d2bc>] __memset+0x60/0x100
>     [<ffffffff80053e1a>] dma_alloc_from_global_coherent+0x1c/0x28
>     [<ffffffff80053056>] dma_direct_alloc+0x98/0x112
>     [<ffffffff8005238c>] dma_alloc_attrs+0x78/0x86
>     [<ffffffff8035fdb4>] rz_dmac_probe+0x3f6/0x50a
>     [<ffffffff803a0694>] platform_probe+0x4c/0x8a
>
> If CONFIG_DMA_GLOBAL_POOL=y, the reserved_mem structure passed to
> rmem_dma_setup() is saved for later use, by saving the passed pointer.
> However, when dma_init_reserved_memory() is called later, the pointer
> has become stale, causing a crash.
>
> E.g. in the RZ/Five case, the referenced memory now contains the
> reserved_mem structure for the "mmode_resv0 at 30000" node (with base
> 0x30000 and size 0x10000), instead of the correct "pma_resv0 at 58000000"
> node (with base 0x58000000 and size 0x8000000).
>
> Fix this by saving the needed reserved_mem structure's contents instead.
>
> Fixes: 8a6e02d0c00e7b62 ("of: reserved_mem: Restructure how the reserved memory regions are processed")
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
>  kernel/dma/coherent.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Cheers,
Prabhakar


From zhihang.shao.iscas at gmail.com  Thu Nov 14 06:42:04 2024
From: zhihang.shao.iscas at gmail.com (Zhihang Shao)
Date: Thu, 14 Nov 2024 14:42:04 +0000
Subject: [PATCH v2] riscv: Optimize crct10dif with zbc extension
In-Reply-To: <20241113134655.GA794@quark.localdomain>
References: <20241113134655.GA794@quark.localdomain>
Message-ID: <20241114144204.427915-1-zhihang.shao.iscas@gmail.com>

The current CRC-T10DIF algorithm is based on table-lookup optimization.
Given the previous work on optimizing crc32 calculations with zbc
extension, it is believed that this will be equally effective for
accelerating crc-t10dif.
Therefore, this patch offers an implementation of crc-t10dif using zbc
extension. This can detect whether the current runtime environment
supports zbc feature and, if so, uses it to accelerate crc-t10dif
calculations.

This patch is tested on QEMU VM with the crypto self-tests both rv64 and
rv32.

Signed-off-by: Zhihang Shao <zhihang.shao.iscas at gmail.com>

---
v2:
- Use crypto self-tests instead. (Eric)
- Fix some format errors in arch/riscv/crypto/Kconfig. (Chunyan)
---
 arch/riscv/crypto/Kconfig               |  13 ++
 arch/riscv/crypto/Makefile              |   4 +
 arch/riscv/crypto/crct10dif-riscv-zbc.c | 182 ++++++++++++++++++++++++
 3 files changed, 199 insertions(+)
 create mode 100644 arch/riscv/crypto/crct10dif-riscv-zbc.c

diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig
index ad58dad9a580..12107bc50bb1 100644
--- a/arch/riscv/crypto/Kconfig
+++ b/arch/riscv/crypto/Kconfig
@@ -29,6 +29,19 @@ config CRYPTO_CHACHA_RISCV64
 	  Architecture: riscv64 using:
 	  - Zvkb vector crypto extension
 
+config CRYPTO_CRCT10DIF_RISCV
+	tristate "Checksum: CRCT10DIF"
+	depends on TOOLCHAIN_HAS_ZBC
+	depends on MMU
+	depends on RISCV_ALTERNATIVE
+	default y
+	help
+	  CRCT10DIF checksum with Zbc extension optimized
+	  To accelerate CRCT10DIF checksum, choose Y here.
+
+	  Architecture: riscv using:
+	  - Zbc extension
+
 config CRYPTO_GHASH_RISCV64
 	tristate "Hash functions: GHASH"
 	depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
diff --git a/arch/riscv/crypto/Makefile b/arch/riscv/crypto/Makefile
index 247c7bc7288c..6f849f4dc4cc 100644
--- a/arch/riscv/crypto/Makefile
+++ b/arch/riscv/crypto/Makefile
@@ -7,6 +7,9 @@ aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o \
 obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o
 chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o
 
+obj-$(CONFIG_CRYPTO_CRCT10DIF_RISCV) += crct10dif-riscv.o
+crct10dif-riscv-y := crct10dif-riscv-zbc.o
+
 obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o
 ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o
 
@@ -21,3 +24,4 @@ sm3-riscv64-y := sm3-riscv64-glue.o sm3-riscv64-zvksh-zvkb.o
 
 obj-$(CONFIG_CRYPTO_SM4_RISCV64) += sm4-riscv64.o
 sm4-riscv64-y := sm4-riscv64-glue.o sm4-riscv64-zvksed-zvkb.o
+
diff --git a/arch/riscv/crypto/crct10dif-riscv-zbc.c b/arch/riscv/crypto/crct10dif-riscv-zbc.c
new file mode 100644
index 000000000000..01571b4286f1
--- /dev/null
+++ b/arch/riscv/crypto/crct10dif-riscv-zbc.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated CRC-T10DIF implementation with RISC-V Zbc extension.
+ *
+ * Copyright (C) 2024 Institute of Software, CAS.
+ */
+
+#include <asm/alternative-macros.h>
+#include <asm/byteorder.h>
+#include <asm/hwcap.h>
+
+#include <crypto/internal/hash.h>
+
+#include <linux/byteorder/generic.h>
+#include <linux/crc-t10dif.h>
+#include <linux/minmax.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+static u16 crc_t10dif_generic_zbc(u16 crc, unsigned char const *p, size_t len);
+
+#define CRCT10DIF_POLY 0x8bb7
+
+#if __riscv_xlen == 64
+#define STEP_ORDER 3
+
+#define CRCT10DIF_POLY_QT_BE 0xf65a57f81d33a48a
+
+static inline u64 crct10dif_prep(u16 crc, unsigned long const *ptr)
+{
+	return ((u64)crc << 48) ^ (__force u64)__cpu_to_be64(*ptr);
+}
+
+#elif __riscv_xlen == 32
+#define STEP_ORDER 2
+#define CRCT10DIF_POLY_QT_BE 0xf65a57f8
+
+static inline u32 crct10dif_prep(u16 crc, unsigned long const *ptr)
+{
+	return ((u32)crc << 16) ^ (__force u32)__cpu_to_be32(*ptr);
+}
+
+#else
+#error "Unexpected __riscv_xlen"
+#endif
+
+static inline u16 crct10dif_zbc(unsigned long s)
+{
+	u16 crc;
+
+	asm volatile   (".option push\n"
+			".option arch,+zbc\n"
+			"clmulh %0, %1, %2\n"
+			"xor    %0, %0, %1\n"
+			"clmul  %0, %0, %3\n"
+			".option pop\n"
+			: "=&r" (crc)
+			: "r"(s),
+			  "r"(CRCT10DIF_POLY_QT_BE),
+			  "r"(CRCT10DIF_POLY)
+			:);
+
+	return crc;
+}
+
+#define STEP (1 << STEP_ORDER)
+#define OFFSET_MASK (STEP - 1)
+
+static inline u16 crct10dif_unaligned(u16 crc, unsigned char const *p, size_t len)
+{
+	size_t bits = len * 8;
+	unsigned long s = 0;
+	u16 crc_low = 0;
+
+	for (int i = 0; i < len; i++)
+		s = *p++ | (s << 8);
+
+	if (len < sizeof(u16)) {
+		s ^= crc >> (16 - bits);
+		crc_low = crc << bits;
+	} else {
+		s ^= (unsigned long)crc << (bits - 16);
+	}
+
+	crc = crct10dif_zbc(s);
+	crc ^= crc_low;
+
+	return crc;
+}
+
+static u16 crc_t10dif_generic_zbc(u16 crc, unsigned char const *p, size_t len)
+{
+	size_t offset, head_len, tail_len;
+	unsigned long const *p_ul;
+	unsigned long s;
+
+	offset = (unsigned long)p & OFFSET_MASK;
+	if (offset && len) {
+		head_len = min(STEP - offset, len);
+		crc = crct10dif_unaligned(crc, p, head_len);
+		p += head_len;
+		len -= head_len;
+	}
+
+	tail_len = len & OFFSET_MASK;
+	len = len >> STEP_ORDER;
+	p_ul = (unsigned long const *)p;
+
+	for (int i = 0; i < len; i++) {
+		s = crct10dif_prep(crc, p_ul);
+		crc = crct10dif_zbc(s);
+		p_ul++;
+	}
+
+	p = (unsigned char const *)p_ul;
+	if (tail_len)
+		crc = crct10dif_unaligned(crc, p, tail_len);
+
+	return crc;
+}
+
+static int crc_t10dif_init(struct shash_desc *desc)
+{
+	u16 *crc = shash_desc_ctx(desc);
+
+	*crc = 0;
+
+	return 0;
+}
+
+static int crc_t10dif_final(struct shash_desc *desc, u8 *out)
+{
+	u16 *crc = shash_desc_ctx(desc);
+
+	*(u16 *)out = *crc;
+
+	return 0;
+}
+
+static int crc_t10dif_update_zbc(struct shash_desc *desc, const u8 *data,
+				unsigned int length)
+{
+	u16 *crc = shash_desc_ctx(desc);
+
+	*crc = crc_t10dif_generic_zbc(*crc, data, length);
+
+	return 0;
+}
+
+static struct shash_alg crc_t10dif_alg = {
+	.digestsize		= CRC_T10DIF_DIGEST_SIZE,
+	.init			= crc_t10dif_init,
+	.update			= crc_t10dif_update_zbc,
+	.final			= crc_t10dif_final,
+	.descsize		= CRC_T10DIF_DIGEST_SIZE,
+
+	.base.cra_name		= "crct10dif",
+	.base.cra_driver_name	= "crct10dif-riscv-zbc",
+	.base.cra_priority	= 150,
+	.base.cra_blocksize	= CRC_T10DIF_BLOCK_SIZE,
+	.base.cra_module	= THIS_MODULE,
+};
+
+static int __init crc_t10dif_mod_init(void)
+{
+	if (riscv_isa_extension_available(NULL, ZBC))
+		return crypto_register_shash(&crc_t10dif_alg);
+
+	return -ENODEV;
+}
+
+static void __exit crc_t10dif_mod_exit(void)
+{
+	crypto_unregister_shash(&crc_t10dif_alg);
+}
+
+module_init(crc_t10dif_mod_init);
+module_exit(crc_t10dif_mod_exit);
+
+MODULE_DESCRIPTION("CRC-T10DIF using RISC-V ZBC Extension");
+MODULE_ALIAS_CRYPTO("crct10dif");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From debug at rivosinc.com  Thu Nov 14 07:50:45 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Thu, 14 Nov 2024 07:50:45 -0800
Subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack
 memory via FWFT sbi call
In-Reply-To: <CAKddAkBCByf570PXfz798FtBbeGQWe2LJpdzxkE+jv3Zd3ZV1w@mail.gmail.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
 <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
 <CAKddAkCCVjNHUinPWtOiK8Ki_ZkdoUCawfv1-+0B69J_1aJv5Q@mail.gmail.com>
 <ZzVNKvCu4MOs7O5z@debug.ba.rivosinc.com>
 <CAKddAkDbGYeONaksq6fzLzx47BHZo3Ar7Sog3MOgf7Y+Birovw@mail.gmail.com>
 <ZzVRbCZP9N4Os8Bj@debug.ba.rivosinc.com>
 <CAKddAkBCByf570PXfz798FtBbeGQWe2LJpdzxkE+jv3Zd3ZV1w@mail.gmail.com>
Message-ID: <ZzYcVW/4M0jab1T4@debug.ba.rivosinc.com>


Hi Nick,

Thanks for reviewing and helping.

On Thu, Nov 14, 2024 at 02:17:30PM +0800, Nick Hu wrote:
>Hi Deepak
>
>On Thu, Nov 14, 2024 at 9:25?AM Deepak Gupta <debug at rivosinc.com> wrote:
>>
>> On Thu, Nov 14, 2024 at 09:20:14AM +0800, Nick Hu wrote:
>> >Hi Deepak
>> >
>> >On Thu, Nov 14, 2024 at 9:06?AM Deepak Gupta <debug at rivosinc.com> wrote:
>> >> >> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
>> >> >> index 356d5397b2a2..6244408ca917 100644
>> >> >> --- a/arch/riscv/kernel/head.S
>> >> >> +++ b/arch/riscv/kernel/head.S
>> >> >> @@ -164,6 +164,12 @@ secondary_start_sbi:
>> >> >>         call relocate_enable_mmu
>> >> >>  #endif
>> >> >>         call .Lsetup_trap_vector
>> >> >> +       li a7, SBI_EXT_FWFT
>> >> >> +       li a6, SBI_EXT_FWFT_SET
>> >> >> +       li a0, SBI_FWFT_SHADOW_STACK
>> >> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
>> >> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
>> >> >> +       ecall
>> >> >>         scs_load_current
>> >> >>         call smp_callin
>> >> >>  #endif /* CONFIG_SMP */
>> >> >> @@ -320,6 +326,12 @@ SYM_CODE_START(_start_kernel)
>> >> >>         la tp, init_task
>> >> >>         la sp, init_thread_union + THREAD_SIZE
>> >> >>         addi sp, sp, -PT_SIZE_ON_STACK
>> >> >> +       li a7, SBI_EXT_FWFT
>> >> >> +       li a6, SBI_EXT_FWFT_SET
>> >> >> +       li a0, SBI_FWFT_SHADOW_STACK
>> >> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
>> >> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
>> >> >> +       ecall
>> >> >>         scs_load_current
>> >> >>
>> >> >>  #ifdef CONFIG_KASAN
>> >> >>
>> >> >> --
>> >> >> 2.45.0
>> >> >>
>> >> >Should we clear the SBI_FWFT_SET_FLAG_LOCK before the cpu hotplug
>> >> >otherwise the menvcfg.sse won't be set by the fwft set sbi call when
>> >> >the hotplug cpu back to kernel?
>> >>
>> >> Hmm...
>> >>
>> >> An incoming hotplug CPU has no features setup on it.
>> >> I see that `sbi_cpu_start` will supply `secondary_start_sbi` as start
>> >> up code for incoming CPU. `secondary_start_sbi` is in head.S which converges
>> >> in `.Lsecondary_start_common`. And thus hotplugged CPU should be
>> >> issuing shadow stack set FWFT sbi as well.
>> >>
>> >> Am I missing something ?
>> >>
>> >This is the correct flow. However the opensbi will deny it due to the
>> >SBI_FWFT_SET_FLAG_LOCK already being set.
>> >So the menvcfg.sse will not set by this flow.
>> >
>> >if (conf->flags & SBI_FWFT_SET_FLAG_LOCK)
>> >                return SBI_EDENIED;
>> >
>>
>> hmm... Why?
>>
>> `conf` is pointing to per-hart state in firmware.
>>
>> On this incoming cpu, opensbi (or equivalent) firmware must have
>> ensured that this per-hart state doesn't have lock set.
>>
>> Am I missing something?
>>
>Current OpenSBI doesn't clear the lock in the warm init of the hotplug path.
>It seems like we need a patch to address it.

Got it thanks.
Since you already know what's the problem, can you send a patch to opensbi.
If you want rather have me do it, let me know. Thanks.

>
>Regards,
>Nick
>> >Regards,
>> >Nick
>> >> >
>> >> >Regards,
>> >> >Nick
>> >> >>
>> >> >> _______________________________________________
>> >> >> linux-riscv mailing list
>> >> >> linux-riscv at lists.infradead.org
>> >> >> http://lists.infradead.org/mailman/listinfo/linux-riscv


From ajones at ventanamicro.com  Thu Nov 14 08:18:45 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:45 +0100
Subject: [RFC PATCH 00/15] iommu/riscv: Add irqbypass support
Message-ID: <20241114161845.502027-17-ajones@ventanamicro.com>

Platforms with implementations of the RISC-V IOMMU and AIA support
directly delivering MSIs of devices assigned to guests to the VCPUs.
VFIO and KVM have a framework to enable such support, which is called
irqbypass. This series enables irqbypass for devices assigned to KVM
guests when all VCPUs are allocated guest interrupt files. The RISC-V
IOMMU and AIA also support MRIFs (memory-resident interrupt files),
but support for those will be posted as a follow-on to this series.

The patches are organized as follows:
  1-3:  Prepare to create an MSI remapping irqdomain parented by the IMSIC
  4-6:  Prepare the IOMMU driver for VFIO domains which will use a single
        stage of translation, but G-stage instead of the first stage
  7-8:  Add support to the IOMMU driver for creating irqdomains
  9-10: Prepare KVM to enable irqbypass
 11-13: Add irqbypass support to the IOMMU driver and KVM
 14-15: Enable VFIO by default

This series is also available here [1] and may be tested with QEMU recent
enough to have the IOMMU model.

Based on linux-next commit 28955f4fa282 ("Add linux-next specific files for 20241112")

[1] https://github.com/jones-drew/linux/commits/riscv/iommu-irqbypass-rfc-v1/

Thanks,
drew


Andrew Jones (10):
  irqchip/riscv-imsic: Use hierarchy to reach irq_set_affinity
  genirq/msi: Provide DOMAIN_BUS_MSI_REMAP
  irqchip/riscv-imsic: Add support for DOMAIN_BUS_MSI_REMAP
  iommu/riscv: Move definitions to iommu.h
  iommu/riscv: Add IRQ domain for interrupt remapping
  RISC-V: KVM: Add irqbypass skeleton
  RISC-V: Define irqbypass vcpu_info
  iommu/riscv: Add guest file irqbypass support
  RISC-V: KVM: Add guest file irqbypass support
  RISC-V: defconfig: Add VFIO modules

Tomasz Jeznach (3):
  iommu/riscv: report iommu capabilities
  RISC-V: KVM: Enable KVM_VFIO interfaces on RISC-V arch
  vfio: enable IOMMU_TYPE1 for RISC-V

Zong Li (2):
  iommu/riscv: use data structure instead of individual values
  iommu/riscv: support GSCID and GVMA invalidation command

 arch/riscv/configs/defconfig               |   2 +
 arch/riscv/include/asm/irq.h               |   9 +
 arch/riscv/include/asm/kvm_host.h          |   3 +
 arch/riscv/kvm/Kconfig                     |   3 +
 arch/riscv/kvm/aia_imsic.c                 | 136 +++++++-
 arch/riscv/kvm/vm.c                        |  60 ++++
 drivers/iommu/riscv/Makefile               |   2 +-
 drivers/iommu/riscv/iommu-bits.h           |  11 +
 drivers/iommu/riscv/iommu-ir.c             | 360 +++++++++++++++++++++
 drivers/iommu/riscv/iommu.c                | 183 ++++++-----
 drivers/iommu/riscv/iommu.h                |  78 +++++
 drivers/irqchip/irq-riscv-imsic-platform.c |  18 +-
 drivers/vfio/Kconfig                       |   2 +-
 include/linux/irqdomain_defs.h             |   1 +
 14 files changed, 776 insertions(+), 92 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-ir.c

-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:46 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:46 +0100
Subject: [RFC PATCH 01/15] irqchip/riscv-imsic: Use hierarchy to reach irq_set_affinity
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-18-ajones@ventanamicro.com>

In order to support IRQ domains which reside between the leaf domains
and IMSIC, put the IMSIC implementation of irq_set_affinity into its
chip.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index c708780e8760..5d7c30ad8855 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -96,9 +96,8 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 				  bool force)
 {
 	struct imsic_vector *old_vec, *new_vec;
-	struct irq_data *pd = d->parent_data;
 
-	old_vec = irq_data_get_irq_chip_data(pd);
+	old_vec = irq_data_get_irq_chip_data(d);
 	if (WARN_ON(!old_vec))
 		return -ENOENT;
 
@@ -116,13 +115,13 @@ static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask *mask
 		return -ENOSPC;
 
 	/* Point device to the new vector */
-	imsic_msi_update_msg(d, new_vec);
+	imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec);
 
 	/* Update irq descriptors with the new vector */
-	pd->chip_data = new_vec;
+	d->chip_data = new_vec;
 
-	/* Update effective affinity of parent irq data */
-	irq_data_update_effective_affinity(pd, cpumask_of(new_vec->cpu));
+	/* Update effective affinity */
+	irq_data_update_effective_affinity(d, cpumask_of(new_vec->cpu));
 
 	/* Move state of the old vector to the new vector */
 	imsic_vector_move(old_vec, new_vec);
@@ -135,6 +134,9 @@ static struct irq_chip imsic_irq_base_chip = {
 	.name			= "IMSIC",
 	.irq_mask		= imsic_irq_mask,
 	.irq_unmask		= imsic_irq_unmask,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= imsic_irq_set_affinity,
+#endif
 	.irq_retrigger		= imsic_irq_retrigger,
 	.irq_compose_msi_msg	= imsic_irq_compose_msg,
 	.flags			= IRQCHIP_SKIP_SET_WAKE |
@@ -245,7 +247,7 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 		if (WARN_ON_ONCE(domain != real_parent))
 			return false;
 #ifdef CONFIG_SMP
-		info->chip->irq_set_affinity = imsic_irq_set_affinity;
+		info->chip->irq_set_affinity = irq_chip_set_affinity_parent;
 #endif
 		break;
 	default:
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:47 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:47 +0100
Subject: [RFC PATCH 02/15] genirq/msi: Provide DOMAIN_BUS_MSI_REMAP
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-19-ajones@ventanamicro.com>

Provide a domain bus token for the upcoming support for the RISC-V
IOMMU interrupt remapping domain, which needs to be distinguished
from NEXUS domains. The new token name is generic, as the only
information that needs to be conveyed is that the IRQ domain will
remap MSIs, i.e. there's nothing RISC-V specific to convey.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 include/linux/irqdomain_defs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/irqdomain_defs.h b/include/linux/irqdomain_defs.h
index 36653e2ee1c9..676eca8147ae 100644
--- a/include/linux/irqdomain_defs.h
+++ b/include/linux/irqdomain_defs.h
@@ -27,6 +27,7 @@ enum irq_domain_bus_token {
 	DOMAIN_BUS_AMDVI,
 	DOMAIN_BUS_DEVICE_MSI,
 	DOMAIN_BUS_WIRED_TO_MSI,
+	DOMAIN_BUS_MSI_REMAP,
 };
 
 #endif /* _LINUX_IRQDOMAIN_DEFS_H */
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:48 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:48 +0100
Subject: [RFC PATCH 03/15] irqchip/riscv-imsic: Add support for DOMAIN_BUS_MSI_REMAP
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-20-ajones@ventanamicro.com>

Unlike a child of an MSI NEXUS domain, a child of an MSI_REMAP domain
will not invoke init_dev_msi_info() with 'domain' equal to
'msi_parent_domain'. This is because the MSI_REMAP domain implements
init_dev_msi_info() with msi_parent_init_dev_msi_info(), which makes
'domain' point to the NEXUS (IMSIC) domain, while keeping
'msi_parent_domain' pointing to itself. The rest of the IMSIC
init_dev_msi_info() implementation works for MSI_REMAP domains,
though, so there's nothing to do to add support except accept the
token.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/irqchip/irq-riscv-imsic-platform.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index 5d7c30ad8855..6a7d7fefda6a 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -246,6 +246,8 @@ static bool imsic_init_dev_msi_info(struct device *dev,
 	case DOMAIN_BUS_NEXUS:
 		if (WARN_ON_ONCE(domain != real_parent))
 			return false;
+		fallthrough;
+	case DOMAIN_BUS_MSI_REMAP:
 #ifdef CONFIG_SMP
 		info->chip->irq_set_affinity = irq_chip_set_affinity_parent;
 #endif
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:49 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:49 +0100
Subject: [RFC PATCH 04/15] iommu/riscv: report iommu capabilities
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-21-ajones@ventanamicro.com>

From: Tomasz Jeznach <tjeznach at rivosinc.com>

Report RISC-V IOMMU capabilities required by VFIO subsystem
to enable PCIe device assignment.

Signed-off-by: Tomasz Jeznach <tjeznach at rivosinc.com>
Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/iommu/riscv/iommu.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 8a05def774bd..3fe4ceba8dd3 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -1462,6 +1462,17 @@ static struct iommu_group *riscv_iommu_device_group(struct device *dev)
 	return generic_device_group(dev);
 }
 
+static bool riscv_iommu_capable(struct device *dev, enum iommu_cap cap)
+{
+	switch (cap) {
+	case IOMMU_CAP_CACHE_COHERENCY:
+	case IOMMU_CAP_DEFERRED_FLUSH:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int riscv_iommu_of_xlate(struct device *dev, const struct of_phandle_args *args)
 {
 	return iommu_fwspec_add_ids(dev, args->args, 1);
@@ -1526,6 +1537,7 @@ static void riscv_iommu_release_device(struct device *dev)
 static const struct iommu_ops riscv_iommu_ops = {
 	.pgsize_bitmap = SZ_4K,
 	.of_xlate = riscv_iommu_of_xlate,
+	.capable = riscv_iommu_capable,
 	.identity_domain = &riscv_iommu_identity_domain,
 	.blocked_domain = &riscv_iommu_blocking_domain,
 	.release_domain = &riscv_iommu_blocking_domain,
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:50 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:50 +0100
Subject: [RFC PATCH 05/15] iommu/riscv: use data structure instead of individual values
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-22-ajones@ventanamicro.com>

From: Zong Li <zong.li at sifive.com>

The parameter will be increased when we need to set up more
bit fields in the device context. Use a data structure to
wrap them up.

Signed-off-by: Zong Li <zong.li at sifive.com>
Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/iommu/riscv/iommu.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 3fe4ceba8dd3..9d7945dc3c24 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -1001,7 +1001,7 @@ static void riscv_iommu_iotlb_inval(struct riscv_iommu_domain *domain,
  * interim translation faults.
  */
 static void riscv_iommu_iodir_update(struct riscv_iommu_device *iommu,
-				     struct device *dev, u64 fsc, u64 ta)
+				     struct device *dev, struct riscv_iommu_dc *new_dc)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct riscv_iommu_dc *dc;
@@ -1035,10 +1035,10 @@ static void riscv_iommu_iodir_update(struct riscv_iommu_device *iommu,
 	for (i = 0; i < fwspec->num_ids; i++) {
 		dc = riscv_iommu_get_dc(iommu, fwspec->ids[i]);
 		tc = READ_ONCE(dc->tc);
-		tc |= ta & RISCV_IOMMU_DC_TC_V;
+		tc |= new_dc->ta & RISCV_IOMMU_DC_TC_V;
 
-		WRITE_ONCE(dc->fsc, fsc);
-		WRITE_ONCE(dc->ta, ta & RISCV_IOMMU_PC_TA_PSCID);
+		WRITE_ONCE(dc->fsc, new_dc->fsc);
+		WRITE_ONCE(dc->ta, new_dc->ta & RISCV_IOMMU_PC_TA_PSCID);
 		/* Update device context, write TC.V as the last step. */
 		dma_wmb();
 		WRITE_ONCE(dc->tc, tc);
@@ -1315,20 +1315,20 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
 	struct riscv_iommu_domain *domain = iommu_domain_to_riscv(iommu_domain);
 	struct riscv_iommu_device *iommu = dev_to_iommu(dev);
 	struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
-	u64 fsc, ta;
+	struct riscv_iommu_dc dc = {0};
 
 	if (!riscv_iommu_pt_supported(iommu, domain->pgd_mode))
 		return -ENODEV;
 
-	fsc = FIELD_PREP(RISCV_IOMMU_PC_FSC_MODE, domain->pgd_mode) |
-	      FIELD_PREP(RISCV_IOMMU_PC_FSC_PPN, virt_to_pfn(domain->pgd_root));
-	ta = FIELD_PREP(RISCV_IOMMU_PC_TA_PSCID, domain->pscid) |
-	     RISCV_IOMMU_PC_TA_V;
+	dc.fsc = FIELD_PREP(RISCV_IOMMU_PC_FSC_MODE, domain->pgd_mode) |
+		 FIELD_PREP(RISCV_IOMMU_PC_FSC_PPN, virt_to_pfn(domain->pgd_root));
+	dc.ta = FIELD_PREP(RISCV_IOMMU_PC_TA_PSCID, domain->pscid) |
+			   RISCV_IOMMU_PC_TA_V;
 
 	if (riscv_iommu_bond_link(domain, dev))
 		return -ENOMEM;
 
-	riscv_iommu_iodir_update(iommu, dev, fsc, ta);
+	riscv_iommu_iodir_update(iommu, dev, &dc);
 	riscv_iommu_bond_unlink(info->domain, dev);
 	info->domain = domain;
 
@@ -1419,9 +1419,12 @@ static int riscv_iommu_attach_blocking_domain(struct iommu_domain *iommu_domain,
 {
 	struct riscv_iommu_device *iommu = dev_to_iommu(dev);
 	struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
+	struct riscv_iommu_dc dc = {0};
+
+	dc.fsc = RISCV_IOMMU_FSC_BARE;
 
 	/* Make device context invalid, translation requests will fault w/ #258 */
-	riscv_iommu_iodir_update(iommu, dev, RISCV_IOMMU_FSC_BARE, 0);
+	riscv_iommu_iodir_update(iommu, dev, &dc);
 	riscv_iommu_bond_unlink(info->domain, dev);
 	info->domain = NULL;
 
@@ -1440,8 +1443,12 @@ static int riscv_iommu_attach_identity_domain(struct iommu_domain *iommu_domain,
 {
 	struct riscv_iommu_device *iommu = dev_to_iommu(dev);
 	struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
+	struct riscv_iommu_dc dc = {0};
+
+	dc.fsc = RISCV_IOMMU_FSC_BARE;
+	dc.ta = RISCV_IOMMU_PC_TA_V;
 
-	riscv_iommu_iodir_update(iommu, dev, RISCV_IOMMU_FSC_BARE, RISCV_IOMMU_PC_TA_V);
+	riscv_iommu_iodir_update(iommu, dev, &dc);
 	riscv_iommu_bond_unlink(info->domain, dev);
 	info->domain = NULL;
 
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:51 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:51 +0100
Subject: [RFC PATCH 06/15] iommu/riscv: support GSCID and GVMA invalidation command
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-23-ajones@ventanamicro.com>

From: Zong Li <zong.li at sifive.com>

This patch adds a ID Allocator for GSCID and a wrap for setting up
GSCID in IOTLB invalidation command.

Set up iohgatp to enable second stage table and flush stage-2 table if
the GSCID is set.

The GSCID of domain should be freed when release domain. GSCID will be
allocated for parent domain in nested IOMMU process.

Signed-off-by: Zong Li <zong.li at sifive.com>
Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/iommu/riscv/iommu-bits.h |  7 +++++++
 drivers/iommu/riscv/iommu.c      | 32 ++++++++++++++++++++++++++------
 2 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/riscv/iommu-bits.h b/drivers/iommu/riscv/iommu-bits.h
index 98daf0e1a306..d72b982cf9bf 100644
--- a/drivers/iommu/riscv/iommu-bits.h
+++ b/drivers/iommu/riscv/iommu-bits.h
@@ -715,6 +715,13 @@ static inline void riscv_iommu_cmd_inval_vma(struct riscv_iommu_command *cmd)
 	cmd->dword1 = 0;
 }
 
+static inline void riscv_iommu_cmd_inval_gvma(struct riscv_iommu_command *cmd)
+{
+	cmd->dword0 = FIELD_PREP(RISCV_IOMMU_CMD_OPCODE, RISCV_IOMMU_CMD_IOTINVAL_OPCODE) |
+		      FIELD_PREP(RISCV_IOMMU_CMD_FUNC, RISCV_IOMMU_CMD_IOTINVAL_FUNC_GVMA);
+	cmd->dword1 = 0;
+}
+
 static inline void riscv_iommu_cmd_inval_set_addr(struct riscv_iommu_command *cmd,
 						  u64 addr)
 {
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 9d7945dc3c24..ef38a1bb3eca 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -45,6 +45,10 @@
 static DEFINE_IDA(riscv_iommu_pscids);
 #define RISCV_IOMMU_MAX_PSCID		(BIT(20) - 1)
 
+/* IOMMU GSCID allocation namespace. */
+static DEFINE_IDA(riscv_iommu_gscids);
+#define RISCV_IOMMU_MAX_GSCID		(BIT(16) - 1)
+
 /* Device resource-managed allocations */
 struct riscv_iommu_devres {
 	void *addr;
@@ -801,6 +805,7 @@ struct riscv_iommu_domain {
 	struct list_head bonds;
 	spinlock_t lock;		/* protect bonds list updates. */
 	int pscid;
+	int gscid;
 	bool amo_enabled;
 	int numa_node;
 	unsigned int pgd_mode;
@@ -954,15 +959,20 @@ static void riscv_iommu_iotlb_inval(struct riscv_iommu_domain *domain,
 
 		/*
 		 * IOTLB invalidation request can be safely omitted if already sent
-		 * to the IOMMU for the same PSCID, and with domain->bonds list
+		 * to the IOMMU for the same PSCID/GSCID, and with domain->bonds list
 		 * arranged based on the device's IOMMU, it's sufficient to check
 		 * last device the invalidation was sent to.
 		 */
 		if (iommu == prev)
 			continue;
 
-		riscv_iommu_cmd_inval_vma(&cmd);
-		riscv_iommu_cmd_inval_set_pscid(&cmd, domain->pscid);
+		if (domain->gscid) {
+			riscv_iommu_cmd_inval_gvma(&cmd);
+			riscv_iommu_cmd_inval_set_gscid(&cmd, domain->gscid);
+		} else {
+			riscv_iommu_cmd_inval_vma(&cmd);
+			riscv_iommu_cmd_inval_set_pscid(&cmd, domain->pscid);
+		}
 		if (len && len < RISCV_IOMMU_IOTLB_INVAL_LIMIT) {
 			for (iova = start; iova < end; iova += PAGE_SIZE) {
 				riscv_iommu_cmd_inval_set_addr(&cmd, iova);
@@ -1039,6 +1049,7 @@ static void riscv_iommu_iodir_update(struct riscv_iommu_device *iommu,
 
 		WRITE_ONCE(dc->fsc, new_dc->fsc);
 		WRITE_ONCE(dc->ta, new_dc->ta & RISCV_IOMMU_PC_TA_PSCID);
+		WRITE_ONCE(dc->iohgatp, new_dc->iohgatp);
 		/* Update device context, write TC.V as the last step. */
 		dma_wmb();
 		WRITE_ONCE(dc->tc, tc);
@@ -1287,8 +1298,10 @@ static void riscv_iommu_free_paging_domain(struct iommu_domain *iommu_domain)
 
 	WARN_ON(!list_empty(&domain->bonds));
 
-	if ((int)domain->pscid > 0)
+	if (domain->pscid > 0)
 		ida_free(&riscv_iommu_pscids, domain->pscid);
+	if (domain->gscid > 0)
+		ida_free(&riscv_iommu_gscids, domain->gscid);
 
 	riscv_iommu_pte_free(domain, _io_pte_entry(pfn, _PAGE_TABLE), NULL);
 	kfree(domain);
@@ -1320,8 +1333,15 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
 	if (!riscv_iommu_pt_supported(iommu, domain->pgd_mode))
 		return -ENODEV;
 
-	dc.fsc = FIELD_PREP(RISCV_IOMMU_PC_FSC_MODE, domain->pgd_mode) |
-		 FIELD_PREP(RISCV_IOMMU_PC_FSC_PPN, virt_to_pfn(domain->pgd_root));
+	if (domain->gscid) {
+		dc.iohgatp = FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_MODE, domain->pgd_mode) |
+			     FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_GSCID, domain->gscid) |
+			     FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_PPN, virt_to_pfn(domain->pgd_root));
+	} else {
+		dc.fsc = FIELD_PREP(RISCV_IOMMU_PC_FSC_MODE, domain->pgd_mode) |
+			 FIELD_PREP(RISCV_IOMMU_PC_FSC_PPN, virt_to_pfn(domain->pgd_root));
+	}
+
 	dc.ta = FIELD_PREP(RISCV_IOMMU_PC_TA_PSCID, domain->pscid) |
 			   RISCV_IOMMU_PC_TA_V;
 
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:52 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:52 +0100
Subject: [RFC PATCH 07/15] iommu/riscv: Move definitions to iommu.h
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-24-ajones@ventanamicro.com>

In order to add the interrupt remapping support in a separate file,
share definitions through the header, as well as making some
functions public.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/iommu/riscv/iommu-bits.h |  4 ++
 drivers/iommu/riscv/iommu.c      | 71 ++++----------------------------
 drivers/iommu/riscv/iommu.h      | 54 ++++++++++++++++++++++++
 3 files changed, 67 insertions(+), 62 deletions(-)

diff --git a/drivers/iommu/riscv/iommu-bits.h b/drivers/iommu/riscv/iommu-bits.h
index d72b982cf9bf..d3d98dbed709 100644
--- a/drivers/iommu/riscv/iommu-bits.h
+++ b/drivers/iommu/riscv/iommu-bits.h
@@ -36,6 +36,10 @@
 #define RISCV_IOMMU_ATP_PPN_FIELD	GENMASK_ULL(43, 0)
 #define RISCV_IOMMU_ATP_MODE_FIELD	GENMASK_ULL(63, 60)
 
+/* RISC-V IOMMU PPN <> PHYS address conversions, PHYS <=> PPN[53:10] */
+#define riscv_iommu_phys_to_ppn(pa)	(((pa) >> 2) & (((1ULL << 44) - 1) << 10))
+#define riscv_iommu_ppn_to_phys(pn)	(((pn) << 2) & (((1ULL << 44) - 1) << 12))
+
 /* 5.3 IOMMU Capabilities (64bits) */
 #define RISCV_IOMMU_REG_CAPABILITIES		0x0000
 #define RISCV_IOMMU_CAPABILITIES_VERSION	GENMASK_ULL(7, 0)
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index ef38a1bb3eca..6e8ea3d22ff5 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -24,23 +24,10 @@
 #include "iommu-bits.h"
 #include "iommu.h"
 
-/* Timeouts in [us] */
-#define RISCV_IOMMU_QCSR_TIMEOUT	150000
-#define RISCV_IOMMU_QUEUE_TIMEOUT	150000
-#define RISCV_IOMMU_DDTP_TIMEOUT	10000000
-#define RISCV_IOMMU_IOTINVAL_TIMEOUT	90000000
-
 /* Number of entries per CMD/FLT queue, should be <= INT_MAX */
 #define RISCV_IOMMU_DEF_CQ_COUNT	8192
 #define RISCV_IOMMU_DEF_FQ_COUNT	4096
 
-/* RISC-V IOMMU PPN <> PHYS address conversions, PHYS <=> PPN[53:10] */
-#define phys_to_ppn(pa)  (((pa) >> 2) & (((1ULL << 44) - 1) << 10))
-#define ppn_to_phys(pn)	 (((pn) << 2) & (((1ULL << 44) - 1) << 12))
-
-#define dev_to_iommu(dev) \
-	iommu_get_iommu_dev(dev, struct riscv_iommu_device, iommu)
-
 /* IOMMU PSCID allocation namespace. */
 static DEFINE_IDA(riscv_iommu_pscids);
 #define RISCV_IOMMU_MAX_PSCID		(BIT(20) - 1)
@@ -177,7 +164,7 @@ static int riscv_iommu_queue_alloc(struct riscv_iommu_device *iommu,
 	if (!queue->base)
 		return -ENOMEM;
 
-	qb = phys_to_ppn(queue->phys) |
+	qb = riscv_iommu_phys_to_ppn(queue->phys) |
 	     FIELD_PREP(RISCV_IOMMU_QUEUE_LOG2SZ_FIELD, logsz);
 
 	/* Update base register and read back to verify hw accepted our write */
@@ -480,15 +467,15 @@ static irqreturn_t riscv_iommu_cmdq_process(int irq, void *data)
 }
 
 /* Send command to the IOMMU command queue */
-static void riscv_iommu_cmd_send(struct riscv_iommu_device *iommu,
-				 struct riscv_iommu_command *cmd)
+void riscv_iommu_cmd_send(struct riscv_iommu_device *iommu,
+			  struct riscv_iommu_command *cmd)
 {
 	riscv_iommu_queue_send(&iommu->cmdq, cmd, sizeof(*cmd));
 }
 
 /* Send IOFENCE.C command and wait for all scheduled commands to complete. */
-static void riscv_iommu_cmd_sync(struct riscv_iommu_device *iommu,
-				 unsigned int timeout_us)
+void riscv_iommu_cmd_sync(struct riscv_iommu_device *iommu,
+			  unsigned int timeout_us)
 {
 	struct riscv_iommu_command cmd;
 	unsigned int prod;
@@ -614,7 +601,7 @@ static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iomm
 		do {
 			ddt = READ_ONCE(*(unsigned long *)ddtp);
 			if (ddt & RISCV_IOMMU_DDTE_V) {
-				ddtp = __va(ppn_to_phys(ddt));
+				ddtp = __va(riscv_iommu_ppn_to_phys(ddt));
 				break;
 			}
 
@@ -622,7 +609,7 @@ static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iomm
 			if (!ptr)
 				return NULL;
 
-			new = phys_to_ppn(__pa(ptr)) | RISCV_IOMMU_DDTE_V;
+			new = riscv_iommu_phys_to_ppn(__pa(ptr)) | RISCV_IOMMU_DDTE_V;
 			old = cmpxchg_relaxed((unsigned long *)ddtp, ddt, new);
 
 			if (old == ddt) {
@@ -687,7 +674,7 @@ static int riscv_iommu_iodir_alloc(struct riscv_iommu_device *iommu)
 		if (ddtp & RISCV_IOMMU_DDTP_BUSY)
 			return -EBUSY;
 
-		iommu->ddt_phys = ppn_to_phys(ddtp);
+		iommu->ddt_phys = riscv_iommu_ppn_to_phys(ddtp);
 		if (iommu->ddt_phys)
 			iommu->ddt_root = devm_ioremap(iommu->dev,
 						       iommu->ddt_phys, PAGE_SIZE);
@@ -734,7 +721,7 @@ static int riscv_iommu_iodir_set_mode(struct riscv_iommu_device *iommu,
 	do {
 		rq_ddtp = FIELD_PREP(RISCV_IOMMU_DDTP_IOMMU_MODE, rq_mode);
 		if (rq_mode > RISCV_IOMMU_DDTP_IOMMU_MODE_BARE)
-			rq_ddtp |= phys_to_ppn(iommu->ddt_phys);
+			rq_ddtp |= riscv_iommu_phys_to_ppn(iommu->ddt_phys);
 
 		riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_DDTP, rq_ddtp);
 		ddtp = riscv_iommu_read_ddtp(iommu);
@@ -799,49 +786,9 @@ static int riscv_iommu_iodir_set_mode(struct riscv_iommu_device *iommu,
 	return 0;
 }
 
-/* This struct contains protection domain specific IOMMU driver data. */
-struct riscv_iommu_domain {
-	struct iommu_domain domain;
-	struct list_head bonds;
-	spinlock_t lock;		/* protect bonds list updates. */
-	int pscid;
-	int gscid;
-	bool amo_enabled;
-	int numa_node;
-	unsigned int pgd_mode;
-	unsigned long *pgd_root;
-};
-
 #define iommu_domain_to_riscv(iommu_domain) \
 	container_of(iommu_domain, struct riscv_iommu_domain, domain)
 
-/* Private IOMMU data for managed devices, dev_iommu_priv_* */
-struct riscv_iommu_info {
-	struct riscv_iommu_domain *domain;
-};
-
-/*
- * Linkage between an iommu_domain and attached devices.
- *
- * Protection domain requiring IOATC and DevATC translation cache invalidations,
- * should be linked to attached devices using a riscv_iommu_bond structure.
- * Devices should be linked to the domain before first use and unlinked after
- * the translations from the referenced protection domain can no longer be used.
- * Blocking and identity domains are not tracked here, as the IOMMU hardware
- * does not cache negative and/or identity (BARE mode) translations, and DevATC
- * is disabled for those protection domains.
- *
- * The device pointer and IOMMU data remain stable in the bond struct after
- * _probe_device() where it's attached to the managed IOMMU, up to the
- * completion of the _release_device() call. The release of the bond structure
- * is synchronized with the device release.
- */
-struct riscv_iommu_bond {
-	struct list_head list;
-	struct rcu_head rcu;
-	struct device *dev;
-};
-
 static int riscv_iommu_bond_link(struct riscv_iommu_domain *domain,
 				 struct device *dev)
 {
diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h
index b1c4664542b4..dd538b19fbb7 100644
--- a/drivers/iommu/riscv/iommu.h
+++ b/drivers/iommu/riscv/iommu.h
@@ -17,8 +17,35 @@
 
 #include "iommu-bits.h"
 
+/* Timeouts in [us] */
+#define RISCV_IOMMU_QCSR_TIMEOUT	150000
+#define RISCV_IOMMU_QUEUE_TIMEOUT	150000
+#define RISCV_IOMMU_DDTP_TIMEOUT	10000000
+#define RISCV_IOMMU_IOTINVAL_TIMEOUT	90000000
+
+/* This struct contains protection domain specific IOMMU driver data. */
+struct riscv_iommu_domain {
+	struct iommu_domain domain;
+	struct list_head bonds;
+	spinlock_t lock;			/* protect bonds list updates. */
+	int pscid;
+	int gscid;
+	int amo_enabled;
+	int numa_node;
+	unsigned int pgd_mode;
+	unsigned long *pgd_root;
+};
+
+/* Private IOMMU data for managed devices, dev_iommu_priv_* */
+struct riscv_iommu_info {
+	struct riscv_iommu_domain *domain;
+};
+
 struct riscv_iommu_device;
 
+#define dev_to_iommu(dev) \
+	iommu_get_iommu_dev(dev, struct riscv_iommu_device, iommu)
+
 struct riscv_iommu_queue {
 	atomic_t prod;				/* unbounded producer allocation index */
 	atomic_t head;				/* unbounded shadow ring buffer consumer index */
@@ -62,9 +89,36 @@ struct riscv_iommu_device {
 	u64 *ddt_root;
 };
 
+/*
+ * Linkage between an iommu_domain and attached devices.
+ *
+ * Protection domain requiring IOATC and DevATC translation cache invalidations,
+ * should be linked to attached devices using a riscv_iommu_bond structure.
+ * Devices should be linked to the domain before first use and unlinked after
+ * the translations from the referenced protection domain can no longer be used.
+ * Blocking and identity domains are not tracked here, as the IOMMU hardware
+ * does not cache negative and/or identity (BARE mode) translations, and DevATC
+ * is disabled for those protection domains.
+ *
+ * The device pointer and IOMMU data remain stable in the bond struct after
+ * _probe_device() where it's attached to the managed IOMMU, up to the
+ * completion of the _release_device() call. The release of the bond structure
+ * is synchronized with the device release.
+ */
+struct riscv_iommu_bond {
+	struct list_head list;
+	struct rcu_head rcu;
+	struct device *dev;
+};
+
 int riscv_iommu_init(struct riscv_iommu_device *iommu);
 void riscv_iommu_remove(struct riscv_iommu_device *iommu);
 
+void riscv_iommu_cmd_send(struct riscv_iommu_device *iommu,
+			  struct riscv_iommu_command *cmd);
+void riscv_iommu_cmd_sync(struct riscv_iommu_device *iommu,
+			  unsigned int timeout_us);
+
 #define riscv_iommu_readl(iommu, addr) \
 	readl_relaxed((iommu)->reg + (addr))
 
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:53 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:53 +0100
Subject: [RFC PATCH 08/15] iommu/riscv: Add IRQ domain for interrupt remapping
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-25-ajones@ventanamicro.com>

This is just a skeleton. Until irq_set_vcpu_affinity() is
implemented the IRQ domain doesn't serve any purpose.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/iommu/riscv/Makefile   |   2 +-
 drivers/iommu/riscv/iommu-ir.c | 209 +++++++++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu.c    |  43 ++++++-
 drivers/iommu/riscv/iommu.h    |  21 ++++
 4 files changed, 270 insertions(+), 5 deletions(-)
 create mode 100644 drivers/iommu/riscv/iommu-ir.c

diff --git a/drivers/iommu/riscv/Makefile b/drivers/iommu/riscv/Makefile
index f54c9ed17d41..8420dd1776cb 100644
--- a/drivers/iommu/riscv/Makefile
+++ b/drivers/iommu/riscv/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_RISCV_IOMMU) += iommu.o iommu-platform.o
+obj-$(CONFIG_RISCV_IOMMU) += iommu.o iommu-ir.o iommu-platform.o
 obj-$(CONFIG_RISCV_IOMMU_PCI) += iommu-pci.o
diff --git a/drivers/iommu/riscv/iommu-ir.c b/drivers/iommu/riscv/iommu-ir.c
new file mode 100644
index 000000000000..c177e064b205
--- /dev/null
+++ b/drivers/iommu/riscv/iommu-ir.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * IOMMU Interrupt Remapping
+ *
+ * Copyright ? 2024 Ventana Micro Systems Inc.
+ */
+#include <linux/irqdomain.h>
+#include <linux/msi.h>
+
+#include "../iommu-pages.h"
+#include "iommu.h"
+
+static size_t riscv_iommu_ir_get_msipte_idx(struct riscv_iommu_domain *domain,
+					    phys_addr_t msi_pa)
+{
+	phys_addr_t addr = msi_pa >> 12;
+	size_t idx;
+
+	if (domain->group_index_bits) {
+		phys_addr_t group_mask = BIT(domain->group_index_bits) - 1;
+		phys_addr_t group_shift = domain->group_index_shift - 12;
+		phys_addr_t group = (addr >> group_shift) & group_mask;
+		phys_addr_t mask = domain->msiptp.msi_addr_mask & ~(group_mask << group_shift);
+
+		idx = addr & mask;
+		idx |= group << fls64(mask);
+	} else {
+		idx = addr & domain->msiptp.msi_addr_mask;
+	}
+
+	return idx;
+}
+
+static struct riscv_iommu_msipte *riscv_iommu_ir_get_msipte(struct riscv_iommu_domain *domain,
+							    phys_addr_t msi_pa)
+{
+	size_t idx;
+
+	if (((msi_pa >> 12) & ~domain->msiptp.msi_addr_mask) != domain->msiptp.msi_addr_pattern)
+		return NULL;
+
+	idx = riscv_iommu_ir_get_msipte_idx(domain, msi_pa);
+	return &domain->msi_root[idx];
+}
+
+static size_t riscv_iommu_ir_nr_msiptes(struct riscv_iommu_domain *domain)
+{
+	phys_addr_t base = domain->msiptp.msi_addr_pattern << 12;
+	phys_addr_t max_addr = base | (domain->msiptp.msi_addr_mask << 12);
+	size_t max_idx = riscv_iommu_ir_get_msipte_idx(domain, max_addr);
+
+	return max_idx + 1;
+}
+
+static struct irq_chip riscv_iommu_irq_chip = {
+	.name			= "IOMMU-IR",
+	.irq_mask		= irq_chip_mask_parent,
+	.irq_unmask		= irq_chip_unmask_parent,
+};
+
+static int riscv_iommu_irq_domain_alloc_irqs(struct irq_domain *irqdomain,
+					     unsigned int irq_base, unsigned int nr_irqs,
+					     void *arg)
+{
+	struct irq_data *data;
+	int i, ret;
+
+	ret = irq_domain_alloc_irqs_parent(irqdomain, irq_base, nr_irqs, arg);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nr_irqs; i++) {
+		data = irq_domain_get_irq_data(irqdomain, irq_base + i);
+		data->chip = &riscv_iommu_irq_chip;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops riscv_iommu_irq_domain_ops = {
+	.alloc = riscv_iommu_irq_domain_alloc_irqs,
+	.free = irq_domain_free_irqs_parent,
+};
+
+static const struct msi_parent_ops riscv_iommu_msi_parent_ops = {
+	.prefix			= "IR-",
+	.supported_flags	= MSI_GENERIC_FLAGS_MASK |
+				  MSI_FLAG_PCI_MSIX,
+	.required_flags		= MSI_FLAG_USE_DEF_DOM_OPS |
+				  MSI_FLAG_USE_DEF_CHIP_OPS,
+	.init_dev_msi_info	= msi_parent_init_dev_msi_info,
+};
+
+int riscv_iommu_irq_domain_create(struct riscv_iommu_domain *domain,
+				  struct device *dev)
+{
+	struct riscv_iommu_device *iommu = dev_to_iommu(dev);
+	struct fwnode_handle *fn;
+	char *fwname;
+
+	if (domain->irqdomain) {
+		dev_set_msi_domain(dev, domain->irqdomain);
+		return 0;
+	}
+
+	if (!(iommu->caps & RISCV_IOMMU_CAPABILITIES_MSI_FLAT)) {
+		dev_warn(iommu->dev, "Cannot enable interrupt remapping\n");
+		return 0;
+	}
+
+	spin_lock_init(&domain->msi_lock);
+	/*
+	 * TODO: The hypervisor should be in control of this size. For now
+	 * we just allocate enough space for 512 VCPUs.
+	 */
+	domain->msi_order = 1;
+	domain->msi_root = iommu_alloc_pages_node(domain->numa_node,
+						  GFP_KERNEL_ACCOUNT, domain->msi_order);
+	if (!domain->msi_root)
+		return -ENOMEM;
+
+	fwname = kasprintf(GFP_KERNEL, "IOMMU-IR-%s", dev_name(dev));
+	if (!fwname) {
+		iommu_free_pages(domain->msi_root, domain->msi_order);
+		return -ENOMEM;
+	}
+
+	fn = irq_domain_alloc_named_fwnode(fwname);
+	kfree(fwname);
+	if (!fn) {
+		dev_err(iommu->dev, "Couldn't allocate fwnode\n");
+		iommu_free_pages(domain->msi_root, domain->msi_order);
+		return -ENOMEM;
+	}
+
+	domain->irqdomain = irq_domain_create_hierarchy(dev_get_msi_domain(dev),
+							0, 0, fn,
+							&riscv_iommu_irq_domain_ops,
+							domain);
+	if (!domain->irqdomain) {
+		dev_err(iommu->dev, "Failed to create IOMMU irq domain\n");
+		iommu_free_pages(domain->msi_root, domain->msi_order);
+		irq_domain_free_fwnode(fn);
+		return -ENOMEM;
+	}
+
+	domain->irqdomain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT |
+				    IRQ_DOMAIN_FLAG_ISOLATED_MSI;
+	domain->irqdomain->msi_parent_ops = &riscv_iommu_msi_parent_ops;
+	irq_domain_update_bus_token(domain->irqdomain, DOMAIN_BUS_MSI_REMAP);
+	dev_set_msi_domain(dev, domain->irqdomain);
+
+	return 0;
+}
+
+void riscv_iommu_ir_get_resv_regions(struct device *dev, struct list_head *head)
+{
+	struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
+	struct riscv_iommu_domain *domain = info->domain;
+	struct iommu_resv_region *reg;
+	phys_addr_t base, addr;
+	size_t nr_pages, i;
+
+	if (!domain || !domain->msiptp.msiptp)
+		return;
+
+	base = domain->msiptp.msi_addr_pattern << 12;
+
+	if (domain->group_index_bits) {
+		phys_addr_t group_mask = BIT(domain->group_index_bits) - 1;
+		phys_addr_t group_shift = domain->group_index_shift - 12;
+		phys_addr_t mask = domain->msiptp.msi_addr_mask & ~(group_mask << group_shift);
+
+		nr_pages = mask + 1;
+	} else {
+		nr_pages = domain->msiptp.msi_addr_mask + 1;
+	}
+
+	for (i = 0; i < BIT(domain->group_index_bits); i++) {
+		addr = base | (i << domain->group_index_shift);
+		reg = iommu_alloc_resv_region(addr, nr_pages * 4096,
+					      0, IOMMU_RESV_MSI, GFP_KERNEL);
+		if (reg)
+			list_add_tail(&reg->list, head);
+	}
+}
+
+void riscv_iommu_irq_domain_remove(struct riscv_iommu_domain *domain)
+{
+	struct fwnode_handle *fn;
+
+	if (!domain->irqdomain)
+		return;
+
+	iommu_free_pages(domain->msi_root, domain->msi_order);
+
+	fn = domain->irqdomain->fwnode;
+	irq_domain_remove(domain->irqdomain);
+	irq_domain_free_fwnode(fn);
+}
+
+void riscv_iommu_irq_domain_unlink(struct riscv_iommu_domain *domain,
+				   struct device *dev)
+{
+	if (!domain || !domain->irqdomain)
+		return;
+
+	dev_set_msi_domain(dev, domain->irqdomain->parent);
+}
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 6e8ea3d22ff5..c4a47b21c58f 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -943,7 +943,8 @@ static void riscv_iommu_iotlb_inval(struct riscv_iommu_domain *domain,
 	rcu_read_unlock();
 }
 
-#define RISCV_IOMMU_FSC_BARE 0
+#define RISCV_IOMMU_FSC_BARE		0
+#define RISCV_IOMMU_IOHGATP_BARE	0
 
 /*
  * Update IODIR for the device.
@@ -1245,6 +1246,8 @@ static void riscv_iommu_free_paging_domain(struct iommu_domain *iommu_domain)
 
 	WARN_ON(!list_empty(&domain->bonds));
 
+	riscv_iommu_irq_domain_remove(domain);
+
 	if (domain->pscid > 0)
 		ida_free(&riscv_iommu_pscids, domain->pscid);
 	if (domain->gscid > 0)
@@ -1276,10 +1279,30 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
 	struct riscv_iommu_device *iommu = dev_to_iommu(dev);
 	struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
 	struct riscv_iommu_dc dc = {0};
+	int ret;
 
 	if (!riscv_iommu_pt_supported(iommu, domain->pgd_mode))
 		return -ENODEV;
 
+	if (riscv_iommu_bond_link(domain, dev))
+		return -ENOMEM;
+
+	if (iommu_domain->type == IOMMU_DOMAIN_UNMANAGED) {
+		domain->gscid = ida_alloc_range(&riscv_iommu_gscids, 1,
+						RISCV_IOMMU_MAX_GSCID, GFP_KERNEL);
+		if (domain->gscid < 0) {
+			riscv_iommu_bond_unlink(domain, dev);
+			return -ENOMEM;
+		}
+
+		ret = riscv_iommu_irq_domain_create(domain, dev);
+		if (ret) {
+			riscv_iommu_bond_unlink(domain, dev);
+			ida_free(&riscv_iommu_gscids, domain->gscid);
+			return ret;
+		}
+	}
+
 	if (domain->gscid) {
 		dc.iohgatp = FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_MODE, domain->pgd_mode) |
 			     FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_GSCID, domain->gscid) |
@@ -1292,10 +1315,9 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
 	dc.ta = FIELD_PREP(RISCV_IOMMU_PC_TA_PSCID, domain->pscid) |
 			   RISCV_IOMMU_PC_TA_V;
 
-	if (riscv_iommu_bond_link(domain, dev))
-		return -ENOMEM;
-
 	riscv_iommu_iodir_update(iommu, dev, &dc);
+
+	riscv_iommu_irq_domain_unlink(info->domain, dev);
 	riscv_iommu_bond_unlink(info->domain, dev);
 	info->domain = domain;
 
@@ -1389,9 +1411,12 @@ static int riscv_iommu_attach_blocking_domain(struct iommu_domain *iommu_domain,
 	struct riscv_iommu_dc dc = {0};
 
 	dc.fsc = RISCV_IOMMU_FSC_BARE;
+	dc.iohgatp = RISCV_IOMMU_IOHGATP_BARE;
 
 	/* Make device context invalid, translation requests will fault w/ #258 */
 	riscv_iommu_iodir_update(iommu, dev, &dc);
+
+	riscv_iommu_irq_domain_unlink(info->domain, dev);
 	riscv_iommu_bond_unlink(info->domain, dev);
 	info->domain = NULL;
 
@@ -1413,15 +1438,24 @@ static int riscv_iommu_attach_identity_domain(struct iommu_domain *iommu_domain,
 	struct riscv_iommu_dc dc = {0};
 
 	dc.fsc = RISCV_IOMMU_FSC_BARE;
+	dc.iohgatp = RISCV_IOMMU_IOHGATP_BARE;
 	dc.ta = RISCV_IOMMU_PC_TA_V;
 
 	riscv_iommu_iodir_update(iommu, dev, &dc);
+
+	riscv_iommu_irq_domain_unlink(info->domain, dev);
 	riscv_iommu_bond_unlink(info->domain, dev);
 	info->domain = NULL;
 
 	return 0;
 }
 
+static void riscv_iommu_get_resv_regions(struct device *dev,
+					 struct list_head *head)
+{
+	riscv_iommu_ir_get_resv_regions(dev, head);
+}
+
 static struct iommu_domain riscv_iommu_identity_domain = {
 	.type = IOMMU_DOMAIN_IDENTITY,
 	.ops = &(const struct iommu_domain_ops) {
@@ -1516,6 +1550,7 @@ static const struct iommu_ops riscv_iommu_ops = {
 	.blocked_domain = &riscv_iommu_blocking_domain,
 	.release_domain = &riscv_iommu_blocking_domain,
 	.domain_alloc_paging = riscv_iommu_alloc_paging_domain,
+	.get_resv_regions = riscv_iommu_get_resv_regions,
 	.device_group = riscv_iommu_device_group,
 	.probe_device = riscv_iommu_probe_device,
 	.release_device	= riscv_iommu_release_device,
diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h
index dd538b19fbb7..6ce71095781c 100644
--- a/drivers/iommu/riscv/iommu.h
+++ b/drivers/iommu/riscv/iommu.h
@@ -23,6 +23,12 @@
 #define RISCV_IOMMU_DDTP_TIMEOUT	10000000
 #define RISCV_IOMMU_IOTINVAL_TIMEOUT	90000000
 
+struct riscv_iommu_msiptp_state {
+	u64 msiptp;
+	u64 msi_addr_mask;
+	u64 msi_addr_pattern;
+};
+
 /* This struct contains protection domain specific IOMMU driver data. */
 struct riscv_iommu_domain {
 	struct iommu_domain domain;
@@ -34,6 +40,13 @@ struct riscv_iommu_domain {
 	int numa_node;
 	unsigned int pgd_mode;
 	unsigned long *pgd_root;
+	u32 group_index_bits;
+	u32 group_index_shift;
+	int msi_order;
+	struct riscv_iommu_msipte *msi_root;
+	spinlock_t msi_lock;
+	struct riscv_iommu_msiptp_state msiptp;
+	struct irq_domain *irqdomain;
 };
 
 /* Private IOMMU data for managed devices, dev_iommu_priv_* */
@@ -119,6 +132,14 @@ void riscv_iommu_cmd_send(struct riscv_iommu_device *iommu,
 void riscv_iommu_cmd_sync(struct riscv_iommu_device *iommu,
 			  unsigned int timeout_us);
 
+int riscv_iommu_irq_domain_create(struct riscv_iommu_domain *domain,
+				  struct device *dev);
+void riscv_iommu_irq_domain_remove(struct riscv_iommu_domain *domain);
+void riscv_iommu_irq_domain_unlink(struct riscv_iommu_domain *domain,
+				   struct device *dev);
+void riscv_iommu_ir_get_resv_regions(struct device *dev,
+				     struct list_head *head);
+
 #define riscv_iommu_readl(iommu, addr) \
 	readl_relaxed((iommu)->reg + (addr))
 
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:54 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:54 +0100
Subject: [RFC PATCH 09/15] RISC-V: KVM: Enable KVM_VFIO interfaces on RISC-V arch
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-26-ajones@ventanamicro.com>

From: Tomasz Jeznach <tjeznach at rivosinc.com>

Enable KVM/VFIO support on RISC-V architecture.

Signed-off-by: Tomasz Jeznach <tjeznach at rivosinc.com>
Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/kvm/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig
index 0c3cbb0915ff..333d95da8ebe 100644
--- a/arch/riscv/kvm/Kconfig
+++ b/arch/riscv/kvm/Kconfig
@@ -29,10 +29,12 @@ config KVM
 	select KVM_GENERIC_DIRTYLOG_READ_PROTECT
 	select KVM_GENERIC_HARDWARE_ENABLING
 	select KVM_MMIO
+	select KVM_VFIO
 	select KVM_XFER_TO_GUEST_WORK
 	select KVM_GENERIC_MMU_NOTIFIER
 	select SCHED_INFO
 	select GUEST_PERF_EVENTS if PERF_EVENTS
+	select SRCU
 	help
 	  Support hosting virtualized guest machines.
 
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:55 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:55 +0100
Subject: [RFC PATCH 10/15] RISC-V: KVM: Add irqbypass skeleton
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-27-ajones@ventanamicro.com>

Add all the functions needed to wire up irqbypass support.
kvm_arch_update_irqfd_routing() is left unimplemented, so return
false from kvm_arch_has_irq_bypass().

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/include/asm/kvm_host.h |  3 ++
 arch/riscv/kvm/Kconfig            |  1 +
 arch/riscv/kvm/aia_imsic.c        |  6 ++++
 arch/riscv/kvm/vm.c               | 60 +++++++++++++++++++++++++++++++
 4 files changed, 70 insertions(+)

diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 35eab6e0f4ae..fef7422939f6 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -114,6 +114,9 @@ struct kvm_arch {
 
 	/* AIA Guest/VM context */
 	struct kvm_aia aia;
+
+#define __KVM_HAVE_ARCH_ASSIGNED_DEVICE
+	atomic_t assigned_device_count;
 };
 
 struct kvm_cpu_trap {
diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig
index 333d95da8ebe..9a4feb1e671d 100644
--- a/arch/riscv/kvm/Kconfig
+++ b/arch/riscv/kvm/Kconfig
@@ -21,6 +21,7 @@ config KVM
 	tristate "Kernel-based Virtual Machine (KVM) support (EXPERIMENTAL)"
 	depends on RISCV_SBI && MMU
 	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQ_BYPASS
 	select HAVE_KVM_IRQ_ROUTING
 	select HAVE_KVM_MSI
 	select HAVE_KVM_VCPU_ASYNC_IOCTL
diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c
index a8085cd8215e..64b1f3713dd5 100644
--- a/arch/riscv/kvm/aia_imsic.c
+++ b/arch/riscv/kvm/aia_imsic.c
@@ -727,6 +727,12 @@ void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu)
 	kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
 }
 
+int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
+				  uint32_t guest_irq, bool set)
+{
+	return -ENXIO;
+}
+
 int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu)
 {
 	unsigned long flags;
diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c
index 7396b8654f45..9c5837518c1a 100644
--- a/arch/riscv/kvm/vm.c
+++ b/arch/riscv/kvm/vm.c
@@ -11,6 +11,9 @@
 #include <linux/module.h>
 #include <linux/uaccess.h>
 #include <linux/kvm_host.h>
+#include <linux/kvm_irqfd.h>
+
+#include <asm/kvm_aia.h>
 
 const struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 	KVM_GENERIC_VM_STATS()
@@ -55,6 +58,63 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 	kvm_riscv_aia_destroy_vm(kvm);
 }
 
+void kvm_arch_start_assignment(struct kvm *kvm)
+{
+	atomic_inc(&kvm->arch.assigned_device_count);
+}
+EXPORT_SYMBOL_GPL(kvm_arch_start_assignment);
+
+void kvm_arch_end_assignment(struct kvm *kvm)
+{
+	atomic_dec(&kvm->arch.assigned_device_count);
+}
+EXPORT_SYMBOL_GPL(kvm_arch_end_assignment);
+
+bool noinstr kvm_arch_has_assigned_device(struct kvm *kvm)
+{
+	return arch_atomic_read(&kvm->arch.assigned_device_count);
+}
+EXPORT_SYMBOL_GPL(kvm_arch_has_assigned_device);
+
+bool kvm_arch_has_irq_bypass(void)
+{
+	return false;
+}
+
+int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
+				     struct irq_bypass_producer *prod)
+{
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(cons, struct kvm_kernel_irqfd, consumer);
+	int ret;
+
+	irqfd->producer = prod;
+	kvm_arch_start_assignment(irqfd->kvm);
+	ret = kvm_arch_update_irqfd_routing(irqfd->kvm, prod->irq, irqfd->gsi, true);
+	if (ret)
+		kvm_arch_end_assignment(irqfd->kvm);
+
+	return ret;
+}
+
+void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
+				      struct irq_bypass_producer *prod)
+{
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(cons, struct kvm_kernel_irqfd, consumer);
+	int ret;
+
+	WARN_ON(irqfd->producer != prod);
+	irqfd->producer = NULL;
+
+	ret = kvm_arch_update_irqfd_routing(irqfd->kvm, prod->irq, irqfd->gsi, false);
+	if (ret)
+		pr_info("irq bypass consumer (token %p) unregistration fails: %d\n",
+			irqfd->consumer.token, ret);
+
+	kvm_arch_end_assignment(irqfd->kvm);
+}
+
 int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irql,
 			  bool line_status)
 {
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:56 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:56 +0100
Subject: [RFC PATCH 11/15] RISC-V: Define irqbypass vcpu_info
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-28-ajones@ventanamicro.com>

The vcpu_info parameter to irq_set_vcpu_affinity() effectively
defines an arch specific IOMMU <=> hypervisor protocol. Provide
a definition for the RISCV IOMMU.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/include/asm/irq.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/riscv/include/asm/irq.h b/arch/riscv/include/asm/irq.h
index 7b038f3b7cb0..8588667cbb5f 100644
--- a/arch/riscv/include/asm/irq.h
+++ b/arch/riscv/include/asm/irq.h
@@ -23,6 +23,15 @@ void riscv_set_intc_hwnode_fn(struct fwnode_handle *(*fn)(void));
 
 struct fwnode_handle *riscv_get_intc_hwnode(void);
 
+struct riscv_iommu_vcpu_info {
+	u64 msi_addr_pattern;
+	u64 msi_addr_mask;
+	u32 group_index_bits;
+	u32 group_index_shift;
+	u64 gpa;
+	u64 hpa;
+};
+
 #ifdef CONFIG_ACPI
 
 enum riscv_irqchip_type {
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:57 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:57 +0100
Subject: [RFC PATCH 12/15] iommu/riscv: Add guest file irqbypass support
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-29-ajones@ventanamicro.com>

Implement irq_set_vcpu_affinity() in the RISCV IOMMU driver.
irq_set_vcpu_affinity() is the channel from a hypervisor to the
IOMMU needed to ensure that assigned devices which direct MSIs to
guest IMSIC addresses will have those MSI writes redirected to
their corresponding guest interrupt files.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/iommu/riscv/iommu-ir.c | 151 +++++++++++++++++++++++++++++++++
 drivers/iommu/riscv/iommu.c    |   4 +-
 drivers/iommu/riscv/iommu.h    |   3 +
 3 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/riscv/iommu-ir.c b/drivers/iommu/riscv/iommu-ir.c
index c177e064b205..958270450ec1 100644
--- a/drivers/iommu/riscv/iommu-ir.c
+++ b/drivers/iommu/riscv/iommu-ir.c
@@ -7,6 +7,8 @@
 #include <linux/irqdomain.h>
 #include <linux/msi.h>
 
+#include <asm/irq.h>
+
 #include "../iommu-pages.h"
 #include "iommu.h"
 
@@ -52,10 +54,159 @@ static size_t riscv_iommu_ir_nr_msiptes(struct riscv_iommu_domain *domain)
 	return max_idx + 1;
 }
 
+static void riscv_iommu_ir_msitbl_inval(struct riscv_iommu_domain *domain,
+					struct riscv_iommu_msipte *pte)
+{
+	struct riscv_iommu_bond *bond;
+	struct riscv_iommu_device *iommu, *prev;
+	struct riscv_iommu_command cmd;
+	u64 addr;
+
+	addr = pfn_to_phys(FIELD_GET(RISCV_IOMMU_MSIPTE_PPN, pte->pte));
+	riscv_iommu_cmd_inval_gvma(&cmd);
+	riscv_iommu_cmd_inval_set_addr(&cmd, addr);
+
+	/* Like riscv_iommu_iotlb_inval(), synchronize with riscv_iommu_bond_link() */
+	smp_mb();
+
+	rcu_read_lock();
+
+	prev = NULL;
+	list_for_each_entry_rcu(bond, &domain->bonds, list) {
+		iommu = dev_to_iommu(bond->dev);
+
+		if (iommu == prev)
+			continue;
+
+		riscv_iommu_cmd_send(iommu, &cmd);
+		riscv_iommu_cmd_sync(iommu, RISCV_IOMMU_IOTINVAL_TIMEOUT);
+		prev = iommu;
+	}
+
+	rcu_read_unlock();
+}
+
+static void riscv_iommu_ir_msitbl_update(struct riscv_iommu_domain *domain,
+					 struct riscv_iommu_msiptp_state *msiptp)
+{
+	struct riscv_iommu_bond *bond;
+	struct riscv_iommu_device *iommu, *prev;
+	struct riscv_iommu_command cmd;
+	struct iommu_fwspec *fwspec;
+	struct riscv_iommu_dc *dc;
+	int i;
+
+	/* Like riscv_iommu_ir_msitbl_inval(), synchronize with riscv_iommu_bond_link() */
+	smp_mb();
+	rcu_read_lock();
+
+	prev = NULL;
+	list_for_each_entry_rcu(bond, &domain->bonds, list) {
+		iommu = dev_to_iommu(bond->dev);
+		fwspec = dev_iommu_fwspec_get(bond->dev);
+
+		for (i = 0; i < fwspec->num_ids; i++) {
+			dc = riscv_iommu_get_dc(iommu, fwspec->ids[i]);
+			WRITE_ONCE(dc->msiptp, msiptp->msiptp);
+			WRITE_ONCE(dc->msi_addr_mask, msiptp->msi_addr_mask);
+			WRITE_ONCE(dc->msi_addr_pattern, msiptp->msi_addr_pattern);
+		}
+
+		dma_wmb();
+
+		if (iommu == prev)
+			continue;
+
+		riscv_iommu_cmd_inval_gvma(&cmd);
+		riscv_iommu_cmd_send(iommu, &cmd);
+		riscv_iommu_cmd_sync(iommu, RISCV_IOMMU_IOTINVAL_TIMEOUT);
+		prev = iommu;
+	}
+
+	rcu_read_unlock();
+}
+
+static int riscv_iommu_ir_msitbl_init(struct riscv_iommu_domain *domain,
+				      struct riscv_iommu_vcpu_info *vcpu_info)
+{
+	domain->msiptp.msi_addr_pattern = vcpu_info->msi_addr_pattern;
+	domain->msiptp.msi_addr_mask = vcpu_info->msi_addr_mask;
+	domain->group_index_bits = vcpu_info->group_index_bits;
+	domain->group_index_shift = vcpu_info->group_index_shift;
+
+	if (riscv_iommu_ir_nr_msiptes(domain) * sizeof(*domain->msi_root) > PAGE_SIZE * 2)
+		return -ENOMEM;
+
+	domain->msiptp.msiptp = virt_to_pfn(domain->msi_root) |
+				FIELD_PREP(RISCV_IOMMU_DC_MSIPTP_MODE,
+					   RISCV_IOMMU_DC_MSIPTP_MODE_FLAT);
+
+	riscv_iommu_ir_msitbl_update(domain, &domain->msiptp);
+
+	return 0;
+}
+
+static int riscv_iommu_irq_set_vcpu_affinity(struct irq_data *data, void *info)
+{
+	struct riscv_iommu_vcpu_info *vcpu_info = info;
+	struct riscv_iommu_domain *domain = data->domain->host_data;
+	struct riscv_iommu_msipte *pte;
+	int ret = -EINVAL;
+	u64 pteval;
+
+	if (WARN_ON(domain->domain.type != IOMMU_DOMAIN_UNMANAGED))
+		return ret;
+
+	spin_lock(&domain->msi_lock);
+
+	if (!domain->msiptp.msiptp) {
+		if (WARN_ON(!vcpu_info))
+			goto out_unlock;
+
+		ret = riscv_iommu_ir_msitbl_init(domain, vcpu_info);
+		if (ret)
+			goto out_unlock;
+	} else if (!vcpu_info) {
+		/*
+		 * Nothing to do here since we don't track host_irq <=> msipte mappings
+		 * nor reference count the ptes. If we did do that tracking then we would
+		 * decrement the reference count of the pte for the host_irq and possibly
+		 * clear its valid bit if it was the last one mapped.
+		 */
+		ret = 0;
+		goto out_unlock;
+	} else if (WARN_ON(vcpu_info->msi_addr_pattern != domain->msiptp.msi_addr_pattern ||
+			   vcpu_info->msi_addr_mask != domain->msiptp.msi_addr_mask ||
+			   vcpu_info->group_index_bits != domain->group_index_bits ||
+			   vcpu_info->group_index_shift != domain->group_index_shift)) {
+		goto out_unlock;
+	}
+
+	pte = riscv_iommu_ir_get_msipte(domain, vcpu_info->gpa);
+	if (!pte)
+		goto out_unlock;
+
+	pteval = FIELD_PREP(RISCV_IOMMU_MSIPTE_M, 3) |
+		 riscv_iommu_phys_to_ppn(vcpu_info->hpa) |
+		 FIELD_PREP(RISCV_IOMMU_MSIPTE_V, 1);
+
+	if (pte->pte != pteval) {
+		pte->pte = pteval;
+		riscv_iommu_ir_msitbl_inval(domain, pte);
+	}
+
+	ret = 0;
+
+out_unlock:
+	spin_unlock(&domain->msi_lock);
+	return ret;
+}
+
 static struct irq_chip riscv_iommu_irq_chip = {
 	.name			= "IOMMU-IR",
 	.irq_mask		= irq_chip_mask_parent,
 	.irq_unmask		= irq_chip_unmask_parent,
+	.irq_set_vcpu_affinity	= riscv_iommu_irq_set_vcpu_affinity,
 };
 
 static int riscv_iommu_irq_domain_alloc_irqs(struct irq_domain *irqdomain,
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index c4a47b21c58f..46ac228ba7ac 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -544,8 +544,8 @@ static irqreturn_t riscv_iommu_fltq_process(int irq, void *data)
 }
 
 /* Lookup and initialize device context info structure. */
-static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iommu,
-						 unsigned int devid)
+struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iommu,
+					  unsigned int devid)
 {
 	const bool base_format = !(iommu->caps & RISCV_IOMMU_CAPABILITIES_MSI_FLAT);
 	unsigned int depth;
diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h
index 6ce71095781c..2ca76edf48f5 100644
--- a/drivers/iommu/riscv/iommu.h
+++ b/drivers/iommu/riscv/iommu.h
@@ -127,6 +127,9 @@ struct riscv_iommu_bond {
 int riscv_iommu_init(struct riscv_iommu_device *iommu);
 void riscv_iommu_remove(struct riscv_iommu_device *iommu);
 
+struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iommu,
+					  unsigned int devid);
+
 void riscv_iommu_cmd_send(struct riscv_iommu_device *iommu,
 			  struct riscv_iommu_command *cmd);
 void riscv_iommu_cmd_sync(struct riscv_iommu_device *iommu,
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:58 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:58 +0100
Subject: [RFC PATCH 13/15] RISC-V: KVM: Add guest file irqbypass support
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-30-ajones@ventanamicro.com>

Implement kvm_arch_update_irqfd_routing() which makes
irq_set_vcpu_affinity() calls whenever the assigned device updates
its target addresses and whenever the hypervisor has migrated a
VCPU to another CPU (which requires changing the guest interrupt
file).

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/kvm/aia_imsic.c | 132 ++++++++++++++++++++++++++++++++++++-
 arch/riscv/kvm/vm.c        |   2 +-
 2 files changed, 130 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c
index 64b1f3713dd5..6a7c23e25f79 100644
--- a/arch/riscv/kvm/aia_imsic.c
+++ b/arch/riscv/kvm/aia_imsic.c
@@ -11,11 +11,13 @@
 #include <linux/bitmap.h>
 #include <linux/irqchip/riscv-imsic.h>
 #include <linux/kvm_host.h>
+#include <linux/kvm_irqfd.h>
 #include <linux/math.h>
 #include <linux/spinlock.h>
 #include <linux/swab.h>
 #include <kvm/iodev.h>
 #include <asm/csr.h>
+#include <asm/irq.h>
 
 #define IMSIC_MAX_EIX	(IMSIC_MAX_ID / BITS_PER_TYPE(u64))
 
@@ -676,6 +678,14 @@ static void imsic_swfile_update(struct kvm_vcpu *vcpu,
 	imsic_swfile_extirq_update(vcpu);
 }
 
+static u64 kvm_riscv_aia_msi_addr_mask(struct kvm_aia *aia)
+{
+	u64 group_mask = BIT(aia->nr_group_bits) - 1;
+
+	return (group_mask << (aia->nr_group_shift - IMSIC_MMIO_PAGE_SHIFT)) |
+	       (BIT(aia->nr_hart_bits + aia->nr_guest_bits) - 1);
+}
+
 void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu)
 {
 	unsigned long flags;
@@ -730,7 +740,120 @@ void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu)
 int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,
 				  uint32_t guest_irq, bool set)
 {
-	return -ENXIO;
+	struct irq_data *irqdata = irq_get_irq_data(host_irq);
+	struct kvm_irq_routing_table *irq_rt;
+	struct kvm_vcpu *vcpu;
+	unsigned long tmp, flags;
+	int idx, ret = -ENXIO;
+
+	if (!set)
+		return irq_set_vcpu_affinity(host_irq, NULL);
+
+	idx = srcu_read_lock(&kvm->irq_srcu);
+	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
+	if (guest_irq >= irq_rt->nr_rt_entries ||
+	    hlist_empty(&irq_rt->map[guest_irq])) {
+		pr_warn_once("no route for guest_irq %u/%u (broken user space?)\n",
+			     guest_irq, irq_rt->nr_rt_entries);
+		goto out;
+	}
+
+	kvm_for_each_vcpu(tmp, vcpu, kvm) {
+		struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
+		gpa_t ippn = vcpu->arch.aia_context.imsic_addr >> IMSIC_MMIO_PAGE_SHIFT;
+		struct kvm_aia *aia = &kvm->arch.aia;
+		struct kvm_kernel_irq_routing_entry *e;
+
+		hlist_for_each_entry(e, &irq_rt->map[guest_irq], link) {
+			struct msi_msg msg[2] = {
+			{
+				.address_hi = e->msi.address_hi,
+				.address_lo = e->msi.address_lo,
+				.data = e->msi.data,
+			},
+			};
+			struct riscv_iommu_vcpu_info vcpu_info = {
+				.msi_addr_mask = kvm_riscv_aia_msi_addr_mask(aia),
+				.group_index_bits = aia->nr_group_bits,
+				.group_index_shift = aia->nr_group_shift,
+			};
+			gpa_t target, tppn;
+
+			if (e->type != KVM_IRQ_ROUTING_MSI)
+				continue;
+
+			target = ((gpa_t)e->msi.address_hi << 32) | e->msi.address_lo;
+			tppn = target >> IMSIC_MMIO_PAGE_SHIFT;
+
+			WARN_ON(target & (IMSIC_MMIO_PAGE_SZ - 1));
+
+			if (ippn != tppn)
+				continue;
+
+			vcpu_info.msi_addr_pattern = tppn & ~vcpu_info.msi_addr_mask;
+			vcpu_info.gpa = target;
+
+			read_lock_irqsave(&imsic->vsfile_lock, flags);
+
+			if (WARN_ON_ONCE(imsic->vsfile_cpu < 0)) {
+				read_unlock_irqrestore(&imsic->vsfile_lock, flags);
+				goto out;
+			}
+
+			vcpu_info.hpa = imsic->vsfile_pa;
+
+			ret = irq_set_vcpu_affinity(host_irq, &vcpu_info);
+			if (ret) {
+				read_unlock_irqrestore(&imsic->vsfile_lock, flags);
+				goto out;
+			}
+
+			irq_data_get_irq_chip(irqdata)->irq_write_msi_msg(irqdata, msg);
+
+			read_unlock_irqrestore(&imsic->vsfile_lock, flags);
+		}
+	}
+
+	ret = 0;
+out:
+	srcu_read_unlock(&kvm->irq_srcu, idx);
+	return ret;
+}
+
+static int kvm_riscv_vcpu_irq_update(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
+	struct kvm_aia *aia = &kvm->arch.aia;
+	u64 mask = kvm_riscv_aia_msi_addr_mask(aia);
+	u64 target = vcpu->arch.aia_context.imsic_addr;
+	struct riscv_iommu_vcpu_info vcpu_info = {
+		.msi_addr_pattern = (target >> IMSIC_MMIO_PAGE_SHIFT) & ~mask,
+		.msi_addr_mask = mask,
+		.group_index_bits = aia->nr_group_bits,
+		.group_index_shift = aia->nr_group_shift,
+		.gpa = target,
+		.hpa = imsic->vsfile_pa,
+	};
+	struct kvm_kernel_irqfd *irqfd;
+	int host_irq, ret;
+
+	spin_lock_irq(&kvm->irqfds.lock);
+
+	list_for_each_entry(irqfd, &kvm->irqfds.items, list) {
+		if (!irqfd->producer)
+			continue;
+		host_irq = irqfd->producer->irq;
+		ret = irq_set_vcpu_affinity(host_irq, &vcpu_info);
+		if (ret) {
+			spin_unlock_irq(&kvm->irqfds.lock);
+			return ret;
+		}
+	}
+
+	spin_unlock_irq(&kvm->irqfds.lock);
+
+	return 0;
 }
 
 int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu)
@@ -797,14 +920,17 @@ int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu)
 	if (ret)
 		goto fail_free_vsfile_hgei;
 
-	/* TODO: Update the IOMMU mapping ??? */
-
 	/* Update new IMSIC VS-file details in IMSIC context */
 	write_lock_irqsave(&imsic->vsfile_lock, flags);
+
 	imsic->vsfile_hgei = new_vsfile_hgei;
 	imsic->vsfile_cpu = vcpu->cpu;
 	imsic->vsfile_va = new_vsfile_va;
 	imsic->vsfile_pa = new_vsfile_pa;
+
+	/* Update the IOMMU mapping */
+	kvm_riscv_vcpu_irq_update(vcpu);
+
 	write_unlock_irqrestore(&imsic->vsfile_lock, flags);
 
 	/*
diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c
index 9c5837518c1a..5f697d9a37da 100644
--- a/arch/riscv/kvm/vm.c
+++ b/arch/riscv/kvm/vm.c
@@ -78,7 +78,7 @@ EXPORT_SYMBOL_GPL(kvm_arch_has_assigned_device);
 
 bool kvm_arch_has_irq_bypass(void)
 {
-	return false;
+	return true;
 }
 
 int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:18:59 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:18:59 +0100
Subject: [RFC PATCH 14/15] vfio: enable IOMMU_TYPE1 for RISC-V
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-31-ajones@ventanamicro.com>

From: Tomasz Jeznach <tjeznach at rivosinc.com>

Enable VFIO support on RISC-V architecture.

Signed-off-by: Tomasz Jeznach <tjeznach at rivosinc.com>
Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 drivers/vfio/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index ceae52fd7586..ad62205b4e45 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -39,7 +39,7 @@ config VFIO_GROUP
 
 config VFIO_CONTAINER
 	bool "Support for the VFIO container /dev/vfio/vfio"
-	select VFIO_IOMMU_TYPE1 if MMU && (X86 || S390 || ARM || ARM64)
+	select VFIO_IOMMU_TYPE1 if MMU && (X86 || S390 || ARM || ARM64 || RISCV)
 	depends on VFIO_GROUP
 	default y
 	help
-- 
2.47.0



From ajones at ventanamicro.com  Thu Nov 14 08:19:00 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 14 Nov 2024 17:19:00 +0100
Subject: [RFC PATCH 15/15] RISC-V: defconfig: Add VFIO modules
In-Reply-To: <20241114161845.502027-17-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
Message-ID: <20241114161845.502027-32-ajones@ventanamicro.com>

Add the VFIO modules to the defconfig to complement KVM now
that there is IOMMU support.

Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
---
 arch/riscv/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index b4a37345703e..10fc9d84a28c 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -242,6 +242,8 @@ CONFIG_RTC_DRV_SUN6I=y
 CONFIG_DMADEVICES=y
 CONFIG_DMA_SUN6I=m
 CONFIG_DW_AXI_DMAC=y
+CONFIG_VFIO=m
+CONFIG_VFIO_PCI=m
 CONFIG_VIRTIO_PCI=y
 CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_INPUT=y
-- 
2.47.0



From irogers at google.com  Thu Nov 14 10:31:04 2024
From: irogers at google.com (Ian Rogers)
Date: Thu, 14 Nov 2024 10:31:04 -0800
Subject: [PATCH v2 0/8] Refactor cpuid and metric table lookup code
In-Reply-To: <20241108025535.wfhke3btch5af4fu@hippo>
References: <20241107162035.52206-1-irogers@google.com> <20241108025535.wfhke3btch5af4fu@hippo>
Message-ID: <CAP-5=fW=RXz-A=xndhs8wkXaKCz-qXB=PemAMvbZpUagvObUoA@mail.gmail.com>

On Thu, Nov 7, 2024 at 6:57?PM Xu Yang <xu.yang_2 at nxp.com> wrote:
>
> On Thu, Nov 07, 2024 at 08:20:27AM -0800, Ian Rogers wrote:
> > Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
> > lookup:
> > https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
> > These patches remove a lot of the logic relating CPUIDs to PMUs so
> > that the PMU isn't part of the question when finding a metric table.
> > For time reasons, it doesn't go as far as allowing system metrics
> > without a metric table as a metric table is needed for metrics to
> > refer to other metrics, and the refactoring of that resolution is a
> > hassle.
>
> For this patchset:
> Tested-by: Xu Yang <xu.yang_2 at nxp.com>

Ping. Would be nice for this to land given the ARM fix and general cleanup.

Thanks,
Ian


From samuel.holland at sifive.com  Thu Nov 14 12:01:30 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Thu, 14 Nov 2024 12:01:30 -0800
Subject: [PATCH] irqchip/riscv-aplic: Fix crash when MSI domain is missing
Message-ID: <20241114200133.3069460-1-samuel.holland@sifive.com>

If the APLIC driver is probed before the IMSIC driver, the parent MSI
domain will be missing, which causes a NULL pointer dereference in
msi_create_device_irq_domain(). Avoid this by deferring probe until the
parent MSI domain is available. Use dev_err_probe() to avoid printing an
error message when returning -EPROBE_DEFER.

Fixes: ca8df97fe679 ("irqchip/riscv-aplic: Add support for MSI-mode")
Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

 drivers/irqchip/irq-riscv-aplic-main.c | 3 ++-
 drivers/irqchip/irq-riscv-aplic-msi.c  | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
index 900e72541db9..93e7c51f944a 100644
--- a/drivers/irqchip/irq-riscv-aplic-main.c
+++ b/drivers/irqchip/irq-riscv-aplic-main.c
@@ -207,7 +207,8 @@ static int aplic_probe(struct platform_device *pdev)
 	else
 		rc = aplic_direct_setup(dev, regs);
 	if (rc)
-		dev_err(dev, "failed to setup APLIC in %s mode\n", msi_mode ? "MSI" : "direct");
+		dev_err_probe(dev, rc, "failed to setup APLIC in %s mode\n",
+			      msi_mode ? "MSI" : "direct");
 
 #ifdef CONFIG_ACPI
 	if (!acpi_disabled)
diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
index 945bff28265c..fb8d1838609f 100644
--- a/drivers/irqchip/irq-riscv-aplic-msi.c
+++ b/drivers/irqchip/irq-riscv-aplic-msi.c
@@ -266,6 +266,9 @@ int aplic_msi_setup(struct device *dev, void __iomem *regs)
 			if (msi_domain)
 				dev_set_msi_domain(dev, msi_domain);
 		}
+
+		if (!dev_get_msi_domain(dev))
+			return -EPROBE_DEFER;
 	}
 
 	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
-- 
2.45.1



From e at freeshell.de  Thu Nov 14 12:13:40 2024
From: e at freeshell.de (E Shattow)
Date: Thu, 14 Nov 2024 12:13:40 -0800
Subject: [PATCH] riscv: dts: starfive: jh7110-milkv-mars: set host mode and vbus pin for on-chip USB 2.0
Message-ID: <20241114201805.24143-2-e@freeshell.de>

Enable host mode USB for Milk-V Mars by setting host mode and connect vbus 
pinctrl.

Note that testing this functionality depends on two features:

1.  commit e10c52e7e064038d9bd67b20bf4ce92077d7d84e "phy: starfive: 
jh7110-usb: Fix link configuration to controller"

2. Setting the USB over-current register to disable. This is done at 
bootloader phase, for example U-Boot: 
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no 
change in functional outcome with this patch applied; there is an error 
visible to the user and usb configuration fails (same as it is now).

Signed-off-by: E Shattow <e at freeshell.de>
---
 .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
index 0d248b671d4b..bddfc7c6b00f 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -53,7 +53,23 @@ &spi0 {
 	status = "okay";
 };
 
+&sysgpio {
+	usb_pins: usb0-0 {
+		driver-vbus-pin {
+			pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS,
+					      GPOEN_ENABLE,
+					      GPI_NONE)>;
+			bias-disable;
+			input-disable;
+			input-schmitt-disable;
+			slew-rate = <0>;
+		};
+	};
+};
+
 &usb0 {
-	dr_mode = "peripheral";
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb_pins>;
 	status = "okay";
 };
-- 
2.45.2



From yikming2222 at gmail.com  Thu Nov 14 13:27:25 2024
From: yikming2222 at gmail.com (Chin Yik Ming)
Date: Fri, 15 Nov 2024 05:27:25 +0800
Subject: [PATCH] riscv: Fix a comment typo in set_mm_asid()
Message-ID: <20241114212725.4172401-1-yikming2222@gmail.com>

s/verion/version

Signed-off-by: Chin Yik Ming <yikming2222 at gmail.com>
---
 arch/riscv/mm/context.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
index 4abe3de23225..55c20ad1f744 100644
--- a/arch/riscv/mm/context.c
+++ b/arch/riscv/mm/context.c
@@ -158,7 +158,7 @@ static void set_mm_asid(struct mm_struct *mm, unsigned int cpu)
 	 *
 	 * - We get a zero back from the cmpxchg and end up waiting on the
 	 *   lock. Taking the lock synchronises with the rollover and so
-	 *   we are forced to see the updated verion.
+	 *   we are forced to see the updated version.
 	 *
 	 * - We get a valid context back from the cmpxchg then we continue
 	 *   using old ASID because __flush_context() would have marked ASID
-- 
2.34.1



From charlie at rivosinc.com  Thu Nov 14 14:08:47 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Thu, 14 Nov 2024 14:08:47 -0800
Subject: [PATCH] riscv: Fix a comment typo in set_mm_asid()
In-Reply-To: <20241114212725.4172401-1-yikming2222@gmail.com>
References: <20241114212725.4172401-1-yikming2222@gmail.com>
Message-ID: <ZzZ072CMku0fsW2x@ghost>

On Fri, Nov 15, 2024 at 05:27:25AM +0800, Chin Yik Ming wrote:
> s/verion/version
> 
> Signed-off-by: Chin Yik Ming <yikming2222 at gmail.com>
> ---
>  arch/riscv/mm/context.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
> index 4abe3de23225..55c20ad1f744 100644
> --- a/arch/riscv/mm/context.c
> +++ b/arch/riscv/mm/context.c
> @@ -158,7 +158,7 @@ static void set_mm_asid(struct mm_struct *mm, unsigned int cpu)
>  	 *
>  	 * - We get a zero back from the cmpxchg and end up waiting on the
>  	 *   lock. Taking the lock synchronises with the rollover and so
> -	 *   we are forced to see the updated verion.
> +	 *   we are forced to see the updated version.
>  	 *
>  	 * - We get a valid context back from the cmpxchg then we continue
>  	 *   using old ASID because __flush_context() would have marked ASID
> -- 
> 2.34.1
> 

Thanks,

Reviewed-by: Charlie Jenkins <charlie at rivosinc.com>



From sboyd at kernel.org  Thu Nov 14 17:29:54 2024
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 14 Nov 2024 17:29:54 -0800
Subject: [PATCH v1 08/11] clk: move meson clk-regmap implementation to common code
In-Reply-To: <20241106-freefall-slider-db379b05821e@spud>
References: <20241002-private-unequal-33cfa6101338@spud> <20241002-hula-unwashed-1c4ddbadbec2@spud> <2b49c4df-a34a-42c5-8d44-9e47da630fe8@linaro.org> <1jwmiqsks3.fsf@starbuckisacylon.baylibre.com> <20241003-tacking-ladylike-dfe2b633e647@spud> <20241106-freefall-slider-db379b05821e@spud>
Message-ID: <430bde3b35382e640843e32a9f351326.sboyd@kernel.org>

Quoting Conor Dooley (2024-11-06 04:56:25)
> On Thu, Oct 03, 2024 at 12:33:40PM +0100, Conor Dooley wrote:
> > > IIRC, Stephen's idea was more the bring regmap support in clk-gate.c,
> > > clk-mux, etc ... I'm not quite sure how make iomem and regmap co-exist
> > > in a manageable/maintainable way within those drivers (without adding yet
> > > another level of abstraction I mean) ? Silently creating a regmap maybe
> > > ? but that's probably a bit heavy. I did not really had time to dig more
> > > on this, I guess no one did.
> > 
> > I guess I have some motivation to looking into it at the moment. I had
> > my reservations about the Meson approach too, liking it more than
> > Qualcomm's didn't mean I completely liked it.
> > It was already my intention to implement point b of your mail, had the
> > general idea here been acceptable, cos that's a divergence from how the
> > generic clock types (that the driver in question currently uses) work.
> > And on that note, I just noticed I left the mild-annoyance variable name
> > "sigh" in the submitted driver changes, which I had used for the
> > clk_regmap struct that your point b in the link relates to.
> > 
> > > I don't really have a preference one way or the other but if it is going
> > > to be exposed in 'include/linux', we need to be sure that's how we want
> > > to do it. With clocks poping in many driver subsystems, it will
> > > difficult to change afterward. 
> > 
> > Yeah, I agree. I didn't expect this to go in right away, and I also
> > didn't want to surge ahead on some rework of the clock types, were
> > people to hate even the reuse.
> 
> Hmm, so how (in-)complete of a regmap implementation can I get away
> with? I only need clk-gate and clk-divider for this patchset...
> 
> Shoving the regmap into the clk structs makes things pretty trivial as I
> don't need to do anything special in any function other than
> clk_*_readl()/clk_*_writel() and the registration code. A flag isn't
> even needed to determine if a clock is a regmap one I don't think, since
> you can just check if the regmap pointer is non-NULL.

For the basic clk types I think it would be good to leave the old stuff
alone. We have already split the logic out into helpers, so I wonder if
we can do this better by making kernel modules for the different basic
regmap clk types and exposing registration APIs. If we force drivers
that use the basic regmap types to 'select' the module then we'll make
it so that we don't include code that isn't used anywhere. That's one of
the problems with the basic clk types, it's always built. It also lets
us avoid making regmap a dependency for the clk framework at large.

Doing that would also let us avoid the flag because it will be explicit
in any registration API, clk_register_divider() vs.
clk_register_regmap_divider(). Yes we duplicate some boiler plate logic
around read-only and registration paths, but this is alright as long as
we can share most of the code and gain the advantage of removing the
code entirely when it isn't used.

I wonder if we can even make a regmap on the fly for the iomem pointers
so that clk_divider_readl() can always use the regmap API to access the
hardware. Sounds wasteful but maybe it would work.

> My use case doesn't
> actually need the registration code changes either as, currently, only reg
> gets set at runtime, but leaving that out is a level of incomplete I'd not
> let myself away with.
> Obviously shoving the extra members into the clk structs has the downside
> of taking up a pointer and a offset worth of memory for each clock of
> that type registered, but it is substantially easier to support devices
> with multiple regmaps that way. Probably moot though since the approach you
> suggested in the thread linked above that implements a clk_hw_get_regmap()
> has to store a pointer to the regmap's identifier which would take up an
> identical amount of memory.

We don't need to store the regmap identifier in the struct clk. We can
store it in the 'struct clk_init_data' with some new field, and only do
that when/if we actually need to. We would need to pass the init data to
the clk_ops::init() callback though. We currently knock that out during
registration so that clk_hw->init is NULL. Probably we can just set that
to NULL after the init routine runs in __clk_core_init().

Long story short, don't add something to 'struct clk_core', 'struct
clk', or 'struct clk_hw' for these details. We can have a 'struct
clk_regmap_hw' that everyone else can build upon:

  struct clk_regmap_hw {
        struct regmap *regmap;
        struct clk_hw hw;
  };

and then set the regmap pointer during registration in
clk_hw_init_regmap().

int clk_hw_init_regmap(struct clk_hw *hw)
{
	struct device *dev;
	struct regmap *regmap;
	struct clk_regmap_hw *rhw;

	rhw = clk_hw_to_clk_regmap_hw(hw);

	dev = clk_hw_get_dev(hw);
	if (!dev)
		return -EINVAL;

	regmap = dev_get_regmap(dev, hw->init->regmap_name);
	if (!regmap)
		return -EINVAL; // Print helpful message
	rhw->regmap = regmap;

	return 0;
}

or we can even make it so that there's clk_hw_init_regmap() and
clk_hw_init_regmap_name() so that drivers can have multiple functions if
the clks need different regmaps.

int my_init_regmap(struct clk_hw *hw)
{
	int ret;

	ret = clk_hw_init_regmap_name(hw, "my_name");
	...
}

If you don't need the multiple regmap support then it's fine to punt
here until later.

> 
> I don't really care which way you want it done, both are pretty easy to
> implement if I can get away with just doing so for the two standard
> clock types that I am using - is it okay to just do those two?
> 

Of course, doing only what is minimally required is better than changing
everything if you're not sure the approach is going to land.


From nick.hu at sifive.com  Thu Nov 14 19:19:39 2024
From: nick.hu at sifive.com (Nick Hu)
Date: Fri, 15 Nov 2024 11:19:39 +0800
Subject: [PATCH v8 24/29] riscv: enable kernel access to shadow stack
 memory via FWFT sbi call
In-Reply-To: <ZzYcVW/4M0jab1T4@debug.ba.rivosinc.com>
References: <20241111-v5_user_cfi_series-v8-0-dce14aa30207@rivosinc.com>
 <20241111-v5_user_cfi_series-v8-24-dce14aa30207@rivosinc.com>
 <CAKddAkCCVjNHUinPWtOiK8Ki_ZkdoUCawfv1-+0B69J_1aJv5Q@mail.gmail.com>
 <ZzVNKvCu4MOs7O5z@debug.ba.rivosinc.com> <CAKddAkDbGYeONaksq6fzLzx47BHZo3Ar7Sog3MOgf7Y+Birovw@mail.gmail.com>
 <ZzVRbCZP9N4Os8Bj@debug.ba.rivosinc.com> <CAKddAkBCByf570PXfz798FtBbeGQWe2LJpdzxkE+jv3Zd3ZV1w@mail.gmail.com>
 <ZzYcVW/4M0jab1T4@debug.ba.rivosinc.com>
Message-ID: <CAKddAkA7X7WeT8Fn6BdEij8sfHvd9cAJWf+8vJAQ95jn70F1Ug@mail.gmail.com>

Hi Deepak

On Thu, Nov 14, 2024 at 11:50?PM Deepak Gupta <debug at rivosinc.com> wrote:
>
>
> Hi Nick,
>
> Thanks for reviewing and helping.
>
> On Thu, Nov 14, 2024 at 02:17:30PM +0800, Nick Hu wrote:
> >Hi Deepak
> >
> >On Thu, Nov 14, 2024 at 9:25?AM Deepak Gupta <debug at rivosinc.com> wrote:
> >>
> >> On Thu, Nov 14, 2024 at 09:20:14AM +0800, Nick Hu wrote:
> >> >Hi Deepak
> >> >
> >> >On Thu, Nov 14, 2024 at 9:06?AM Deepak Gupta <debug at rivosinc.com> wrote:
> >> >> >> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> >> >> >> index 356d5397b2a2..6244408ca917 100644
> >> >> >> --- a/arch/riscv/kernel/head.S
> >> >> >> +++ b/arch/riscv/kernel/head.S
> >> >> >> @@ -164,6 +164,12 @@ secondary_start_sbi:
> >> >> >>         call relocate_enable_mmu
> >> >> >>  #endif
> >> >> >>         call .Lsetup_trap_vector
> >> >> >> +       li a7, SBI_EXT_FWFT
> >> >> >> +       li a6, SBI_EXT_FWFT_SET
> >> >> >> +       li a0, SBI_FWFT_SHADOW_STACK
> >> >> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
> >> >> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
> >> >> >> +       ecall
> >> >> >>         scs_load_current
> >> >> >>         call smp_callin
> >> >> >>  #endif /* CONFIG_SMP */
> >> >> >> @@ -320,6 +326,12 @@ SYM_CODE_START(_start_kernel)
> >> >> >>         la tp, init_task
> >> >> >>         la sp, init_thread_union + THREAD_SIZE
> >> >> >>         addi sp, sp, -PT_SIZE_ON_STACK
> >> >> >> +       li a7, SBI_EXT_FWFT
> >> >> >> +       li a6, SBI_EXT_FWFT_SET
> >> >> >> +       li a0, SBI_FWFT_SHADOW_STACK
> >> >> >> +       li a1, 1 /* enable supervisor to access shadow stack access */
> >> >> >> +       li a2, SBI_FWFT_SET_FLAG_LOCK
> >> >> >> +       ecall
> >> >> >>         scs_load_current
> >> >> >>
> >> >> >>  #ifdef CONFIG_KASAN
> >> >> >>
> >> >> >> --
> >> >> >> 2.45.0
> >> >> >>
> >> >> >Should we clear the SBI_FWFT_SET_FLAG_LOCK before the cpu hotplug
> >> >> >otherwise the menvcfg.sse won't be set by the fwft set sbi call when
> >> >> >the hotplug cpu back to kernel?
> >> >>
> >> >> Hmm...
> >> >>
> >> >> An incoming hotplug CPU has no features setup on it.
> >> >> I see that `sbi_cpu_start` will supply `secondary_start_sbi` as start
> >> >> up code for incoming CPU. `secondary_start_sbi` is in head.S which converges
> >> >> in `.Lsecondary_start_common`. And thus hotplugged CPU should be
> >> >> issuing shadow stack set FWFT sbi as well.
> >> >>
> >> >> Am I missing something ?
> >> >>
> >> >This is the correct flow. However the opensbi will deny it due to the
> >> >SBI_FWFT_SET_FLAG_LOCK already being set.
> >> >So the menvcfg.sse will not set by this flow.
> >> >
> >> >if (conf->flags & SBI_FWFT_SET_FLAG_LOCK)
> >> >                return SBI_EDENIED;
> >> >
> >>
> >> hmm... Why?
> >>
> >> `conf` is pointing to per-hart state in firmware.
> >>
> >> On this incoming cpu, opensbi (or equivalent) firmware must have
> >> ensured that this per-hart state doesn't have lock set.
> >>
> >> Am I missing something?
> >>
> >Current OpenSBI doesn't clear the lock in the warm init of the hotplug path.
> >It seems like we need a patch to address it.
>
> Got it thanks.
> Since you already know what's the problem, can you send a patch to opensbi.
> If you want rather have me do it, let me know. Thanks.
>
No problem. I'll send a patch to opensbi.

Regards,
Nick
> >
> >Regards,
> >Nick
> >> >Regards,
> >> >Nick
> >> >> >
> >> >> >Regards,
> >> >> >Nick
> >> >> >>
> >> >> >> _______________________________________________
> >> >> >> linux-riscv mailing list
> >> >> >> linux-riscv at lists.infradead.org
> >> >> >> http://lists.infradead.org/mailman/listinfo/linux-riscv


From prabhakar.mahadev-lad.rj at bp.renesas.com  Fri Nov 15 03:13:45 2024
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Prabhakar)
Date: Fri, 15 Nov 2024 11:13:45 +0000
Subject: [PATCH] riscv: perf: Drop defining `perf_instruction_pointer()` and `perf_misc_flags()`
Message-ID: <20241115111345.17750-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

With commit 2c47e7a74f44 ("perf/core: Correct perf sampling with guest
VMs"), the perf core now handles the functionality previously requiring
arch-specific definitions of `perf_instruction_pointer()` and
`perf_misc_flags()`. As these definitions are no longer necessary for
RISC-V, this patch removes their implementation and declarations.

This cleanup aligns the RISC-V architecture with the updated perf core
mechanism, reducing code redundancy and improving maintainability.

Fixes: 2c47e7a74f44 ("perf/core: Correct perf sampling with guest VMs")
Reported-by: Chris Paterson <Chris.Paterson2 at renesas.com>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
 arch/riscv/include/asm/perf_event.h |  3 ---
 arch/riscv/kernel/perf_callchain.c  | 28 ----------------------------
 2 files changed, 31 deletions(-)

diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h
index 38926b4a902d..bcc928fd3785 100644
--- a/arch/riscv/include/asm/perf_event.h
+++ b/arch/riscv/include/asm/perf_event.h
@@ -10,9 +10,6 @@
 
 #ifdef CONFIG_PERF_EVENTS
 #include <linux/perf_event.h>
-extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
-extern unsigned long perf_misc_flags(struct pt_regs *regs);
-#define perf_misc_flags(regs) perf_misc_flags(regs)
 #define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs
 
 #define perf_arch_fetch_caller_regs(regs, __ip) { \
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
index c2c81a80f816..b465bc9eb870 100644
--- a/arch/riscv/kernel/perf_callchain.c
+++ b/arch/riscv/kernel/perf_callchain.c
@@ -46,31 +46,3 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 
 	walk_stackframe(NULL, regs, fill_callchain, entry);
 }
-
-unsigned long perf_instruction_pointer(struct pt_regs *regs)
-{
-	if (perf_guest_state())
-		return perf_guest_get_ip();
-
-	return instruction_pointer(regs);
-}
-
-unsigned long perf_misc_flags(struct pt_regs *regs)
-{
-	unsigned int guest_state = perf_guest_state();
-	unsigned long misc = 0;
-
-	if (guest_state) {
-		if (guest_state & PERF_GUEST_USER)
-			misc |= PERF_RECORD_MISC_GUEST_USER;
-		else
-			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
-	} else {
-		if (user_mode(regs))
-			misc |= PERF_RECORD_MISC_USER;
-		else
-			misc |= PERF_RECORD_MISC_KERNEL;
-	}
-
-	return misc;
-}
-- 
2.25.1



From ajones at ventanamicro.com  Fri Nov 15 04:11:18 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Fri, 15 Nov 2024 13:11:18 +0100
Subject: [PATCH] riscv: perf: Drop defining `perf_instruction_pointer()`
 and `perf_misc_flags()`
In-Reply-To: <20241115111345.17750-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20241115111345.17750-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20241115-829a0b75f783dad6dac037a5@orel>

On Fri, Nov 15, 2024 at 11:13:45AM +0000, Prabhakar wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> With commit 2c47e7a74f44 ("perf/core: Correct perf sampling with guest
> VMs"), the perf core now handles the functionality previously requiring
> arch-specific definitions of `perf_instruction_pointer()` and
> `perf_misc_flags()`. As these definitions are no longer necessary for
> RISC-V, this patch removes their implementation and declarations.
> 
> This cleanup aligns the RISC-V architecture with the updated perf core
> mechanism, reducing code redundancy and improving maintainability.
> 
> Fixes: 2c47e7a74f44 ("perf/core: Correct perf sampling with guest VMs")
> Reported-by: Chris Paterson <Chris.Paterson2 at renesas.com>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
>  arch/riscv/include/asm/perf_event.h |  3 ---
>  arch/riscv/kernel/perf_callchain.c  | 28 ----------------------------
>  2 files changed, 31 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h
> index 38926b4a902d..bcc928fd3785 100644
> --- a/arch/riscv/include/asm/perf_event.h
> +++ b/arch/riscv/include/asm/perf_event.h
> @@ -10,9 +10,6 @@
>  
>  #ifdef CONFIG_PERF_EVENTS
>  #include <linux/perf_event.h>
> -extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
> -extern unsigned long perf_misc_flags(struct pt_regs *regs);
> -#define perf_misc_flags(regs) perf_misc_flags(regs)
>  #define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs
>  
>  #define perf_arch_fetch_caller_regs(regs, __ip) { \
> diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
> index c2c81a80f816..b465bc9eb870 100644
> --- a/arch/riscv/kernel/perf_callchain.c
> +++ b/arch/riscv/kernel/perf_callchain.c
> @@ -46,31 +46,3 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
>  
>  	walk_stackframe(NULL, regs, fill_callchain, entry);
>  }
> -
> -unsigned long perf_instruction_pointer(struct pt_regs *regs)
> -{
> -	if (perf_guest_state())
> -		return perf_guest_get_ip();
> -
> -	return instruction_pointer(regs);
> -}
> -
> -unsigned long perf_misc_flags(struct pt_regs *regs)
> -{
> -	unsigned int guest_state = perf_guest_state();
> -	unsigned long misc = 0;
> -
> -	if (guest_state) {
> -		if (guest_state & PERF_GUEST_USER)
> -			misc |= PERF_RECORD_MISC_GUEST_USER;
> -		else
> -			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
> -	} else {
> -		if (user_mode(regs))
> -			misc |= PERF_RECORD_MISC_USER;
> -		else
> -			misc |= PERF_RECORD_MISC_KERNEL;
> -	}
> -
> -	return misc;
> -}
> -- 
> 2.25.1
>

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>


From ajones at ventanamicro.com  Fri Nov 15 05:05:32 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Fri, 15 Nov 2024 14:05:32 +0100
Subject: [PATCH 08/11] riscv: alternative: Add an ALTERNATIVE_3 macro
In-Reply-To: <20241102000843.1301099-9-samuel.holland@sifive.com>
References: <20241102000843.1301099-1-samuel.holland@sifive.com>
 <20241102000843.1301099-9-samuel.holland@sifive.com>
Message-ID: <20241115-1c2467159f117132dc94db26@orel>

On Fri, Nov 01, 2024 at 05:08:02PM -0700, Samuel Holland wrote:
> ALT_FIXUP_PMA() is already using ALTERNATIVE_2(), but needs to be
> extended to handle a fourth case. Add ALTERNATIVE_3(), which extends
> ALTERNATIVE_2() with another block of new content.
> 
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
> 
>  arch/riscv/include/asm/alternative-macros.h | 45 ++++++++++++++++++---
>  1 file changed, 40 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/alternative-macros.h b/arch/riscv/include/asm/alternative-macros.h
> index 721ec275ce57..b6027a8b6b50 100644
> --- a/arch/riscv/include/asm/alternative-macros.h
> +++ b/arch/riscv/include/asm/alternative-macros.h
> @@ -50,8 +50,17 @@
>  	ALT_NEW_CONTENT \vendor_id_2, \patch_id_2, \enable_2, "\new_c_2"
>  .endm
>  
> +.macro ALTERNATIVE_CFG_3 old_c, new_c_1, vendor_id_1, patch_id_1, enable_1,	\
> +				new_c_2, vendor_id_2, patch_id_2, enable_2,	\
> +				new_c_3, vendor_id_3, patch_id_3, enable_3
> +	ALTERNATIVE_CFG_2 "\old_c", "\new_c_1", \vendor_id_1, \patch_id_1, \enable_1 \
> +				    "\new_c_2", \vendor_id_2, \patch_id_2, \enable_2 \

We don't want the '\' on the end of the above line.

> +	ALT_NEW_CONTENT \vendor_id_3, \patch_id_3, \enable_3, "\new_c_3"
> +.endm
> +
>  #define __ALTERNATIVE_CFG(...)		ALTERNATIVE_CFG __VA_ARGS__
>  #define __ALTERNATIVE_CFG_2(...)	ALTERNATIVE_CFG_2 __VA_ARGS__
> +#define __ALTERNATIVE_CFG_3(...)	ALTERNATIVE_CFG_3 __VA_ARGS__
>  
>  #else /* !__ASSEMBLY__ */
>  
> @@ -98,6 +107,13 @@
>  	__ALTERNATIVE_CFG(old_c, new_c_1, vendor_id_1, patch_id_1, enable_1)	\
>  	ALT_NEW_CONTENT(vendor_id_2, patch_id_2, enable_2, new_c_2)
>  
> +#define __ALTERNATIVE_CFG_3(old_c, new_c_1, vendor_id_1, patch_id_1, enable_1,	\
> +				   new_c_2, vendor_id_2, patch_id_2, enable_2,	\
> +				   new_c_3, vendor_id_3, patch_id_3, enable_3)	\
> +	__ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, patch_id_1, enable_1,	\
> +				   new_c_2, vendor_id_2, patch_id_2, enable_2)	\
> +	ALT_NEW_CONTENT(vendor_id_3, patch_id_3, enable_3, new_c_3)
> +
>  #endif /* __ASSEMBLY__ */
>  
>  #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, patch_id, CONFIG_k)	\
> @@ -108,6 +124,13 @@
>  	__ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, patch_id_1, IS_ENABLED(CONFIG_k_1),	\
>  				   new_c_2, vendor_id_2, patch_id_2, IS_ENABLED(CONFIG_k_2))
>  
> +#define _ALTERNATIVE_CFG_3(old_c, new_c_1, vendor_id_1, patch_id_1, CONFIG_k_1,		\
> +				  new_c_2, vendor_id_2, patch_id_2, CONFIG_k_2,		\
> +				  new_c_3, vendor_id_3, patch_id_3, CONFIG_k_3)		\
> +	__ALTERNATIVE_CFG_3(old_c, new_c_1, vendor_id_1, patch_id_1, IS_ENABLED(CONFIG_k_1),	\
> +				   new_c_2, vendor_id_2, patch_id_2, IS_ENABLED(CONFIG_k_2),	\
> +				   new_c_3, vendor_id_3, patch_id_3, IS_ENABLED(CONFIG_k_3))
> +
>  #else /* CONFIG_RISCV_ALTERNATIVE */
>  #ifdef __ASSEMBLY__
>  
> @@ -121,6 +144,9 @@
>  #define _ALTERNATIVE_CFG_2(old_c, ...)	\
>  	ALTERNATIVE_CFG old_c
>  
> +#define _ALTERNATIVE_CFG_3(old_c, ...)	\
> +	ALTERNATIVE_CFG old_c
> +
>  #else /* !__ASSEMBLY__ */
>  
>  #define __ALTERNATIVE_CFG(old_c)	\
> @@ -132,6 +158,9 @@
>  #define _ALTERNATIVE_CFG_2(old_c, ...)	\
>  	__ALTERNATIVE_CFG(old_c)
>  
> +#define _ALTERNATIVE_CFG_3(old_c, ...)	\
> +	__ALTERNATIVE_CFG(old_c)
> +
>  #endif /* __ASSEMBLY__ */
>  #endif /* CONFIG_RISCV_ALTERNATIVE */
>  
> @@ -152,15 +181,21 @@
>  	_ALTERNATIVE_CFG(old_content, new_content, vendor_id, patch_id, CONFIG_k)
>  
>  /*
> - * A vendor wants to replace an old_content, but another vendor has used
> - * ALTERNATIVE() to patch its customized content at the same location. In
> - * this case, this vendor can create a new macro ALTERNATIVE_2() based
> - * on the following sample code and then replace ALTERNATIVE() with
> - * ALTERNATIVE_2() to append its customized content.
> + * Variant of ALTERNATIVE() that supports two sets of replacement content.
>   */
>  #define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1,		\
>  				   new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2)		\
>  	_ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1,	\
>  					new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2)
>  
> +/*
> + * Variant of ALTERNATIVE() that supports three sets of replacement content.
> + */
> +#define ALTERNATIVE_3(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1,		\
> +				   new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2,		\
> +				   new_content_3, vendor_id_3, patch_id_3, CONFIG_k_3)		\
> +	_ALTERNATIVE_CFG_3(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1,	\
> +					new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2,	\
> +					new_content_3, vendor_id_3, patch_id_3, CONFIG_k_3)
> +
>  #endif
> -- 
> 2.45.1
>

Otherwise,

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>


From ajones at ventanamicro.com  Fri Nov 15 05:24:24 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Fri, 15 Nov 2024 14:24:24 +0100
Subject: [PATCH v2] cpuidle: riscv-sbi: fix device node release in early
 exit of for_each_possible_cpu
In-Reply-To: <20241031-cpuidle-riscv-sbi-cleanup-v2-1-aae62d383118@gmail.com>
References: <20241031-cpuidle-riscv-sbi-cleanup-v2-1-aae62d383118@gmail.com>
Message-ID: <20241115-20b5e02dd05173bfdc3a7d7f@orel>

On Thu, Oct 31, 2024 at 01:21:17PM +0100, Javier Carrasco wrote:
> The 'np' device_node is initialized via of_cpu_device_node_get(), which
> requires explicit calls to of_node_put() when it is no longer required
> to avoid leaking the resource.
> 
> Instead of adding the missing calls to of_node_put() in all execution
> paths, use the cleanup attribute for 'np' by means of the __free()
> macro, which automatically calls of_node_put() when the variable goes
> out of scope. Given that 'np' is only used within the
> for_each_possible_cpu(), reduce its scope to release the nood after
> every iteration of the loop.
> 
> Fixes: 6abf32f1d9c5 ("cpuidle: Add RISC-V SBI CPU idle driver")
> Signed-off-by: Javier Carrasco <javier.carrasco.cruz at gmail.com>
> ---
> Changes in v2:
> - Squash patches for mainline solution without intermediate steps.
> - Link to v1: https://lore.kernel.org/r/20241030-cpuidle-riscv-sbi-cleanup-v1-0-5e08a22c9409 at gmail.com
> ---
>  drivers/cpuidle/cpuidle-riscv-sbi.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c
> index 14462c092039..3a78d6b7598b 100644
> --- a/drivers/cpuidle/cpuidle-riscv-sbi.c
> +++ b/drivers/cpuidle/cpuidle-riscv-sbi.c
> @@ -504,12 +504,13 @@ static int sbi_cpuidle_probe(struct platform_device *pdev)
>  	int cpu, ret;
>  	struct cpuidle_driver *drv;
>  	struct cpuidle_device *dev;
> -	struct device_node *np, *pds_node;
> +	struct device_node *pds_node;
>  
>  	/* Detect OSI support based on CPU DT nodes */
>  	sbi_cpuidle_use_osi = true;
>  	for_each_possible_cpu(cpu) {
> -		np = of_cpu_device_node_get(cpu);
> +		struct device_node *np __free(device_node) =
> +			of_cpu_device_node_get(cpu);

nit: wrapping the line is unnecessary, we have 100 char width.

>  		if (np &&
>  		    of_property_present(np, "power-domains") &&
>  		    of_property_present(np, "power-domain-names")) {
> 
> ---
> base-commit: 6fb2fa9805c501d9ade047fc511961f3273cdcb5
> change-id: 20241029-cpuidle-riscv-sbi-cleanup-e9b3cb96e16d
> 
> Best regards,
> -- 
> Javier Carrasco <javier.carrasco.cruz at gmail.com>
>

Otherwise,

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>


From naresh.kamboju at linaro.org  Fri Nov 15 05:25:08 2024
From: naresh.kamboju at linaro.org (Naresh Kamboju)
Date: Fri, 15 Nov 2024 18:55:08 +0530
Subject: riscv: include/linux/perf_event.h:1679:84: error: macro
 "perf_misc_flags" passed 2 arguments, but takes just 1
Message-ID: <CA+G9fYv=qPeZKkF+ntWxUXbAKjz4gXnBM8y60C4F=YHv+jgZZw@mail.gmail.com>

The following builds failed with clang-19 and gcc-13 on the
 Linux next-20241115 tags on riscv architecture.

First seen on Linux next-20241115 tag.
  Good: next-20241114
  Bad:  next-20241115

build:
  * clang-13-lkftconfig
  * clang-19-lkftconfig
  * clang-nightly-lkftconfig

Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>

Build log:
---------
In file included from include/linux/perf/riscv_pmu.h:12,
                 from arch/riscv/include/asm/kvm_vcpu_pmu.h:12,
                 from arch/riscv/include/asm/kvm_host.h:23,
                 from arch/riscv/kernel/asm-offsets.c:12:
include/linux/perf_event.h:1679:84: error: macro "perf_misc_flags"
passed 2 arguments, but takes just 1
 1679 | extern unsigned long perf_misc_flags(struct perf_event *event,
struct pt_regs *regs);
      |
                    ^
In file included from include/linux/perf_event.h:25:
arch/riscv/include/asm/perf_event.h:15: note: macro "perf_misc_flags"
defined here
   15 | #define perf_misc_flags(regs) perf_misc_flags(regs)
      |
include/linux/perf_event.h:1679:22: error: 'perf_misc_flags'
redeclared as different kind of symbol
 1679 | extern unsigned long perf_misc_flags(struct perf_event *event,
struct pt_regs *regs);
      |                      ^~~~~~~~~~~~~~~
arch/riscv/include/asm/perf_event.h:14:22: note: previous declaration
of 'perf_misc_flags' with type 'long unsigned int(struct pt_regs *)'
   14 | extern unsigned long perf_misc_flags(struct pt_regs *regs);
      |                      ^~~~~~~~~~~~~~~
include/linux/perf_event.h:1680:22: error: conflicting types for
'perf_instruction_pointer'; have 'long unsigned int(struct perf_event
*, struct pt_regs *)'
 1680 | extern unsigned long perf_instruction_pointer(struct perf_event *event,
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~
arch/riscv/include/asm/perf_event.h:13:22: note: previous declaration
of 'perf_instruction_pointer' with type 'long unsigned int(struct
pt_regs *)'
   13 | extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~
make[3]: *** [scripts/Makefile.build:102:
arch/riscv/kernel/asm-offsets.s] Error 1


Build image:
-----------
- https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20241115/testrun/25823358/suite/build/test/gcc-13-defconfig/details/
- https://qa-reports.linaro.org/lkft/linux-next-master/build/next-20241115/testrun/25823358/suite/build/test/gcc-13-defconfig/log
- https://storage.tuxsuite.com/public/linaro/lkft/builds/2osJj2d60yO8ruYvm0gjhi4YHS5/

Steps to reproduce:
------------
- tuxmake --runtime podman --target-arch riscv --toolchain gcc-13
--kconfig defconfig

metadata:
----
  git describe: next-20241115
  git repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
  git sha: 744cf71b8bdfcdd77aaf58395e068b7457634b2c
  kernel config:
https://storage.tuxsuite.com/public/linaro/lkft/builds/2osJj2d60yO8ruYvm0gjhi4YHS5/config
  build url: https://storage.tuxsuite.com/public/linaro/lkft/builds/2osJj2d60yO8ruYvm0gjhi4YHS5/
  toolchain: clang-19 and gcc-13
  config: lkftconfig
  arch: riscv

--
Linaro LKFT
https://lkft.linaro.org


From robh at kernel.org  Fri Nov 15 07:13:03 2024
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 15 Nov 2024 09:13:03 -0600
Subject: [PATCH] riscv: dts: starfive: jh7110-milkv-mars: set host mode
 and vbus pin for on-chip USB 2.0
In-Reply-To: <20241114201805.24143-2-e@freeshell.de>
References: <20241114201805.24143-2-e@freeshell.de>
Message-ID: <173168321484.2749832.8147306978765028453.robh@kernel.org>


On Thu, 14 Nov 2024 12:13:40 -0800, E Shattow wrote:
> Enable host mode USB for Milk-V Mars by setting host mode and connect vbus
> pinctrl.
> 
> Note that testing this functionality depends on two features:
> 
> 1.  commit e10c52e7e064038d9bd67b20bf4ce92077d7d84e "phy: starfive:
> jh7110-usb: Fix link configuration to controller"
> 
> 2. Setting the USB over-current register to disable. This is done at
> bootloader phase, for example U-Boot:
> https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/
> 
> If the over-current register is not prepared for us then the result is no
> change in functional outcome with this patch applied; there is an error
> visible to the user and usb configuration fails (same as it is now).
> 
> Signed-off-by: E Shattow <e at freeshell.de>
> ---
>  .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


New warnings running 'make CHECK_DTBS=y starfive/jh7110-milkv-mars.dtb' for 20241114201805.24143-2-e at freeshell.de:

arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dtb: pinctrl at 13040000: usb0-0: 'driver-vbus-pin' does not match any of the regexes: '-pins$', 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/pinctrl/starfive,jh7110-sys-pinctrl.yaml#







From robin.murphy at arm.com  Fri Nov 15 07:20:36 2024
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 15 Nov 2024 15:20:36 +0000
Subject: [RFC PATCH 04/15] iommu/riscv: report iommu capabilities
In-Reply-To: <20241114161845.502027-21-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-21-ajones@ventanamicro.com>
Message-ID: <ddd40bc3-7f2a-43c2-8918-a10c63bd05ba@arm.com>

On 14/11/2024 4:18 pm, Andrew Jones wrote:
> From: Tomasz Jeznach <tjeznach at rivosinc.com>
> 
> Report RISC-V IOMMU capabilities required by VFIO subsystem
> to enable PCIe device assignment.

IOMMU_CAP_DEFERRED_FLUSH has nothing at all to do with VFIO. As far as I 
can tell from what's queued, riscv_iommu_unmap_pages() isn't really 
implementing the full optimisation to get the most out of it either.

I guess IOMMU_CAP_CACHE_COHERENCY falls out of the assumption of a 
coherent IOMMU and lack of PBMT support making everything implicitly 
IOMMU_CACHE all the time whether you want it or not, but clarifying that 
might be nice (especially since there's some chance that something will 
eventually come along to break it...)

Thanks,
Robin.

> Signed-off-by: Tomasz Jeznach <tjeznach at rivosinc.com>
> Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
> ---
>   drivers/iommu/riscv/iommu.c | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
> index 8a05def774bd..3fe4ceba8dd3 100644
> --- a/drivers/iommu/riscv/iommu.c
> +++ b/drivers/iommu/riscv/iommu.c
> @@ -1462,6 +1462,17 @@ static struct iommu_group *riscv_iommu_device_group(struct device *dev)
>   	return generic_device_group(dev);
>   }
>   
> +static bool riscv_iommu_capable(struct device *dev, enum iommu_cap cap)
> +{
> +	switch (cap) {
> +	case IOMMU_CAP_CACHE_COHERENCY:
> +	case IOMMU_CAP_DEFERRED_FLUSH:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
>   static int riscv_iommu_of_xlate(struct device *dev, const struct of_phandle_args *args)
>   {
>   	return iommu_fwspec_add_ids(dev, args->args, 1);
> @@ -1526,6 +1537,7 @@ static void riscv_iommu_release_device(struct device *dev)
>   static const struct iommu_ops riscv_iommu_ops = {
>   	.pgsize_bitmap = SZ_4K,
>   	.of_xlate = riscv_iommu_of_xlate,
> +	.capable = riscv_iommu_capable,
>   	.identity_domain = &riscv_iommu_identity_domain,
>   	.blocked_domain = &riscv_iommu_blocking_domain,
>   	.release_domain = &riscv_iommu_blocking_domain,


From james.clark at linaro.org  Fri Nov 15 07:35:55 2024
From: james.clark at linaro.org (James Clark)
Date: Fri, 15 Nov 2024 15:35:55 +0000
Subject: [PATCH v2 0/8] Refactor cpuid and metric table lookup code
In-Reply-To: <20241107162035.52206-1-irogers@google.com>
References: <20241107162035.52206-1-irogers@google.com>
Message-ID: <215ca9a2-0a63-4d0c-8402-5cb1f2bb0794@linaro.org>



On 07/11/2024 4:20 pm, Ian Rogers wrote:
> Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
> lookup:
> https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
> These patches remove a lot of the logic relating CPUIDs to PMUs so
> that the PMU isn't part of the question when finding a metric table.
> For time reasons, it doesn't go as far as allowing system metrics
> without a metric table as a metric table is needed for metrics to
> refer to other metrics, and the refactoring of that resolution is a
> hassle.
> 
> Ian Rogers (7):
>    perf header: Move is_cpu_online to numa bench
>    perf header: Refactor get_cpuid to take a CPU for ARM
>    perf arm64 header: Use cpu argument in get_cpuid
>    perf header: Avoid transitive PMU includes
>    perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
>    perf jevents: Add map_for_cpu
>    perf pmu: Move pmu_metrics_table__find and remove ARM override
> 
> Xu Yang (1):
>    perf jevents: fix breakage when do perf stat on system metric
> 
>   tools/perf/arch/arm64/util/arm-spe.c     | 14 +---
>   tools/perf/arch/arm64/util/header.c      | 73 ++++++++++-----------
>   tools/perf/arch/arm64/util/pmu.c         | 20 ------
>   tools/perf/arch/loongarch/util/header.c  |  4 +-
>   tools/perf/arch/powerpc/util/header.c    |  4 +-
>   tools/perf/arch/riscv/util/header.c      |  4 +-
>   tools/perf/arch/s390/util/header.c       |  6 +-
>   tools/perf/arch/x86/util/auxtrace.c      |  3 +-
>   tools/perf/arch/x86/util/header.c        |  5 +-
>   tools/perf/bench/numa.c                  | 53 +++++++++++++++
>   tools/perf/builtin-kvm.c                 |  4 +-
>   tools/perf/pmu-events/empty-pmu-events.c | 39 ++++++-----
>   tools/perf/pmu-events/jevents.py         | 39 ++++++-----
>   tools/perf/pmu-events/pmu-events.h       |  2 +-
>   tools/perf/tests/expr.c                  |  5 +-
>   tools/perf/util/env.c                    |  4 +-
>   tools/perf/util/expr.c                   |  6 +-
>   tools/perf/util/header.c                 | 82 ++++++++----------------
>   tools/perf/util/header.h                 | 23 +++----
>   tools/perf/util/pmu.c                    | 25 --------
>   tools/perf/util/pmu.h                    |  2 -
>   tools/perf/util/probe-event.c            |  1 +
>   22 files changed, 189 insertions(+), 229 deletions(-)
> 

Reviewed-by: James Clark <james.clark at linaro.org>



From palmer at rivosinc.com  Fri Nov 15 07:38:59 2024
From: palmer at rivosinc.com (Palmer Dabbelt)
Date: Fri, 15 Nov 2024 07:38:59 -0800 (PST)
Subject: [GIT PULL] A Single RISC-V Fix for 6.12-rc8
Message-ID: <mhng-257c7a1f-aca6-48f9-b3ec-6a4673f8d33e@palmer-ri-x1c9>

The following changes since commit 59b723cd2adbac2a34fc8e12c74ae26ae45bf230:

  Linux 6.12-rc6 (2024-11-03 14:05:52 -1000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git tags/riscv-for-linus-6.12-rc8

for you to fetch changes up to 57f7c7dc78cd09622b12920d92b40c1ce11b234e:

  drivers: perf: Fix wrong put_cpu() placement (2024-11-12 07:34:27 -0800)

----------------------------------------------------------------
A Single RISC-V Fix for 6.12-rc8

* A fix for the CPU perf driver that avoids leaking CPU ID references on
  systems without snapshot support.

----------------------------------------------------------------
Alexandre Ghiti (1):
      drivers: perf: Fix wrong put_cpu() placement

 drivers/perf/riscv_pmu_sbi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)


From acme at kernel.org  Fri Nov 15 07:43:05 2024
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Fri, 15 Nov 2024 12:43:05 -0300
Subject: [PATCH v2 0/8] Refactor cpuid and metric table lookup code
In-Reply-To: <215ca9a2-0a63-4d0c-8402-5cb1f2bb0794@linaro.org>
References: <20241107162035.52206-1-irogers@google.com>
 <215ca9a2-0a63-4d0c-8402-5cb1f2bb0794@linaro.org>
Message-ID: <ZzdsCWpAULCe839R@x1>

On Fri, Nov 15, 2024 at 03:35:55PM +0000, James Clark wrote:
> 
> 
> On 07/11/2024 4:20 pm, Ian Rogers wrote:
> > Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
> > lookup:
> > https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
> > These patches remove a lot of the logic relating CPUIDs to PMUs so
> > that the PMU isn't part of the question when finding a metric table.
> > For time reasons, it doesn't go as far as allowing system metrics
> > without a metric table as a metric table is needed for metrics to
> > refer to other metrics, and the refactoring of that resolution is a
> > hassle.
> > 
> > Ian Rogers (7):
> >    perf header: Move is_cpu_online to numa bench
> >    perf header: Refactor get_cpuid to take a CPU for ARM
> >    perf arm64 header: Use cpu argument in get_cpuid
> >    perf header: Avoid transitive PMU includes
> >    perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
> >    perf jevents: Add map_for_cpu
> >    perf pmu: Move pmu_metrics_table__find and remove ARM override
> > 
> > Xu Yang (1):
> >    perf jevents: fix breakage when do perf stat on system metric
> > 
> >   tools/perf/arch/arm64/util/arm-spe.c     | 14 +---
> >   tools/perf/arch/arm64/util/header.c      | 73 ++++++++++-----------
> >   tools/perf/arch/arm64/util/pmu.c         | 20 ------
> >   tools/perf/arch/loongarch/util/header.c  |  4 +-
> >   tools/perf/arch/powerpc/util/header.c    |  4 +-
> >   tools/perf/arch/riscv/util/header.c      |  4 +-
> >   tools/perf/arch/s390/util/header.c       |  6 +-
> >   tools/perf/arch/x86/util/auxtrace.c      |  3 +-
> >   tools/perf/arch/x86/util/header.c        |  5 +-
> >   tools/perf/bench/numa.c                  | 53 +++++++++++++++
> >   tools/perf/builtin-kvm.c                 |  4 +-
> >   tools/perf/pmu-events/empty-pmu-events.c | 39 ++++++-----
> >   tools/perf/pmu-events/jevents.py         | 39 ++++++-----
> >   tools/perf/pmu-events/pmu-events.h       |  2 +-
> >   tools/perf/tests/expr.c                  |  5 +-
> >   tools/perf/util/env.c                    |  4 +-
> >   tools/perf/util/expr.c                   |  6 +-
> >   tools/perf/util/header.c                 | 82 ++++++++----------------
> >   tools/perf/util/header.h                 | 23 +++----
> >   tools/perf/util/pmu.c                    | 25 --------
> >   tools/perf/util/pmu.h                    |  2 -
> >   tools/perf/util/probe-event.c            |  1 +
> >   22 files changed, 189 insertions(+), 229 deletions(-)
> > 
> 
> Reviewed-by: James Clark <james.clark at linaro.org>

Thanks for reviewing James, I'm doing a round of tests to push what I
have in tmp.perf-tools-next to perf-tools-next so that it gets test
merged on linux-next and later today I'll escape from the holiday and
take a last look on this series, apply and test.

- Arnaldo


From apatel at ventanamicro.com  Fri Nov 15 07:42:58 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Fri, 15 Nov 2024 21:12:58 +0530
Subject: [PATCH] irqchip/riscv-aplic: Fix crash when MSI domain is missing
In-Reply-To: <20241114200133.3069460-1-samuel.holland@sifive.com>
References: <20241114200133.3069460-1-samuel.holland@sifive.com>
Message-ID: <CAK9=C2UyfmHqtYYK-WeSRk3=6bjs5nzDmw9ntudbCnPOYxLtXg@mail.gmail.com>

On Fri, Nov 15, 2024 at 1:31?AM Samuel Holland
<samuel.holland at sifive.com> wrote:
>
> If the APLIC driver is probed before the IMSIC driver, the parent MSI
> domain will be missing, which causes a NULL pointer dereference in
> msi_create_device_irq_domain(). Avoid this by deferring probe until the
> parent MSI domain is available. Use dev_err_probe() to avoid printing an
> error message when returning -EPROBE_DEFER.

The -EPROBE_DEFER is not needed because we expect that platforms to
use "msi-parent" DT property in APLIC DT node which in-turn allows Linux
DD framework to re-order probing based on fw_devlink dependencies. The
APLIC DT bindings mandates that any of "interrupt-extended" or "msi-parent"
DT properties MUST be present.

Can you elaborate a bit more on how you are hitting this issue ?

Regards,
Anup

>
> Fixes: ca8df97fe679 ("irqchip/riscv-aplic: Add support for MSI-mode")
> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> ---
>
>  drivers/irqchip/irq-riscv-aplic-main.c | 3 ++-
>  drivers/irqchip/irq-riscv-aplic-msi.c  | 3 +++
>  2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
> index 900e72541db9..93e7c51f944a 100644
> --- a/drivers/irqchip/irq-riscv-aplic-main.c
> +++ b/drivers/irqchip/irq-riscv-aplic-main.c
> @@ -207,7 +207,8 @@ static int aplic_probe(struct platform_device *pdev)
>         else
>                 rc = aplic_direct_setup(dev, regs);
>         if (rc)
> -               dev_err(dev, "failed to setup APLIC in %s mode\n", msi_mode ? "MSI" : "direct");
> +               dev_err_probe(dev, rc, "failed to setup APLIC in %s mode\n",
> +                             msi_mode ? "MSI" : "direct");
>
>  #ifdef CONFIG_ACPI
>         if (!acpi_disabled)
> diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
> index 945bff28265c..fb8d1838609f 100644
> --- a/drivers/irqchip/irq-riscv-aplic-msi.c
> +++ b/drivers/irqchip/irq-riscv-aplic-msi.c
> @@ -266,6 +266,9 @@ int aplic_msi_setup(struct device *dev, void __iomem *regs)
>                         if (msi_domain)
>                                 dev_set_msi_domain(dev, msi_domain);
>                 }
> +
> +               if (!dev_get_msi_domain(dev))
> +                       return -EPROBE_DEFER;
>         }
>
>         if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
> --
> 2.45.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From samuel.holland at sifive.com  Fri Nov 15 07:57:00 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Fri, 15 Nov 2024 09:57:00 -0600
Subject: [PATCH] irqchip/riscv-aplic: Fix crash when MSI domain is missing
In-Reply-To: <CAK9=C2UyfmHqtYYK-WeSRk3=6bjs5nzDmw9ntudbCnPOYxLtXg@mail.gmail.com>
References: <20241114200133.3069460-1-samuel.holland@sifive.com>
 <CAK9=C2UyfmHqtYYK-WeSRk3=6bjs5nzDmw9ntudbCnPOYxLtXg@mail.gmail.com>
Message-ID: <1bce34c6-c2d0-4b2b-a8f9-7bc8737702b1@sifive.com>

Hi Anup,

On 2024-11-15 9:42 AM, Anup Patel wrote:
> On Fri, Nov 15, 2024 at 1:31?AM Samuel Holland
> <samuel.holland at sifive.com> wrote:
>>
>> If the APLIC driver is probed before the IMSIC driver, the parent MSI
>> domain will be missing, which causes a NULL pointer dereference in
>> msi_create_device_irq_domain(). Avoid this by deferring probe until the
>> parent MSI domain is available. Use dev_err_probe() to avoid printing an
>> error message when returning -EPROBE_DEFER.
> 
> The -EPROBE_DEFER is not needed because we expect that platforms to
> use "msi-parent" DT property in APLIC DT node which in-turn allows Linux
> DD framework to re-order probing based on fw_devlink dependencies. The
> APLIC DT bindings mandates that any of "interrupt-extended" or "msi-parent"
> DT properties MUST be present.
> 
> Can you elaborate a bit more on how you are hitting this issue ?

I agree that fw_devlink should help avoid the situation where we need to return
-EPROBE_DEFER, but the kernel must still not crash even if fw_devlink is
disabled (which is a perfectly valid thing to do: "fw_devlink=off" on the kernel
command line) or if fw_devlink fails to come up with the ideal probe order.
fw_devlink is an optimization. It should not be relied on for correctness. In my
specific case, fw_devlink got the order wrong due to some false dependency
cycles, which I sent a patch for separately[1].

Regards,
Samuel

[1]:
https://lore.kernel.org/lkml/20241114195652.3068725-1-samuel.holland at sifive.com/

>> Fixes: ca8df97fe679 ("irqchip/riscv-aplic: Add support for MSI-mode")
>> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
>> ---
>>
>>  drivers/irqchip/irq-riscv-aplic-main.c | 3 ++-
>>  drivers/irqchip/irq-riscv-aplic-msi.c  | 3 +++
>>  2 files changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
>> index 900e72541db9..93e7c51f944a 100644
>> --- a/drivers/irqchip/irq-riscv-aplic-main.c
>> +++ b/drivers/irqchip/irq-riscv-aplic-main.c
>> @@ -207,7 +207,8 @@ static int aplic_probe(struct platform_device *pdev)
>>         else
>>                 rc = aplic_direct_setup(dev, regs);
>>         if (rc)
>> -               dev_err(dev, "failed to setup APLIC in %s mode\n", msi_mode ? "MSI" : "direct");
>> +               dev_err_probe(dev, rc, "failed to setup APLIC in %s mode\n",
>> +                             msi_mode ? "MSI" : "direct");
>>
>>  #ifdef CONFIG_ACPI
>>         if (!acpi_disabled)
>> diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
>> index 945bff28265c..fb8d1838609f 100644
>> --- a/drivers/irqchip/irq-riscv-aplic-msi.c
>> +++ b/drivers/irqchip/irq-riscv-aplic-msi.c
>> @@ -266,6 +266,9 @@ int aplic_msi_setup(struct device *dev, void __iomem *regs)
>>                         if (msi_domain)
>>                                 dev_set_msi_domain(dev, msi_domain);
>>                 }
>> +
>> +               if (!dev_get_msi_domain(dev))
>> +                       return -EPROBE_DEFER;
>>         }
>>
>>         if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
>> --
>> 2.45.1
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv



From roypat at amazon.co.uk  Fri Nov 15 08:59:13 2024
From: roypat at amazon.co.uk (Patrick Roy)
Date: Fri, 15 Nov 2024 16:59:13 +0000
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <f4c5d0a6-a582-44e3-8949-c199cc0bfba7@redhat.com>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <4aa0ccf4-ebbe-4244-bc85-8bc8dcd14e74@redhat.com>
 <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
 <d1a69eb7-85d5-4ffa-88e2-f4841713c1d7@redhat.com>
 <90c9d8c0-814e-4c86-86ef-439cb5552cb6@amazon.co.uk>
 <10e4d078-3cdb-4d1c-a1a3-80e91b247217@redhat.com>
 <02f77d32-e2a1-431b-bb67-33d36c06acd3@amazon.co.uk>
 <f4c5d0a6-a582-44e3-8949-c199cc0bfba7@redhat.com>
Message-ID: <f1f34ac0-d505-4982-aad9-86a0db9f4a35@amazon.co.uk>



On Tue, 2024-11-12 at 14:52 +0000, David Hildenbrand wrote:
> On 12.11.24 15:40, Patrick Roy wrote:
>> I remember talking to someone at some point about whether we could reuse
>> the proc-local stuff for guest memory, but I cannot remember the outcome
>> of that discussion... (or maybe I just wanted to have a discussion about
>> it, but forgot to follow up on that thought?).  I guess we wouldn't use
>> proc-local _allocations_, but rather just set up proc-local mappings of
>> the gmem allocations that have been removed from the direct map.
> 
> Yes. And likely only for memory we really access / try access, if possible.

Well, if we start on-demand mm-local mapping the things we want to
access, we're back in TLB flush hell, no? And we can't know
ahead-of-time what needs to be mapped, so everything would need to be
mapped (unless we do something like mm-local mapping a page on first
access, and then just never unmapping it again, under the assumption
that establishing the mapping won't be expensive)

>>
>> I'm wondering, where exactly would be the differences to Sean's idea
>> about messing with the CR3 register inside KVM to temporarily install
>> page tables that contain all the gmem stuff, conceptually? Wouldn't we
>> run into the same interrupt problems that Sean foresaw for the CR3
>> stuff? (which, admittedly, I still don't quite follow what these are :(
>> ).
> 
> I'd need some more details on that. If anything would rely on the direct
> mapping (from IRQ context?) than ... we obviously cannot remove the
> direct mapping :)

I've talked to Fares internally, and it seems that generally doing
mm-local mappings of guest memory would work for us. We also figured out
what the "interrupt problem" is, namely that if we receive an interrupt
while executing in a context that has mm-local mappings available, those
mappings will continue to be available while the interrupt is being
handled. I'm talking to my security folks to see how much of a concern
this is for the speculation hardening we're trying to achieve. Will keep
you in the loop there :)

> -- 
> Cheers,
> 
> David / dhildenb
> 

Best, 
Patrick


From david at redhat.com  Fri Nov 15 09:10:33 2024
From: david at redhat.com (David Hildenbrand)
Date: Fri, 15 Nov 2024 18:10:33 +0100
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <f1f34ac0-d505-4982-aad9-86a0db9f4a35@amazon.co.uk>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <4aa0ccf4-ebbe-4244-bc85-8bc8dcd14e74@redhat.com>
 <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
 <d1a69eb7-85d5-4ffa-88e2-f4841713c1d7@redhat.com>
 <90c9d8c0-814e-4c86-86ef-439cb5552cb6@amazon.co.uk>
 <10e4d078-3cdb-4d1c-a1a3-80e91b247217@redhat.com>
 <02f77d32-e2a1-431b-bb67-33d36c06acd3@amazon.co.uk>
 <f4c5d0a6-a582-44e3-8949-c199cc0bfba7@redhat.com>
 <f1f34ac0-d505-4982-aad9-86a0db9f4a35@amazon.co.uk>
Message-ID: <dcdce8e1-51da-42da-a892-59c6ccd9de23@redhat.com>

On 15.11.24 17:59, Patrick Roy wrote:
> 
> 
> On Tue, 2024-11-12 at 14:52 +0000, David Hildenbrand wrote:
>> On 12.11.24 15:40, Patrick Roy wrote:
>>> I remember talking to someone at some point about whether we could reuse
>>> the proc-local stuff for guest memory, but I cannot remember the outcome
>>> of that discussion... (or maybe I just wanted to have a discussion about
>>> it, but forgot to follow up on that thought?).  I guess we wouldn't use
>>> proc-local _allocations_, but rather just set up proc-local mappings of
>>> the gmem allocations that have been removed from the direct map.
>>
>> Yes. And likely only for memory we really access / try access, if possible.
> 
> Well, if we start on-demand mm-local mapping the things we want to
> access, we're back in TLB flush hell, no?

At least the on-demand mapping shouldn't require a TLB flush? Only 
"unmapping" if we want to restrict the size of a "mapped pool" of 
restricted size.

Anyhow, this would be a pure optimization, to avoid the expense of 
mapping everything, when in practice you'd like not access most of it.

(my theory, happy to be told I'm wrong :) )

> And we can't know
> ahead-of-time what needs to be mapped, so everything would need to be
> mapped (unless we do something like mm-local mapping a page on first
> access, and then just never unmapping it again, under the assumption
> that establishing the mapping won't be expensive)

Right, the whole problem is that we don't know that upfront.

> 
>>>
>>> I'm wondering, where exactly would be the differences to Sean's idea
>>> about messing with the CR3 register inside KVM to temporarily install
>>> page tables that contain all the gmem stuff, conceptually? Wouldn't we
>>> run into the same interrupt problems that Sean foresaw for the CR3
>>> stuff? (which, admittedly, I still don't quite follow what these are :(
>>> ).
>>
>> I'd need some more details on that. If anything would rely on the direct
>> mapping (from IRQ context?) than ... we obviously cannot remove the
>> direct mapping :)
> 
> I've talked to Fares internally, and it seems that generally doing
> mm-local mappings of guest memory would work for us. We also figured out
> what the "interrupt problem" is, namely that if we receive an interrupt
> while executing in a context that has mm-local mappings available, those
> mappings will continue to be available while the interrupt is being
> handled.

Isn't that likely also the case with secretmem where we removed the 
directmap, but have an effective per-mm mapping in the (user-space 
portion) of the page table?

> I'm talking to my security folks to see how much of a concern
> this is for the speculation hardening we're trying to achieve. Will keep
> you in the loop there :)

Thanks!

-- 
Cheers,

David / dhildenb



From roypat at amazon.co.uk  Fri Nov 15 09:23:47 2024
From: roypat at amazon.co.uk (Patrick Roy)
Date: Fri, 15 Nov 2024 17:23:47 +0000
Subject: [RFC PATCH v3 0/6] Direct Map Removal for guest_memfd
In-Reply-To: <dcdce8e1-51da-42da-a892-59c6ccd9de23@redhat.com>
References: <20241030134912.515725-1-roypat@amazon.co.uk>
 <4aa0ccf4-ebbe-4244-bc85-8bc8dcd14e74@redhat.com>
 <27646c08-f724-49f7-9f45-d03bad500219@amazon.co.uk>
 <d1a69eb7-85d5-4ffa-88e2-f4841713c1d7@redhat.com>
 <90c9d8c0-814e-4c86-86ef-439cb5552cb6@amazon.co.uk>
 <10e4d078-3cdb-4d1c-a1a3-80e91b247217@redhat.com>
 <02f77d32-e2a1-431b-bb67-33d36c06acd3@amazon.co.uk>
 <f4c5d0a6-a582-44e3-8949-c199cc0bfba7@redhat.com>
 <f1f34ac0-d505-4982-aad9-86a0db9f4a35@amazon.co.uk>
 <dcdce8e1-51da-42da-a892-59c6ccd9de23@redhat.com>
Message-ID: <81d14448-29eb-4496-b876-ef6de526a840@amazon.co.uk>



On Fri, 2024-11-15 at 17:10 +0000, David Hildenbrand wrote:
>> [...]
>>
>> I've talked to Fares internally, and it seems that generally doing
>> mm-local mappings of guest memory would work for us. We also figured out
>> what the "interrupt problem" is, namely that if we receive an interrupt
>> while executing in a context that has mm-local mappings available, those
>> mappings will continue to be available while the interrupt is being
>> handled.
> 
> Isn't that likely also the case with secretmem where we removed the
> directmap, but have an effective per-mm mapping in the (user-space
> portion) of the page table?

Mh, that's an excellent point, I never thought of that. But with
secretmem, the memory would still be protected by SMAP (admittedly, I
have no idea how much this is worth in the face of all these speculative
issues), right?

>> I'm talking to my security folks to see how much of a concern
>> this is for the speculation hardening we're trying to achieve. Will keep
>> you in the loop there :)
> 
> Thanks!
> 
> -- 
> Cheers,
> 
> David / dhildenb

Best,
Patrick


From pr-tracker-bot at kernel.org  Fri Nov 15 11:48:59 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 15 Nov 2024 19:48:59 +0000
Subject: [GIT PULL] A Single RISC-V Fix for 6.12-rc8
In-Reply-To: <mhng-257c7a1f-aca6-48f9-b3ec-6a4673f8d33e@palmer-ri-x1c9>
References: <mhng-257c7a1f-aca6-48f9-b3ec-6a4673f8d33e@palmer-ri-x1c9>
Message-ID: <173170013917.2698975.1950787133841750972.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 15 Nov 2024 07:38:59 -0800 (PST):

> git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git tags/riscv-for-linus-6.12-rc8

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/e8bdb3c8be08c9a3edc0a373c0aa8729355a0705

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From aurelien at aurel32.net  Fri Nov 15 13:49:12 2024
From: aurelien at aurel32.net (Aurelien Jarno)
Date: Fri, 15 Nov 2024 22:49:12 +0100
Subject: [PATCH] riscv/entry: get correct syscall number from
 syscall_get_nr()
In-Reply-To: <87sesgftng.fsf@all.your.base.are.belong.to.us>
References: <87ldya4nv0.ffs@tglx>
 <87sesgftng.fsf@all.your.base.are.belong.to.us>
Message-ID: <ZzfB2LfsD0ATjLMv@aurel32.net>

On 2024-10-28 02:45, Bj?rn T?pel wrote:
> Thanks for helping out to dissect this! Much appreciated!
> 
> Thomas Gleixner <tglx at linutronix.de> writes:
> 
> > Let me look at your failure analysis from your first reply:
> >
> >>  1. strace "tracing": Requires that regs->a0 is not tampered with prior
> >>     ptrace notification
> >> 
> >>     E.g.:
> >>     | # ./strace /
> >>     | execve("/", ["/"], 0x7ffffaac3890 /* 21 vars */) = -1 EACCES (Permission denied)
> >>     | ./strace: exec: Permission denied
> >>     | +++ exited with 1 +++
> >>     | # ./disable_ptrace_get_syscall_info ./strace /
> >>     | execve(0xffffffffffffffda, ["/"], 0x7fffd893ce10 /* 21 vars */) = -1 EACCES (Permission denied)
> >>     | ./strace: exec: Permission denied
> >>     | +++ exited with 1 +++
> >> 
> >>     In the second case, arg0 is prematurely set to -ENOSYS
> >>     (0xffffffffffffffda).
> >
> > That's expected if ptrace_get_syscall_info() is not used. Plain dumping
> > registers will give you the current value on all architectures.
> > ptrace_get_syscall_info() exist exactly for that reason.
> 
> Noted! So this shouldn't be considered as a regression. IOW, the
> existing upstream code is OK for this scenario.

Not however that it breaks some programs, for instance I arrived on this
thread by debugging python-ptrace. I'll try to look at adding support
for ptrace_get_syscall_info(), but I am afraid we will find more broken
programs.

Regards
Aurelien

[1] https://buildd.debian.org/status/fetch.php?pkg=python-ptrace&arch=riscv64&ver=0.9.9-0.1%2Bb2&stamp=1731547088&raw=0

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien at aurel32.net                     http://aurel32.net


From javier.carrasco.cruz at gmail.com  Fri Nov 15 15:32:39 2024
From: javier.carrasco.cruz at gmail.com (Javier Carrasco)
Date: Sat, 16 Nov 2024 00:32:39 +0100
Subject: [PATCH v3] cpuidle: riscv-sbi: fix device node release in early
 exit of for_each_possible_cpu
Message-ID: <20241116-cpuidle-riscv-sbi-cleanup-v3-1-a3a46372ce08@gmail.com>

The 'np' device_node is initialized via of_cpu_device_node_get(), which
requires explicit calls to of_node_put() when it is no longer required
to avoid leaking the resource.

Instead of adding the missing calls to of_node_put() in all execution
paths, use the cleanup attribute for 'np' by means of the __free()
macro, which automatically calls of_node_put() when the variable goes
out of scope. Given that 'np' is only used within the
for_each_possible_cpu(), reduce its scope to release the nood after
every iteration of the loop.

Fixes: 6abf32f1d9c5 ("cpuidle: Add RISC-V SBI CPU idle driver")
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Javier Carrasco <javier.carrasco.cruz at gmail.com>
---
Changes in v3:
- Unwrap line (100 char width).
- Link to v2: https://lore.kernel.org/r/20241031-cpuidle-riscv-sbi-cleanup-v2-1-aae62d383118 at gmail.com

Changes in v2:
- Squash patches for mainline solution without intermediate steps.
- Link to v1: https://lore.kernel.org/r/20241030-cpuidle-riscv-sbi-cleanup-v1-0-5e08a22c9409 at gmail.com
---
 drivers/cpuidle/cpuidle-riscv-sbi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c
index 14462c092039..0c92a628bbd4 100644
--- a/drivers/cpuidle/cpuidle-riscv-sbi.c
+++ b/drivers/cpuidle/cpuidle-riscv-sbi.c
@@ -504,12 +504,12 @@ static int sbi_cpuidle_probe(struct platform_device *pdev)
 	int cpu, ret;
 	struct cpuidle_driver *drv;
 	struct cpuidle_device *dev;
-	struct device_node *np, *pds_node;
+	struct device_node *pds_node;
 
 	/* Detect OSI support based on CPU DT nodes */
 	sbi_cpuidle_use_osi = true;
 	for_each_possible_cpu(cpu) {
-		np = of_cpu_device_node_get(cpu);
+		struct device_node *np __free(device_node) = of_cpu_device_node_get(cpu);
 		if (np &&
 		    of_property_present(np, "power-domains") &&
 		    of_property_present(np, "power-domain-names")) {

---
base-commit: 744cf71b8bdfcdd77aaf58395e068b7457634b2c
change-id: 20241029-cpuidle-riscv-sbi-cleanup-e9b3cb96e16d

Best regards,
-- 
Javier Carrasco <javier.carrasco.cruz at gmail.com>



From e at freeshell.de  Fri Nov 15 22:17:07 2024
From: e at freeshell.de (E Shattow)
Date: Fri, 15 Nov 2024 22:17:07 -0800
Subject: [PATCH v2 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
Message-ID: <20241116061719.36409-2-e@freeshell.de>

Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host mode
and connect vbus pinctrl.

This functionality depends on:

1. commit e10c52e7e064038d9bd67b20bf4ce92077d7d84e
"phy: starfive: jh7110-usb: Fix link configuration to controller"

2. Setting the USB over-current register to disable. This is done at
bootloader phase, for example U-Boot:
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no
change in functional outcome with this patch applied; there is an error
visible to the user and this additional usb configuration fails (same as
it is now). The existing three VL805 connected USB ports via PCIe on 
Milk-V Mars are not affected.

Changes since v1:
 - series name (was "[PATCH] riscv: dts: starfive: jh7110-milkv-mars: set host mode and vbus pin for on-chip USB 2.0")
 - adjust pin label to obey dtschema
 - use cover letter

E Shattow (1):
  riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function

 .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

-- 
2.45.2



From e at freeshell.de  Fri Nov 15 22:17:09 2024
From: e at freeshell.de (E Shattow)
Date: Fri, 15 Nov 2024 22:17:09 -0800
Subject: [PATCH v2 1/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
In-Reply-To: <20241116061719.36409-2-e@freeshell.de>
References: <20241116061719.36409-2-e@freeshell.de>
Message-ID: <20241116061719.36409-4-e@freeshell.de>

Set host mode and vbus pin for JH7110 on-chip USB 2.0

Signed-off-by: E Shattow <e at freeshell.de>
---
 .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
index 0d248b671d4b..3bd62ab78523 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -53,7 +53,23 @@ &spi0 {
 	status = "okay";
 };
 
+&sysgpio {
+	usb0_pins: usb0-0 {
+		vbus-pins {
+			pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS,
+					      GPOEN_ENABLE,
+					      GPI_NONE)>;
+			bias-disable;
+			input-disable;
+			input-schmitt-disable;
+			slew-rate = <0>;
+		};
+	};
+};
+
 &usb0 {
-	dr_mode = "peripheral";
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins>;
 	status = "okay";
 };
-- 
2.45.2



From zhangkai at iscas.ac.cn  Sat Nov 16 02:42:58 2024
From: zhangkai at iscas.ac.cn (zhangkai at iscas.ac.cn)
Date: Sat, 16 Nov 2024 18:42:58 +0800 (GMT+08:00)
Subject: [PATCH] riscv: fix memory leakage in
 process_accumulated_relocations
Message-ID: <35cab46a.6d145.19334919ed0.Coremail.zhangkai@iscas.ac.cn>

When module relocation is done, process_accumulated_relocations()
frees all dynamic allocated memory. rel_head_iter-&gt;rel_entry is
missed to free that kmemleak might report:

unreferenced object 0xffffffd880c5fc40 (size 16):
  comm "insmod", pid 1101, jiffies 4295045138
  hex dump (first 16 bytes):
    e0 c0 f5 87 d8 ff ff ff 60 c5 f5 87 d8 ff ff ff  ........`.......
  backtrace (crc d2ecb20c):
    [&lt;00000000b01655f6&gt;] kmalloc_trace_noprof+0x268/0x2f6
    [&lt;000000006dc0067a&gt;] add_relocation_to_accumulate.constprop.0+0xf2/0x1aa
    [&lt;00000000e1b29a36&gt;] apply_relocate_add+0x13c/0x36e
    [&lt;000000007543f1fb&gt;] load_module+0x5c6/0x83e
    [&lt;00000000abce12e8&gt;] init_module_from_file+0x74/0xaa
    [&lt;0000000049413e3d&gt;] idempotent_init_module+0x116/0x22e
    [&lt;00000000f9b98b85&gt;] __riscv_sys_finit_module+0x62/0xae

Signed-off-by: Kai Zhang <zhangkai at iscas.ac.cn>
---
 arch/riscv/kernel/module.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index 1cd461f3d87..f8c3c4b47dc 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -643,6 +643,7 @@ process_accumulated_relocations(struct module *me,
                        }
                        reloc_handlers[curr_type].accumulate_handler(
                                me, location, buffer);
+                       kfree(rel_head_iter-&gt;rel_entry);
                        kfree(rel_head_iter);
                }
                kfree(bucket_iter);
-- 
2.39.5

</zhangkai at iscas.ac.cn>

From zhangkai at iscas.ac.cn  Sat Nov 16 04:07:18 2024
From: zhangkai at iscas.ac.cn (laokz)
Date: Sat, 16 Nov 2024 20:07:18 +0800
Subject: [resend PATCH] riscv: fix memory leakage in
 process_accumulated_relocations
Message-ID: <a9058ac757636e4f5160a0bd11abeb3c111fc9a5.camel@iscas.ac.cn>

Sorry for last weird email.
---

When module relocation is done, process_accumulated_relocations()
frees all dynamic allocated memory. rel_head_iter->rel_entry is
missed to free that kmemleak might report:

unreferenced object 0xffffffd880c5fc40 (size 16):
? comm "insmod", pid 1101, jiffies 4295045138
? hex dump (first 16 bytes):
??? e0 c0 f5 87 d8 ff ff ff 60 c5 f5 87 d8 ff ff ff? ........`.......
? backtrace (crc d2ecb20c):
??? [<00000000b01655f6>] kmalloc_trace_noprof+0x268/0x2f6
??? [<000000006dc0067a>]
add_relocation_to_accumulate.constprop.0+0xf2/0x1aa
??? [<00000000e1b29a36>] apply_relocate_add+0x13c/0x36e
??? [<000000007543f1fb>] load_module+0x5c6/0x83e
??? [<00000000abce12e8>] init_module_from_file+0x74/0xaa
??? [<0000000049413e3d>] idempotent_init_module+0x116/0x22e
??? [<00000000f9b98b85>] __riscv_sys_finit_module+0x62/0xae

Signed-off-by: Kai Zhang <zhangkai at iscas.ac.cn>
---
?arch/riscv/kernel/module.c | 1 +
?1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index 1cd461f3d87..f8c3c4b47dc 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -643,6 +643,7 @@ process_accumulated_relocations(struct module *me,
??????????????????????? }
??????????????????????? reloc_handlers[curr_type].accumulate_handler(
??????????????????????????????? me, location, buffer);
+?????????????????????? kfree(rel_head_iter->rel_entry);
??????????????????????? kfree(rel_head_iter);
??????????????? }
??????????????? kfree(bucket_iter);



From prabhakar.mahadev-lad.rj at bp.renesas.com  Sat Nov 16 08:05:06 2024
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Prabhakar)
Date: Sat, 16 Nov 2024 16:05:06 +0000
Subject: [PATCH v2] riscv: perf: Drop defining `perf_instruction_pointer()` and `perf_misc_flags()`
Message-ID: <20241116160506.5324-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

With commit 2c47e7a74f44 ("perf/core: Correct perf sampling with guest
VMs"), the perf core now handles the functionality previously requiring
arch-specific definitions of `perf_instruction_pointer()` and
`perf_misc_flags()`. As these definitions are no longer necessary for
RISC-V, this patch removes their implementation and declarations.

This change also fixes the following build issue on RISC-V:

    ./include/linux/perf_event.h:1679:84: error: macro "perf_misc_flags" passed 2 arguments, but takes just 1
    ./include/linux/perf_event.h:1679:22: error: 'perf_misc_flags' redeclared as different kind of symbol
    ./include/linux/perf_event.h:1680:22: error: conflicting types for 'perf_instruction_pointer'; have 'long unsigned int(struct perf_event *, struct pt_regs *)'

The above errors arise from conflicts between the core definitions in
`linux/perf_event.h` and the RISC-V-specific definitions in
`arch/riscv/include/asm/perf_event.h`. Removing the RISC-V-specific
definitions resolves these issues and aligns the architecture with the
updated perf core.

Fixes: 2c47e7a74f44 ("perf/core: Correct perf sampling with guest VMs")
Reported-by: Chris Paterson <Chris.Paterson2 at renesas.com>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---
v1->v2
- Update commit message to say it fixes build issue
- Included RB tag from Andrew
---
 arch/riscv/include/asm/perf_event.h |  3 ---
 arch/riscv/kernel/perf_callchain.c  | 28 ----------------------------
 2 files changed, 31 deletions(-)

diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h
index 38926b4a902d..bcc928fd3785 100644
--- a/arch/riscv/include/asm/perf_event.h
+++ b/arch/riscv/include/asm/perf_event.h
@@ -10,9 +10,6 @@
 
 #ifdef CONFIG_PERF_EVENTS
 #include <linux/perf_event.h>
-extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
-extern unsigned long perf_misc_flags(struct pt_regs *regs);
-#define perf_misc_flags(regs) perf_misc_flags(regs)
 #define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs
 
 #define perf_arch_fetch_caller_regs(regs, __ip) { \
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
index c2c81a80f816..b465bc9eb870 100644
--- a/arch/riscv/kernel/perf_callchain.c
+++ b/arch/riscv/kernel/perf_callchain.c
@@ -46,31 +46,3 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 
 	walk_stackframe(NULL, regs, fill_callchain, entry);
 }
-
-unsigned long perf_instruction_pointer(struct pt_regs *regs)
-{
-	if (perf_guest_state())
-		return perf_guest_get_ip();
-
-	return instruction_pointer(regs);
-}
-
-unsigned long perf_misc_flags(struct pt_regs *regs)
-{
-	unsigned int guest_state = perf_guest_state();
-	unsigned long misc = 0;
-
-	if (guest_state) {
-		if (guest_state & PERF_GUEST_USER)
-			misc |= PERF_RECORD_MISC_GUEST_USER;
-		else
-			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
-	} else {
-		if (user_mode(regs))
-			misc |= PERF_RECORD_MISC_USER;
-		else
-			misc |= PERF_RECORD_MISC_KERNEL;
-	}
-
-	return misc;
-}
-- 
2.25.1



From acme at kernel.org  Sat Nov 16 11:47:06 2024
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Sat, 16 Nov 2024 16:47:06 -0300
Subject: [PATCH v2 0/8] Refactor cpuid and metric table lookup code
In-Reply-To: <ZzdsCWpAULCe839R@x1>
References: <20241107162035.52206-1-irogers@google.com>
 <215ca9a2-0a63-4d0c-8402-5cb1f2bb0794@linaro.org>
 <ZzdsCWpAULCe839R@x1>
Message-ID: <Zzj2usdkgdyZ9Z8I@x1>

On Fri, Nov 15, 2024 at 12:43:05PM -0300, Arnaldo Carvalho de Melo wrote:
> On Fri, Nov 15, 2024 at 03:35:55PM +0000, James Clark wrote:
> > 
> > 
> > On 07/11/2024 4:20 pm, Ian Rogers wrote:
> > > Xu Yang <xu.yang_2 at nxp.com> reported issues with the system metric
> > > lookup:
> > > https://lore.kernel.org/linux-perf-users/20241106085441.3945502-1-xu.yang_2 at nxp.com/
> > > These patches remove a lot of the logic relating CPUIDs to PMUs so
> > > that the PMU isn't part of the question when finding a metric table.
> > > For time reasons, it doesn't go as far as allowing system metrics
> > > without a metric table as a metric table is needed for metrics to
> > > refer to other metrics, and the refactoring of that resolution is a
> > > hassle.
> > > 
> > > Ian Rogers (7):
> > >    perf header: Move is_cpu_online to numa bench
> > >    perf header: Refactor get_cpuid to take a CPU for ARM
> > >    perf arm64 header: Use cpu argument in get_cpuid
> > >    perf header: Avoid transitive PMU includes
> > >    perf header: Pass a perf_cpu rather than a PMU to get_cpuid_str
> > >    perf jevents: Add map_for_cpu
> > >    perf pmu: Move pmu_metrics_table__find and remove ARM override
> > > 
> > > Xu Yang (1):
> > >    perf jevents: fix breakage when do perf stat on system metric
> > > 
> > >   tools/perf/arch/arm64/util/arm-spe.c     | 14 +---
> > >   tools/perf/arch/arm64/util/header.c      | 73 ++++++++++-----------
> > >   tools/perf/arch/arm64/util/pmu.c         | 20 ------
> > >   tools/perf/arch/loongarch/util/header.c  |  4 +-
> > >   tools/perf/arch/powerpc/util/header.c    |  4 +-
> > >   tools/perf/arch/riscv/util/header.c      |  4 +-
> > >   tools/perf/arch/s390/util/header.c       |  6 +-
> > >   tools/perf/arch/x86/util/auxtrace.c      |  3 +-
> > >   tools/perf/arch/x86/util/header.c        |  5 +-
> > >   tools/perf/bench/numa.c                  | 53 +++++++++++++++
> > >   tools/perf/builtin-kvm.c                 |  4 +-
> > >   tools/perf/pmu-events/empty-pmu-events.c | 39 ++++++-----
> > >   tools/perf/pmu-events/jevents.py         | 39 ++++++-----
> > >   tools/perf/pmu-events/pmu-events.h       |  2 +-
> > >   tools/perf/tests/expr.c                  |  5 +-
> > >   tools/perf/util/env.c                    |  4 +-
> > >   tools/perf/util/expr.c                   |  6 +-
> > >   tools/perf/util/header.c                 | 82 ++++++++----------------
> > >   tools/perf/util/header.h                 | 23 +++----
> > >   tools/perf/util/pmu.c                    | 25 --------
> > >   tools/perf/util/pmu.h                    |  2 -
> > >   tools/perf/util/probe-event.c            |  1 +
> > >   22 files changed, 189 insertions(+), 229 deletions(-)
> > > 
> > 
> > Reviewed-by: James Clark <james.clark at linaro.org>
> 
> Thanks for reviewing James, I'm doing a round of tests to push what I
> have in tmp.perf-tools-next to perf-tools-next so that it gets test
> merged on linux-next and later today I'll escape from the holiday and
> take a last look on this series, apply and test.

Applied locally, pushing to tmp.perf-tools-next as I'm still testing the
hwmon case, building it on an 32-bit ARM machine:

processor	: 3
model name	: ARMv7 Processor rev 4 (v7l)
BogoMIPS	: 38.40
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xd03
CPU revision	: 4

Hardware	: BCM2835
Revision	: a020d3
Serial		: 00000000783939e0
Model		: Raspberry Pi 3 Model B Plus Rev 1.3

- Arnaldo


From emil.renner.berthing at canonical.com  Sat Nov 16 13:32:50 2024
From: emil.renner.berthing at canonical.com (Emil Renner Berthing)
Date: Sat, 16 Nov 2024 16:32:50 -0500
Subject: [PATCH v2] riscv: defconfig: enable pinctrl and dwmac support for TH1520
In-Reply-To: <20241113184333.829716-1-drew@pdp7.com>
References: <20241113184333.829716-1-drew@pdp7.com>
Message-ID: <CAJM55Z_RchO-Ke1aXXAaB5f-OJEYcHU6n+MVtBTCUSXrHOQp1Q@mail.gmail.com>

Drew Fustini wrote:
> Enable pinctrl and ethernet dwmac driver for the TH1520 SoC boards like
> the BeagleV Ahead and the Sipeed LicheePi 4A.
>
> Signed-off-by: Drew Fustini <drew at pdp7.com>

Reviewed-by: Emil Renner Berthing <emil.renner.berthing at canonical.com>

> ---
> Changes in v2:
>  - Switch CONFIG_DWMAC_THEAD from built-in to module
>
>
>  arch/riscv/configs/defconfig | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
> index b4a37345703e..d26e670404b6 100644
> --- a/arch/riscv/configs/defconfig
> +++ b/arch/riscv/configs/defconfig
> @@ -167,6 +167,7 @@ CONFIG_PINCTRL_SOPHGO_CV1800B=y
>  CONFIG_PINCTRL_SOPHGO_CV1812H=y
>  CONFIG_PINCTRL_SOPHGO_SG2000=y
>  CONFIG_PINCTRL_SOPHGO_SG2002=y
> +CONFIG_PINCTRL_TH1520=y
>  CONFIG_GPIO_DWAPB=y
>  CONFIG_GPIO_SIFIVE=y
>  CONFIG_POWER_RESET_GPIO_RESTART=y
> @@ -242,6 +243,7 @@ CONFIG_RTC_DRV_SUN6I=y
>  CONFIG_DMADEVICES=y
>  CONFIG_DMA_SUN6I=m
>  CONFIG_DW_AXI_DMAC=y
> +CONFIG_DWMAC_THEAD=m
>  CONFIG_VIRTIO_PCI=y
>  CONFIG_VIRTIO_BALLOON=y
>  CONFIG_VIRTIO_INPUT=y
> --
> 2.34.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From e at freeshell.de  Sun Nov 17 19:45:07 2024
From: e at freeshell.de (E Shattow)
Date: Sun, 17 Nov 2024 19:45:07 -0800
Subject: [PATCH v3 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
Message-ID: <20241118034558.43226-2-e@freeshell.de>

Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host mode
and connect vbus pinctrl.

This functionality depends on setting the USB over-current register to disable at bootloader phase, for example U-Boot:
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no
change in functional outcome with this patch applied; there is an error
visible to the user and this additional usb configuration fails (same as
it is now). The existing three VL805 connected USB ports via PCIe on
Milk-V Mars are not affected.

Changes since v2:
 - Rebase on 6.12

Changes since v1:
 - series name (was "[PATCH] riscv: dts: starfive: jh7110-milkv-mars: set host mode and vbus pin for on-chip USB 2.0")
 - adjust pin label to obey dtschema
 - use cover letter

E Shattow (1):
  riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function

 .../boot/dts/starfive/jh7110-milkv-mars.dts   | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

-- 
2.45.2



From e at freeshell.de  Sun Nov 17 19:45:09 2024
From: e at freeshell.de (E Shattow)
Date: Sun, 17 Nov 2024 19:45:09 -0800
Subject: [PATCH 1/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
In-Reply-To: <20241118034558.43226-2-e@freeshell.de>
References: <20241118034558.43226-2-e@freeshell.de>
Message-ID: <20241118034558.43226-4-e@freeshell.de>

Milk-V Mars set host mode and vbus pin for JH7110 on-chip USB 2.0

Signed-off-by: E Shattow <e at freeshell.de>
---
 .../boot/dts/starfive/jh7110-milkv-mars.dts   | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
index 5cb9e99e1dac..45d4f7556521 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -35,3 +35,24 @@ &phy0 {
 	rx-internal-delay-ps = <1500>;
 	tx-internal-delay-ps = <1500>;
 };
+
+&sysgpio {
+        usb0_pins: usb0-0 {
+                vbus-pins {
+                        pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS,
+                                              GPOEN_ENABLE,
+                                              GPI_NONE)>;
+                        bias-disable;
+                        input-disable;
+                        input-schmitt-disable;
+                        slew-rate = <0>;
+                };
+        };
+};
+
+&usb0 {
+        dr_mode = "host";
+        pinctrl-names = "default";
+        pinctrl-0 = <&usb0_pins>;
+        status = "okay";
+};
-- 
2.45.2



From e at freeshell.de  Sun Nov 17 20:02:09 2024
From: e at freeshell.de (E Shattow)
Date: Sun, 17 Nov 2024 20:02:09 -0800
Subject: [PATCH v1 0/1] riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function
Message-ID: <20241118040250.43625-1-e@freeshell.de>

Enable host mode JH7110 on-chip USB for Pine64 Star64 by setting host mode
and connect vbus pinctrl.

This functionality depends on setting the USB over-current register to disable at bootloader phase, for example U-Boot:
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no
change in functional outcome with this patch applied; there is an error
visible to the user and this usb configuration fails (same as it is now).

E Shattow (1):
  riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function

 .../dts/starfive/jh7110-pine64-star64.dts     | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

-- 
2.45.2



From e at freeshell.de  Sun Nov 17 20:02:10 2024
From: e at freeshell.de (E Shattow)
Date: Sun, 17 Nov 2024 20:02:10 -0800
Subject: [PATCH 1/1] riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function
In-Reply-To: <20241118040250.43625-1-e@freeshell.de>
References: <20241118040250.43625-1-e@freeshell.de>
Message-ID: <20241118040250.43625-2-e@freeshell.de>

Pine64 Star64 set host mode and vbus pin for JH7110 on-chip USB 2.0

Signed-off-by: E Shattow <e at freeshell.de>
---
 .../dts/starfive/jh7110-pine64-star64.dts     | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
index 8e39fdc73ecb..9f608d00d3d3 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
@@ -62,3 +62,24 @@ &phy1 {
 	motorcomm,tx-clk-10-inverted;
 	motorcomm,tx-clk-100-inverted;
 };
+
+&sysgpio {
+        usb0_pins: usb0-0 {
+                vbus-pins {
+                        pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS,
+                                              GPOEN_ENABLE,
+                                              GPI_NONE)>;
+                        bias-disable;
+                        input-disable;
+                        input-schmitt-disable;
+                        slew-rate = <0>;
+                };
+        };
+};
+
+&usb0 {
+        dr_mode = "host";
+        pinctrl-names = "default";
+        pinctrl-0 = <&usb0_pins>;
+        status = "okay";
+};
-- 
2.45.2



From apatel at ventanamicro.com  Mon Nov 18 00:19:31 2024
From: apatel at ventanamicro.com (Anup Patel)
Date: Mon, 18 Nov 2024 13:49:31 +0530
Subject: [PATCH] irqchip/riscv-aplic: Fix crash when MSI domain is missing
In-Reply-To: <1bce34c6-c2d0-4b2b-a8f9-7bc8737702b1@sifive.com>
References: <20241114200133.3069460-1-samuel.holland@sifive.com>
 <CAK9=C2UyfmHqtYYK-WeSRk3=6bjs5nzDmw9ntudbCnPOYxLtXg@mail.gmail.com> <1bce34c6-c2d0-4b2b-a8f9-7bc8737702b1@sifive.com>
Message-ID: <CAK9=C2UUq=k9JHrO9zeiPhdmakyzigm9ToQFM2S90bQs31=98w@mail.gmail.com>

On Fri, Nov 15, 2024 at 9:27?PM Samuel Holland
<samuel.holland at sifive.com> wrote:
>
> Hi Anup,
>
> On 2024-11-15 9:42 AM, Anup Patel wrote:
> > On Fri, Nov 15, 2024 at 1:31?AM Samuel Holland
> > <samuel.holland at sifive.com> wrote:
> >>
> >> If the APLIC driver is probed before the IMSIC driver, the parent MSI
> >> domain will be missing, which causes a NULL pointer dereference in
> >> msi_create_device_irq_domain(). Avoid this by deferring probe until the
> >> parent MSI domain is available. Use dev_err_probe() to avoid printing an
> >> error message when returning -EPROBE_DEFER.
> >
> > The -EPROBE_DEFER is not needed because we expect that platforms to
> > use "msi-parent" DT property in APLIC DT node which in-turn allows Linux
> > DD framework to re-order probing based on fw_devlink dependencies. The
> > APLIC DT bindings mandates that any of "interrupt-extended" or "msi-parent"
> > DT properties MUST be present.
> >
> > Can you elaborate a bit more on how you are hitting this issue ?
>
> I agree that fw_devlink should help avoid the situation where we need to return
> -EPROBE_DEFER, but the kernel must still not crash even if fw_devlink is
> disabled (which is a perfectly valid thing to do: "fw_devlink=off" on the kernel
> command line) or if fw_devlink fails to come up with the ideal probe order.
> fw_devlink is an optimization. It should not be relied on for correctness. In my
> specific case, fw_devlink got the order wrong due to some false dependency
> cycles, which I sent a patch for separately[1].

The RISC-V kernel is heavily dependent on fw_devlink based probe ordering
and more upcoming drivers are going to increase this dependency.
For example, we also have RISC-V IOMMU driver that needs to be probed
after IMSIC since it can use MSIs.

I think we should ensure that fw_devlink can't be disabled/turned-off for the
RISC-V kernel. If this is not possible then we should have very verbose
boot-time warning when fw_devlink is disabled/turned-off.

Your other "interrupt-parent" related fix [1] looks fine to me.

Regards,
Anup

>
> Regards,
> Samuel
>
> [1]:
> https://lore.kernel.org/lkml/20241114195652.3068725-1-samuel.holland at sifive.com/
>
> >> Fixes: ca8df97fe679 ("irqchip/riscv-aplic: Add support for MSI-mode")
> >> Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
> >> ---
> >>
> >>  drivers/irqchip/irq-riscv-aplic-main.c | 3 ++-
> >>  drivers/irqchip/irq-riscv-aplic-msi.c  | 3 +++
> >>  2 files changed, 5 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
> >> index 900e72541db9..93e7c51f944a 100644
> >> --- a/drivers/irqchip/irq-riscv-aplic-main.c
> >> +++ b/drivers/irqchip/irq-riscv-aplic-main.c
> >> @@ -207,7 +207,8 @@ static int aplic_probe(struct platform_device *pdev)
> >>         else
> >>                 rc = aplic_direct_setup(dev, regs);
> >>         if (rc)
> >> -               dev_err(dev, "failed to setup APLIC in %s mode\n", msi_mode ? "MSI" : "direct");
> >> +               dev_err_probe(dev, rc, "failed to setup APLIC in %s mode\n",
> >> +                             msi_mode ? "MSI" : "direct");
> >>
> >>  #ifdef CONFIG_ACPI
> >>         if (!acpi_disabled)
> >> diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
> >> index 945bff28265c..fb8d1838609f 100644
> >> --- a/drivers/irqchip/irq-riscv-aplic-msi.c
> >> +++ b/drivers/irqchip/irq-riscv-aplic-msi.c
> >> @@ -266,6 +266,9 @@ int aplic_msi_setup(struct device *dev, void __iomem *regs)
> >>                         if (msi_domain)
> >>                                 dev_set_msi_domain(dev, msi_domain);
> >>                 }
> >> +
> >> +               if (!dev_get_msi_domain(dev))
> >> +                       return -EPROBE_DEFER;
> >>         }
> >>
> >>         if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
> >> --
> >> 2.45.1
> >>
> >>
> >> _______________________________________________
> >> linux-riscv mailing list
> >> linux-riscv at lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/linux-riscv
>


From namcao at linutronix.de  Mon Nov 18 01:13:33 2024
From: namcao at linutronix.de (Nam Cao)
Date: Mon, 18 Nov 2024 10:13:33 +0100
Subject: [PATCH] riscv: Fix sleeping in invalid context in die()
Message-ID: <20241118091333.1185288-1-namcao@linutronix.de>

die() can be called in exception handler, and therefore cannot sleep.
However, die() takes spinlock_t which can sleep with PREEMPT_RT enabled.
That causes the following warning:

BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 285, name: mutex
preempt_count: 110001, expected: 0
RCU nest depth: 0, expected: 0
CPU: 0 UID: 0 PID: 285 Comm: mutex Not tainted 6.12.0-rc7-00022-ge19049cf7d56-dirty #234
Hardware name: riscv-virtio,qemu (DT)
Call Trace:
    dump_backtrace+0x1c/0x24
    show_stack+0x2c/0x38
    dump_stack_lvl+0x5a/0x72
    dump_stack+0x14/0x1c
    __might_resched+0x130/0x13a
    rt_spin_lock+0x2a/0x5c
    die+0x24/0x112
    do_trap_insn_illegal+0xa0/0xea
    _new_vmalloc_restore_context_a0+0xcc/0xd8
Oops - illegal instruction [#1]

Switch to use raw_spinlock_t, which does not sleep even with PREEMPT_RT
enabled.

Fixes: 76d2a0493a17 ("RISC-V: Init and Halt Code")
Signed-off-by: Nam Cao <namcao at linutronix.de>
Cc: stable at vger.kernel.org
---
stable backport is probably not needed for versions earlier than 6.12
because PREEMPT_RT is not enabled. But it doesn't hurt..
---
 arch/riscv/kernel/traps.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 51ebfd23e007..8ff8e8b36524 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -35,7 +35,7 @@
 
 int show_unhandled_signals = 1;
 
-static DEFINE_SPINLOCK(die_lock);
+static DEFINE_RAW_SPINLOCK(die_lock);
 
 static int copy_code(struct pt_regs *regs, u16 *val, const u16 *insns)
 {
@@ -81,7 +81,7 @@ void die(struct pt_regs *regs, const char *str)
 
 	oops_enter();
 
-	spin_lock_irqsave(&die_lock, flags);
+	raw_spin_lock_irqsave(&die_lock, flags);
 	console_verbose();
 	bust_spinlocks(1);
 
@@ -100,7 +100,7 @@ void die(struct pt_regs *regs, const char *str)
 
 	bust_spinlocks(0);
 	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
-	spin_unlock_irqrestore(&die_lock, flags);
+	raw_spin_unlock_irqrestore(&die_lock, flags);
 	oops_exit();
 
 	if (in_interrupt())
-- 
2.39.5



From kirill.shutemov at linux.intel.com  Mon Nov 18 01:43:02 2024
From: kirill.shutemov at linux.intel.com (Kirill A. Shutemov)
Date: Mon, 18 Nov 2024 11:43:02 +0200
Subject: [PATCHv2 0/2] x86/mm: Make memremap(MEMREMAP_WB) map memory as
 encrypted by default
In-Reply-To: <j54jizfjzubkejbkobyryl33i4ejhoek4ynshtethkiidkx7le@2p22g3fxxedz>
References: <20241021105723.2707507-1-kirill.shutemov@linux.intel.com>
 <j54jizfjzubkejbkobyryl33i4ejhoek4ynshtethkiidkx7le@2p22g3fxxedz>
Message-ID: <oh7zs7c4drl7i35dt3bxunqhlefrmcej7yd2bjxvdzpnqgtyk6@qkl6vvipa54d>

On Tue, Oct 29, 2024 at 05:11:26PM +0200, Kirill A. Shutemov wrote:
> On Mon, Oct 21, 2024 at 01:57:21PM +0300, Kirill A. Shutemov wrote:
> > Make memremap(MEMREMAP_WB) produce encrypted/private mapping by default
> > unless MEMREMAP_DEC is specified.
> > 
> > It fixes crash on kexec in TDX guests if CONFIG_EISA is enabled.
> 
> Ping? Any feedback is welcome.

The patchset fixes crash. Please consider applying.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


From valentina.fernandezalanis at microchip.com  Mon Nov 18 07:53:54 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Mon, 18 Nov 2024 15:53:54 +0000
Subject: [PATCH v1] firmware: microchip: fix UL_IAP lock check in mpfs_auto_update_state()
Message-ID: <20241118155354.697411-1-valentina.fernandezalanis@microchip.com>

To verify that Auto Update is possible, the mpfs_auto_update_state()
function performs a "Query Security Service Request" to the system
controller.

Previously, the check was performed on the first element of the
response message, which was accessed using a 32-bit pointer. This
caused the bitwise operation to reference incorrect data, as the
response should be inspected at the byte level. Fixed this by casting
the response to a  u8 * pointer, ensuring the check correctly inspects
the appropriate byte of the response message.

Additionally, rename "UL_Auto Update" to "UL_IAP" to match the
PolarFire Family System Services User Guide.

Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
---
 drivers/firmware/microchip/mpfs-auto-update.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/microchip/mpfs-auto-update.c b/drivers/firmware/microchip/mpfs-auto-update.c
index 0f7ec8848202..df1d69bdc1d7 100644
--- a/drivers/firmware/microchip/mpfs-auto-update.c
+++ b/drivers/firmware/microchip/mpfs-auto-update.c
@@ -402,10 +402,10 @@ static int mpfs_auto_update_available(struct mpfs_auto_update_priv *priv)
 		return -EIO;
 
 	/*
-	 * Bit 5 of byte 1 is "UL_Auto Update" & if it is set, Auto Update is
+	 * Bit 5 of byte 1 is "UL_IAP" & if it is set, Auto Update is
 	 * not possible.
 	 */
-	if (response_msg[1] & AUTO_UPDATE_FEATURE_ENABLED)
+	if ((((u8 *)response_msg)[1] & AUTO_UPDATE_FEATURE_ENABLED))
 		return -EPERM;
 
 	return 0;
-- 
2.34.1



From bp at alien8.de  Mon Nov 18 08:46:16 2024
From: bp at alien8.de (Borislav Petkov)
Date: Mon, 18 Nov 2024 17:46:16 +0100
Subject: [PATCHv2 2/2] x86/mm: Make memremap(MEMREMAP_WB) map memory as
 encrypted by default
In-Reply-To: <20241021105723.2707507-3-kirill.shutemov@linux.intel.com>
References: <20241021105723.2707507-1-kirill.shutemov@linux.intel.com>
 <20241021105723.2707507-3-kirill.shutemov@linux.intel.com>
Message-ID: <20241118164616.GAZztvWGs9cOV8t20_@fat_crate.local>

On Mon, Oct 21, 2024 at 01:57:23PM +0300, Kirill A. Shutemov wrote:
> It fixes crash on kexec in TDX guests if CONFIG_EISA is enabled.

Do TDX guests even need EISA?

"The EISA bus saw limited use between 1988 and 1995 when it was made obsolete
by the PCI bus."

Sounds like no to me.

We usually simply stop coco guests from touching such legacy ranges:

f30470c190c2 ("x86/boot: Skip video memory access in the decompressor for SEV-ES/SNP")

so can you do that too?

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


From oliver.upton at linux.dev  Mon Nov 18 08:57:28 2024
From: oliver.upton at linux.dev (Oliver Upton)
Date: Mon, 18 Nov 2024 08:57:28 -0800
Subject: [PATCH v2] riscv: perf: Drop defining
 `perf_instruction_pointer()` and `perf_misc_flags()`
In-Reply-To: <20241116160506.5324-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20241116160506.5324-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <Zztx-EBqXcFdBSPj@linux.dev>

On Sat, Nov 16, 2024 at 04:05:06PM +0000, Prabhakar wrote:
> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> With commit 2c47e7a74f44 ("perf/core: Correct perf sampling with guest
> VMs"), the perf core now handles the functionality previously requiring
> arch-specific definitions of `perf_instruction_pointer()` and
> `perf_misc_flags()`. As these definitions are no longer necessary for
> RISC-V, this patch removes their implementation and declarations.
> 
> This change also fixes the following build issue on RISC-V:
> 
>     ./include/linux/perf_event.h:1679:84: error: macro "perf_misc_flags" passed 2 arguments, but takes just 1
>     ./include/linux/perf_event.h:1679:22: error: 'perf_misc_flags' redeclared as different kind of symbol
>     ./include/linux/perf_event.h:1680:22: error: conflicting types for 'perf_instruction_pointer'; have 'long unsigned int(struct perf_event *, struct pt_regs *)'
> 
> The above errors arise from conflicts between the core definitions in
> `linux/perf_event.h` and the RISC-V-specific definitions in
> `arch/riscv/include/asm/perf_event.h`. Removing the RISC-V-specific
> definitions resolves these issues and aligns the architecture with the
> updated perf core.
> 
> Fixes: 2c47e7a74f44 ("perf/core: Correct perf sampling with guest VMs")
> Reported-by: Chris Paterson <Chris.Paterson2 at renesas.com>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>

Reviewed-by: Oliver Upton <oliver.upton at linux.dev>

-- 
Thanks,
Oliver


From rostedt at goodmis.org  Mon Nov 18 10:25:01 2024
From: rostedt at goodmis.org (Steven Rostedt)
Date: Mon, 18 Nov 2024 13:25:01 -0500
Subject: [PATCH v7 0/8] x86/module: use large ROX pages for text
 allocations
In-Reply-To: <20241023162711.2579610-1-rppt@kernel.org>
References: <20241023162711.2579610-1-rppt@kernel.org>
Message-ID: <20241118132501.4eddb46c@gandalf.local.home>

On Wed, 23 Oct 2024 19:27:03 +0300
Mike Rapoport <rppt at kernel.org> wrote:

> From: "Mike Rapoport (Microsoft)" <rppt at kernel.org>
> 
> Hi,
> 
> This is an updated version of execmem ROX caches.
> 

FYI, I booted a kernel before and after applying these patches with my
change:

  https://lore.kernel.org/20241017113105.1edfa943 at gandalf.local.home

Before these patches:

 # cat /sys/kernel/tracing/dyn_ftrace_total_info
57695 pages:231 groups: 9
ftrace boot update time = 14733459 (ns)
ftrace module total update time = 449016 (ns)

After:

 # cat /sys/kernel/tracing/dyn_ftrace_total_info
57708 pages:231 groups: 9
ftrace boot update time = 47195374 (ns)
ftrace module total update time = 592080 (ns)

Which caused boot time to slowdown by over 30ms. That may not seem like
much, but we are very concerned about boot time and are fighting every ms
we can get.

-- Steve


From rppt at kernel.org  Mon Nov 18 10:40:26 2024
From: rppt at kernel.org (Mike Rapoport)
Date: Mon, 18 Nov 2024 10:40:26 -0800
Subject: [PATCH v7 0/8] x86/module: use large ROX pages for text
 allocations
In-Reply-To: <20241118132501.4eddb46c@gandalf.local.home>
References: <20241023162711.2579610-1-rppt@kernel.org>
 <20241118132501.4eddb46c@gandalf.local.home>
Message-ID: <ZzuKGoj99rIuMaBE@kernel.org>

On Mon, Nov 18, 2024 at 01:25:01PM -0500, Steven Rostedt wrote:
> On Wed, 23 Oct 2024 19:27:03 +0300
> Mike Rapoport <rppt at kernel.org> wrote:
> 
> > From: "Mike Rapoport (Microsoft)" <rppt at kernel.org>
> > 
> > Hi,
> > 
> > This is an updated version of execmem ROX caches.
> > 
> 
> FYI, I booted a kernel before and after applying these patches with my
> change:
> 
>   https://lore.kernel.org/20241017113105.1edfa943 at gandalf.local.home
> 
> Before these patches:
> 
>  # cat /sys/kernel/tracing/dyn_ftrace_total_info
> 57695 pages:231 groups: 9
> ftrace boot update time = 14733459 (ns)
> ftrace module total update time = 449016 (ns)
> 
> After:
> 
>  # cat /sys/kernel/tracing/dyn_ftrace_total_info
> 57708 pages:231 groups: 9
> ftrace boot update time = 47195374 (ns)
> ftrace module total update time = 592080 (ns)
> 
> Which caused boot time to slowdown by over 30ms. That may not seem like
> much, but we are very concerned about boot time and are fighting every ms
> we can get.

Hmm, looks like this change was lost in rebase :/

@Andrew, should I send it as a patch on top of mm-stable?

diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 8da0e66ca22d..859902dd06fc 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -111,17 +111,22 @@ static int ftrace_verify_code(unsigned long ip, const char *old_code)
  */
 static int __ref
 ftrace_modify_code_direct(unsigned long ip, const char *old_code,
-			  const char *new_code)
+			  const char *new_code, struct module *mod)
 {
 	int ret = ftrace_verify_code(ip, old_code);
 	if (ret)
 		return ret;
 
 	/* replace the text with the new text */
-	if (ftrace_poke_late)
+	if (ftrace_poke_late) {
 		text_poke_queue((void *)ip, new_code, MCOUNT_INSN_SIZE, NULL);
-	else
+	} else if (!mod) {
 		text_poke_early((void *)ip, new_code, MCOUNT_INSN_SIZE);
+	} else {
+		mutex_lock(&text_mutex);
+		text_poke((void *)ip, new_code, MCOUNT_INSN_SIZE);
+		mutex_unlock(&text_mutex);
+	}
 	return 0;
 }
 
@@ -142,7 +147,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long ad
 	 * just modify the code directly.
 	 */
 	if (addr == MCOUNT_ADDR)
-		return ftrace_modify_code_direct(ip, old, new);
+		return ftrace_modify_code_direct(ip, old, new, mod);
 
 	/*
 	 * x86 overrides ftrace_replace_code -- this function will never be used
@@ -161,7 +166,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	new = ftrace_call_replace(ip, addr);
 
 	/* Should only be called when module is loaded */
-	return ftrace_modify_code_direct(rec->ip, old, new);
+	return ftrace_modify_code_direct(rec->ip, old, new, NULL);
 }
 
 /*


> -- Steve

-- 
Sincerely yours,
Mike.


From jgg at ziepe.ca  Mon Nov 18 10:43:36 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Mon, 18 Nov 2024 14:43:36 -0400
Subject: [RFC PATCH 08/15] iommu/riscv: Add IRQ domain for interrupt
 remapping
In-Reply-To: <20241114161845.502027-25-ajones@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-25-ajones@ventanamicro.com>
Message-ID: <20241118184336.GB559636@ziepe.ca>

On Thu, Nov 14, 2024 at 05:18:53PM +0100, Andrew Jones wrote:
> @@ -1276,10 +1279,30 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
>  	struct riscv_iommu_device *iommu = dev_to_iommu(dev);
>  	struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
>  	struct riscv_iommu_dc dc = {0};
> +	int ret;
>  
>  	if (!riscv_iommu_pt_supported(iommu, domain->pgd_mode))
>  		return -ENODEV;
>  
> +	if (riscv_iommu_bond_link(domain, dev))
> +		return -ENOMEM;
> +
> +	if (iommu_domain->type == IOMMU_DOMAIN_UNMANAGED) {

Drivers should not be making tests like this.

> +		domain->gscid = ida_alloc_range(&riscv_iommu_gscids, 1,
> +						RISCV_IOMMU_MAX_GSCID, GFP_KERNEL);
> +		if (domain->gscid < 0) {
> +			riscv_iommu_bond_unlink(domain, dev);
> +			return -ENOMEM;
> +		}
> +
> +		ret = riscv_iommu_irq_domain_create(domain, dev);
> +		if (ret) {
> +			riscv_iommu_bond_unlink(domain, dev);
> +			ida_free(&riscv_iommu_gscids, domain->gscid);
> +			return ret;
> +		}
> +	}

What are you trying to do? Make something behave different for VFIO?
That isn't OK, we are trying to remove all the hacky VFIO special
cases in drivers.

What is the HW issue here? It is very very strange (and probably not
going to work right) that the irq domains change when domain
attachment changes.

The IRQ setup should really be fixed before any device drivers probe
onto the device.

Jason


From linus.walleij at linaro.org  Mon Nov 18 14:51:35 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 18 Nov 2024 23:51:35 +0100
Subject: [PATCH v4] pinctrl: k210: Undef K210_PC_DEFAULT
In-Reply-To: <20241113071201.5440-1-zhangjiao2@cmss.chinamobile.com>
References: <20241113071201.5440-1-zhangjiao2@cmss.chinamobile.com>
Message-ID: <CACRpkdauNYwqBhNuV5Z_ToyCzRwLyLPPMUSfoZa6in7J-y3B=A@mail.gmail.com>

On Wed, Nov 13, 2024 at 8:12?AM zhangjiao2
<zhangjiao2 at cmss.chinamobile.com> wrote:

> From: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
>
> When the temporary macro K210_PC_DEFAULT is not needed anymore,
> use its name in the #undef statement instead of
> the incorrect "DEFAULT" name.
>
> Fixes: d4c34d09ab03 ("pinctrl: Add RISC-V Canaan Kendryte K210 FPIOA driver")
> Signed-off-by: zhang jiao <zhangjiao2 at cmss.chinamobile.com>
> Reviewed-by: Damien Le Moal <dlemoal at kernel.org>
> ---
> v3->v4:
>         Modify commit info and add review tag.

v4 patch applied!

Yours,
Linus Walleij


From cyrilbur at tenstorrent.com  Mon Nov 18 15:01:08 2024
From: cyrilbur at tenstorrent.com (Cyril Bur)
Date: Mon, 18 Nov 2024 23:01:08 +0000
Subject: [PATCH v2 0/4] riscv: uaccess: optimizations
Message-ID: <20241118230112.2872978-1-cyrilbur@tenstorrent.com>

Orignally sent by Jisheng Zhang <jszhang at kernel.org>

This series tries to optimize riscv uaccess in the following way:

patch1 implement the user_access_begin and families, I.E the unsafe
accessors. when a function like strncpy_from_user() is called,
the userspace access protection is disabled and enabled for every
word read. After patch1, the protection is disabled at the beginning
of the copy and enabled at the end.

patch2 is a simple clean up

patch3 uses 'asm goto' for put_user()
patch4 uses 'asm goto output' for get_user()

Both patch3 and patch4 are based on the fact -- 'asm goto' and
'asm goto output'generates noticeably better code since we don't need
to test the error etc, the exception just jumps to the error handling
directly.

V2:
I've taken on this series as there isn't any response from Jisheng. No
significant changes other than build fixes.
- Fixes build breakage in patch 3 to do with not having used 'goto' keyword.
- Fixes build breakage in patch 4 on 32bit not having delcared __ptr in the
  macro.
I did read the discussion this series generated. It isn't clear to me
which direction to take the patches, if any.



From cyrilbur at tenstorrent.com  Mon Nov 18 15:01:09 2024
From: cyrilbur at tenstorrent.com (Cyril Bur)
Date: Mon, 18 Nov 2024 23:01:09 +0000
Subject: [PATCH v2 1/4] riscv: implement user_access_begin and families
In-Reply-To: <20241118230112.2872978-1-cyrilbur@tenstorrent.com>
References: <20241118230112.2872978-1-cyrilbur@tenstorrent.com>
Message-ID: <20241118230112.2872978-2-cyrilbur@tenstorrent.com>

From: Jisheng Zhang <jszhang at kernel.org>

Currently, when a function like strncpy_from_user() is called,
the userspace access protection is disabled and enabled
for every word read.

By implementing user_access_begin and families, the protection
is disabled at the beginning of the copy and enabled at the end.

The __inttype macro is borrowed from x86 implementation.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
Signed-off-by: Cyril Bur <cyrilbur at tenstorrent.com>
---
 arch/riscv/include/asm/uaccess.h | 63 ++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index 72ec1d9bd3f3..09d4ca37522c 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -28,6 +28,19 @@
 #define __disable_user_access()							\
 	__asm__ __volatile__ ("csrc sstatus, %0" : : "r" (SR_SUM) : "memory")
 
+/*
+ * This is the smallest unsigned integer type that can fit a value
+ * (up to 'long long')
+ */
+#define __inttype(x) __typeof__(		\
+	__typefits(x,char,			\
+	  __typefits(x,short,			\
+	    __typefits(x,int,			\
+	      __typefits(x,long,0ULL)))))
+
+#define __typefits(x,type,not) \
+	__builtin_choose_expr(sizeof(x)<=sizeof(type),(unsigned type)0,not)
+
 /*
  * The exception table consists of pairs of addresses: the first is the
  * address of an instruction that is allowed to fault, and the second is
@@ -335,6 +348,56 @@ do {									\
 		goto err_label;						\
 } while (0)
 
+static __must_check __always_inline bool user_access_begin(const void __user *ptr, size_t len)
+{
+	if (unlikely(!access_ok(ptr,len)))
+		return 0;
+	__enable_user_access();
+	return 1;
+}
+#define user_access_begin(a,b)	user_access_begin(a,b)
+#define user_access_end()	__disable_user_access();
+
+static inline unsigned long user_access_save(void) { return 0UL; }
+static inline void user_access_restore(unsigned long enabled) { }
+
+#define unsafe_put_user(x, ptr, label)	do {				\
+	long __kr_err = 0;						\
+	__put_user_nocheck(x, (ptr), __kr_err);				\
+	if (__kr_err) goto label;					\
+} while (0)
+
+#define unsafe_get_user(x, ptr, label)	do {				\
+	long __kr_err = 0;						\
+	__inttype(*(ptr)) __gu_val;					\
+	__get_user_nocheck(__gu_val, (ptr), __kr_err);			\
+	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
+	if (__kr_err) goto label;					\
+} while (0)
+
+/*
+ * We want the unsafe accessors to always be inlined and use
+ * the error labels - thus the macro games.
+ */
+#define unsafe_copy_loop(dst, src, len, type, label)				\
+	while (len >= sizeof(type)) {						\
+		unsafe_put_user(*(type *)(src),(type __user *)(dst),label);	\
+		dst += sizeof(type);						\
+		src += sizeof(type);						\
+		len -= sizeof(type);						\
+	}
+
+#define unsafe_copy_to_user(_dst,_src,_len,label)			\
+do {									\
+	char __user *__ucu_dst = (_dst);				\
+	const char *__ucu_src = (_src);					\
+	size_t __ucu_len = (_len);					\
+	unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label);	\
+	unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label);	\
+	unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label);	\
+	unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label);	\
+} while (0)
+
 #else /* CONFIG_MMU */
 #include <asm-generic/uaccess.h>
 #endif /* CONFIG_MMU */
-- 
2.34.1



From cyrilbur at tenstorrent.com  Mon Nov 18 15:01:10 2024
From: cyrilbur at tenstorrent.com (Cyril Bur)
Date: Mon, 18 Nov 2024 23:01:10 +0000
Subject: [PATCH v2 2/4] riscv: uaccess: use input constraints for ptr of __put_user
In-Reply-To: <20241118230112.2872978-1-cyrilbur@tenstorrent.com>
References: <20241118230112.2872978-1-cyrilbur@tenstorrent.com>
Message-ID: <20241118230112.2872978-3-cyrilbur@tenstorrent.com>

From: Jisheng Zhang <jszhang at kernel.org>

I believe the output constraints "=m" is not necessary, because
the instruction itself is "write", we don't need the compiler
to "write" for us. So tell compiler we read from memory instead
of writing.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
Signed-off-by: Cyril Bur <cyrilbur at tenstorrent.com>
---
 arch/riscv/include/asm/uaccess.h | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index 09d4ca37522c..84b084e388a7 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -186,11 +186,11 @@ do {								\
 	__typeof__(*(ptr)) __x = x;				\
 	__asm__ __volatile__ (					\
 		"1:\n"						\
-		"	" insn " %z2, %1\n"			\
+		"	" insn " %z1, %2\n"			\
 		"2:\n"						\
 		_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0)		\
-		: "+r" (err), "=m" (*(ptr))			\
-		: "rJ" (__x));					\
+		: "+r" (err)			\
+		: "rJ" (__x), "m"(*(ptr)));					\
 } while (0)
 
 #ifdef CONFIG_64BIT
@@ -203,16 +203,16 @@ do {								\
 	u64 __x = (__typeof__((x)-(x)))(x);			\
 	__asm__ __volatile__ (					\
 		"1:\n"						\
-		"	sw %z3, %1\n"				\
+		"	sw %z1, %3\n"				\
 		"2:\n"						\
-		"	sw %z4, %2\n"				\
+		"	sw %z2, %4\n"				\
 		"3:\n"						\
 		_ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0)		\
 		_ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0)		\
-		: "+r" (err),					\
-			"=m" (__ptr[__LSW]),			\
-			"=m" (__ptr[__MSW])			\
-		: "rJ" (__x), "rJ" (__x >> 32));		\
+		: "+r" (err)					\
+		: "rJ" (__x), "rJ" (__x >> 32),			\
+			"m" (__ptr[__LSW]),			\
+			"m" (__ptr[__MSW]));			\
 } while (0)
 #endif /* CONFIG_64BIT */
 
-- 
2.34.1



From cyrilbur at tenstorrent.com  Mon Nov 18 15:01:11 2024
From: cyrilbur at tenstorrent.com (Cyril Bur)
Date: Mon, 18 Nov 2024 23:01:11 +0000
Subject: [PATCH v2 3/4] riscv: uaccess: use 'asm goto' for put_user()
In-Reply-To: <20241118230112.2872978-1-cyrilbur@tenstorrent.com>
References: <20241118230112.2872978-1-cyrilbur@tenstorrent.com>
Message-ID: <20241118230112.2872978-4-cyrilbur@tenstorrent.com>

From: Jisheng Zhang <jszhang at kernel.org>

'asm goto' generates noticeably better code since we don't need to
test the error etc, the exception just jumps to the error handling
directly.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
Signed-off-by: Cyril Bur <cyrilbur at tenstorrent.com>
---
 arch/riscv/include/asm/uaccess.h | 70 +++++++++++++++-----------------
 1 file changed, 33 insertions(+), 37 deletions(-)

diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index 84b084e388a7..916df594ef3c 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -181,61 +181,66 @@ do {								\
 		((x) = (__force __typeof__(x))0, -EFAULT);	\
 })
 
-#define __put_user_asm(insn, x, ptr, err)			\
+#define __put_user_asm(insn, x, ptr, label)			\
 do {								\
 	__typeof__(*(ptr)) __x = x;				\
-	__asm__ __volatile__ (					\
+	asm goto(						\
 		"1:\n"						\
-		"	" insn " %z1, %2\n"			\
-		"2:\n"						\
-		_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0)		\
-		: "+r" (err)			\
-		: "rJ" (__x), "m"(*(ptr)));					\
+		"	" insn " %z0, %1\n"			\
+		_ASM_EXTABLE(1b, %l2)				\
+		: : "rJ" (__x), "m"(*(ptr)) : : label);		\
 } while (0)
 
 #ifdef CONFIG_64BIT
-#define __put_user_8(x, ptr, err) \
-	__put_user_asm("sd", x, ptr, err)
+#define __put_user_8(x, ptr, label) \
+	__put_user_asm("sd", x, ptr, label)
 #else /* !CONFIG_64BIT */
-#define __put_user_8(x, ptr, err)				\
+#define __put_user_8(x, ptr, label)				\
 do {								\
 	u32 __user *__ptr = (u32 __user *)(ptr);		\
 	u64 __x = (__typeof__((x)-(x)))(x);			\
-	__asm__ __volatile__ (					\
+	asm goto(						\
 		"1:\n"						\
-		"	sw %z1, %3\n"				\
+		"	sw %z0, %2\n"				\
 		"2:\n"						\
-		"	sw %z2, %4\n"				\
-		"3:\n"						\
-		_ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0)		\
-		_ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0)		\
-		: "+r" (err)					\
-		: "rJ" (__x), "rJ" (__x >> 32),			\
+		"	sw %z1, %3\n"				\
+		_ASM_EXTABLE(1b, %l4)				\
+		_ASM_EXTABLE(2b, %l4)				\
+		: : "rJ" (__x), "rJ" (__x >> 32),		\
 			"m" (__ptr[__LSW]),			\
-			"m" (__ptr[__MSW]));			\
+			"m" (__ptr[__MSW]) : : label);		\
 } while (0)
 #endif /* CONFIG_64BIT */
 
-#define __put_user_nocheck(x, __gu_ptr, __pu_err)					\
+#define __put_user_nocheck(x, __gu_ptr, label)			\
 do {								\
 	switch (sizeof(*__gu_ptr)) {				\
 	case 1:							\
-		__put_user_asm("sb", (x), __gu_ptr, __pu_err);	\
+		__put_user_asm("sb", (x), __gu_ptr, label);	\
 		break;						\
 	case 2:							\
-		__put_user_asm("sh", (x), __gu_ptr, __pu_err);	\
+		__put_user_asm("sh", (x), __gu_ptr, label);	\
 		break;						\
 	case 4:							\
-		__put_user_asm("sw", (x), __gu_ptr, __pu_err);	\
+		__put_user_asm("sw", (x), __gu_ptr, label);	\
 		break;						\
 	case 8:							\
-		__put_user_8((x), __gu_ptr, __pu_err);	\
+		__put_user_8((x), __gu_ptr, label);		\
 		break;						\
 	default:						\
 		BUILD_BUG();					\
 	}							\
 } while (0)
 
+#define __put_user_error(x, ptr, err)				\
+do {								\
+	__label__ err_label;					\
+	__put_user_nocheck(x, ptr, err_label);			\
+	break;							\
+err_label:							\
+	(err) = -EFAULT;					\
+} while (0)
+
 /**
  * __put_user: - Write a simple value into user space, with less checking.
  * @x:   Value to copy to user space.
@@ -266,7 +271,7 @@ do {								\
 	__chk_user_ptr(__gu_ptr);				\
 								\
 	__enable_user_access();					\
-	__put_user_nocheck(__val, __gu_ptr, __pu_err);		\
+	__put_user_error(__val, __gu_ptr, __pu_err);		\
 	__disable_user_access();				\
 								\
 	__pu_err;						\
@@ -340,13 +345,7 @@ do {									\
 } while (0)
 
 #define __put_kernel_nofault(dst, src, type, err_label)			\
-do {									\
-	long __kr_err = 0;						\
-									\
-	__put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err);	\
-	if (unlikely(__kr_err))						\
-		goto err_label;						\
-} while (0)
+	__put_user_nocheck(*((type *)(src)), (type *)(dst), err_label);
 
 static __must_check __always_inline bool user_access_begin(const void __user *ptr, size_t len)
 {
@@ -361,11 +360,8 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt
 static inline unsigned long user_access_save(void) { return 0UL; }
 static inline void user_access_restore(unsigned long enabled) { }
 
-#define unsafe_put_user(x, ptr, label)	do {				\
-	long __kr_err = 0;						\
-	__put_user_nocheck(x, (ptr), __kr_err);				\
-	if (__kr_err) goto label;					\
-} while (0)
+#define unsafe_put_user(x, ptr, label)					\
+	__put_user_nocheck(x, (ptr), label);
 
 #define unsafe_get_user(x, ptr, label)	do {				\
 	long __kr_err = 0;						\
-- 
2.34.1



From cyrilbur at tenstorrent.com  Mon Nov 18 15:01:12 2024
From: cyrilbur at tenstorrent.com (Cyril Bur)
Date: Mon, 18 Nov 2024 23:01:12 +0000
Subject: [PATCH v2 4/4] riscv: uaccess: use 'asm goto output' for get_user
In-Reply-To: <20241118230112.2872978-1-cyrilbur@tenstorrent.com>
References: <20241118230112.2872978-1-cyrilbur@tenstorrent.com>
Message-ID: <20241118230112.2872978-5-cyrilbur@tenstorrent.com>

From: Jisheng Zhang <jszhang at kernel.org>

'asm goto output' generates noticeably better code since we don't need
to test the error etc, the exception just jumps to the error handling
directly.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
Signed-off-by: Cyril Bur <cyrilbur at tenstorrent.com>
---
 arch/riscv/include/asm/uaccess.h | 90 +++++++++++++++++++++++---------
 1 file changed, 65 insertions(+), 25 deletions(-)

diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index 916df594ef3c..62a2ddf8c542 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -63,27 +63,56 @@
  * call.
  */
 
-#define __get_user_asm(insn, x, ptr, err)			\
+#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
+#define __get_user_asm(insn, x, ptr, label)			\
+	asm_goto_output(					\
+		"1:\n"						\
+		"	" insn " %0, %1\n"			\
+		_ASM_EXTABLE_UACCESS_ERR(1b, %l2, %0)		\
+		: "=&r" (x)					\
+		: "m" (*(ptr)) : : label)
+#else /* !CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
+#define __get_user_asm(insn, x, ptr, label)			\
 do {								\
-	__typeof__(x) __x;					\
+	long __gua_err = 0;					\
 	__asm__ __volatile__ (					\
 		"1:\n"						\
 		"	" insn " %1, %2\n"			\
 		"2:\n"						\
 		_ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1)	\
-		: "+r" (err), "=&r" (__x)			\
+		: "+r" (__gua_err), "=&r" (x)			\
 		: "m" (*(ptr)));				\
-	(x) = __x;						\
+	if (__gua_err)						\
+		goto label;					\
 } while (0)
+#endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
 
 #ifdef CONFIG_64BIT
-#define __get_user_8(x, ptr, err) \
-	__get_user_asm("ld", x, ptr, err)
+#define __get_user_8(x, ptr, label) \
+	__get_user_asm("ld", x, ptr, label)
 #else /* !CONFIG_64BIT */
-#define __get_user_8(x, ptr, err)				\
+
+#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
+#define __get_user_8(x, ptr, label)				\
+	u32 __user *__ptr = (u32 __user *)(ptr);		\
+	u32 __lo, __hi;						\
+	asm_goto_output(					\
+		"1:\n"						\
+		"	lw %0, %2\n"				\
+		"2:\n"						\
+		"	lw %1, %3\n"				\
+		_ASM_EXTABLE_UACCESS_ERR(1b, %l4, %0)		\
+		_ASM_EXTABLE_UACCESS_ERR(2b, %l4, %0)		\
+		: "=&r" (__lo), "=r" (__hi)			\
+		: "m" (__ptr[__LSW]), "m" (__ptr[__MSW])	\
+		: : label)
+
+#else /* !CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
+#define __get_user_8(x, ptr, label)				\
 do {								\
 	u32 __user *__ptr = (u32 __user *)(ptr);		\
 	u32 __lo, __hi;						\
+	long __gu8_err = 0;					\
 	__asm__ __volatile__ (					\
 		"1:\n"						\
 		"	lw %1, %3\n"				\
@@ -92,35 +121,51 @@ do {								\
 		"3:\n"						\
 		_ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1)	\
 		_ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1)	\
-		: "+r" (err), "=&r" (__lo), "=r" (__hi)		\
+		: "+r" (__gu8_err), "=&r" (__lo), "=r" (__hi)	\
 		: "m" (__ptr[__LSW]), "m" (__ptr[__MSW]));	\
-	if (err)						\
+	if (__gu8_err) {					\
 		__hi = 0;					\
+		goto label;					\
+	}							\
 	(x) = (__typeof__(x))((__typeof__((x)-(x)))(		\
 		(((u64)__hi << 32) | __lo)));			\
 } while (0)
+#endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
+
 #endif /* CONFIG_64BIT */
 
-#define __get_user_nocheck(x, __gu_ptr, __gu_err)		\
+#define __get_user_nocheck(x, __gu_ptr, label)			\
 do {								\
 	switch (sizeof(*__gu_ptr)) {				\
 	case 1:							\
-		__get_user_asm("lb", (x), __gu_ptr, __gu_err);	\
+		__get_user_asm("lb", (x), __gu_ptr, label);	\
 		break;						\
 	case 2:							\
-		__get_user_asm("lh", (x), __gu_ptr, __gu_err);	\
+		__get_user_asm("lh", (x), __gu_ptr, label);	\
 		break;						\
 	case 4:							\
-		__get_user_asm("lw", (x), __gu_ptr, __gu_err);	\
+		__get_user_asm("lw", (x), __gu_ptr, label);	\
 		break;						\
 	case 8:							\
-		__get_user_8((x), __gu_ptr, __gu_err);	\
+		__get_user_8((x), __gu_ptr, label);		\
 		break;						\
 	default:						\
 		BUILD_BUG();					\
 	}							\
 } while (0)
 
+#define __get_user_error(x, ptr, err)					\
+do {									\
+	__label__ __gu_failed;						\
+									\
+	__get_user_nocheck(x, ptr, __gu_failed);			\
+		err = 0;						\
+		break;							\
+__gu_failed:								\
+		x = 0;							\
+		err = -EFAULT;						\
+} while (0)
+
 /**
  * __get_user: - Get a simple variable from user space, with less checking.
  * @x:   Variable to store result.
@@ -145,13 +190,16 @@ do {								\
 ({								\
 	const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);	\
 	long __gu_err = 0;					\
+	__typeof__(x) __gu_val;					\
 								\
 	__chk_user_ptr(__gu_ptr);				\
 								\
 	__enable_user_access();					\
-	__get_user_nocheck(x, __gu_ptr, __gu_err);		\
+	__get_user_error(__gu_val, __gu_ptr, __gu_err);		\
 	__disable_user_access();				\
 								\
+	(x) = __gu_val;						\
+								\
 	__gu_err;						\
 })
 
@@ -336,13 +384,7 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
 }
 
 #define __get_kernel_nofault(dst, src, type, err_label)			\
-do {									\
-	long __kr_err = 0;						\
-									\
-	__get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err);	\
-	if (unlikely(__kr_err))						\
-		goto err_label;						\
-} while (0)
+	__get_user_nocheck(*((type *)(dst)), (type *)(src), err_label);
 
 #define __put_kernel_nofault(dst, src, type, err_label)			\
 	__put_user_nocheck(*((type *)(src)), (type *)(dst), err_label);
@@ -364,11 +406,9 @@ static inline void user_access_restore(unsigned long enabled) { }
 	__put_user_nocheck(x, (ptr), label);
 
 #define unsafe_get_user(x, ptr, label)	do {				\
-	long __kr_err = 0;						\
 	__inttype(*(ptr)) __gu_val;					\
-	__get_user_nocheck(__gu_val, (ptr), __kr_err);			\
+	__get_user_nocheck(__gu_val, (ptr), label);			\
 	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
-	if (__kr_err) goto label;					\
 } while (0)
 
 /*
-- 
2.34.1



From e at freeshell.de  Mon Nov 18 17:44:34 2024
From: e at freeshell.de (E Shattow)
Date: Mon, 18 Nov 2024 17:44:34 -0800
Subject: [PATCH v4 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
Message-ID: <20241119014449.49936-1-e@freeshell.de>

Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host mode
and connect vbus pinctrl.

This functionality depends on setting the USB over-current register to disable at bootloader phase, for example U-Boot:
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no
change in functional outcome with this patch applied; there is an error
visible to the user and this additional usb configuration fails (same as
it is now). The existing three VL805 connected USB ports via PCIe on
Milk-V Mars are not affected.

Changes since v3:
 - Rebase on linux-next/master
 - use tabs for code indent

Changes since v2:
 - Rebase on 6.12

Changes since v1:
 - series name (was "[PATCH] riscv: dts: starfive: jh7110-milkv-mars: set host mode and vbus pin for on-chip USB 2.0")
 - adjust pin label to obey dtschema
 - use cover letter

E Shattow (1):
  riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function

 .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

-- 
2.45.2



From e at freeshell.de  Mon Nov 18 17:44:35 2024
From: e at freeshell.de (E Shattow)
Date: Mon, 18 Nov 2024 17:44:35 -0800
Subject: [PATCH v4 1/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
In-Reply-To: <20241119014449.49936-1-e@freeshell.de>
References: <20241119014449.49936-1-e@freeshell.de>
Message-ID: <20241119014449.49936-2-e@freeshell.de>

Milk-V Mars set host mode and vbus pin for JH7110 on-chip USB 2.0

Signed-off-by: E Shattow <e at freeshell.de>
---
 .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
index 0d248b671d4b..3bd62ab78523 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -53,7 +53,23 @@ &spi0 {
 	status = "okay";
 };
 
+&sysgpio {
+	usb0_pins: usb0-0 {
+		vbus-pins {
+			pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS,
+					      GPOEN_ENABLE,
+					      GPI_NONE)>;
+			bias-disable;
+			input-disable;
+			input-schmitt-disable;
+			slew-rate = <0>;
+		};
+	};
+};
+
 &usb0 {
-	dr_mode = "peripheral";
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins>;
 	status = "okay";
 };
-- 
2.45.2



From e at freeshell.de  Mon Nov 18 19:12:18 2024
From: e at freeshell.de (E Shattow)
Date: Mon, 18 Nov 2024 19:12:18 -0800
Subject: [PATCH v2 0/1] riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function
Message-ID: <20241119031232.50726-1-e@freeshell.de>

Enable host mode JH7110 on-chip USB for Pine64 Star64 by setting host mode
and connect vbus pinctrl.

This functionality depends on setting the USB over-current register to disable at bootloader phase, for example U-Boot:
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no
change in functional outcome with this patch applied; there is an error
visible to the user and this usb configuration fails (same as it is now).

Changes since v1:
 - Rebase on linux-next/master
 - use tabs for code indent

E Shattow (1):
  riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function

 .../boot/dts/starfive/jh7110-pine64-star64.dts | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

-- 
2.45.2



From e at freeshell.de  Mon Nov 18 19:12:19 2024
From: e at freeshell.de (E Shattow)
Date: Mon, 18 Nov 2024 19:12:19 -0800
Subject: [PATCH v2 1/1] riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function
In-Reply-To: <20241119031232.50726-1-e@freeshell.de>
References: <20241119031232.50726-1-e@freeshell.de>
Message-ID: <20241119031232.50726-2-e@freeshell.de>

Pine64 Star64 set host mode and vbus pin for JH7110 on-chip USB 2.0

Signed-off-by: E Shattow <e at freeshell.de>
---
 .../boot/dts/starfive/jh7110-pine64-star64.dts | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
index fe4a490ecc61..b764d4d92fd9 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
@@ -80,7 +80,23 @@ &spi0 {
 	status = "okay";
 };
 
+&sysgpio {
+	usb0_pins: usb0-0 {
+		vbus-pins {
+			pinmux = <GPIOMUX(25,  GPOUT_SYS_USB_DRIVE_VBUS,
+					       GPOEN_ENABLE,
+					       GPI_NONE)>;
+			bias-disable;
+			input-disable;
+			input-schmitt-disable;
+			slew-rate = <0>;
+		};
+	};
+};
+
 &usb0 {
-	dr_mode = "peripheral";
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins>;
 	status = "okay";
 };
-- 
2.45.2



From ajones at ventanamicro.com  Mon Nov 18 23:49:37 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Tue, 19 Nov 2024 08:49:37 +0100
Subject: [RFC PATCH 08/15] iommu/riscv: Add IRQ domain for interrupt
 remapping
In-Reply-To: <20241118184336.GB559636@ziepe.ca>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-25-ajones@ventanamicro.com>
 <20241118184336.GB559636@ziepe.ca>
Message-ID: <20241119-62ff49fc1eedba051838dba2@orel>

On Mon, Nov 18, 2024 at 02:43:36PM -0400, Jason Gunthorpe wrote:
> On Thu, Nov 14, 2024 at 05:18:53PM +0100, Andrew Jones wrote:
> > @@ -1276,10 +1279,30 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
> >  	struct riscv_iommu_device *iommu = dev_to_iommu(dev);
> >  	struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
> >  	struct riscv_iommu_dc dc = {0};
> > +	int ret;
> >  
> >  	if (!riscv_iommu_pt_supported(iommu, domain->pgd_mode))
> >  		return -ENODEV;
> >  
> > +	if (riscv_iommu_bond_link(domain, dev))
> > +		return -ENOMEM;
> > +
> > +	if (iommu_domain->type == IOMMU_DOMAIN_UNMANAGED) {
> 
> Drivers should not be making tests like this.
> 
> > +		domain->gscid = ida_alloc_range(&riscv_iommu_gscids, 1,
> > +						RISCV_IOMMU_MAX_GSCID, GFP_KERNEL);
> > +		if (domain->gscid < 0) {
> > +			riscv_iommu_bond_unlink(domain, dev);
> > +			return -ENOMEM;
> > +		}
> > +
> > +		ret = riscv_iommu_irq_domain_create(domain, dev);
> > +		if (ret) {
> > +			riscv_iommu_bond_unlink(domain, dev);
> > +			ida_free(&riscv_iommu_gscids, domain->gscid);
> > +			return ret;
> > +		}
> > +	}
> 
> What are you trying to do? Make something behave different for VFIO?
> That isn't OK, we are trying to remove all the hacky VFIO special
> cases in drivers.
> 
> What is the HW issue here? It is very very strange (and probably not
> going to work right) that the irq domains change when domain
> attachment changes.
> 
> The IRQ setup should really be fixed before any device drivers probe
> onto the device.

I can't disagree with the statement that this looks hacky, but considering
a VFIO domain needs to use the g-stage for its single-stage translation
and a paging domain for the host would use s-stage, then it seems we need
to identify the VFIO domains for their special treatment. Is there an
example of converting VFIO special casing in other drivers to something
cleaner that you can point me at?

The IRQ domain will only be useful for device assignment, as that's when
an MSI translation will be needed. I can't think of any problems that
could arise from only creating the IRQ domain when probing assigned
devices, but I could certainly be missing something. Do you have some
potential problems in mind?

Thanks,
drew


From mingo at kernel.org  Mon Nov 18 23:52:28 2024
From: mingo at kernel.org (Ingo Molnar)
Date: Tue, 19 Nov 2024 08:52:28 +0100
Subject: [PATCH v2] riscv: perf: Drop defining
 `perf_instruction_pointer()` and `perf_misc_flags()`
In-Reply-To: <20241116160506.5324-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20241116160506.5324-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <ZzxDvLKGz1ouWzgX@gmail.com>


* Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:

> From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> 
> With commit 2c47e7a74f44 ("perf/core: Correct perf sampling with guest
> VMs"), the perf core now handles the functionality previously requiring
> arch-specific definitions of `perf_instruction_pointer()` and
> `perf_misc_flags()`. As these definitions are no longer necessary for
> RISC-V, this patch removes their implementation and declarations.
> 
> This change also fixes the following build issue on RISC-V:
> 
>     ./include/linux/perf_event.h:1679:84: error: macro "perf_misc_flags" passed 2 arguments, but takes just 1
>     ./include/linux/perf_event.h:1679:22: error: 'perf_misc_flags' redeclared as different kind of symbol
>     ./include/linux/perf_event.h:1680:22: error: conflicting types for 'perf_instruction_pointer'; have 'long unsigned int(struct perf_event *, struct pt_regs *)'
> 
> The above errors arise from conflicts between the core definitions in
> `linux/perf_event.h` and the RISC-V-specific definitions in
> `arch/riscv/include/asm/perf_event.h`. Removing the RISC-V-specific
> definitions resolves these issues and aligns the architecture with the
> updated perf core.
> 
> Fixes: 2c47e7a74f44 ("perf/core: Correct perf sampling with guest VMs")

Yeah, so the Fixes tag is wrong - this is not a build bug
with that commit, and your patch does not even apply to
the perf events tree.

This is a semantic merge conflict that arises in linux-next - the
riscv version of perf_instruction_pointer() function doesn't even
exist in the perf tree...

AFAICS the problem is that the riscv tree applied this commit:

  5bb5ccb3e8d8 ("riscv: perf: add guest vs host distinction")

While the perf tree solved this in a more generic fashion:

  2c47e7a74f44 perf/core: Correct perf sampling with guest VMs
  baff01f3d75f perf/x86: Refactor misc flag assignments
  3e807cf07d96 perf/powerpc: Use perf_arch_instruction_pointer()
  04782e63917d perf/core: Hoist perf_instruction_pointer() and perf_misc_flags()
  e33ed362cf9e perf/arm: Drop unused functions

So I believe, assuming the perf version works fine on riscv
(I haven't tested it), that the solution is to revert
5bb5ccb3e8d8 either in the riscv tree, or upon merging it.

Thanks,

	Ingo


From kirill.shutemov at linux.intel.com  Tue Nov 19 00:21:05 2024
From: kirill.shutemov at linux.intel.com (Kirill A. Shutemov)
Date: Tue, 19 Nov 2024 10:21:05 +0200
Subject: [PATCHv2 2/2] x86/mm: Make memremap(MEMREMAP_WB) map memory as
 encrypted by default
In-Reply-To: <20241118164616.GAZztvWGs9cOV8t20_@fat_crate.local>
References: <20241021105723.2707507-1-kirill.shutemov@linux.intel.com>
 <20241021105723.2707507-3-kirill.shutemov@linux.intel.com>
 <20241118164616.GAZztvWGs9cOV8t20_@fat_crate.local>
Message-ID: <s4frmqwtuvclinuu7ttyzfpe7bj7hju5xgt6sxzy3gyt3prr62@rrgvhkv4lgwv>

On Mon, Nov 18, 2024 at 05:46:16PM +0100, Borislav Petkov wrote:
> On Mon, Oct 21, 2024 at 01:57:23PM +0300, Kirill A. Shutemov wrote:
> > It fixes crash on kexec in TDX guests if CONFIG_EISA is enabled.
> 
> Do TDX guests even need EISA?
> 
> "The EISA bus saw limited use between 1988 and 1995 when it was made obsolete
> by the PCI bus."
> 
> Sounds like no to me.
> 
> We usually simply stop coco guests from touching such legacy ranges:
> 
> f30470c190c2 ("x86/boot: Skip video memory access in the decompressor for SEV-ES/SNP")
> 
> so can you do that too?

Sure, we can workaround every place that touches such ranges. Or we can
address problem at the root and make creating decrypted/shared mappings
explicit.

Such mappings have both functional (as we see here) and security
implications (VMM can manipulate the guest memory range). We should not
create decrypted mappings by default on legacy interfaces.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


From ajones at ventanamicro.com  Tue Nov 19 00:28:46 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Tue, 19 Nov 2024 09:28:46 +0100
Subject: [RFC PATCH 04/15] iommu/riscv: report iommu capabilities
In-Reply-To: <ddd40bc3-7f2a-43c2-8918-a10c63bd05ba@arm.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-21-ajones@ventanamicro.com>
 <ddd40bc3-7f2a-43c2-8918-a10c63bd05ba@arm.com>
Message-ID: <20241119-76c9ff71b8834ef886b3ca86@orel>

On Fri, Nov 15, 2024 at 03:20:36PM +0000, Robin Murphy wrote:
> On 14/11/2024 4:18 pm, Andrew Jones wrote:
> > From: Tomasz Jeznach <tjeznach at rivosinc.com>
> > 
> > Report RISC-V IOMMU capabilities required by VFIO subsystem
> > to enable PCIe device assignment.
> 
> IOMMU_CAP_DEFERRED_FLUSH has nothing at all to do with VFIO. As far as I can
> tell from what's queued, riscv_iommu_unmap_pages() isn't really implementing
> the full optimisation to get the most out of it either.

Thanks, Robin. I'll drop this cap for the next version.

> 
> I guess IOMMU_CAP_CACHE_COHERENCY falls out of the assumption of a coherent
> IOMMU and lack of PBMT support making everything implicitly IOMMU_CACHE all
> the time whether you want it or not, but clarifying that might be nice
> (especially since there's some chance that something will eventually come
> along to break it...)

Yes, riscv selects ARCH_DMA_DEFAULT_COHERENT and the riscv IOMMU hardware
descriptions don't provide any way to say otherwise. I can put a comment
above the IOMMU_CAP_CACHE_COHERENCY case which states "The RISC-V IOMMU is
always DMA cache coherent", or did you have something else in mind?

Thanks,
drew

> 
> Thanks,
> Robin.
> 
> > Signed-off-by: Tomasz Jeznach <tjeznach at rivosinc.com>
> > Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
> > ---
> >   drivers/iommu/riscv/iommu.c | 12 ++++++++++++
> >   1 file changed, 12 insertions(+)
> > 
> > diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
> > index 8a05def774bd..3fe4ceba8dd3 100644
> > --- a/drivers/iommu/riscv/iommu.c
> > +++ b/drivers/iommu/riscv/iommu.c
> > @@ -1462,6 +1462,17 @@ static struct iommu_group *riscv_iommu_device_group(struct device *dev)
> >   	return generic_device_group(dev);
> >   }
> > +static bool riscv_iommu_capable(struct device *dev, enum iommu_cap cap)
> > +{
> > +	switch (cap) {
> > +	case IOMMU_CAP_CACHE_COHERENCY:
> > +	case IOMMU_CAP_DEFERRED_FLUSH:
> > +		return true;
> > +	default:
> > +		return false;
> > +	}
> > +}
> > +
> >   static int riscv_iommu_of_xlate(struct device *dev, const struct of_phandle_args *args)
> >   {
> >   	return iommu_fwspec_add_ids(dev, args->args, 1);
> > @@ -1526,6 +1537,7 @@ static void riscv_iommu_release_device(struct device *dev)
> >   static const struct iommu_ops riscv_iommu_ops = {
> >   	.pgsize_bitmap = SZ_4K,
> >   	.of_xlate = riscv_iommu_of_xlate,
> > +	.capable = riscv_iommu_capable,
> >   	.identity_domain = &riscv_iommu_identity_domain,
> >   	.blocked_domain = &riscv_iommu_blocking_domain,
> >   	.release_domain = &riscv_iommu_blocking_domain,


From ajones at ventanamicro.com  Tue Nov 19 00:34:07 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Tue, 19 Nov 2024 09:34:07 +0100
Subject: [PATCH v2] riscv: perf: Drop defining
 `perf_instruction_pointer()` and `perf_misc_flags()`
In-Reply-To: <ZzxDvLKGz1ouWzgX@gmail.com>
References: <20241116160506.5324-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <ZzxDvLKGz1ouWzgX@gmail.com>
Message-ID: <20241119-8542ffd5c08526b665895722@orel>

On Tue, Nov 19, 2024 at 08:52:28AM +0100, Ingo Molnar wrote:
> 
> * Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:
> 
> > From: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> > 
> > With commit 2c47e7a74f44 ("perf/core: Correct perf sampling with guest
> > VMs"), the perf core now handles the functionality previously requiring
> > arch-specific definitions of `perf_instruction_pointer()` and
> > `perf_misc_flags()`. As these definitions are no longer necessary for
> > RISC-V, this patch removes their implementation and declarations.
> > 
> > This change also fixes the following build issue on RISC-V:
> > 
> >     ./include/linux/perf_event.h:1679:84: error: macro "perf_misc_flags" passed 2 arguments, but takes just 1
> >     ./include/linux/perf_event.h:1679:22: error: 'perf_misc_flags' redeclared as different kind of symbol
> >     ./include/linux/perf_event.h:1680:22: error: conflicting types for 'perf_instruction_pointer'; have 'long unsigned int(struct perf_event *, struct pt_regs *)'
> > 
> > The above errors arise from conflicts between the core definitions in
> > `linux/perf_event.h` and the RISC-V-specific definitions in
> > `arch/riscv/include/asm/perf_event.h`. Removing the RISC-V-specific
> > definitions resolves these issues and aligns the architecture with the
> > updated perf core.
> > 
> > Fixes: 2c47e7a74f44 ("perf/core: Correct perf sampling with guest VMs")
> 
> Yeah, so the Fixes tag is wrong - this is not a build bug
> with that commit, and your patch does not even apply to
> the perf events tree.
> 
> This is a semantic merge conflict that arises in linux-next - the
> riscv version of perf_instruction_pointer() function doesn't even
> exist in the perf tree...
> 
> AFAICS the problem is that the riscv tree applied this commit:
> 
>   5bb5ccb3e8d8 ("riscv: perf: add guest vs host distinction")
> 
> While the perf tree solved this in a more generic fashion:
> 
>   2c47e7a74f44 perf/core: Correct perf sampling with guest VMs
>   baff01f3d75f perf/x86: Refactor misc flag assignments
>   3e807cf07d96 perf/powerpc: Use perf_arch_instruction_pointer()
>   04782e63917d perf/core: Hoist perf_instruction_pointer() and perf_misc_flags()
>   e33ed362cf9e perf/arm: Drop unused functions
> 
> So I believe, assuming the perf version works fine on riscv
> (I haven't tested it), that the solution is to revert
> 5bb5ccb3e8d8 either in the riscv tree, or upon merging it.

Hi Ingo,

This patch isn't a complete revert of 5bb5ccb3e8d8. The early returns in
perf_callchain_user() and perf_callchain_kernel() should remain and the
CONFIG_PERF_EVENTS #ifdef in arch/riscv/include/asm/perf_event.h should
remain as well.

Thanks,
drew


From namcao at linutronix.de  Tue Nov 19 03:10:56 2024
From: namcao at linutronix.de (Nam Cao)
Date: Tue, 19 Nov 2024 12:10:56 +0100
Subject: [PATCH] riscv: kprobes: Fix incorrect address calculation
Message-ID: <20241119111056.2554419-1-namcao@linutronix.de>

p->ainsn.api.insn is a pointer to u32, therefore arithmetic operations are
multiplied by four. This is clearly undesirable for this case.

Cast it to (void *) first before any calculation.

Below is a sample before/after. The dumped memory is two kprobe slots, the
first slot has

  - c.addiw a0, 0x1c (0x7125)
  - ebreak           (0x00100073)

and the second slot has:

  - c.addiw a0, -4   (0x7135)
  - ebreak           (0x00100073)

Before this patch:

(gdb) x/16xh 0xff20000000135000
0xff20000000135000:	0x7125	0x0000	0x0000	0x0000	0x7135	0x0010	0x0000	0x0000
0xff20000000135010:	0x0073	0x0010	0x0000	0x0000	0x0000	0x0000	0x0000	0x0000

After this patch:

(gdb) x/16xh 0xff20000000125000
0xff20000000125000:	0x7125	0x0073	0x0010	0x0000	0x7135	0x0073	0x0010	0x0000
0xff20000000125010:	0x0000	0x0000	0x0000	0x0000	0x0000	0x0000	0x0000	0x0000

Fixes: b1756750a397 ("riscv: kprobes: Use patch_text_nosync() for insn slots")
Signed-off-by: Nam Cao <namcao at linutronix.de>
Cc: stable at vger.kernel.org
---
 arch/riscv/kernel/probes/kprobes.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c
index 474a65213657..d2dacea1aedd 100644
--- a/arch/riscv/kernel/probes/kprobes.c
+++ b/arch/riscv/kernel/probes/kprobes.c
@@ -30,7 +30,7 @@ static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
 	p->ainsn.api.restore = (unsigned long)p->addr + len;
 
 	patch_text_nosync(p->ainsn.api.insn, &p->opcode, len);
-	patch_text_nosync(p->ainsn.api.insn + len, &insn, GET_INSN_LENGTH(insn));
+	patch_text_nosync((void *)p->ainsn.api.insn + len, &insn, GET_INSN_LENGTH(insn));
 }
 
 static void __kprobes arch_prepare_simulate(struct kprobe *p)
-- 
2.39.5



From jgg at ziepe.ca  Tue Nov 19 06:00:47 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Tue, 19 Nov 2024 10:00:47 -0400
Subject: [RFC PATCH 08/15] iommu/riscv: Add IRQ domain for interrupt
 remapping
In-Reply-To: <20241119-62ff49fc1eedba051838dba2@orel>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-25-ajones@ventanamicro.com>
 <20241118184336.GB559636@ziepe.ca>
 <20241119-62ff49fc1eedba051838dba2@orel>
Message-ID: <20241119140047.GC559636@ziepe.ca>

On Tue, Nov 19, 2024 at 08:49:37AM +0100, Andrew Jones wrote:
> On Mon, Nov 18, 2024 at 02:43:36PM -0400, Jason Gunthorpe wrote:
> > On Thu, Nov 14, 2024 at 05:18:53PM +0100, Andrew Jones wrote:
> > > @@ -1276,10 +1279,30 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
> > >  	struct riscv_iommu_device *iommu = dev_to_iommu(dev);
> > >  	struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
> > >  	struct riscv_iommu_dc dc = {0};
> > > +	int ret;
> > >  
> > >  	if (!riscv_iommu_pt_supported(iommu, domain->pgd_mode))
> > >  		return -ENODEV;
> > >  
> > > +	if (riscv_iommu_bond_link(domain, dev))
> > > +		return -ENOMEM;
> > > +
> > > +	if (iommu_domain->type == IOMMU_DOMAIN_UNMANAGED) {
> > 
> > Drivers should not be making tests like this.
> > 
> > > +		domain->gscid = ida_alloc_range(&riscv_iommu_gscids, 1,
> > > +						RISCV_IOMMU_MAX_GSCID, GFP_KERNEL);
> > > +		if (domain->gscid < 0) {
> > > +			riscv_iommu_bond_unlink(domain, dev);
> > > +			return -ENOMEM;
> > > +		}
> > > +
> > > +		ret = riscv_iommu_irq_domain_create(domain, dev);
> > > +		if (ret) {
> > > +			riscv_iommu_bond_unlink(domain, dev);
> > > +			ida_free(&riscv_iommu_gscids, domain->gscid);
> > > +			return ret;
> > > +		}
> > > +	}
> > 
> > What are you trying to do? Make something behave different for VFIO?
> > That isn't OK, we are trying to remove all the hacky VFIO special
> > cases in drivers.
> > 
> > What is the HW issue here? It is very very strange (and probably not
> > going to work right) that the irq domains change when domain
> > attachment changes.
> > 
> > The IRQ setup should really be fixed before any device drivers probe
> > onto the device.
> 
> I can't disagree with the statement that this looks hacky, but considering
> a VFIO domain needs to use the g-stage for its single-stage translation
> and a paging domain for the host would use s-stage, then it seems we need
> to identify the VFIO domains for their special treatment.

This is the wrong thinking entirely. There is no such thing as a "VFIO
domain".

Default VFIO created domains should act excatly the same as a DMA API
domain.

If you want your system to have irq remapping, then it should be on by
default and DMA API gets remapping too. There would need to be a very
strong reason not to do that in order to make something special for
riscv. If so you'd need to add some kind of flag to select it.

Until you reach nested translation there is no "need" for VFIO to use
any particular stage. The design is that default VFIO uses the same
stage as the DMA API because it is doing the same basic default
translation function.

Nested translation has a control to select the stage, and you can
then force the g-stage for VFIO users at that point.

Regardless, you must not use UNMANAGED as some indication of VFIO,
that is not what it means, that is not what it is for.

> Is there an example of converting VFIO special casing in other
> drivers to something cleaner that you can point me at?

Nobody has had an issue where they want interrupt remapping on/off
depending on VFIO. I think that is inherently wrong.

> The IRQ domain will only be useful for device assignment, as that's when
> an MSI translation will be needed. I can't think of any problems that
> could arise from only creating the IRQ domain when probing assigned
> devices, but I could certainly be missing something. Do you have some
> potential problems in mind?

I'm not an expert in the interrupt subsystem, but my understanding was
we expect the interrupt domains/etc to be static once a device driver
is probed. Changing things during iommu domain attach is after drivers
are probed. I don't really expect it to work correctly in all corner
cases.

VFIO is allowed to change the translation as it operates and we expect
that interrupts are not disturbed.

Jason


From robh at kernel.org  Tue Nov 19 06:12:36 2024
From: robh at kernel.org (Rob Herring)
Date: Tue, 19 Nov 2024 08:12:36 -0600
Subject: [PATCH v3 3/4] dt-bindings: mailbox: add binding for Microchip
 IPC mailbox controller
In-Reply-To: <20241105183513.1358736-4-valentina.fernandezalanis@microchip.com>
References: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
 <20241105183513.1358736-4-valentina.fernandezalanis@microchip.com>
Message-ID: <20241119141236.GA1099946-robh@kernel.org>

On Tue, Nov 05, 2024 at 06:35:12PM +0000, Valentina Fernandez wrote:
> Add a dt-binding for the Microchip Inter-Processor Communication (IPC)
> mailbox controller.
> 
> Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
> ---
>  .../bindings/mailbox/microchip,sbi-ipc.yaml   | 117 ++++++++++++++++++
>  1 file changed, 117 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml b/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
> new file mode 100644
> index 000000000000..9e67c09e4bea
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
> @@ -0,0 +1,117 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mailbox/microchip,sbi-ipc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Microchip Inter-processor communication (IPC) mailbox controller
> +
> +maintainers:
> +  - Valentina Fernandez <valentina.fernandezalanis at microchip.com>
> +
> +description:
> +  The Microchip Inter-processor Communication (IPC) facilitates
> +  message passing between processors using an interrupt signaling
> +  mechanism.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - description:
> +          Intended for use by software running in supervisor privileged
> +          mode (s-mode). This SBI interface is compatible with the Mi-V
> +          Inter-hart Communication (IHC) IP.
> +        items:
> +          - const: microchip,sbi-ipc
> +
> +      - description:
> +          SoC-specific compatible, intended for use by the SBI
> +          implementation in machine mode (m-mode).
> +        items:
> +          - const: microchip,miv-ihc-rtl-v2

Usually SoC specific compatibles don't have version numbers. And all 
hardware in an SoC is RTL at some point. So microchip,miv-ihc should be 
sufficient if 'miv' is an SoC.

> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    minItems: 1
> +    maxItems: 5
> +
> +  interrupt-names:
> +    minItems: 1
> +    maxItems: 5
> +    items:
> +      pattern: "^hart-[0-5]+$"
> +
> +  "#mbox-cells":
> +    description: >
> +      For the SBI "device", the cell represents the global "logical" channel IDs.
> +      The meaning of channel IDs are platform firmware dependent.
> +
> +      For the SoC-specific compatible string, the cell represents the physical
> +      channel and does not vary based on the platform firmware.
> +    const: 1
> +
> +  microchip,ihc-chan-disabled-mask:
> +    description: >
> +      Represents the enable/disable state of the bi-directional IHC
> +      channels within the MIV-IHC IP configuration.
> +
> +      The mask is a 16-bit value, but only the first 15 bits are utilized.
> +      Each of the bits corresponds to one of the 15 IHC channels.

That can be expressed as a constraint:

maximum: 0x7fff

Then you can drop this paragraph.

> +
> +      A bit set to '1' indicates that the corresponding channel is disabled,
> +      and any read or write operations to that channel will return zero.
> +
> +      A bit set to '0' indicates that the corresponding channel is enabled
> +      and will be accessible through its dedicated address range registers.
> +
> +      The remaining bit of the 16-bit mask is reserved and should be ignored.

And drop this one.

> +
> +      The actual enable/disable state of each channel is determined by the
> +      IP block?s configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint16
> +    default: 0
> +
> +required:
> +  - compatible
> +  - interrupts
> +  - interrupt-names
> +  - "#mbox-cells"
> +
> +additionalProperties: false
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: microchip,sbi-ipc
> +    then:
> +      properties:
> +        reg: false
> +        microchip,ihc-chan-disabled-mask: false
> +    else:
> +      required:
> +        - reg
> +        - microchip,ihc-chan-disabled-mask
> +
> +examples:
> +  - |
> +    mailbox {
> +      compatible = "microchip,sbi-ipc";
> +      interrupt-parent = <&plic>;
> +      interrupts = <180>, <179>, <178>;
> +      interrupt-names = "hart-1", "hart-2", "hart-3";
> +      #mbox-cells = <1>;
> +    };
> +  - |
> +    mailbox at 50000000 {
> +      compatible = "microchip,miv-ihc-rtl-v2";
> +      microchip,ihc-chan-disabled-mask = /bits/ 16 <0>;
> +      reg = <0x50000000 0x1C000>;
> +      interrupt-parent = <&plic>;
> +      interrupts = <180>, <179>, <178>;
> +      interrupt-names = "hart-1", "hart-2", "hart-3";
> +      #mbox-cells = <1>;
> +    };
> -- 
> 2.34.1
> 


From ajones at ventanamicro.com  Tue Nov 19 07:03:05 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Tue, 19 Nov 2024 16:03:05 +0100
Subject: =?US-ASCII?Q?Re=3A_=5BRFC_PATCH_08/15=5D_iommu/riscv=3A_A?=
 =?US-ASCII?Q?dd_IRQ_domain_for_interrupt_remapping?=
In-Reply-To: <20241119140047.GC559636@ziepe.ca>
References: <20241114161845.502027-17-ajones@ventanamicro.com> <20241114161845.502027-25-ajones@ventanamicro.com> <20241118184336.GB559636@ziepe.ca> <20241119-62ff49fc1eedba051838dba2@orel> <20241119140047.GC559636@ziepe.ca>
Message-ID: <DE13E1DF-7C68-461D-ADCD-8141B1ACEA5E@ventanamicro.com>

On November 19, 2024 3:00:47 PM GMT+01:00, Jason Gunthorpe <jgg at ziepe.ca> wrote:
>On Tue, Nov 19, 2024 at 08:49:37AM +0100, Andrew Jones wrote:
>> On Mon, Nov 18, 2024 at 02:43:36PM -0400, Jason Gunthorpe wrote:
>> > On Thu, Nov 14, 2024 at 05:18:53PM +0100, Andrew Jones wrote:
>> > > @@ -1276,10 +1279,30 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
>> > >  	struct riscv_iommu_device *iommu = dev_to_iommu(dev);
>> > >  	struct riscv_iommu_info *info = dev_iommu_priv_get(dev);
>> > >  	struct riscv_iommu_dc dc = {0};
>> > > +	int ret;
>> > >  
>> > >  	if (!riscv_iommu_pt_supported(iommu, domain->pgd_mode))
>> > >  		return -ENODEV;
>> > >  
>> > > +	if (riscv_iommu_bond_link(domain, dev))
>> > > +		return -ENOMEM;
>> > > +
>> > > +	if (iommu_domain->type == IOMMU_DOMAIN_UNMANAGED) {
>> > 
>> > Drivers should not be making tests like this.
>> > 
>> > > +		domain->gscid = ida_alloc_range(&riscv_iommu_gscids, 1,
>> > > +						RISCV_IOMMU_MAX_GSCID, GFP_KERNEL);
>> > > +		if (domain->gscid < 0) {
>> > > +			riscv_iommu_bond_unlink(domain, dev);
>> > > +			return -ENOMEM;
>> > > +		}
>> > > +
>> > > +		ret = riscv_iommu_irq_domain_create(domain, dev);
>> > > +		if (ret) {
>> > > +			riscv_iommu_bond_unlink(domain, dev);
>> > > +			ida_free(&riscv_iommu_gscids, domain->gscid);
>> > > +			return ret;
>> > > +		}
>> > > +	}
>> > 
>> > What are you trying to do? Make something behave different for VFIO?
>> > That isn't OK, we are trying to remove all the hacky VFIO special
>> > cases in drivers.
>> > 
>> > What is the HW issue here? It is very very strange (and probably not
>> > going to work right) that the irq domains change when domain
>> > attachment changes.
>> > 
>> > The IRQ setup should really be fixed before any device drivers probe
>> > onto the device.
>> 
>> I can't disagree with the statement that this looks hacky, but considering
>> a VFIO domain needs to use the g-stage for its single-stage translation
>> and a paging domain for the host would use s-stage, then it seems we need
>> to identify the VFIO domains for their special treatment.
>
>This is the wrong thinking entirely. There is no such thing as a "VFIO
>domain".
>
>Default VFIO created domains should act excatly the same as a DMA API
>domain.
>
>If you want your system to have irq remapping, then it should be on by
>default and DMA API gets remapping too. There would need to be a very
>strong reason not to do that in order to make something special for
>riscv. If so you'd need to add some kind of flag to select it.
>
>Until you reach nested translation there is no "need" for VFIO to use
>any particular stage. The design is that default VFIO uses the same
>stage as the DMA API because it is doing the same basic default
>translation function.

The RISC-V IOMMU needs to use g-stage for device assignment, if we also want to enable irqbypass, because the IOMMU is specified to only look at the MSI table when g-stage is in use. This is actually another reason the irq domain only makes sense for device assignment.

>
>Nested translation has a control to select the stage, and you can
>then force the g-stage for VFIO users at that point.

We could force riscv device assignment to always be nested, and when not providing an iommu to the guest, it will still be single-stage, but g-stage, but I don't think that's currently possible with VFIO, is it?

>
>Regardless, you must not use UNMANAGED as some indication of VFIO,
>that is not what it means, that is not what it is for.
>
>> Is there an example of converting VFIO special casing in other
>> drivers to something cleaner that you can point me at?
>
>Nobody has had an issue where they want interrupt remapping on/off
>depending on VFIO. I think that is inherently wrong.
>
>> The IRQ domain will only be useful for device assignment, as that's when
>> an MSI translation will be needed. I can't think of any problems that
>> could arise from only creating the IRQ domain when probing assigned
>> devices, but I could certainly be missing something. Do you have some
>> potential problems in mind?
>
>I'm not an expert in the interrupt subsystem, but my understanding was
>we expect the interrupt domains/etc to be static once a device driver
>is probed. Changing things during iommu domain attach is after drivers
>are probed. I don't really expect it to work correctly in all corner
>cases.

With VFIO the iommu domain attach comes after an unbind/bind, so the new driver is probed. I think that's a safe time. However, if there could be cases where the attach does not follow an unbind/bind, then I agree that wouldn't be safe. I'll consider always creating an IRQ domain, even if it won't provide any additional functionality unless the device is assigned.

>
>VFIO is allowed to change the translation as it operates and we expect
>that interrupts are not disturbed.
>

The IRQ domain stays the same during operation, the only changes are the mappings from what the guest believes are its s-mode interrupt files to the hypervisor selected guest interrupt files, and these changes are made possible by the IRQ domain's vcpu-affinity support.

Thanks,
drew


From jgg at ziepe.ca  Tue Nov 19 07:36:22 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Tue, 19 Nov 2024 11:36:22 -0400
Subject: [RFC PATCH 08/15] iommu/riscv: Add IRQ domain for interrupt
 remapping
In-Reply-To: <DE13E1DF-7C68-461D-ADCD-8141B1ACEA5E@ventanamicro.com>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-25-ajones@ventanamicro.com>
 <20241118184336.GB559636@ziepe.ca>
 <20241119-62ff49fc1eedba051838dba2@orel>
 <20241119140047.GC559636@ziepe.ca>
 <DE13E1DF-7C68-461D-ADCD-8141B1ACEA5E@ventanamicro.com>
Message-ID: <20241119153622.GD559636@ziepe.ca>

On Tue, Nov 19, 2024 at 04:03:05PM +0100, Andrew Jones wrote:

> >This is the wrong thinking entirely. There is no such thing as a "VFIO
> >domain".
> >
> >Default VFIO created domains should act excatly the same as a DMA API
> >domain.
> >
> >If you want your system to have irq remapping, then it should be on by
> >default and DMA API gets remapping too. There would need to be a very
> >strong reason not to do that in order to make something special for
> >riscv. If so you'd need to add some kind of flag to select it.
> >
> >Until you reach nested translation there is no "need" for VFIO to use
> >any particular stage. The design is that default VFIO uses the same
> >stage as the DMA API because it is doing the same basic default
> >translation function.
> 
> The RISC-V IOMMU needs to use g-stage for device assignment, if we
> also want to enable irqbypass, because the IOMMU is specified to
> only look at the MSI table when g-stage is in use. This is actually
> another reason the irq domain only makes sense for device
> assignment.

Most HW has enablable interrupt remapping and typically Linux just
turns it always on.

Is there a reason the DMA API shouldn't use this translation mode too?
That seems to be the main issue here, you are trying to avoid
interrupt remapping for DMA API and use it only for VFIO, and haven't
explained why we need such complexity. Just use it always?

> >Nested translation has a control to select the stage, and you can
> >then force the g-stage for VFIO users at that point.
> 
> We could force riscv device assignment to always be nested, and when
> not providing an iommu to the guest, it will still be single-stage,
> but g-stage, but I don't think that's currently possible with VFIO,
> is it?

That isn't what I mean, I mean you should not be forcing the kind of
domain being created until you get to special cases like nested.

Default VFIO should work the same as the DMA API.

> >> The IRQ domain will only be useful for device assignment, as that's when
> >> an MSI translation will be needed. I can't think of any problems that
> >> could arise from only creating the IRQ domain when probing assigned
> >> devices, but I could certainly be missing something. Do you have some
> >> potential problems in mind?
> >
> >I'm not an expert in the interrupt subsystem, but my understanding was
> >we expect the interrupt domains/etc to be static once a device driver
> >is probed. Changing things during iommu domain attach is after drivers
> >are probed. I don't really expect it to work correctly in all corner
> >cases.
> 
> With VFIO the iommu domain attach comes after an unbind/bind, so the
> new driver is probed.

That's the opposite of what I mean. The irq domain should be setup
*before* VFIO binds to the driver.

Changing the active irq_domain while VFIO is already probed to the
device is highly unlikely to work right in all cases.

> I think that's a safe time. However, if there
> could be cases where the attach does not follow an unbind/bind, then
> I agree that wouldn't be safe.

These cases exist.

> I'll consider always creating an IRQ
> domain, even if it won't provide any additional functionality unless
> the device is assigned.

That isn't ideal, the translation under the IRQs shouldn't really be
changing as the translation under the IOMMU changes.

Further, VFIO assumes iommu_group_has_isolated_msi(), ie
IRQ_DOMAIN_FLAG_ISOLATED_MSI, is fixed while it is is bound. Will that
be true if the iommu is flapping all about? What will you do when VFIO
has it attached to a blocked domain?

It just doesn't make sense to change something so fundamental as the
interrupt path on an iommu domain attachement. :\

> >VFIO is allowed to change the translation as it operates and we expect
> >that interrupts are not disturbed.
> 
> The IRQ domain stays the same during operation, the only changes are
> the mappings from what the guest believes are its s-mode interrupt
> files to the hypervisor selected guest interrupt files, and these
> changes are made possible by the IRQ domain's vcpu-affinity support.

That is only the case when talking about kvm, this all still has to
work fully for non-kvm VFIO uses cases too.

Jason


From cleger at rivosinc.com  Tue Nov 19 08:57:36 2024
From: cleger at rivosinc.com (=?UTF-8?B?Q2zDqW1lbnQgTMOpZ2Vy?=)
Date: Tue, 19 Nov 2024 17:57:36 +0100
Subject: [PATCH] riscv: fix memory leakage in
 process_accumulated_relocations
In-Reply-To: <35cab46a.6d145.19334919ed0.Coremail.zhangkai@iscas.ac.cn>
References: <35cab46a.6d145.19334919ed0.Coremail.zhangkai@iscas.ac.cn>
Message-ID: <ffcdbcbe-a5f6-48f4-a0a3-0d35c6c80050@rivosinc.com>



On 16/11/2024 11:42, zhangkai at iscas.ac.cn wrote:
> When module relocation is done, process_accumulated_relocations()
> frees all dynamic allocated memory. rel_head_iter-&gt;rel_entry is
> missed to free that kmemleak might report:
> 
> unreferenced object 0xffffffd880c5fc40 (size 16):
>   comm "insmod", pid 1101, jiffies 4295045138
>   hex dump (first 16 bytes):
>     e0 c0 f5 87 d8 ff ff ff 60 c5 f5 87 d8 ff ff ff  ........`.......
>   backtrace (crc d2ecb20c):
>     [&lt;00000000b01655f6&gt;] kmalloc_trace_noprof+0x268/0x2f6
>     [&lt;000000006dc0067a&gt;] add_relocation_to_accumulate.constprop.0+0xf2/0x1aa
>     [&lt;00000000e1b29a36&gt;] apply_relocate_add+0x13c/0x36e
>     [&lt;000000007543f1fb&gt;] load_module+0x5c6/0x83e
>     [&lt;00000000abce12e8&gt;] init_module_from_file+0x74/0xaa
>     [&lt;0000000049413e3d&gt;] idempotent_init_module+0x116/0x22e
>     [&lt;00000000f9b98b85&gt;] __riscv_sys_finit_module+0x62/0xae
> 
> Signed-off-by: Kai Zhang <zhangkai at iscas.ac.cn>
> ---
>  arch/riscv/kernel/module.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
> index 1cd461f3d87..f8c3c4b47dc 100644
> --- a/arch/riscv/kernel/module.c
> +++ b/arch/riscv/kernel/module.c
> @@ -643,6 +643,7 @@ process_accumulated_relocations(struct module *me,
>                         }
>                         reloc_handlers[curr_type].accumulate_handler(
>                                 me, location, buffer);
> +                       kfree(rel_head_iter-&gt;rel_entry);

Hey Kai,

Your patch output is messed up probably due to some encoding issue.

But looknig at it and the module code, it seems like rel_entry does not
need to be a pointer. It can be a plain "struct list_head rel_entry" and
then simply pass the list_head pointer rather than allocating/freeing
it. That remove an allocation as well as some memory leak.

BTW, for fixes, you should add a Fixes: tag with the original commit
sha1 that introduced the bug.

Thanks,

Cl?ment

>                         kfree(rel_head_iter);
>                 }
>                 kfree(bucket_iter);



From atishp at rivosinc.com  Tue Nov 19 12:29:48 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Tue, 19 Nov 2024 12:29:48 -0800
Subject: [PATCH 0/8] Add SBI v3.0 PMU enhancements
Message-ID: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>

SBI v3.0 specification[1] added two new improvements to the PMU chaper.

1. Added an additional get_event_info function to query event availablity
in bulk instead of individual SBI calls for each event. This helps in
improving the boot time.

2. Raw event width allowed by the platform is widened to have 56 bits
with RAW event v2 as per new clarification in the priv ISA[2].

Apart from implementing these new features, this series adds a fix
in firmware event mapping and updates the kvm SBI implementation to
SBI v3.0.

The opensbi patches can be found at [3]. This series can be found at [4].

[1] https://github.com/riscv-non-isa/riscv-sbi-doc/releases/download/vv3.0-rc2/riscv-sbi.pdf
[2] https://github.com/riscv/riscv-isa-manual/issues/1578
[3] https://github.com/atishp04/opensbi/tree/b4/pmu_event_info
[4] https://github.com/atishp04/linux/tree/b4/pmu_event_info

Signed-off-by: Atish Patra <atishp at rivosinc.com>
---
Atish Patra (8):
      drivers/perf: riscv: Add SBI v3.0 flag
      drivers/perf: riscv: Fix Platform firmware event data
      drivers/perf: riscv: Add raw event v2 support
      RISC-V: KVM: Add support for Raw event v2
      drivers/perf: riscv: Implement PMU event info function
      drivers/perf: riscv: Export PMU event info function
      RISC-V: KVM: Implement get event info function
      RISC-V: KVM: Upgrade the supported SBI version to 3.0

 arch/riscv/include/asm/kvm_vcpu_pmu.h |   3 +
 arch/riscv/include/asm/kvm_vcpu_sbi.h |   2 +-
 arch/riscv/include/asm/sbi.h          |  12 +++
 arch/riscv/kvm/vcpu_pmu.c             |  71 +++++++++++++
 arch/riscv/kvm/vcpu_sbi_pmu.c         |   3 +
 drivers/perf/riscv_pmu_sbi.c          | 184 +++++++++++++++++++++++++---------
 include/linux/perf/riscv_pmu.h        |   2 +
 7 files changed, 228 insertions(+), 49 deletions(-)
---
base-commit: acb481ddd977ab669128bab61024d05e7dc1654f
change-id: 20241018-pmu_event_info-986e21ce6bd3
--
Regards,
Atish patra



From atishp at rivosinc.com  Tue Nov 19 12:29:49 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Tue, 19 Nov 2024 12:29:49 -0800
Subject: [PATCH 1/8] drivers/perf: riscv: Add SBI v3.0 flag
In-Reply-To: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
Message-ID: <20241119-pmu_event_info-v1-1-a4f9691421f8@rivosinc.com>

There are new PMU related features introduced in SBI v3.0.
1. Raw Event v2 which allows mhpmeventX value to be 56 bit wide.
2. Get Event info function to do a bulk query at one shot.

Signed-off-by: Atish Patra <atishp at rivosinc.com>
---
 drivers/perf/riscv_pmu_sbi.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 391ca1422cae..cb98efa9b106 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -63,6 +63,7 @@ PMU_FORMAT_ATTR(event, "config:0-47");
 PMU_FORMAT_ATTR(firmware, "config:62-63");
 
 static bool sbi_v2_available;
+static bool sbi_v3_available;
 static DEFINE_STATIC_KEY_FALSE(sbi_pmu_snapshot_available);
 #define sbi_pmu_snapshot_available() \
 	static_branch_unlikely(&sbi_pmu_snapshot_available)
@@ -1450,6 +1451,9 @@ static int __init pmu_sbi_devinit(void)
 	if (sbi_spec_version >= sbi_mk_version(2, 0))
 		sbi_v2_available = true;
 
+	if (sbi_spec_version >= sbi_mk_version(3, 0))
+		sbi_v3_available = true;
+
 	ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_RISCV_STARTING,
 				      "perf/riscv/pmu:starting",
 				      pmu_sbi_starting_cpu, pmu_sbi_dying_cpu);

-- 
2.34.1



From atishp at rivosinc.com  Tue Nov 19 12:29:51 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Tue, 19 Nov 2024 12:29:51 -0800
Subject: [PATCH 3/8] drivers/perf: riscv: Add raw event v2 support
In-Reply-To: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
Message-ID: <20241119-pmu_event_info-v1-3-a4f9691421f8@rivosinc.com>

SBI v3.0 introduced a new raw event type that allows wider
mhpmeventX width to be programmed via CFG_MATCH.

Use the raw event v2 if SBI v3.0 is available.

Signed-off-by: Atish Patra <atishp at rivosinc.com>
---
 arch/riscv/include/asm/sbi.h |  4 ++++
 drivers/perf/riscv_pmu_sbi.c | 18 ++++++++++++------
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 9be38b05f4ad..3ee9bfa5e77c 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -159,7 +159,10 @@ struct riscv_pmu_snapshot_data {
 
 #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
 #define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
+/* SBI v3.0 allows extended hpmeventX width value */
+#define RISCV_PMU_RAW_EVENT_V2_MASK GENMASK_ULL(55, 0)
 #define RISCV_PMU_RAW_EVENT_IDX 0x20000
+#define RISCV_PMU_RAW_EVENT_V2_IDX 0x30000
 #define RISCV_PLAT_FW_EVENT	0xFFFF
 
 /** General pmu event codes specified in SBI PMU extension */
@@ -217,6 +220,7 @@ enum sbi_pmu_event_type {
 	SBI_PMU_EVENT_TYPE_HW = 0x0,
 	SBI_PMU_EVENT_TYPE_CACHE = 0x1,
 	SBI_PMU_EVENT_TYPE_RAW = 0x2,
+	SBI_PMU_EVENT_TYPE_RAW_V2 = 0x3,
 	SBI_PMU_EVENT_TYPE_FW = 0xf,
 };
 
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 50cbdbf66bb7..f0e845ff6b79 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -59,7 +59,7 @@ asm volatile(ALTERNATIVE(						\
 #define PERF_EVENT_FLAG_USER_ACCESS	BIT(SYSCTL_USER_ACCESS)
 #define PERF_EVENT_FLAG_LEGACY		BIT(SYSCTL_LEGACY)
 
-PMU_FORMAT_ATTR(event, "config:0-47");
+PMU_FORMAT_ATTR(event, "config:0-55");
 PMU_FORMAT_ATTR(firmware, "config:62-63");
 
 static bool sbi_v2_available;
@@ -527,18 +527,24 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
 		break;
 	case PERF_TYPE_RAW:
 		/*
-		 * As per SBI specification, the upper 16 bits must be unused
-		 * for a hardware raw event.
+		 * As per SBI v0.3 specification,
+		 *  -- the upper 16 bits must be unused for a hardware raw event.
+		 * As per SBI v3.0 specification,
+		 *  -- the upper 8 bits must be unused for a hardware raw event.
 		 * Bits 63:62 are used to distinguish between raw events
 		 * 00 - Hardware raw event
 		 * 10 - SBI firmware events
 		 * 11 - Risc-V platform specific firmware event
 		 */
-
 		switch (config >> 62) {
 		case 0:
-			ret = RISCV_PMU_RAW_EVENT_IDX;
-			*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
+			if (sbi_v3_available) {
+				*econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
+				ret = RISCV_PMU_RAW_EVENT_V2_IDX;
+			} else {
+				*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
+				ret = RISCV_PMU_RAW_EVENT_IDX;
+			}
 			break;
 		case 2:
 			ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);

-- 
2.34.1



From atishp at rivosinc.com  Tue Nov 19 12:29:50 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Tue, 19 Nov 2024 12:29:50 -0800
Subject: [PATCH 2/8] drivers/perf: riscv: Fix Platform firmware event data
In-Reply-To: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
Message-ID: <20241119-pmu_event_info-v1-2-a4f9691421f8@rivosinc.com>

Platform firmware event data field is allowed to be 62 bits for
Linux as uppper most two bits are reserved to indicate SBI fw or
platform specific firmware events.
However, the event data field is masked as per the hardware raw
event mask which is not correct.

Fix the platform firmware event data field with proper mask.

Fixes: f0c9363db2dd ("perf/riscv-sbi: Add platform specific firmware event handling")

Signed-off-by: Atish Patra <atishp at rivosinc.com>
---
 arch/riscv/include/asm/sbi.h |  1 +
 drivers/perf/riscv_pmu_sbi.c | 12 +++++-------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 98f631b051db..9be38b05f4ad 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -158,6 +158,7 @@ struct riscv_pmu_snapshot_data {
 };
 
 #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
+#define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
 #define RISCV_PMU_RAW_EVENT_IDX 0x20000
 #define RISCV_PLAT_FW_EVENT	0xFFFF
 
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index cb98efa9b106..50cbdbf66bb7 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -508,7 +508,6 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
 {
 	u32 type = event->attr.type;
 	u64 config = event->attr.config;
-	u64 raw_config_val;
 	int ret;
 
 	/*
@@ -529,21 +528,20 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
 	case PERF_TYPE_RAW:
 		/*
 		 * As per SBI specification, the upper 16 bits must be unused
-		 * for a raw event.
+		 * for a hardware raw event.
 		 * Bits 63:62 are used to distinguish between raw events
 		 * 00 - Hardware raw event
 		 * 10 - SBI firmware events
 		 * 11 - Risc-V platform specific firmware event
 		 */
-		raw_config_val = config & RISCV_PMU_RAW_EVENT_MASK;
+
 		switch (config >> 62) {
 		case 0:
 			ret = RISCV_PMU_RAW_EVENT_IDX;
-			*econfig = raw_config_val;
+			*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
 			break;
 		case 2:
-			ret = (raw_config_val & 0xFFFF) |
-				(SBI_PMU_EVENT_TYPE_FW << 16);
+			ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
 			break;
 		case 3:
 			/*
@@ -552,7 +550,7 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
 			 * Event data - raw event encoding
 			 */
 			ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
-			*econfig = raw_config_val;
+			*econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
 			break;
 		}
 		break;

-- 
2.34.1



From atishp at rivosinc.com  Tue Nov 19 12:29:52 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Tue, 19 Nov 2024 12:29:52 -0800
Subject: [PATCH 4/8] RISC-V: KVM: Add support for Raw event v2
In-Reply-To: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
Message-ID: <20241119-pmu_event_info-v1-4-a4f9691421f8@rivosinc.com>

SBI v3.0 introuced a new raw event type v2 for wider mhpmeventX
programming. Add the support in kvm for that.

Signed-off-by: Atish Patra <atishp at rivosinc.com>
---
 arch/riscv/kvm/vcpu_pmu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 2707a51b082c..efd66835c2b8 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -60,6 +60,7 @@ static u32 kvm_pmu_get_perf_event_type(unsigned long eidx)
 		type = PERF_TYPE_HW_CACHE;
 		break;
 	case SBI_PMU_EVENT_TYPE_RAW:
+	case SBI_PMU_EVENT_TYPE_RAW_V2:
 	case SBI_PMU_EVENT_TYPE_FW:
 		type = PERF_TYPE_RAW;
 		break;
@@ -128,6 +129,9 @@ static u64 kvm_pmu_get_perf_event_config(unsigned long eidx, uint64_t evt_data)
 	case SBI_PMU_EVENT_TYPE_RAW:
 		config = evt_data & RISCV_PMU_RAW_EVENT_MASK;
 		break;
+	case SBI_PMU_EVENT_TYPE_RAW_V2:
+		config = evt_data & RISCV_PMU_RAW_EVENT_V2_MASK;
+		break;
 	case SBI_PMU_EVENT_TYPE_FW:
 		if (ecode < SBI_PMU_FW_MAX)
 			config = (1ULL << 63) | ecode;

-- 
2.34.1



From atishp at rivosinc.com  Tue Nov 19 12:29:53 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Tue, 19 Nov 2024 12:29:53 -0800
Subject: [PATCH 5/8] drivers/perf: riscv: Implement PMU event info function
In-Reply-To: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
Message-ID: <20241119-pmu_event_info-v1-5-a4f9691421f8@rivosinc.com>

With the new SBI PMU event info function, we can query the availability
of the all standard SBI PMU events at boot time with a single ecall.
This improves the bootime by avoiding making an SBI call for each
standard PMU event. Since this function is defined only in SBI v3.0,
invoke this only if the underlying SBI implementation is v3.0 or higher.

Signed-off-by: Atish Patra <atishp at rivosinc.com>
---
 arch/riscv/include/asm/sbi.h |  7 +++++
 drivers/perf/riscv_pmu_sbi.c | 71 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 3ee9bfa5e77c..c04f64fbc01d 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -134,6 +134,7 @@ enum sbi_ext_pmu_fid {
 	SBI_EXT_PMU_COUNTER_FW_READ,
 	SBI_EXT_PMU_COUNTER_FW_READ_HI,
 	SBI_EXT_PMU_SNAPSHOT_SET_SHMEM,
+	SBI_EXT_PMU_EVENT_GET_INFO,
 };
 
 union sbi_pmu_ctr_info {
@@ -157,6 +158,12 @@ struct riscv_pmu_snapshot_data {
 	u64 reserved[447];
 };
 
+struct riscv_pmu_event_info {
+	u32 event_idx;
+	u32 output;
+	u64 event_data;
+};
+
 #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
 #define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
 /* SBI v3.0 allows extended hpmeventX width value */
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index f0e845ff6b79..2a6527cc9d97 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -100,6 +100,7 @@ static unsigned int riscv_pmu_irq;
 /* Cache the available counters in a bitmask */
 static unsigned long cmask;
 
+static int pmu_event_find_cache(u64 config);
 struct sbi_pmu_event_data {
 	union {
 		union {
@@ -299,6 +300,68 @@ static struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
 	},
 };
 
+static int pmu_sbi_check_event_info(void)
+{
+	int num_events = ARRAY_SIZE(pmu_hw_event_map) + PERF_COUNT_HW_CACHE_MAX *
+			 PERF_COUNT_HW_CACHE_OP_MAX * PERF_COUNT_HW_CACHE_RESULT_MAX;
+	struct riscv_pmu_event_info *event_info_shmem;
+	phys_addr_t base_addr;
+	int i, j, k, result = 0, count = 0;
+	struct sbiret ret;
+
+	event_info_shmem = (struct riscv_pmu_event_info *)
+			   kcalloc(num_events, sizeof(*event_info_shmem), GFP_KERNEL);
+	if (!event_info_shmem) {
+		pr_err("Can not allocate memory for event info query\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
+		event_info_shmem[count++].event_idx = pmu_hw_event_map[i].event_idx;
+
+	for (i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) {
+		for (int j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) {
+			for (int k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++)
+				event_info_shmem[count++].event_idx =
+							pmu_cache_event_map[i][j][k].event_idx;
+		}
+	}
+
+	base_addr = __pa(event_info_shmem);
+	if (IS_ENABLED(CONFIG_32BIT))
+		ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_EVENT_GET_INFO, lower_32_bits(base_addr),
+				upper_32_bits(base_addr), count, 0, 0, 0);
+	else
+		ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_EVENT_GET_INFO, base_addr, 0,
+				count, 0, 0, 0);
+	if (ret.error) {
+		result = -EOPNOTSUPP;
+		goto free_mem;
+	}
+	/* Do we need some barriers here or priv mode transition will ensure that */
+	for (i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++) {
+		if (!(event_info_shmem[i].output & 0x01))
+			pmu_hw_event_map[i].event_idx = -ENOENT;
+	}
+
+	count = ARRAY_SIZE(pmu_hw_event_map);
+
+	for (i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) {
+		for (j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) {
+			for (k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++) {
+				if (!(event_info_shmem[count].output & 0x01))
+					pmu_cache_event_map[i][j][k].event_idx = -ENOENT;
+				count++;
+			}
+		}
+	}
+
+free_mem:
+	kfree(event_info_shmem);
+
+	return result;
+}
+
 static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
 {
 	struct sbiret ret;
@@ -316,6 +379,14 @@ static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
 
 static void pmu_sbi_check_std_events(struct work_struct *work)
 {
+	int ret;
+
+	if (sbi_v3_available) {
+		ret = pmu_sbi_check_event_info();
+		if (!ret)
+			return;
+	}
+
 	for (int i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
 		pmu_sbi_check_event(&pmu_hw_event_map[i]);
 

-- 
2.34.1



From atishp at rivosinc.com  Tue Nov 19 12:29:54 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Tue, 19 Nov 2024 12:29:54 -0800
Subject: [PATCH 6/8] drivers/perf: riscv: Export PMU event info function
In-Reply-To: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
Message-ID: <20241119-pmu_event_info-v1-6-a4f9691421f8@rivosinc.com>

The event mapping function can be used in event info function to find out
the corresponding SBI PMU event encoding during the get_event_info function
as well. Refactor and export it so that it can be invoked from kvm and
internal driver.

Signed-off-by: Atish Patra <atishp at rivosinc.com>
---
 drivers/perf/riscv_pmu_sbi.c   | 111 ++++++++++++++++++++++-------------------
 include/linux/perf/riscv_pmu.h |   2 +
 2 files changed, 62 insertions(+), 51 deletions(-)

diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 2a6527cc9d97..8ddd094c82ad 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -414,6 +414,65 @@ static bool pmu_sbi_ctr_is_fw(int cidx)
 	return (info->type == SBI_PMU_CTR_TYPE_FW) ? true : false;
 }
 
+int riscv_pmu_get_event_info(u32 type, u64 config, u64 *econfig)
+{
+	int ret = -ENOENT;
+
+	switch (type) {
+	case PERF_TYPE_HARDWARE:
+		if (config >= PERF_COUNT_HW_MAX)
+			return -EINVAL;
+		ret = pmu_hw_event_map[config].event_idx;
+		break;
+	case PERF_TYPE_HW_CACHE:
+		ret = pmu_event_find_cache(config);
+		break;
+	case PERF_TYPE_RAW:
+		/*
+		 * As per SBI v0.3 specification,
+		 *  -- the upper 16 bits must be unused for a hardware raw event.
+		 * As per SBI v3.0 specification,
+		 *  -- the upper 8 bits must be unused for a hardware raw event.
+		 * Bits 63:62 are used to distinguish between raw events
+		 * 00 - Hardware raw event
+		 * 10 - SBI firmware events
+		 * 11 - Risc-V platform specific firmware event
+		 */
+		switch (config >> 62) {
+		case 0:
+			if (sbi_v3_available) {
+				if (econfig)
+					*econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
+				ret = RISCV_PMU_RAW_EVENT_V2_IDX;
+			} else {
+				if (econfig)
+					*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
+				ret = RISCV_PMU_RAW_EVENT_IDX;
+			}
+			break;
+		case 2:
+			ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
+			break;
+		case 3:
+			/*
+			 * For Risc-V platform specific firmware events
+			 * Event code - 0xFFFF
+			 * Event data - raw event encoding
+			 */
+			ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
+			if (econfig)
+				*econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(riscv_pmu_get_event_info);
+
 /*
  * Returns the counter width of a programmable counter and number of hardware
  * counters. As we don't support heterogeneous CPUs yet, it is okay to just
@@ -579,7 +638,6 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
 {
 	u32 type = event->attr.type;
 	u64 config = event->attr.config;
-	int ret;
 
 	/*
 	 * Ensure we are finished checking standard hardware events for
@@ -587,56 +645,7 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
 	 */
 	flush_work(&check_std_events_work);
 
-	switch (type) {
-	case PERF_TYPE_HARDWARE:
-		if (config >= PERF_COUNT_HW_MAX)
-			return -EINVAL;
-		ret = pmu_hw_event_map[event->attr.config].event_idx;
-		break;
-	case PERF_TYPE_HW_CACHE:
-		ret = pmu_event_find_cache(config);
-		break;
-	case PERF_TYPE_RAW:
-		/*
-		 * As per SBI v0.3 specification,
-		 *  -- the upper 16 bits must be unused for a hardware raw event.
-		 * As per SBI v3.0 specification,
-		 *  -- the upper 8 bits must be unused for a hardware raw event.
-		 * Bits 63:62 are used to distinguish between raw events
-		 * 00 - Hardware raw event
-		 * 10 - SBI firmware events
-		 * 11 - Risc-V platform specific firmware event
-		 */
-		switch (config >> 62) {
-		case 0:
-			if (sbi_v3_available) {
-				*econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
-				ret = RISCV_PMU_RAW_EVENT_V2_IDX;
-			} else {
-				*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
-				ret = RISCV_PMU_RAW_EVENT_IDX;
-			}
-			break;
-		case 2:
-			ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
-			break;
-		case 3:
-			/*
-			 * For Risc-V platform specific firmware events
-			 * Event code - 0xFFFF
-			 * Event data - raw event encoding
-			 */
-			ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
-			*econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
-			break;
-		}
-		break;
-	default:
-		ret = -ENOENT;
-		break;
-	}
-
-	return ret;
+	return riscv_pmu_get_event_info(type, config, econfig);
 }
 
 static void pmu_sbi_snapshot_free(struct riscv_pmu *pmu)
diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h
index 701974639ff2..4a5e3209c473 100644
--- a/include/linux/perf/riscv_pmu.h
+++ b/include/linux/perf/riscv_pmu.h
@@ -91,6 +91,8 @@ struct riscv_pmu *riscv_pmu_alloc(void);
 int riscv_pmu_get_hpm_info(u32 *hw_ctr_width, u32 *num_hw_ctr);
 #endif
 
+int riscv_pmu_get_event_info(u32 type, u64 config, u64 *econfig);
+
 #endif /* CONFIG_RISCV_PMU */
 
 #endif /* _RISCV_PMU_H */

-- 
2.34.1



From atishp at rivosinc.com  Tue Nov 19 12:29:55 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Tue, 19 Nov 2024 12:29:55 -0800
Subject: [PATCH 7/8] RISC-V: KVM: Implement get event info function
In-Reply-To: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
Message-ID: <20241119-pmu_event_info-v1-7-a4f9691421f8@rivosinc.com>

The new get_event_info funciton allows the guest to query the presence
of multiple events with single SBI call. Currently, the perf driver
in linux guest invokes it for all the standard SBI PMU events. Support
the SBI function implementation in KVM as well.

Signed-off-by: Atish Patra <atishp at rivosinc.com>
---
 arch/riscv/include/asm/kvm_vcpu_pmu.h |  3 ++
 arch/riscv/kvm/vcpu_pmu.c             | 67 +++++++++++++++++++++++++++++++++++
 arch/riscv/kvm/vcpu_sbi_pmu.c         |  3 ++
 3 files changed, 73 insertions(+)

diff --git a/arch/riscv/include/asm/kvm_vcpu_pmu.h b/arch/riscv/include/asm/kvm_vcpu_pmu.h
index 1d85b6617508..9a930afc8f57 100644
--- a/arch/riscv/include/asm/kvm_vcpu_pmu.h
+++ b/arch/riscv/include/asm/kvm_vcpu_pmu.h
@@ -98,6 +98,9 @@ void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu);
 int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long saddr_low,
 				      unsigned long saddr_high, unsigned long flags,
 				      struct kvm_vcpu_sbi_return *retdata);
+int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low,
+				  unsigned long saddr_high, unsigned long num_events,
+				  unsigned long flags, struct kvm_vcpu_sbi_return *retdata);
 void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu);
 void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu);
 
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index efd66835c2b8..a30f7ec31479 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -456,6 +456,73 @@ int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long s
 	return 0;
 }
 
+int kvm_riscv_vcpu_pmu_event_info(struct kvm_vcpu *vcpu, unsigned long saddr_low,
+				  unsigned long saddr_high, unsigned long num_events,
+				  unsigned long flags, struct kvm_vcpu_sbi_return *retdata)
+{
+	unsigned long hva;
+	struct riscv_pmu_event_info *einfo;
+	int shmem_size = num_events * sizeof(*einfo);
+	bool writable;
+	gpa_t shmem;
+	u32 eidx, etype;
+	u64 econfig;
+	int ret;
+
+	if (flags != 0 || (saddr_low & (SZ_16 - 1))) {
+		ret = SBI_ERR_INVALID_PARAM;
+		goto out;
+	}
+
+	shmem = saddr_low;
+	if (saddr_high != 0) {
+		if (IS_ENABLED(CONFIG_32BIT)) {
+			shmem |= ((gpa_t)saddr_high << 32);
+		} else {
+			ret = SBI_ERR_INVALID_ADDRESS;
+			goto out;
+		}
+	}
+
+	hva = kvm_vcpu_gfn_to_hva_prot(vcpu, shmem >> PAGE_SHIFT, &writable);
+	if (kvm_is_error_hva(hva) || !writable) {
+		ret = SBI_ERR_INVALID_ADDRESS;
+		goto out;
+	}
+
+	einfo = kzalloc(shmem_size, GFP_KERNEL);
+	if (!einfo)
+		return -ENOMEM;
+
+	ret = kvm_vcpu_read_guest(vcpu, shmem, einfo, shmem_size);
+	if (ret) {
+		ret = SBI_ERR_FAILURE;
+		goto free_mem;
+	}
+
+	for (int i = 0; i < num_events; i++) {
+		eidx = einfo[i].event_idx;
+		etype = kvm_pmu_get_perf_event_type(eidx);
+		econfig = kvm_pmu_get_perf_event_config(eidx, einfo[i].event_data);
+		ret = riscv_pmu_get_event_info(etype, econfig, NULL);
+		if (ret > 0)
+			einfo[i].output = 1;
+	}
+
+	kvm_vcpu_write_guest(vcpu, shmem, einfo, shmem_size);
+	if (ret) {
+		ret = SBI_ERR_FAILURE;
+		goto free_mem;
+	}
+
+free_mem:
+	kfree(einfo);
+out:
+	retdata->err_val = ret;
+
+	return 0;
+}
+
 int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu,
 				struct kvm_vcpu_sbi_return *retdata)
 {
diff --git a/arch/riscv/kvm/vcpu_sbi_pmu.c b/arch/riscv/kvm/vcpu_sbi_pmu.c
index e4be34e03e83..a020d979d179 100644
--- a/arch/riscv/kvm/vcpu_sbi_pmu.c
+++ b/arch/riscv/kvm/vcpu_sbi_pmu.c
@@ -73,6 +73,9 @@ static int kvm_sbi_ext_pmu_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
 	case SBI_EXT_PMU_SNAPSHOT_SET_SHMEM:
 		ret = kvm_riscv_vcpu_pmu_snapshot_set_shmem(vcpu, cp->a0, cp->a1, cp->a2, retdata);
 		break;
+	case SBI_EXT_PMU_EVENT_GET_INFO:
+		ret = kvm_riscv_vcpu_pmu_event_info(vcpu, cp->a0, cp->a1, cp->a2, cp->a3, retdata);
+		break;
 	default:
 		retdata->err_val = SBI_ERR_NOT_SUPPORTED;
 	}

-- 
2.34.1



From atishp at rivosinc.com  Tue Nov 19 12:29:56 2024
From: atishp at rivosinc.com (Atish Patra)
Date: Tue, 19 Nov 2024 12:29:56 -0800
Subject: [PATCH 8/8] RISC-V: KVM: Upgrade the supported SBI version to 3.0
In-Reply-To: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
Message-ID: <20241119-pmu_event_info-v1-8-a4f9691421f8@rivosinc.com>

Upgrade the SBI version to v3.0 so that corresponding features
can be enabled in the guest.

Signed-off-by: Atish Patra <atishp at rivosinc.com>
---
 arch/riscv/include/asm/kvm_vcpu_sbi.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h
index b96705258cf9..239457b864d7 100644
--- a/arch/riscv/include/asm/kvm_vcpu_sbi.h
+++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h
@@ -11,7 +11,7 @@
 
 #define KVM_SBI_IMPID 3
 
-#define KVM_SBI_VERSION_MAJOR 2
+#define KVM_SBI_VERSION_MAJOR 3
 #define KVM_SBI_VERSION_MINOR 0
 
 enum kvm_riscv_sbi_ext_status {

-- 
2.34.1



From atishp at atishpatra.org  Tue Nov 19 12:32:26 2024
From: atishp at atishpatra.org (Atish Patra)
Date: Tue, 19 Nov 2024 12:32:26 -0800
Subject: [PATCH v3 2/4] riscv: export __cpuid_to_hartid_map
In-Reply-To: <20241111215220.GA1993016-robh@kernel.org>
References: <20241105183513.1358736-1-valentina.fernandezalanis@microchip.com>
 <20241105183513.1358736-3-valentina.fernandezalanis@microchip.com> <20241111215220.GA1993016-robh@kernel.org>
Message-ID: <CAOnJCU+ac07aT9jLf5zqB+HnzHyqLMZE-Mz+cJDTdMAkS6LRTg@mail.gmail.com>

On Mon, Nov 11, 2024 at 1:52?PM Rob Herring <robh at kernel.org> wrote:
>
> On Tue, Nov 05, 2024 at 06:35:11PM +0000, Valentina Fernandez wrote:
> > EXPORT_SYMBOL_GPL() is missing for __cpuid_to_hartid_map array.
> > Export this symbol to allow drivers compiled as modules to use
> > cpuid_to_hartid_map().
> >
> > Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
> > ---
> >  arch/riscv/kernel/smp.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
> > index c180a647a30e..d58b5e751286 100644
> > --- a/arch/riscv/kernel/smp.c
> > +++ b/arch/riscv/kernel/smp.c
> > @@ -43,6 +43,7 @@ enum ipi_message_type {
> >  unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = {
> >       [0 ... NR_CPUS-1] = INVALID_HARTID
> >  };
> > +EXPORT_SYMBOL_GPL(__cpuid_to_hartid_map);
>
> Why can't riscv implement cpu_logical_map() like other arches?
>

We can and we should :)

> We really should have a common implementation too, but that's probably
> too much to ask I guess.
>
> Rob
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv



-- 
Regards,
Atish


From bigeasy at linutronix.de  Wed Nov 20 00:50:45 2024
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Wed, 20 Nov 2024 09:50:45 +0100
Subject: [PATCH] riscv: Fix sleeping in invalid context in die()
In-Reply-To: <20241118091333.1185288-1-namcao@linutronix.de>
References: <20241118091333.1185288-1-namcao@linutronix.de>
Message-ID: <20241120085045.LJ5b7oh9@linutronix.de>

On 2024-11-18 10:13:33 [+0100], Nam Cao wrote:
> die() can be called in exception handler, and therefore cannot sleep.
> However, die() takes spinlock_t which can sleep with PREEMPT_RT enabled.
> That causes the following warning:
> 
> BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
> in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 285, name: mutex
> preempt_count: 110001, expected: 0
> RCU nest depth: 0, expected: 0
> CPU: 0 UID: 0 PID: 285 Comm: mutex Not tainted 6.12.0-rc7-00022-ge19049cf7d56-dirty #234
> Hardware name: riscv-virtio,qemu (DT)
> Call Trace:
>     dump_backtrace+0x1c/0x24
>     show_stack+0x2c/0x38
>     dump_stack_lvl+0x5a/0x72
>     dump_stack+0x14/0x1c
>     __might_resched+0x130/0x13a
>     rt_spin_lock+0x2a/0x5c
>     die+0x24/0x112
>     do_trap_insn_illegal+0xa0/0xea
>     _new_vmalloc_restore_context_a0+0xcc/0xd8
> Oops - illegal instruction [#1]
> 
> Switch to use raw_spinlock_t, which does not sleep even with PREEMPT_RT
> enabled.
> 
> Fixes: 76d2a0493a17 ("RISC-V: Init and Halt Code")
> Signed-off-by: Nam Cao <namcao at linutronix.de>
> Cc: stable at vger.kernel.org

Reviewed-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

The die_lock() is probably do let one CPU die at a time. On x86 there is
support for for recursive die so if it happens, you don't spin on the
die_lock and see nothing. Not sure if this is a thing.

Sebastian


From geert+renesas at glider.be  Wed Nov 20 02:27:50 2024
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 20 Nov 2024 11:27:50 +0100
Subject: [PATCH] riscv: defconfig: Disable Renesas SoC support
Message-ID: <d33c9e3245c0bd3073d9618fcd014ba37e90e6bd.1732098271.git.geert+renesas@glider.be>

Follow-up to commit e36ddf3226864e09 ("riscv: defconfig: Disable RZ/Five
peripheral support") in v6.12-rc1:

  - Disable ARCH_RENESAS, too, as currently RZ/Five is the sole Renesas
    RISC-V SoC,
  - Drop no longer needed explicit disable of USB_XHCI_RCAR, which
    depends on ARCH_RENESAS.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Apparently I forgot to submit this, probably due to Palmer's version
https://lore.kernel.org/all/20240917131936.18980-1-palmer at rivosinc.com

 arch/riscv/configs/defconfig | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index b4a37345703eb357..db0ce2c2c766ac15 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -27,7 +27,6 @@ CONFIG_EXPERT=y
 # CONFIG_SYSFS_SYSCALL is not set
 CONFIG_PROFILING=y
 CONFIG_ARCH_MICROCHIP=y
-CONFIG_ARCH_RENESAS=y
 CONFIG_ARCH_SIFIVE=y
 CONFIG_ARCH_SOPHGO=y
 CONFIG_SOC_STARFIVE=y
@@ -201,7 +200,6 @@ CONFIG_USB=y
 CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_PLATFORM=y
-# CONFIG_USB_XHCI_RCAR is not set
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
 CONFIG_USB_OHCI_HCD=y
-- 
2.34.1



From bjorn at kernel.org  Wed Nov 20 05:12:02 2024
From: bjorn at kernel.org (=?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?=)
Date: Wed, 20 Nov 2024 14:12:02 +0100
Subject: [PATCH fixes] riscv: mm: Do not call pmd dtor on vmemmap page table teardown
Message-ID: <20241120131203.1859787-1-bjorn@kernel.org>

From: Bj?rn T?pel <bjorn at rivosinc.com>

The vmemmap's, which is used for RV64 with SPARSEMEM_VMEMMAP, page
tables are populated using pmd (page middle directory) hugetables.
However, the pmd allocation is not using the generic mechanism used by
the VMA code (e.g. pmd_alloc()), or the RISC-V specific
create_pgd_mapping()/alloc_pmd_late(). Instead, the vmemmap page table
code allocates a page, and calls vmemmap_set_pmd(). This results in
that the pmd ctor is *not* called, nor would it make sense to do so.

Now, when tearing down a vmemmap page table pmd, the cleanup code
would unconditionally, and incorrectly call the pmd dtor, which
results in a crash (best case).

This issue was found when running the HMM selftests:

  | tools/testing/selftests/mm# ./test_hmm.sh smoke
  | ... # when unloading the test_hmm.ko module
  | page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10915b
  | flags: 0x1000000000000000(node=0|zone=1)
  | raw: 1000000000000000 0000000000000000 dead000000000122 0000000000000000
  | raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
  | page dumped because: VM_BUG_ON_PAGE(ptdesc->pmd_huge_pte)
  | ------------[ cut here ]------------
  | kernel BUG at include/linux/mm.h:3080!
  | Kernel BUG [#1]
  | Modules linked in: test_hmm(-) sch_fq_codel fuse drm drm_panel_orientation_quirks backlight dm_mod
  | CPU: 1 UID: 0 PID: 514 Comm: modprobe Tainted: G        W          6.12.0-00982-gf2a4f1682d07 #2
  | Tainted: [W]=WARN
  | Hardware name: riscv-virtio qemu/qemu, BIOS 2024.10 10/01/2024
  | epc : remove_pgd_mapping+0xbec/0x1070
  |  ra : remove_pgd_mapping+0xbec/0x1070
  | epc : ffffffff80010a68 ra : ffffffff80010a68 sp : ff20000000a73940
  |  gp : ffffffff827b2d88 tp : ff6000008785da40 t0 : ffffffff80fbce04
  |  t1 : 0720072007200720 t2 : 706d756420656761 s0 : ff20000000a73a50
  |  s1 : ff6000008915cff8 a0 : 0000000000000039 a1 : 0000000000000008
  |  a2 : ff600003fff0de20 a3 : 0000000000000000 a4 : 0000000000000000
  |  a5 : 0000000000000000 a6 : c0000000ffffefff a7 : ffffffff824469b8
  |  s2 : ff1c0000022456c0 s3 : ff1ffffffdbfffff s4 : ff6000008915c000
  |  s5 : ff6000008915c000 s6 : ff6000008915c000 s7 : ff1ffffffdc00000
  |  s8 : 0000000000000001 s9 : ff1ffffffdc00000 s10: ffffffff819a31f0
  |  s11: ffffffffffffffff t3 : ffffffff8000c950 t4 : ff60000080244f00
  |  t5 : ff60000080244000 t6 : ff20000000a73708
  | status: 0000000200000120 badaddr: ffffffff80010a68 cause: 0000000000000003
  | [<ffffffff80010a68>] remove_pgd_mapping+0xbec/0x1070
  | [<ffffffff80fd238e>] vmemmap_free+0x14/0x1e
  | [<ffffffff8032e698>] section_deactivate+0x220/0x452
  | [<ffffffff8032ef7e>] sparse_remove_section+0x4a/0x58
  | [<ffffffff802f8700>] __remove_pages+0x7e/0xba
  | [<ffffffff803760d8>] memunmap_pages+0x2bc/0x3fe
  | [<ffffffff02a3ca28>] dmirror_device_remove_chunks+0x2ea/0x518 [test_hmm]
  | [<ffffffff02a3e026>] hmm_dmirror_exit+0x3e/0x1018 [test_hmm]
  | [<ffffffff80102c14>] __riscv_sys_delete_module+0x15a/0x2a6
  | [<ffffffff80fd020c>] do_trap_ecall_u+0x1f2/0x266
  | [<ffffffff80fde0a2>] _new_vmalloc_restore_context_a0+0xc6/0xd2
  | Code: bf51 7597 0184 8593 76a5 854a 4097 0029 80e7 2c00 (9002) 7597
  | ---[ end trace 0000000000000000 ]---
  | Kernel panic - not syncing: Fatal exception in interrupt

Add a check to avoid calling the pmd dtor, if the calling context is
vmemmap_free().

Fixes: c75a74f4ba19 ("riscv: mm: Add memory hotplugging support")
Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
---
 arch/riscv/mm/init.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 0e8c20adcd98..fc53ce748c80 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -1566,7 +1566,7 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
 	pmd_clear(pmd);
 }
 
-static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
+static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud, bool is_vmemmap)
 {
 	struct page *page = pud_page(*pud);
 	struct ptdesc *ptdesc = page_ptdesc(page);
@@ -1579,7 +1579,8 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
 			return;
 	}
 
-	pagetable_pmd_dtor(ptdesc);
+	if (!is_vmemmap)
+		pagetable_pmd_dtor(ptdesc);
 	if (PageReserved(page))
 		free_reserved_page(page);
 	else
@@ -1703,7 +1704,7 @@ static void __meminit remove_pud_mapping(pud_t *pud_base, unsigned long addr, un
 		remove_pmd_mapping(pmd_base, addr, next, is_vmemmap, altmap);
 
 		if (pgtable_l4_enabled)
-			free_pmd_table(pmd_base, pudp);
+			free_pmd_table(pmd_base, pudp, is_vmemmap);
 	}
 }
 

base-commit: 57f7c7dc78cd09622b12920d92b40c1ce11b234e
-- 
2.45.2



From bjorn at kernel.org  Wed Nov 20 05:25:22 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Wed, 20 Nov 2024 14:25:22 +0100
Subject: [PATCH] tools: Override makefile ARCH variable if defined, but
 empty
In-Reply-To: <20241106193208.290067-1-bjorn@kernel.org>
References: <20241106193208.290067-1-bjorn@kernel.org>
Message-ID: <87r076nikd.fsf@all.your.base.are.belong.to.us>

Bj?rn T?pel <bjorn at kernel.org> writes:

> From: Bj?rn T?pel <bjorn at rivosinc.com>
>
> There are a number of tools (bpftool, selftests), that require a
> "bootstrap" build. Here, a bootstrap build is a build host variant of
> a target. E.g., assume that you're performing a bpftool cross-build on
> x86 to riscv, a bootstrap build would then be an x86 variant of
> bpftool. The typical way to perform the host build variant, is to pass
> "ARCH=" in a sub-make. However, if a variable has been set with a
> command argument, then ordinary assignments in the makefile are
> ignored.
>
> This side-effect results in that ARCH, and variables depending on ARCH
> are not set.
>
> Workaround by overriding ARCH to the host arch, if ARCH is empty.
>
> Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>

Arnaldo/Palmer/Quentin:

A bit unsure what tree this patch should go. It's very important for the
RISC-V builds, so maybe via Palmer's RISC-V tree?

Opinions? Just want to make sure it doesn't fall between any chairs!
:-)


Bj?rn


From max.hsu at sifive.com  Wed Nov 20 05:52:13 2024
From: max.hsu at sifive.com (Max Hsu)
Date: Wed, 20 Nov 2024 21:52:13 +0800
Subject: [PATCH RFC v2 3/3] riscv: KVM: Add Svukte extension support for Guest/VM
In-Reply-To: <CAK9=C2WEU53TD+tnWRLC1iLRf+j607s=bZXevkogTnr-cmhPGw@mail.gmail.com>
References: <20240927-dev-maxh-svukte-rebase-2-v2-0-9afe57c33aee@sifive.com>
 <20240927-dev-maxh-svukte-rebase-2-v2-3-9afe57c33aee@sifive.com>
 <CAAhSdy0ncLTAjEE1s-GWL95sscxwQFsKn1rXyA1_VVfk1bQBiw@mail.gmail.com>
 <CAHibDywpKUE7r4UfcudDSBZCM=JAC5s40uf+PwQE+oMvZy4aVA@mail.gmail.com> <CAK9=C2WEU53TD+tnWRLC1iLRf+j607s=bZXevkogTnr-cmhPGw@mail.gmail.com>
Message-ID: <CAHibDyxWBHeKOx=sT63EmEwhwyAYMQ3TE2tkOSK8V45PhjztPA@mail.gmail.com>

Hi Anup,

>From your reply, I think my commit message was misleading.
Therefore, I will send RFC v3 patches and explain the guest scenario in the
cover letter.

Thanks for the suggestion.

Best regards,
Max Hsu

On Mon, Nov 4, 2024 at 9:19?PM Anup Patel <apatel at ventanamicro.com> wrote:
>
> On Mon, Nov 4, 2024 at 1:14?PM Max Hsu <max.hsu at sifive.com> wrote:
> >
> > Hi Anup,
> >
> > Thank you for the suggestion.
> >
> > I?m not entirely sure if I fully understand it, but I believe the
> > hypervisor should be able to disable the Svukte extension.
> >
> > Inside the switch-case of kvm_riscv_vcpu_isa_disable_allowed(),
> > the default case breaks and returns true.
> >
> > So that means when the KVM_RISCV_ISA_EXT_SVUKTE passed into
> > kvm_riscv_vcpu_isa_disable_allowed() it will return true.
> >
> > If I've misunderstood, please let me know.
>
> I don't see any code in this patch which disables/enables Svukte for
> Guest based on KVM ONE_REG interface.
>
> Regards,
> Anup
>
> >
> > Best regards,
> > Max Hsu
> >
> > On Fri, Oct 25, 2024 at 3:17?AM Anup Patel <anup at brainfault.org> wrote:
> > >
> > > On Fri, Sep 27, 2024 at 7:12?PM Max Hsu <max.hsu at sifive.com> wrote:
> > > >
> > > > Add KVM ISA extension ONE_REG interface to allow VMM tools to
> > > > detect and enable Svukte extension for Guest/VM.
> > > >
> > > > Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
> > > > Signed-off-by: Max Hsu <max.hsu at sifive.com>
> > > > ---
> > > >  arch/riscv/include/uapi/asm/kvm.h | 1 +
> > > >  arch/riscv/kvm/vcpu_onereg.c      | 1 +
> > > >  2 files changed, 2 insertions(+)
> > > >
> > > > diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
> > > > index e97db3296456e19f79ca02e4c4f70ae1b4abb48b..41b466b7ffaec421e8389d3f5b178580091a2c98 100644
> > > > --- a/arch/riscv/include/uapi/asm/kvm.h
> > > > +++ b/arch/riscv/include/uapi/asm/kvm.h
> > > > @@ -175,6 +175,7 @@ enum KVM_RISCV_ISA_EXT_ID {
> > > >         KVM_RISCV_ISA_EXT_ZCF,
> > > >         KVM_RISCV_ISA_EXT_ZCMOP,
> > > >         KVM_RISCV_ISA_EXT_ZAWRS,
> > > > +       KVM_RISCV_ISA_EXT_SVUKTE,
> > > >         KVM_RISCV_ISA_EXT_MAX,
> > > >  };
> > > >
> > > > diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
> > > > index b319c4c13c54ce22d2a7552f4c9f256a0c50780e..67237d6e53882a9fcd2cf265aa1704f25cc4a701 100644
> > > > --- a/arch/riscv/kvm/vcpu_onereg.c
> > > > +++ b/arch/riscv/kvm/vcpu_onereg.c
> > > > @@ -41,6 +41,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
> > > >         KVM_ISA_EXT_ARR(SVINVAL),
> > > >         KVM_ISA_EXT_ARR(SVNAPOT),
> > > >         KVM_ISA_EXT_ARR(SVPBMT),
> > > > +       KVM_ISA_EXT_ARR(SVUKTE),
> > > >         KVM_ISA_EXT_ARR(ZACAS),
> > > >         KVM_ISA_EXT_ARR(ZAWRS),
> > > >         KVM_ISA_EXT_ARR(ZBA),
> > >
> > > The KVM_RISCV_ISA_EXT_SVUKTE should be added to the
> > > switch-case in kvm_riscv_vcpu_isa_disable_allowed() because
> > > hypervisor seems to have no way to disable Svukte for the Guest
> > > when it's available on the Host.
> > >
> > > Regards,
> > > Anup
> >


From max.hsu at sifive.com  Wed Nov 20 05:55:18 2024
From: max.hsu at sifive.com (Max Hsu)
Date: Wed, 20 Nov 2024 21:55:18 +0800
Subject: [PATCH RFC 1/3] dt-bindings: riscv: Add Svukte entry
In-Reply-To: <eb8f399b-fa09-47fd-8102-9b65b0839dd5@ghiti.fr>
References: <20240920-dev-maxh-svukte-rebase-v1-0-7864a88a62bd@sifive.com>
 <20240920-dev-maxh-svukte-rebase-v1-1-7864a88a62bd@sifive.com> <eb8f399b-fa09-47fd-8102-9b65b0839dd5@ghiti.fr>
Message-ID: <CAHibDyzOWrKwEZ_7K2f2MY9DFn4sD5QjDEQ42u8DTaftN6Fuvw@mail.gmail.com>

Hi Alexandre,

Thanks for the suggestion.
I will send a typo fix in the RFC v3 patches

Best regards,
Max Hsu

On Thu, Nov 14, 2024 at 12:15?AM Alexandre Ghiti <alex at ghiti.fr> wrote:
>
> Hi Max,
>
> On 20/09/2024 09:39, Max Hsu wrote:
> > Add an entry for the Svukte extension to the riscv,isa-extensions
> > property.
> >
> > Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
> > Signed-off-by: Max Hsu <max.hsu at sifive.com>
> > ---
> >   Documentation/devicetree/bindings/riscv/extensions.yaml | 7 +++++++
> >   1 file changed, 7 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
> > index a06dbc6b4928958704855c8993291b036e3d1a63..df96aea5e53a70b0cb8905332464a42a264e56e6 100644
> > --- a/Documentation/devicetree/bindings/riscv/extensions.yaml
> > +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
> > @@ -171,6 +171,13 @@ properties:
> >               memory types as ratified in the 20191213 version of the privileged
> >               ISA specification.
> >
> > +        - const: svukte
> > +          description:
> > +            The standard Svukte supervisor-level extensions for making user-mode
>
>
> s/extensions/extension
>
>
> > +            accesses to supervisor memory raise page faults in constant time,
> > +            mitigating attacks that attempt to discover the supervisor
> > +            software's address-space layout, as PR#1564 of riscv-isa-manual.
> > +
> >           - const: zacas
> >             description: |
> >               The Zacas extension for Atomic Compare-and-Swap (CAS) instructions
> >
>
> You'll need a new version for the proper commit sha1 once it gets
> ratified anyway, so with the typo fixed, you can add:
>
> Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
>
> Thanks,
>
> Alex
>


From max.hsu at sifive.com  Wed Nov 20 06:09:31 2024
From: max.hsu at sifive.com (Max Hsu)
Date: Wed, 20 Nov 2024 22:09:31 +0800
Subject: [PATCH RFC v3 0/3] riscv: add Svukte extension
Message-ID: <20241120-dev-maxh-svukte-v3-v3-0-1e533d41ae15@sifive.com>

RISC-V privileged spec will be added with Svukte extension [1]

Svukte introduce senvcfg.UKTE and hstatus.HUKTE bitfield.
which makes user-mode access to supervisor memory raise page faults
in constant time, mitigating attacks that attempt to discover the
supervisor software's address-space layout.

In the Linux kernel, since the hstatus.HU bit is not enabled,
the following patches only enable the use of senvcfg.UKTE.

For Guest environments, because a Guest OS (not limited to Linux)
may hold mappings from GVA to GPA, the Guest OS should decide
whether to enable the protection provided by the Svukte extension.
Therefore, the functions kvm_riscv_vcpu_isa_(enable|disable)_allowed
can use default case (which will return true) in the switch-case.

If the Guest environment wants to change senvcfg.UKTE, KVM already
provides the senvcfg CSR swap support via
kvm_riscv_vcpu_swap_in_(host|guest)_state.
Thus, there is no concern about the Guest OS affecting the Host OS.

The following patches add
- dt-binding of Svukte ISA string
- CSR bit definition, ISA detection, senvcfg.UKTE enablement in kernel
- KVM ISA support for Svukte extension

Changes in v3:
- rebase on riscv/for-next
- fixed typo in the dt-binding for the Svukte ISA string
- updated the commit message for KVM support for the Svukte extension
- Link to v2: https://lore.kernel.org/all/20240927-dev-maxh-svukte-rebase-2-v2-0-9afe57c33aee at sifive.com/

Changes in v2:
- rebase on riscv/for-next (riscv-for-linus-6.12-mw1)
- modify the description of dt-binding on Svukte ISA string
- Link to v1: https://lore.kernel.org/all/20240920-dev-maxh-svukte-rebase-v1-0-7864a88a62bd at sifive.com/

Link: https://github.com/riscv/riscv-isa-manual/pull/1564 [1]

Signed-off-by: Max Hsu <max.hsu at sifive.com>

---
Max Hsu (3):
      dt-bindings: riscv: Add Svukte entry
      riscv: Add Svukte extension support
      riscv: KVM: Add Svukte extension support for Guest/VM

 Documentation/devicetree/bindings/riscv/extensions.yaml | 9 +++++++++
 arch/riscv/include/asm/csr.h                            | 2 ++
 arch/riscv/include/asm/hwcap.h                          | 1 +
 arch/riscv/include/uapi/asm/kvm.h                       | 1 +
 arch/riscv/kernel/cpufeature.c                          | 5 +++++
 arch/riscv/kvm/vcpu_onereg.c                            | 1 +
 6 files changed, 19 insertions(+)
---
base-commit: 0eb512779d642b21ced83778287a0f7a3ca8f2a1
change-id: 20241115-dev-maxh-svukte-v3-af46d650ac0b

Best regards,
-- 
Max Hsu <max.hsu at sifive.com>



From max.hsu at sifive.com  Wed Nov 20 06:09:32 2024
From: max.hsu at sifive.com (Max Hsu)
Date: Wed, 20 Nov 2024 22:09:32 +0800
Subject: [PATCH RFC v3 1/3] dt-bindings: riscv: Add Svukte entry
In-Reply-To: <20241120-dev-maxh-svukte-v3-v3-0-1e533d41ae15@sifive.com>
References: <20241120-dev-maxh-svukte-v3-v3-0-1e533d41ae15@sifive.com>
Message-ID: <20241120-dev-maxh-svukte-v3-v3-1-1e533d41ae15@sifive.com>

Add an entry for the Svukte extension to the riscv,isa-extensions
property.

Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
Reviewed-by: Deepak Gupta <debug at rivosinc.com>
Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Signed-off-by: Max Hsu <max.hsu at sifive.com>
---
 Documentation/devicetree/bindings/riscv/extensions.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
index af7e5237b2c03085611daad9e1e39aa93cc8ae95..bf177274b5c6f4cd1c842b4221ca5bbfc2960a0a 100644
--- a/Documentation/devicetree/bindings/riscv/extensions.yaml
+++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
@@ -189,6 +189,15 @@ properties:
             memory types as ratified in the 20191213 version of the privileged
             ISA specification.
 
+        - const: svukte
+          description:
+            The standard Svukte supervisor-level extension for making user-mode
+            accesses to supervisor memory raise page faults in constant time,
+            mitigating attacks that attempt to discover the supervisor
+            software's address-space layout. Currently under review as Pull
+            Request number 1564 at commit 81dc9277 ("Svukte v0.3") of
+            riscv-isa-manual.
+
         - const: svvptc
           description:
             The standard Svvptc supervisor-level extension for

-- 
2.43.2



From max.hsu at sifive.com  Wed Nov 20 06:09:33 2024
From: max.hsu at sifive.com (Max Hsu)
Date: Wed, 20 Nov 2024 22:09:33 +0800
Subject: [PATCH RFC v3 2/3] riscv: Add Svukte extension support
In-Reply-To: <20241120-dev-maxh-svukte-v3-v3-0-1e533d41ae15@sifive.com>
References: <20241120-dev-maxh-svukte-v3-v3-0-1e533d41ae15@sifive.com>
Message-ID: <20241120-dev-maxh-svukte-v3-v3-2-1e533d41ae15@sifive.com>

Svukte extension introduce senvcfg.UKTE, hstatus.HUKTE.

This patch add CSR bit definition, and detects if Svukte ISA extension
is available, cpufeature will set the correspond bit field so the
svukte-qualified memory accesses are protected in a manner that is
timing-independent of the faulting virtual address.

Since hstatus.HU is not enabled by linux, enabling hstatus.HUKTE will
not be affective.

Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
Reviewed-by: Deepak Gupta <debug at rivosinc.com>
Signed-off-by: Max Hsu <max.hsu at sifive.com>
---
 arch/riscv/include/asm/csr.h   | 2 ++
 arch/riscv/include/asm/hwcap.h | 1 +
 arch/riscv/kernel/cpufeature.c | 5 +++++
 3 files changed, 8 insertions(+)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index fe5d4eb9adea1d4e3065a4d6e2ff361a52aecc44..67ff78f7e480bcbfef04e58191ef85d5434f427e 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -126,6 +126,7 @@
 #define HSTATUS_VSXL		_AC(0x300000000, UL)
 #define HSTATUS_VSXL_SHIFT	32
 #endif
+#define HSTATUS_HUKTE		_AC(0x01000000, UL)
 #define HSTATUS_VTSR		_AC(0x00400000, UL)
 #define HSTATUS_VTW		_AC(0x00200000, UL)
 #define HSTATUS_VTVM		_AC(0x00100000, UL)
@@ -203,6 +204,7 @@
 #define ENVCFG_PMM_PMLEN_0		(_AC(0x0, ULL) << 32)
 #define ENVCFG_PMM_PMLEN_7		(_AC(0x2, ULL) << 32)
 #define ENVCFG_PMM_PMLEN_16		(_AC(0x3, ULL) << 32)
+#define ENVCFG_UKTE			(_AC(1, UL) << 8)
 #define ENVCFG_CBZE			(_AC(1, UL) << 7)
 #define ENVCFG_CBCFE			(_AC(1, UL) << 6)
 #define ENVCFG_CBIE_SHIFT		4
diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index 08d2a5697466d07fe2319a2423f04657177db37f..98488d8ebf528ff5cd494ab753d91b77accd2488 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -98,6 +98,7 @@
 #define RISCV_ISA_EXT_SSNPM		89
 #define RISCV_ISA_EXT_ZABHA		90
 #define RISCV_ISA_EXT_ZICCRSE		91
+#define RISCV_ISA_EXT_SVUKTE		92
 
 #define RISCV_ISA_EXT_XLINUXENVCFG	127
 
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index eb904ca64ad03565c6d521350f5e6b4c5cb9c6d9..a38e40477f0123eb7e80b096a38e0f956c9d4bc0 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -389,6 +389,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
 	__RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL),
 	__RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT),
 	__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
+	__RISCV_ISA_EXT_SUPERSET(svukte, RISCV_ISA_EXT_SVUKTE, riscv_xlinuxenvcfg_exts),
 	__RISCV_ISA_EXT_DATA(svvptc, RISCV_ISA_EXT_SVVPTC),
 };
 
@@ -931,6 +932,10 @@ void __init riscv_user_isa_enable(void)
 		current->thread.envcfg |= ENVCFG_CBZE;
 	else if (any_cpu_has_zicboz)
 		pr_warn("Zicboz disabled as it is unavailable on some harts\n");
+
+	if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SVUKTE))
+		current->thread.envcfg |= ENVCFG_UKTE;
+
 }
 
 #ifdef CONFIG_RISCV_ALTERNATIVE

-- 
2.43.2



From max.hsu at sifive.com  Wed Nov 20 06:09:34 2024
From: max.hsu at sifive.com (Max Hsu)
Date: Wed, 20 Nov 2024 22:09:34 +0800
Subject: [PATCH RFC v3 3/3] riscv: KVM: Add Svukte extension support for
 Guest/VM
In-Reply-To: <20241120-dev-maxh-svukte-v3-v3-0-1e533d41ae15@sifive.com>
References: <20241120-dev-maxh-svukte-v3-v3-0-1e533d41ae15@sifive.com>
Message-ID: <20241120-dev-maxh-svukte-v3-v3-3-1e533d41ae15@sifive.com>

Add KVM_RISCV_ISA_EXT_SVUKTE for VMM to detect the enablement
or disablement the Svukte extension for Guest/VM

Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
Signed-off-by: Max Hsu <max.hsu at sifive.com>
---
 arch/riscv/include/uapi/asm/kvm.h | 1 +
 arch/riscv/kvm/vcpu_onereg.c      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 4f24201376b17215315cf1fb8888d0a562dc76ac..158f9253658c4c28a533b2bda179fb48bf41e1fc 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -177,6 +177,7 @@ enum KVM_RISCV_ISA_EXT_ID {
 	KVM_RISCV_ISA_EXT_ZAWRS,
 	KVM_RISCV_ISA_EXT_SMNPM,
 	KVM_RISCV_ISA_EXT_SSNPM,
+	KVM_RISCV_ISA_EXT_SVUKTE,
 	KVM_RISCV_ISA_EXT_MAX,
 };
 
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 5b68490ad9b75fef6a18289d8c5cf9291594e01e..4c3a77cdeed0956e21e53d1ab4e948a170ac5c5c 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -43,6 +43,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
 	KVM_ISA_EXT_ARR(SVINVAL),
 	KVM_ISA_EXT_ARR(SVNAPOT),
 	KVM_ISA_EXT_ARR(SVPBMT),
+	KVM_ISA_EXT_ARR(SVUKTE),
 	KVM_ISA_EXT_ARR(ZACAS),
 	KVM_ISA_EXT_ARR(ZAWRS),
 	KVM_ISA_EXT_ARR(ZBA),

-- 
2.43.2



From zhangkai at iscas.ac.cn  Wed Nov 20 06:23:26 2024
From: zhangkai at iscas.ac.cn (laokz)
Date: Wed, 20 Nov 2024 22:23:26 +0800
Subject: [PATCH] riscv: fix memory leakage in
 process_accumulated_relocations
In-Reply-To: <ffcdbcbe-a5f6-48f4-a0a3-0d35c6c80050@rivosinc.com>
References: <35cab46a.6d145.19334919ed0.Coremail.zhangkai@iscas.ac.cn>
	 <ffcdbcbe-a5f6-48f4-a0a3-0d35c6c80050@rivosinc.com>
Message-ID: <c26cbfe04f9c50f5b721a9e954c1213b8c5b0508.camel@iscas.ac.cn>

On Tue, 2024-11-19 at 17:57 +0100, Cl?ment L?ger wrote:
> 
> 
> On 16/11/2024 11:42, zhangkai at iscas.ac.cn?wrote:
> > When module relocation is done, process_accumulated_relocations()
> > frees all dynamic allocated memory. rel_head_iter-&gt;rel_entry is
> > missed to free that kmemleak might report:
> > 
> > unreferenced object 0xffffffd880c5fc40 (size 16):
> > ? comm "insmod", pid 1101, jiffies 4295045138
> > ? hex dump (first 16 bytes):
> > ??? e0 c0 f5 87 d8 ff ff ff 60 c5 f5 87 d8 ff ff ff?
> > ........`.......
> > ? backtrace (crc d2ecb20c):
> > ??? [&lt;00000000b01655f6&gt;] kmalloc_trace_noprof+0x268/0x2f6
> > ??? [&lt;000000006dc0067a&gt;]
> > add_relocation_to_accumulate.constprop.0+0xf2/0x1aa
> > ??? [&lt;00000000e1b29a36&gt;] apply_relocate_add+0x13c/0x36e
> > ??? [&lt;000000007543f1fb&gt;] load_module+0x5c6/0x83e
> > ??? [&lt;00000000abce12e8&gt;] init_module_from_file+0x74/0xaa
> > ??? [&lt;0000000049413e3d&gt;] idempotent_init_module+0x116/0x22e
> > ??? [&lt;00000000f9b98b85&gt;] __riscv_sys_finit_module+0x62/0xae
> > 
> > Signed-off-by: Kai Zhang <zhangkai at iscas.ac.cn>
> > ---
> > ?arch/riscv/kernel/module.c | 1 +
> > ?1 file changed, 1 insertion(+)
> > 
> > diff --git a/arch/riscv/kernel/module.c
> > b/arch/riscv/kernel/module.c
> > index 1cd461f3d87..f8c3c4b47dc 100644
> > --- a/arch/riscv/kernel/module.c
> > +++ b/arch/riscv/kernel/module.c
> > @@ -643,6 +643,7 @@ process_accumulated_relocations(struct module
> > *me,
> > ??????????????????????? }
> > ???????????????????????
> > reloc_handlers[curr_type].accumulate_handler(
> > ??????????????????????????????? me, location, buffer);
> > +?????????????????????? kfree(rel_head_iter-&gt;rel_entry);
> 
> Hey Kai,
> 
> Your patch output is messed up probably due to some encoding issue.

Sorry, I've already resent one.

> But looknig at it and the module code, it seems like rel_entry does
> not
> need to be a pointer. It can be a plain "struct list_head rel_entry"
> and

I didn't find the plain(none pointer) usage. Where please?

> then simply pass the list_head pointer rather than allocating/freeing
> it. That remove an allocation as well as some memory leak.
> 
> BTW, for fixes, you should add a Fixes: tag with the original commit
> sha1 that introduced the bug.
Thank you. I'll try.

laokz

> Thanks,
> 
> Cl?ment
> 
> > ??????????????????????? kfree(rel_head_iter);
> > ??????????????? }
> > ??????????????? kfree(bucket_iter);



From prabhakar.csengg at gmail.com  Wed Nov 20 12:55:25 2024
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Wed, 20 Nov 2024 20:55:25 +0000
Subject: [PATCH] riscv: defconfig: Disable Renesas SoC support
In-Reply-To: <d33c9e3245c0bd3073d9618fcd014ba37e90e6bd.1732098271.git.geert+renesas@glider.be>
References: <d33c9e3245c0bd3073d9618fcd014ba37e90e6bd.1732098271.git.geert+renesas@glider.be>
Message-ID: <CA+V-a8uo3R8OpzRCJWLU9K=DgKw=JrLdLX76RER1mt9Lqmi6KQ@mail.gmail.com>

On Wed, Nov 20, 2024 at 10:28?AM Geert Uytterhoeven
<geert+renesas at glider.be> wrote:
>
> Follow-up to commit e36ddf3226864e09 ("riscv: defconfig: Disable RZ/Five
> peripheral support") in v6.12-rc1:
>
>   - Disable ARCH_RENESAS, too, as currently RZ/Five is the sole Renesas
>     RISC-V SoC,
>   - Drop no longer needed explicit disable of USB_XHCI_RCAR, which
>     depends on ARCH_RENESAS.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
> Apparently I forgot to submit this, probably due to Palmer's version
> https://lore.kernel.org/all/20240917131936.18980-1-palmer at rivosinc.com
>
>  arch/riscv/configs/defconfig | 2 --
>  1 file changed, 2 deletions(-)
>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Cheers,
Prabhakar

> diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
> index b4a37345703eb357..db0ce2c2c766ac15 100644
> --- a/arch/riscv/configs/defconfig
> +++ b/arch/riscv/configs/defconfig
> @@ -27,7 +27,6 @@ CONFIG_EXPERT=y
>  # CONFIG_SYSFS_SYSCALL is not set
>  CONFIG_PROFILING=y
>  CONFIG_ARCH_MICROCHIP=y
> -CONFIG_ARCH_RENESAS=y
>  CONFIG_ARCH_SIFIVE=y
>  CONFIG_ARCH_SOPHGO=y
>  CONFIG_SOC_STARFIVE=y
> @@ -201,7 +200,6 @@ CONFIG_USB=y
>  CONFIG_USB_OTG=y
>  CONFIG_USB_XHCI_HCD=y
>  CONFIG_USB_XHCI_PLATFORM=y
> -# CONFIG_USB_XHCI_RCAR is not set
>  CONFIG_USB_EHCI_HCD=y
>  CONFIG_USB_EHCI_HCD_PLATFORM=y
>  CONFIG_USB_OHCI_HCD=y
> --
> 2.34.1
>
>


From troymitchell988 at gmail.com  Wed Nov 20 20:11:19 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Thu, 21 Nov 2024 12:11:19 +0800
Subject: [PATCH v3 2/2] i2c: spacemit: add support for SpacemiT K1 SoC
In-Reply-To: <20241114064943-GYA998060@gentoo>
References: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
 <20241112-k1-i2c-master-v3-2-5005b70dc208@gmail.com>
 <20241114064943-GYA998060@gentoo>
Message-ID: <46a81098-3092-44a0-a625-bd17b4ba0e2b@gmail.com>

Hi, Yixun. thanks for ur review.

On 2024/11/14 14:49, Yixun Lan wrote:
> On 11:07 Tue 12 Nov     , Troy Mitchell wrote:
>> From: Troy Mitchell <troymitchell988 at gmail.com>
>>
>> This patch introduces basic I2C support for the SpacemiT K1 SoC,
>> utilizing interrupts for transfers.
>>
>> The driver has been tested using i2c-tools on a Bananapi-F3 board,
>> and basic I2C read/write operations have been confirmed to work.
>>
>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>> ---
>>  drivers/i2c/busses/Kconfig  |  19 ++
>>  drivers/i2c/busses/Makefile |   1 +
>>  drivers/i2c/busses/i2c-k1.c | 656 ++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 676 insertions(+)
>>
>> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
>> index 6b3ba7e5723a..91630f55667f 100644
>> --- a/drivers/i2c/busses/Kconfig
>> +++ b/drivers/i2c/busses/Kconfig
>> @@ -779,6 +779,25 @@ config I2C_JZ4780
>>  
>>  	 If you don't know what to do here, say N.
>>  
>> +config I2C_K1
>> +	tristate "Spacemit K1 I2C adapter"
>> +	depends on ARCH_SPACEMIT || COMPILE_TEST
>> +	depends on OF
>> +	help
>> +	  This option enables support for the I2C interface on the Spacemit K1
>> +	  platform.
>> +
>> +	  If you enable this configuration, the kernel will include support for
>> +	  the I2C adapter specific to the Spacemit K1 platform. This driver ca
>> +	  be used to manage I2C bus transactions, which are necessary for
>> +	  interfacing with I2C peripherals such as sensors, EEPROMs, and other
>> +	  devices.
>> +
>> +	  This driver can also be compiled as a module. If you choose to build
>> +	  it as a module, the resulting kernel module will be named `i2c-k1`.
>> +	  Loading this module will enable the I2C functionality for the K1
>> +	  platform dynamically, without requiring a rebuild of the kernel.
>> +
>>  config I2C_KEBA
>>  	tristate "KEBA I2C controller support"
>>  	depends on HAS_IOMEM
>> diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
>> index ecc07c50f2a0..9744b0e58598 100644
>> --- a/drivers/i2c/busses/Makefile
>> +++ b/drivers/i2c/busses/Makefile
>> @@ -76,6 +76,7 @@ obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
>>  obj-$(CONFIG_I2C_IMX_LPI2C)	+= i2c-imx-lpi2c.o
>>  obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
>>  obj-$(CONFIG_I2C_JZ4780)	+= i2c-jz4780.o
>> +obj-$(CONFIG_I2C_K1)		+= i2c-k1.o
>>  obj-$(CONFIG_I2C_KEBA)		+= i2c-keba.o
>>  obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
>>  obj-$(CONFIG_I2C_LPC2K)		+= i2c-lpc2k.o
>> diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c
>> new file mode 100644
>> index 000000000000..12bb71625e0a
>> --- /dev/null
>> +++ b/drivers/i2c/busses/i2c-k1.c
>> @@ -0,0 +1,656 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (C) 2024 Troy Mitchell <troymitchell988 at gmail.com>
>> + */
>> +
>> + #include <linux/clk.h>
>> + #include <linux/i2c.h>
>> + #include <linux/iopoll.h>
>> + #include <linux/module.h>
>> + #include <linux/of_address.h>
>> + #include <linux/platform_device.h>
>> +
>> +/* spacemit i2c registers */
>> +#define ICR          0x0		/* Control Register */
>> +#define ISR          0x4		/* Status Register */
>> +#define ISAR         0x8		/* Slave Address Register */
>> +#define IDBR         0xc		/* Data Buffer Register */
>> +#define ILCR         0x10		/* Load Count Register */
>> +#define IWCR         0x14		/* Wait Count Register */
>> +#define IRST_CYC     0x18		/* Bus reset cycle counter */
>> +#define IBMR         0x1c		/* Bus monitor register */
>> +#define IWFIFO       0x20		/* Write FIFO Register */
>> +#define IWFIFO_WPTR  0x24		/* Write FIFO Write Pointer Register */
>> +#define IWFIFO_RPTR  0x28		/* Write FIFO Read Pointer Register */
>> +#define IRFIFO       0x2c		/* Read FIFO Register */
>> +#define IRFIFO_WPTR  0x30		/* Read FIFO Write Pointer Register */
>> +#define IRFIFO_RPTR  0x34		/* Read FIFO Read Pointer Register */
>> +
>> +/* register ICR fields */
>> +#define CR_START        BIT(0)		/* start bit */
>> +#define CR_STOP         BIT(1)		/* stop bit */
>> +#define CR_ACKNAK       BIT(2)		/* send ACK(0) or NAK(1) */
>> +#define CR_TB           BIT(3)		/* transfer byte bit */
>> +#define CR_TXBEGIN      BIT(4)		/* transaction begin */
>> +#define CR_FIFOEN       BIT(5)		/* enable FIFO mode */
>> +#define CR_GPIOEN       BIT(6)		/* enable GPIO mode for SCL in HS */
>> +#define CR_DMAEN        BIT(7)		/* enable DMA for TX and RX FIFOs */
>> +#define CR_MODE_FAST    BIT(8)		/* bus mode (master operation) */
>> +#define CR_MODE_HIGH    BIT(9)		/* bus mode (master operation) */
>> +#define CR_UR           BIT(10)		/* unit reset */
>> +#define CR_RSTREQ       BIT(11)		/* i2c bus reset request */
>> +#define CR_MA           BIT(12)		/* master abort */
>> +#define CR_SCLE         BIT(13)		/* master clock enable */
>> +#define CR_IUE          BIT(14)		/* unit enable */
>> +#define CR_HS_STRETCH   BIT(16)		/* I2C hs stretch */
>> +#define CR_ALDIE        BIT(18)		/* enable arbitration interrupt */
>> +#define CR_DTEIE        BIT(19)		/* enable tx interrupts */
>> +#define CR_DRFIE        BIT(20)		/* enable rx interrupts */
>> +#define CR_GCD          BIT(21)		/* general call disable */
>> +#define CR_BEIE         BIT(22)		/* enable bus error ints */
>> +#define CR_SADIE        BIT(23)		/* slave address detected int enable */
>> +#define CR_SSDIE        BIT(24)		/* slave STOP detected int enable */
>> +#define CR_MSDIE        BIT(25)		/* master STOP detected int enable */
>> +#define CR_MSDE         BIT(26)		/* master STOP detected enable */
>> +#define CR_TXDONEIE     BIT(27)		/* transaction done int enable */
>> +#define CR_TXEIE        BIT(28)		/* transmit FIFO empty int enable */
>> +#define CR_RXHFIE       BIT(29)		/* receive FIFO half-full int enable */
>> +#define CR_RXFIE        BIT(30)		/* receive FIFO full int enable */
>> +#define CR_RXOVIE       BIT(31)		/* receive FIFO overrun int enable */
>> +
>> +/* register ISR fields */
>> +#define SR_RWM          BIT(13)		/* read/write mode */
>> +#define SR_ACKNAK       BIT(14)		/* ACK/NACK status */
>> +#define SR_UB           BIT(15)		/* unit busy */
>> +#define SR_IBB          BIT(16)		/* i2c bus busy */
>> +#define SR_EBB          BIT(17)		/* early bus busy */
>> +#define SR_ALD          BIT(18)		/* arbitration loss detected */
>> +#define SR_ITE          BIT(19)		/* tx buffer empty */
>> +#define SR_IRF          BIT(20)		/* rx buffer full */
>> +#define SR_GCAD         BIT(21)		/* general call address detected */
>> +#define SR_BED          BIT(22)		/* bus error no ACK/NAK */
>> +#define SR_SAD          BIT(23)		/* slave address detected */
>> +#define SR_SSD          BIT(24)		/* slave stop detected */
>> +#define SR_MSD          BIT(26)		/* master stop detected */
>> +#define SR_TXDONE       BIT(27)		/* transaction done */
>> +#define SR_TXE          BIT(28)		/* tx FIFO empty */
>> +#define SR_RXHF         BIT(29)		/* rx FIFO half-full */
>> +#define SR_RXF          BIT(30)		/* rx FIFO full */
>> +#define SR_RXOV         BIT(31)		/* RX FIFO overrun */
>> +
>> +/* register ILCR fields */
>> +#define LCR_SLV         0x000001FF	/* SLV: bit[8:0] */
>> +#define LCR_FLV         0x0003FE00	/* FLV: bit[17:9] */
>> +#define LCR_HLVH        0x07FC0000	/* HLVH: bit[26:18] */
>> +#define LCR_HLVL        0xF8000000	/* HLVL: bit[31:27] */
>> +
>> +/* register IWCR fields */
>> +#define WCR_COUNT       0x0000001F	/* COUNT: bit[4:0] */
>> +#define WCR_COUNT1      0x000003E0	/* HS_COUNT1: bit[9:5] */
>> +#define WCR_COUNT2      0x00007C00	/* HS_COUNT2: bit[14:10] */
>> +
>> +/* register IBMR fields */
>> +#define BMR_SDA         BIT(0)		/* SDA line level */
>> +#define BMR_SCL         BIT(1)		/* SCL line level */
>> +
>> +/* register IWFIFO fields */
>> +#define WFIFO_DATA_MSK      0x000000FF  /* data: bit[7:0] */
>> +#define WFIFO_CTRL_MSK      0x000003E0  /* control: bit[11:8] */
>> +#define WFIFO_CTRL_START    BIT(8)      /* start bit */
>> +#define WFIFO_CTRL_STOP     BIT(9)      /* stop bit */
>> +#define WFIFO_CTRL_ACKNAK   BIT(10)     /* send ACK(0) or NAK(1) */
>> +#define WFIFO_CTRL_TB       BIT(11)     /* transfer byte bit */
>> +
>> +/* status register init value */
>> +#define I2C_INT_STATUS_MASK    0xfffc0000  /* SR bits[31:18] */
>> +#define I2C_INT_CTRL_MASK      (CR_ALDIE | CR_DTEIE | CR_DRFIE | \
>> +				CR_BEIE | CR_TXDONEIE | CR_TXEIE | \
>> +				CR_RXHFIE | CR_RXFIE | CR_RXOVIE | \
>> +				CR_MSDIE)
>> +
>> +/* i2c bus recover timeout: us */
>> +#define I2C_BUS_RECOVER_TIMEOUT		(100000)
>> +
>> +#define I2C_FAST_MODE_FREQ		(400000)
>> +
>> +enum spacemit_i2c_state {
>> +	STATE_IDLE,
>> +	STATE_START,
>> +	STATE_READ,
>> +	STATE_WRITE,
>> +};
>> +
>> +enum spacemit_i2c_dir {
>> +	DIR_WRITE,
>> +	DIR_READ
>> +};
>> +
>> +/* i2c-spacemit driver's main struct */
>> +struct spacemit_i2c_dev {
>> +	struct device *dev;
>> +	struct i2c_adapter adapt;
>> +
>> +	/* hardware resources */
>> +	void __iomem *base;
>> +	int irq;
>> +
>> +	struct i2c_msg *msgs;
>> +	int msg_num;
>> +	struct i2c_msg *cur_msg;
>> +
>> +	/* index of the current message being processed */
>> +	int msg_idx;
>> +	u8 *msg_buf;
>> +	/* the number of unprocessed bytes remaining in each message  */
>> +	size_t unprocessed;
>> +
>> +	enum spacemit_i2c_state state;
>> +	enum spacemit_i2c_dir dir;
>> +	struct completion complete;
>> +	u32 status;
>> +	u32 err;
>> +};
>> +
>> +static void spacemit_i2c_enable(struct spacemit_i2c_dev *i2c)
>> +{
>> +	u32 val;
>> +
>> +	val = readl(i2c->base + ICR);
>> +	writel(val | CR_IUE, i2c->base + ICR);
>> +}
>> +
>> +static void spacemit_i2c_disable(struct spacemit_i2c_dev *i2c)
>> +{
>> +	u32 val;
>> +
>> +	val = readl(i2c->base + ICR);
>> +	val &= ~CR_IUE;
>> +	writel(val, i2c->base + ICR);
>> +}
>> +
>> +static void spacemit_i2c_reset(struct spacemit_i2c_dev *i2c)
>> +{
>> +	writel(CR_UR, i2c->base + ICR);
>> +	udelay(5);
>> +	writel(0, i2c->base + ICR);
>> +}
>> +
>> +static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c);
>> +
>> +static void spacemit_i2c_bus_reset(struct spacemit_i2c_dev *i2c)
>> +{
>> +	u32 status;
>> +
>> +	/* if bus is locked, reset unit. 0: locked */
>> +	status = readl(i2c->base + IBMR);
>> +	if ((status & BMR_SDA) && (status & BMR_SCL))
>> +		return;
>> +
>> +	spacemit_i2c_reset(i2c);
>> +	usleep_range(10, 20);
>> +
>> +	/* check scl status again */
>> +	status = readl(i2c->base + IBMR);
>> +	if (!(status & BMR_SCL))
>> +		dev_warn_ratelimited(i2c->dev, "unit reset failed\n");
>> +}
>> +
>> +static int spacemit_i2c_recover_bus_busy(struct spacemit_i2c_dev *i2c)
>> +{
>> +	int ret = 0;
>> +	u32 val;
>> +
>> +	val = readl(i2c->base + ISR);
>> +	if (likely(!(val & (SR_UB | SR_IBB))))
>> +		return 0;
>> +
>> +	ret = readl_poll_timeout(i2c->base + ISR, val, !(val & (SR_UB | SR_IBB)),
>> +				 1500, I2C_BUS_RECOVER_TIMEOUT);
>> +	if (unlikely(ret)) {
>> +		spacemit_i2c_reset(i2c);
>> +		ret = -EAGAIN;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static void spacemit_i2c_check_bus_release(struct spacemit_i2c_dev *i2c)
>> +{
>> +	/* in case bus is not released after transfer completes */
>> +	if (unlikely(readl(i2c->base + ISR) & SR_EBB)) {
>> +		spacemit_i2c_bus_reset(i2c);
>> +		usleep_range(90, 150);
>> +	}
>> +}
>> +
>> +static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c)
>> +{
>> +	u32 val = 0;
>> +
>> +	/*
>> +	 * Unmask interrupt bits for all xfer mode:
>> +	 * bus error, arbitration loss detected.
>> +	 * For transaction complete signal, we use master stop
>> +	 * interrupt, so we don't need to unmask CR_TXDONEIE.
>> +	 */
>> +	val |= CR_BEIE | CR_ALDIE;
>> +
>> +	/*
>> +	 * Unmask interrupt bits for interrupt xfer mode:
>> +	 * DBR rx full.
>> +	 * For tx empty interrupt CR_DTEIE, we only
>> +	 * need to enable when trigger byte transfer to start
>> +	 * data sending.
>> +	 */
>> +	val |= CR_DRFIE;
>> +
>> +	/* set speed bits: default fast mode */
>> +	val |= CR_MODE_FAST;
>> +
>> +	/* disable response to general call */
>> +	val |= CR_GCD;
>> +
>> +	/* enable SCL clock output */
>> +	val |= CR_SCLE;
>> +
>> +	/* enable master stop detected */
>> +	val |= CR_MSDE | CR_MSDIE;
>> +
>> +	writel(val, i2c->base + ICR);
>> +}
>> +
>> +static inline void
>> +spacemit_i2c_clear_int_status(struct spacemit_i2c_dev *i2c, u32 mask)
>> +{
>> +	writel(mask & I2C_INT_STATUS_MASK, i2c->base + ISR);
>> +}
>> +
>> +static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c)
>> +{
>> +	u32 slave_addr_rw, val;
>> +
>> +	i2c->dir = i2c->cur_msg->flags & I2C_M_RD;
>> +	i2c->state = STATE_START;
>> +
>> +	if (i2c->cur_msg->flags & I2C_M_RD)
>> +		slave_addr_rw = ((i2c->cur_msg->addr & 0x7f) << 1) | 1;
>> +	else
>> +		slave_addr_rw = (i2c->cur_msg->addr & 0x7f) << 1;
>> +
>> +	writel(slave_addr_rw, i2c->base + IDBR);
>> +
>> +	val = readl(i2c->base + ICR);
>> +
>> +	/* send start pulse */
>> +	val &= ~CR_STOP;
>> +	val |= CR_START | CR_TB | CR_DTEIE;
>> +	writel(val, i2c->base + ICR);
>> +}
>> +
>> +static void spacemit_i2c_stop(struct spacemit_i2c_dev *i2c)
>> +{
>> +	u32 val;
>> +
>> +	val = readl(i2c->base + ICR);
>> +
>> +	val |= CR_STOP | CR_ALDIE | CR_TB;
>> +
>> +	if (i2c->dir == DIR_READ)
>> +		val |= CR_ACKNAK;
>> +
>> +	writel(val, i2c->base + ICR);
>> +}
>> +
>> +static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
>> +{
>> +	unsigned long time_left;
>> +
>> +	for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) {
>> +		i2c->cur_msg = i2c->msgs + i2c->msg_idx;
>> +		i2c->msg_buf = i2c->cur_msg->buf;
>> +		i2c->err = 0;
>> +		i2c->status = 0;
>> +		i2c->unprocessed = i2c->cur_msg->len;
>> +
>> +		reinit_completion(&i2c->complete);
>> +
>> +		spacemit_i2c_start(i2c);
>> +
>> +		time_left = wait_for_completion_timeout(&i2c->complete,
>> +							i2c->adapt.timeout);
>> +		if (unlikely(time_left == 0)) {
>> +			dev_alert(i2c->dev, "msg completion timeout\n");
>> +			spacemit_i2c_bus_reset(i2c);
>> +			spacemit_i2c_reset(i2c);
>> +			return -ETIMEDOUT;
>> +		}
>> +
>> +		if (unlikely(i2c->err))
>> +			return spacemit_i2c_handle_err(i2c);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c)
>> +{
>> +	if (i2c->dir == DIR_READ) {
>> +		if (i2c->unprocessed == 1 && i2c->msg_idx == i2c->msg_num - 1)
>> +			return 1;
>> +	} else if (i2c->dir == DIR_WRITE) {
>> +		if (!i2c->unprocessed && i2c->msg_idx == i2c->msg_num - 1)
>> +			return 1;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void spacemit_i2c_handle_write(struct spacemit_i2c_dev *i2c)
>> +{
>> +	/* if transfer completes, ISR will handle it */
>> +	if (i2c->status & SR_MSD)
>> +		return;
>> +
>> +	if (i2c->unprocessed) {
>> +		writel(*i2c->msg_buf++, i2c->base + IDBR);
>> +		i2c->unprocessed--;
>> +		return;
>> +	}
>> +
>> +	/* STATE_IDLE avoids trigger next byte */
>> +	i2c->state = STATE_IDLE;
>> +	complete(&i2c->complete);
>> +}
>> +
>> +static void spacemit_i2c_handle_read(struct spacemit_i2c_dev *i2c)
>> +{
>> +	if (i2c->unprocessed) {
>> +		*i2c->msg_buf++ = readl(i2c->base + IDBR);
>> +		i2c->unprocessed--;
>> +	}
>> +
>> +	/* if transfer completes, ISR will handle it */
>> +	if (i2c->status & (SR_MSD | SR_ACKNAK))
>> +		return;
>> +
>> +	/* it has to append stop bit in icr that read last byte */
>> +	if (i2c->unprocessed)
>> +		return;
>> +
>> +	/* STATE_IDLE avoids trigger next byte */
>> +	i2c->state = STATE_IDLE;
>> +	complete(&i2c->complete);
>> +}
>> +
>> +static void spacemit_i2c_handle_start(struct spacemit_i2c_dev *i2c)
>> +{
>> +	if (i2c->dir == DIR_READ) {
>> +		i2c->state = STATE_READ;
>> +		return;
>> +	}
>> +
>> +	if (i2c->dir == DIR_WRITE) {
>> +		i2c->state = STATE_WRITE;
>> +		spacemit_i2c_handle_write(i2c);
>> +	}
>> +}
>> +
>> +static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c)
>> +{
>> +	if (!i2c->err)
>> +		return 0;
>> +
>> +	dev_dbg(i2c->dev, "i2c error status: 0x%08x\n",	i2c->status);
>> +
>> +	if (i2c->err & (SR_BED | SR_ALD))
>> +		spacemit_i2c_reset(i2c);
>> +
>> +	if (i2c->err & (SR_RXOV | SR_ALD))
>> +		return -EAGAIN;
>> +
>> +	return (i2c->status & SR_ACKNAK) ? -ENXIO : -EIO;
>> +}
>> +
>> +static void spacemit_i2c_err_check(struct spacemit_i2c_dev *i2c)
>> +{
>> +	u32 val;
>> +	/*
>> +	 * send transaction complete signal:
>> +	 * error happens, detect master stop
>> +	 */
>> +	if (likely(i2c->err || (i2c->status & SR_MSD))) {
>> +		/*
>> +		 * Here the transaction is already done, we don't need any
>> +		 * other interrupt signals from now, in case any interrupt
>> +		 * happens before spacemit_i2c_xfer to disable irq and i2c unit,
>> +		 * we mask all the interrupt signals and clear the interrupt
>> +		 * status.
>> +		 */
>> +		val = readl(i2c->base + ICR);
>> +		val &= ~I2C_INT_CTRL_MASK;
>> +		writel(val, i2c->base + ICR);
>> +
>> +		spacemit_i2c_clear_int_status(i2c, I2C_INT_STATUS_MASK);
>> +
>> +		i2c->state = STATE_IDLE;
>> +		complete(&i2c->complete);
>> +	}
>> +}
>> +
>> +static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
>> +{
>> +	struct spacemit_i2c_dev *i2c = devid;
>> +	u32 status, val;
>> +
>> +	status = readl(i2c->base + ISR);
>> +	if (!status)
>> +		return IRQ_HANDLED;
>> +
>> +	i2c->status = status;
>> +
>> +	i2c->err = status & (SR_BED | SR_RXOV | SR_ALD);
>> +
>> +	spacemit_i2c_clear_int_status(i2c, status);
>> +
>> +	if (unlikely(i2c->err))
>> +		goto err_out;
>> +
>> +	val = readl(i2c->base + ICR);
>> +
>> +	val &= ~(CR_TB | CR_ACKNAK | CR_STOP | CR_START);
>> +	writel(val, i2c->base + ICR);
>> +
>> +	switch (i2c->state) {
>> +	case STATE_START:
>> +		spacemit_i2c_handle_start(i2c);
>> +		break;
>> +	case STATE_READ:
>> +		spacemit_i2c_handle_read(i2c);
>> +		break;
>> +	case STATE_WRITE:
>> +		spacemit_i2c_handle_write(i2c);
>> +		break;
>> +	default:
>> +		break;
>> +	}
>> +
>> +	if (i2c->state != STATE_IDLE) {
>> +		if (spacemit_i2c_is_last_msg(i2c)) {
>> +			/* trigger next byte with stop */
>> +			spacemit_i2c_stop(i2c);
>> +		} else {
>> +			/* trigger next byte */
>> +			val |= CR_ALDIE | CR_TB;
>> +			writel(val, i2c->base + ICR);
>> +		}
>> +	}
>> +
>> +err_out:
>> +	spacemit_i2c_err_check(i2c);
>> +	return IRQ_HANDLED;
>> +}
>> +
>> +static void spacemit_i2c_calc_timeout(struct spacemit_i2c_dev *i2c)
>> +{
>> +	unsigned long timeout;
>> +	int idx = 0, cnt = 0, freq;
>> +
>> +	while (idx < i2c->msg_num) {
>> +		cnt += (i2c->msgs + idx)->len + 1;
>> +		idx++;
>> +	}
>> +
>> +	freq = I2C_FAST_MODE_FREQ;
> so this will set frequency to fast mode (400K), this contradict with PATCH[1/2] which
> says default clock-frequency is 100000, either you need to change the code? or
> update the dt-binding?
I will update the dt-binding in next version.
> 
>> +	/*
>> +	 * multiply by 9 because each byte in I2C transmission requires
>> +	 * 9 clock cycles: 8 bits of data plus 1 ACK/NACK bit.
>> +	 */
>> +	timeout = cnt * 9 * USEC_PER_SEC / freq;
>> +
>> +	i2c->adapt.timeout = usecs_to_jiffies(timeout + USEC_PER_SEC / 2) / i2c->msg_num;
>> +}
>> +
>> +static inline int spacemit_i2c_xfer_core(struct spacemit_i2c_dev *i2c)
> drop inline? IMO, it isn't worth here for long function
okay
> 
>> +{
>> +	int ret = 0;
> no need to initilize to 0
ok
>> +
>> +	spacemit_i2c_reset(i2c);
>> +
>> +	spacemit_i2c_calc_timeout(i2c);
>> +
>> +	spacemit_i2c_init(i2c);
>> +
>> +	spacemit_i2c_enable(i2c);
>> +	enable_irq(i2c->irq);
>> +
>> +	/* i2c wait for bus busy */
>> +	ret = spacemit_i2c_recover_bus_busy(i2c);
>> +	if (unlikely(ret))
>> +		return ret;
>> +
>> +	ret = spacemit_i2c_xfer_msg(i2c);
>> +	if (unlikely(ret < 0)) {
>> +		dev_dbg(i2c->dev, "i2c transfer error\n");
>> +		/* timeout error should not be overridden, and the transfer
>> +		 * error will be confirmed by err handle function latter,
>> +		 * the reset should be invalid argument error.
>> +		 */
>> +		if (ret != -ETIMEDOUT)
>> +			ret = -EINVAL;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static int
>> +spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg msgs[], int num)
> no need to wrap the line, it makes the code a little bit weird..
> 
> current policy increase to 100characters, the old 80-column is not enforced
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bdc48fa11e46f867ea4d75fa59ee87a7f48be144
ok
> 
>> +{
>> +	struct spacemit_i2c_dev *i2c = i2c_get_adapdata(adapt);
>> +	int ret;
>> +
>> +	i2c->msgs = msgs;
>> +	i2c->msg_num = num;
>> +
>> +	ret = spacemit_i2c_xfer_core(i2c);
>> +	if (likely(!ret))
>> +		spacemit_i2c_check_bus_release(i2c);
>> +
>> +	disable_irq(i2c->irq);
>> +
>> +	spacemit_i2c_disable(i2c);
>> +
>> +	if (unlikely((ret == -ETIMEDOUT || ret == -EAGAIN)))
>> +		dev_alert(i2c->dev, "i2c transfer failed, ret %d err 0x%x\n", ret, i2c->err);
>> +
>> +	return ret < 0 ? ret : num;
>> +}
>> +
>> +static u32 spacemit_i2c_func(struct i2c_adapter *adap)
>> +{
>> +	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
>> +}
>> +
>> +static const struct i2c_algorithm spacemit_i2c_algo = {
>> +	.xfer = spacemit_i2c_xfer,
>> +	.functionality = spacemit_i2c_func,
>> +};
>> +
>> +static int spacemit_i2c_probe(struct platform_device *pdev)
>> +{
>> +	struct spacemit_i2c_dev *i2c;
>> +	struct device_node *of_node = pdev->dev.of_node;
>> +	struct clk *clk;
>> +	int ret = 0;
>> +
>> +	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
>> +	if (!i2c)
>> +		return -ENOMEM;
>> +
>> +	i2c->dev = &pdev->dev;
>> +
>> +	i2c->base = devm_platform_ioremap_resource(pdev, 0);
>> +	if (IS_ERR(i2c->base))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(i2c->base), "failed to do ioremap");
>> +
>> +	i2c->irq = platform_get_irq(pdev, 0);
>> +	if (i2c->irq < 0)
>> +		return dev_err_probe(&pdev->dev, i2c->irq, "failed to get irq resource");
>> +
>> +	ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
>> +			       IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(i2c->dev), i2c);
>> +	if (ret)
>> +		return dev_err_probe(&pdev->dev, ret, "failed to request irq");
>> +
>> +	disable_irq(i2c->irq);
>> +
>> +	clk = devm_clk_get_enabled(&pdev->dev, NULL);
>> +	if (IS_ERR(clk))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk), "failed to enable clock");
>> +
> I'd suggest also to handle pin request here, since pinctrl driver is merged
> 
> https://lore.kernel.org/all/CACRpkdYnaJsKKfcdhHeMGTTp86M+wNODzZx2e=OYbxQ4Jc4Rjw at mail.gmail.com/
sry, I don't understand what pin I need to request?
> 
>> +	i2c_set_adapdata(&i2c->adapt, i2c);
>> +	i2c->adapt.owner = THIS_MODULE;
>> +	i2c->adapt.algo = &spacemit_i2c_algo;
>> +	i2c->adapt.dev.parent = i2c->dev;
>> +	i2c->adapt.nr = pdev->id;
>> +
>> +	i2c->adapt.dev.of_node = of_node;
>> +	i2c->adapt.algo_data = i2c;
>> +
>> +	strscpy(i2c->adapt.name, "spacemit-i2c-adapter", sizeof(i2c->adapt.name));
>> +
>> +	init_completion(&i2c->complete);
>> +
>> +	ret = i2c_add_numbered_adapter(&i2c->adapt);
>> +	if (ret)
>> +		return dev_err_probe(&pdev->dev, ret, "failed to add i2c adapter");
>> +
>> +	platform_set_drvdata(pdev, i2c);
>> +
>> +	return 0;
>> +}
>> +
>> +static void spacemit_i2c_remove(struct platform_device *pdev)
>> +{
>> +	struct spacemit_i2c_dev *i2c = platform_get_drvdata(pdev);
>> +
>> +	i2c_del_adapter(&i2c->adapt);
>> +}
>> +
>> +static const struct of_device_id spacemit_i2c_of_match[] = {
>> +	{ .compatible = "spacemit,k1-i2c", },
>> +	{ /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, spacemit_i2c_of_match);
>> +
>> +static struct platform_driver spacemit_i2c_driver = {
>> +	.probe = spacemit_i2c_probe,
>> +	.remove = spacemit_i2c_remove,
>> +	.driver = {
>> +		.name = "i2c-k1",
>> +		.of_match_table = spacemit_i2c_of_match,
>> +	},
>> +};
>> +module_platform_driver(spacemit_i2c_driver);
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_DESCRIPTION("I2C bus driver for SpacemiT K1 SoC");
>>
>> -- 
>> 2.34.1
>>
> 

-- 
Troy Mitchell


From troymitchell988 at gmail.com  Wed Nov 20 20:12:04 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Thu, 21 Nov 2024 12:12:04 +0800
Subject: [PATCH v3 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <20241114070601-GYA1001363@gentoo>
References: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
 <20241112-k1-i2c-master-v3-1-5005b70dc208@gmail.com>
 <20241112-aged-trailing-cffda6af0944@spud> <20241114070601-GYA1001363@gentoo>
Message-ID: <9a1e20a0-6a79-4bb3-990c-a1c6dfb22f1c@gmail.com>

Hi, Yixun. Thanks for ur review.

On 2024/11/14 15:06, Yixun Lan wrote:
> On 18:03 Tue 12 Nov     , Conor Dooley wrote:
>> On Tue, Nov 12, 2024 at 11:07:39AM +0800, Troy Mitchell wrote:
>>> From: Troy Mitchell <troymitchell988 at gmail.com>
>>>
>>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
>>> and supports FIFO transmission.
>>>
>>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
>>> ---
>>>  .../devicetree/bindings/i2c/spacemit,k1-i2c.yaml   | 52 ++++++++++++++++++++++
>>>  1 file changed, 52 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>> new file mode 100644
>>> index 000000000000..e8cce360bf03
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
>>> @@ -0,0 +1,52 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: I2C controller embedded in SpacemiT's K1 SoC
>>> +
>>> +maintainers:
>>> +  - Troy Mitchell <troymitchell988 at gmail.com>
>>> +
>>> +properties:
>>> +  compatible:
>>> +    const: spacemit,k1-i2c
>>> +
>>> +  reg:
>>> +    maxItems: 1
>>> +
>>> +  interrupts:
>>> +    maxItems: 1
>>> +
>>> +  clocks:
>>> +    maxItems: 1
>>> +
>>> +  clock-frequency:
>>> +    description:
>>> +      Desired I2C bus clock frequency in Hz.
>>> +      K1 supports standard, fast, high-speed modes, from 1 to 3300000.
> while we are here, I'd suggest rephrase the sentence above to align it better with the doc
> 
> K1 support three different modes which running different frequencies
> standard speed mode: up to 100000 (100Hz)
> fast speed mode    : up to 400000 (400Hz)
> high speed mode    : up to 3300000 (3.3Mhz)>
>>> +    default: 100000
>>> +    minimum: 1
I will modify `description` and drop `minimum` in next version
>>> +    maximum: 3300000
>>
>> It's sufficient to define just default and max btw, the min is set in
>> i2c-controller.yaml (in dt-schema itself). Don't respin for that alone.
> +1, the minimum settings isn't really useful, clearly not apply in the practical case
> 
>>
>> Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
>>> +
>>> +required:
>>> +  - compatible
>>> +  - reg
>>> +  - interrupts
>>> +  - clocks
>>> +
>>> +unevaluatedProperties: false
>>> +
>>> +examples:
>>> +  - |
>>> +    i2c at d4010800 {
>>> +        compatible = "spacemit,k1-i2c";
>>> +        reg = <0xd4010800 0x38>;
>>> +        interrupt-parent = <&plic>;
>>> +        interrupts = <36>;
>>> +        clocks = <&ccu 90>;
>>> +        clock-frequency = <100000>;
>>> +    };
>>> +
>>> +...
>>>
>>> -- 
>>> 2.34.1
>>>
> 
> 
> 

-- 
Troy Mitchell


From charlie at rivosinc.com  Wed Nov 20 20:22:23 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 20 Nov 2024 20:22:23 -0800
Subject: [PATCH RFT 00/16] perf tools: Use generic syscall scripts for
 all archs
In-Reply-To: <ZylaRaMqEsEjYjs6@ghost>
References: <20241104-perf_syscalltbl-v1-0-9adae5c761ef@rivosinc.com>
 <3b56fc50-4c6c-4520-adba-461797a3b5ec@app.fastmail.com>
 <Zyk9hX8CB_2rbWsi@ghost>
 <CAP-5=fUdZRbCp+2ghEUdp+qJ1BuMDuTtw9R+dFAaom+3oqQV_g@mail.gmail.com>
 <ZylaRaMqEsEjYjs6@ghost>
Message-ID: <Zz61f02p8s52G6ba@ghost>

On Mon, Nov 04, 2024 at 03:35:33PM -0800, Charlie Jenkins wrote:
> On Mon, Nov 04, 2024 at 02:03:28PM -0800, Ian Rogers wrote:
> > On Mon, Nov 4, 2024 at 1:32?PM Charlie Jenkins <charlie at rivosinc.com> wrote:
> > >
> > > On Mon, Nov 04, 2024 at 10:13:18PM +0100, Arnd Bergmann wrote:
> > > > On Mon, Nov 4, 2024, at 22:06, Charlie Jenkins wrote:
> > > > > Standardize the generation of syscall headers around syscall tables.
> > > > > Previously each architecture independently selected how syscall headers
> > > > > would be generated, or would not define a way and fallback onto
> > > > > libaudit. Convert all architectures to use a standard syscall header
> > > > > generation script and allow each architecture to override the syscall
> > > > > table to use if they do not use the generic table.
> > > > >
> > > > > As a result of these changes, no architecture will require libaudit, and
> > > > > so the fallback case of using libaudit is removed by this series.
> > > > >
> > > > > Testing:
> > > > >
> > > > > I have tested that the syscall mappings of id to name generation works
> > > > > as expected for every architecture, but I have only validated that perf
> > > > > trace compiles and runs as expected on riscv, arm64, and x86_64.
> > > > >
> > > > > Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> > > >
> > > > Thanks for doing this, I had plans to do this myself, but hadn't
> > > > completed that bit so far. I'm travelling at the moment, so I'm
> > > > not sure I have time to look at it in enough detail this week.
> > > >
> > > > One problem I ran into doing this previously was the incompatible
> > > > format of the tables for x86 and s390, which have conflicting
> > > > interpretations of what the '-' character means. It's possible
> > > > that this is only really relevant for the in-kernel table,
> > > > not the version in tools.
> > > >
> > >
> > > I don't think that is an issue for this usecase because the only
> > > information that is taken from the syscall table is the number and the
> > > name of the syscall. '-' doesn't appear in either of these columns!
> > 
> > This is cool stuff. An area that may not be immediately apparent for
> > improvement is that the x86-64 build only has access to the 64-bit
> > syscall table. Perhaps all the syscall tables should always be built
> > and then at runtime the architecture of the perf.data file, etc. used
> > to choose the appropriate one. The cleanup to add an ELF host #define
> > could help with this:
> > https://lore.kernel.org/linux-perf-users/20241017002520.59124-1-irogers at google.com/
> 
> Oh that's a great idea! I think these changes will make it more seamless
> to make that a reality.
> 
> > 
> > Ultimately I'd like to see less arch code as it inherently makes cross
> > platform worker harder. That doesn't impact this work which I'm happy
> > to review.
> 
> Yeah I agree. Reducing arch code was the motivation for this change.
> There was the issue a couple weeks ago that caused all architectures
> that used libaudit to break from commit 7a2fb5619cc1fb53 ("perf trace:
> Fix iteration of syscall ids in syscalltbl->entries"), so this change
> will eliminate that source of difference between architectures.
> 
> - Charlie
> 
> > 
> > Thanks,
> > Ian

Let me know if you have any feedback on this series!

- Charlie



From namhyung at kernel.org  Wed Nov 20 22:04:51 2024
From: namhyung at kernel.org (Namhyung Kim)
Date: Wed, 20 Nov 2024 22:04:51 -0800
Subject: [PATCH] tools: Override makefile ARCH variable if defined, but
 empty
In-Reply-To: <87r076nikd.fsf@all.your.base.are.belong.to.us>
References: <20241106193208.290067-1-bjorn@kernel.org>
 <87r076nikd.fsf@all.your.base.are.belong.to.us>
Message-ID: <Zz7Ng9CzrF_ciAz-@google.com>

On Wed, Nov 20, 2024 at 02:25:22PM +0100, Bj?rn T?pel wrote:
> Bj?rn T?pel <bjorn at kernel.org> writes:
> 
> > From: Bj?rn T?pel <bjorn at rivosinc.com>
> >
> > There are a number of tools (bpftool, selftests), that require a
> > "bootstrap" build. Here, a bootstrap build is a build host variant of
> > a target. E.g., assume that you're performing a bpftool cross-build on
> > x86 to riscv, a bootstrap build would then be an x86 variant of
> > bpftool. The typical way to perform the host build variant, is to pass
> > "ARCH=" in a sub-make. However, if a variable has been set with a
> > command argument, then ordinary assignments in the makefile are
> > ignored.
> >
> > This side-effect results in that ARCH, and variables depending on ARCH
> > are not set.
> >
> > Workaround by overriding ARCH to the host arch, if ARCH is empty.
> >
> > Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
> > Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>

Reviewed-by: Namhyung Kim <namhyung at kernel.org>

> 
> Arnaldo/Palmer/Quentin:
> 
> A bit unsure what tree this patch should go. It's very important for the
> RISC-V builds, so maybe via Palmer's RISC-V tree?

I think it'd be best to route this through the bpf tree as it seems the
main target is bpftool.  But given the size and the scope of the change,
it should be fine with perf-tools or RISC-V tree.

Thanks,
Namhyung

> 
> Opinions? Just want to make sure it doesn't fall between any chairs!
> :-)
> 
> 
> Bj?rn


From ajones at ventanamicro.com  Thu Nov 21 01:32:28 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 21 Nov 2024 10:32:28 +0100
Subject: [PATCH v2] riscv: Call secondary mmu notifier when flushing the
 tlb
In-Reply-To: <20240328073838.8776-1-alexghiti@rivosinc.com>
References: <20240328073838.8776-1-alexghiti@rivosinc.com>
Message-ID: <20241121-e97820f8c09de9bcedfe885d@orel>

On Thu, Mar 28, 2024 at 08:38:38AM +0100, Alexandre Ghiti wrote:
> This is required to allow the IOMMU driver to correctly flush its own
> TLB.
> 
> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> ---
> 
> Changes in v2:
> - Rebase on top of 6.9-rc1
> 
>  arch/riscv/mm/tlbflush.c | 39 +++++++++++++++++++++++----------------
>  1 file changed, 23 insertions(+), 16 deletions(-)
>

Hi Alex,

Is this patch still something we need?

Thanks,
drew


From alex at ghiti.fr  Thu Nov 21 02:36:34 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Thu, 21 Nov 2024 11:36:34 +0100
Subject: [PATCH v2] riscv: Call secondary mmu notifier when flushing the
 tlb
In-Reply-To: <20241121-e97820f8c09de9bcedfe885d@orel>
References: <20240328073838.8776-1-alexghiti@rivosinc.com>
 <20241121-e97820f8c09de9bcedfe885d@orel>
Message-ID: <0456b6b4-1453-444d-8cd8-38715dc9f845@ghiti.fr>

Hi Andrew,

On 21/11/2024 10:32, Andrew Jones wrote:
> On Thu, Mar 28, 2024 at 08:38:38AM +0100, Alexandre Ghiti wrote:
>> This is required to allow the IOMMU driver to correctly flush its own
>> TLB.
>>
>> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
>> ---
>>
>> Changes in v2:
>> - Rebase on top of 6.9-rc1
>>
>>   arch/riscv/mm/tlbflush.c | 39 +++++++++++++++++++++++----------------
>>   1 file changed, 23 insertions(+), 16 deletions(-)
>>
> Hi Alex,
>
> Is this patch still something we need?
>
> Thanks,
> drew


Yes I think so, hopefully it gets merged.

Thanks,

Alex

> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From qmo at kernel.org  Thu Nov 21 03:29:59 2024
From: qmo at kernel.org (Quentin Monnet)
Date: Thu, 21 Nov 2024 11:29:59 +0000
Subject: [PATCH] tools: Override makefile ARCH variable if defined, but
 empty
In-Reply-To: <Zz7Ng9CzrF_ciAz-@google.com>
References: <20241106193208.290067-1-bjorn@kernel.org>
 <87r076nikd.fsf@all.your.base.are.belong.to.us> <Zz7Ng9CzrF_ciAz-@google.com>
Message-ID: <6a960374-0cd2-4de9-8fc6-c8fe21097b6b@kernel.org>

2024-11-20 22:04 UTC-0800 ~ Namhyung Kim <namhyung at kernel.org>
> On Wed, Nov 20, 2024 at 02:25:22PM +0100, Bj?rn T?pel wrote:
>> Bj?rn T?pel <bjorn at kernel.org> writes:
>>
>>> From: Bj?rn T?pel <bjorn at rivosinc.com>
>>>
>>> There are a number of tools (bpftool, selftests), that require a
>>> "bootstrap" build. Here, a bootstrap build is a build host variant of
>>> a target. E.g., assume that you're performing a bpftool cross-build on
>>> x86 to riscv, a bootstrap build would then be an x86 variant of
>>> bpftool. The typical way to perform the host build variant, is to pass
>>> "ARCH=" in a sub-make. However, if a variable has been set with a
>>> command argument, then ordinary assignments in the makefile are
>>> ignored.
>>>
>>> This side-effect results in that ARCH, and variables depending on ARCH
>>> are not set.
>>>
>>> Workaround by overriding ARCH to the host arch, if ARCH is empty.
>>>
>>> Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
>>> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
> 
> Reviewed-by: Namhyung Kim <namhyung at kernel.org>


Acked-by: Quentin Monnet <qmo at kernel.org>


>> Arnaldo/Palmer/Quentin:
>>
>> A bit unsure what tree this patch should go. It's very important for the
>> RISC-V builds, so maybe via Palmer's RISC-V tree?
> 
> I think it'd be best to route this through the bpf tree as it seems the
> main target is bpftool.  But given the size and the scope of the change,
> it should be fine with perf-tools or RISC-V tree.


The bpf tree would make sense to me as well (but I don't merge patches
myself; let me Cc BPF maintainers).

Quentin


From bp at alien8.de  Thu Nov 21 03:49:52 2024
From: bp at alien8.de (Borislav Petkov)
Date: Thu, 21 Nov 2024 12:49:52 +0100
Subject: [PATCHv2 2/2] x86/mm: Make memremap(MEMREMAP_WB) map memory as
 encrypted by default
In-Reply-To: <s4frmqwtuvclinuu7ttyzfpe7bj7hju5xgt6sxzy3gyt3prr62@rrgvhkv4lgwv>
References: <20241021105723.2707507-1-kirill.shutemov@linux.intel.com>
 <20241021105723.2707507-3-kirill.shutemov@linux.intel.com>
 <20241118164616.GAZztvWGs9cOV8t20_@fat_crate.local>
 <s4frmqwtuvclinuu7ttyzfpe7bj7hju5xgt6sxzy3gyt3prr62@rrgvhkv4lgwv>
Message-ID: <20241121114952.GCZz8eYEVa3yubYQzO@fat_crate.local>

On Tue, Nov 19, 2024 at 10:21:05AM +0200, Kirill A. Shutemov wrote:
> Sure, we can workaround every place that touches such ranges.

Every place? Which every place? I thought this is only an EISA issue?

Then clearly your changelogs need to expand considerably more what we're
*really* addressing here.

> Or we can address problem at the root and make creating decrypted/shared
> mappings explicit.

What is the problem? That KVM implicitly converts memory to shared? Why does
KVM do that an can it be fixed not to?

Doesn't sound like the guest's problem.

Or maybe this needs a lot more explanation what we're fixing here.

> Such mappings have both functional (as we see here) and security
> implications (VMM can manipulate the guest memory range). We should not
> create decrypted mappings by default on legacy interfaces.

So we're getting closer.

The changes themselves are fine but your text is missing a lot about what
we're fixing here. When I asked, I barely scratched the surface. So can we
elaborate here pls?

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


From anup at brainfault.org  Thu Nov 21 04:55:38 2024
From: anup at brainfault.org (Anup Patel)
Date: Thu, 21 Nov 2024 18:25:38 +0530
Subject: [GIT PULL] KVM/riscv changes for 6.13, part #2
Message-ID: <CAAhSdy2mLBzE63wpQrOaHtOV0rwqkaxTUMBA9oMZsk68o0EHMg@mail.gmail.com>

Hi Paolo,

As mentioned in the last PR, here are the remaining KVM RISC-V
changes for 6.13 which mainly consists of Svade/Svadu extension
support for Host and Guest/VM.

Please note that Palmer has not yet sent the RISC-V PR for 6.13
so these patches will conflict with the RISC-V tree.

Please pull.

Regards,
Anup

The following changes since commit 332fa4a802b16ccb727199da685294f85f9880cb:

  riscv: kvm: Fix out-of-bounds array access (2024-11-05 13:27:32 +0530)

are available in the Git repository at:

  https://github.com/kvm-riscv/linux.git tags/kvm-riscv-6.13-2

for you to fetch changes up to c74bfe4ffe8c1ca94e3d60ec7af06cf679e23583:

  KVM: riscv: selftests: Add Svade and Svadu Extension to get-reg-list
test (2024-11-21 17:40:16 +0530)

----------------------------------------------------------------
KVM/riscv changes for 6.13 part #2

- Svade and Svadu extension support for Host and Guest/VM

----------------------------------------------------------------
Yong-Xuan Wang (4):
      RISC-V: Add Svade and Svadu Extensions Support
      dt-bindings: riscv: Add Svade and Svadu Entries
      RISC-V: KVM: Add Svade and Svadu Extensions Support for Guest/VM
      KVM: riscv: selftests: Add Svade and Svadu Extension to get-reg-list test

 .../devicetree/bindings/riscv/extensions.yaml      | 28 ++++++++++++++++++++++
 arch/riscv/Kconfig                                 |  1 +
 arch/riscv/include/asm/csr.h                       |  1 +
 arch/riscv/include/asm/hwcap.h                     |  2 ++
 arch/riscv/include/asm/pgtable.h                   | 13 +++++++++-
 arch/riscv/include/uapi/asm/kvm.h                  |  2 ++
 arch/riscv/kernel/cpufeature.c                     | 12 ++++++++++
 arch/riscv/kvm/vcpu.c                              |  4 ++++
 arch/riscv/kvm/vcpu_onereg.c                       | 15 ++++++++++++
 tools/testing/selftests/kvm/riscv/get-reg-list.c   |  8 +++++++
 10 files changed, 85 insertions(+), 1 deletion(-)


From devnull+shankerwangmiao.gmail.com at kernel.org  Thu Nov 21 06:25:21 2024
From: devnull+shankerwangmiao.gmail.com at kernel.org (Miao Wang via B4 Relay)
Date: Thu, 21 Nov 2024 22:25:21 +0800
Subject: [PATCH v4] ACPI: introduce acpi_arch_init
Message-ID: <20241121-intro-acpi-arch-init-v4-1-b1fb517e7d8b@gmail.com>

From: Miao Wang <shankerwangmiao at gmail.com>

To avoid arch-specific code in general ACPI initialization flow,
we introduce a weak symbol acpi_arch_init. Currently, arm64 and
riscv can utillize this to insert their arch-specific flow. In
the future, other architectures can also have chance to define
their own arch-specific acpi initialization process if necessary.

Reviewed-by: Sunil V L <sunilvl at ventanamicro.com>
Reviewed-by: Sudeep Holla <sudeep.holla at arm.com>
Acked-by: Hanjun Guo <guohanjun at huawei.com>
Signed-off-by: Miao Wang <shankerwangmiao at gmail.com>
---
Changes from v1
- Change acpi_arch_init from a static inline stub to a weak function
  according to Haijun Guo's advice
---
Changes from v2:
- Add __init attribute to the weak acpi_arch_init stub
- Link to v2: https://lore.kernel.org/r/20240807-intro-acpi-arch-init-v2-1-9231e23a7721 at gmail.com
---
Changes in v4:
- Rebased to recent Linus's tree
- Consolidate acpi_arm_init and acpi_riscv_init into acpi_arch_init
- Link to v3: https://lore.kernel.org/r/20240808-intro-acpi-arch-init-v3-1-ba510859baff at gmail.com
---
 drivers/acpi/arm64/init.c |  2 +-
 drivers/acpi/bus.c        |  5 +++--
 drivers/acpi/riscv/init.c |  2 +-
 include/linux/acpi.h      | 12 +-----------
 4 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/arm64/init.c b/drivers/acpi/arm64/init.c
index d0c8aed90fd16f9a7fe62b8c551c0cd091cb91ec..7a47d8095a7dd5f3dac6e0754d6271bf6de269ff 100644
--- a/drivers/acpi/arm64/init.c
+++ b/drivers/acpi/arm64/init.c
@@ -2,7 +2,7 @@
 #include <linux/acpi.h>
 #include "init.h"
 
-void __init acpi_arm_init(void)
+void __init acpi_arch_init(void)
 {
 	if (IS_ENABLED(CONFIG_ACPI_AGDI))
 		acpi_agdi_init();
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 16917dc3ad604cc537d05bb2c0034ff5a9181fd0..058910af82bca689577909e8967073ca3198b3c8 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1434,6 +1434,8 @@ static int __init acpi_bus_init(void)
 struct kobject *acpi_kobj;
 EXPORT_SYMBOL_GPL(acpi_kobj);
 
+void __weak __init acpi_arch_init(void) { }
+
 static int __init acpi_init(void)
 {
 	int result;
@@ -1461,8 +1463,7 @@ static int __init acpi_init(void)
 	acpi_viot_early_init();
 	acpi_hest_init();
 	acpi_ghes_init();
-	acpi_arm_init();
-	acpi_riscv_init();
+	acpi_arch_init();
 	acpi_scan_init();
 	acpi_ec_init();
 	acpi_debugfs_init();
diff --git a/drivers/acpi/riscv/init.c b/drivers/acpi/riscv/init.c
index 5ef97905a72759ea2aab3195e56b7ee580eded96..673e4d5dd752719ae7ed0017c8b5b1c688cf9b4b 100644
--- a/drivers/acpi/riscv/init.c
+++ b/drivers/acpi/riscv/init.c
@@ -7,7 +7,7 @@
 #include <linux/acpi.h>
 #include "init.h"
 
-void __init acpi_riscv_init(void)
+void __init acpi_arch_init(void)
 {
 	riscv_acpi_init_gsi_mapping();
 }
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 7dd24acd9ffeedbe47ac392bd939309408c0afa3..05f39fbfa4856d2e6b7d45d9580cc82963764d55 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1530,17 +1530,7 @@ static inline int find_acpi_cpu_topology_hetero_id(unsigned int cpu)
 }
 #endif
 
-#ifdef CONFIG_ARM64
-void acpi_arm_init(void);
-#else
-static inline void acpi_arm_init(void) { }
-#endif
-
-#ifdef CONFIG_RISCV
-void acpi_riscv_init(void);
-#else
-static inline void acpi_riscv_init(void) { }
-#endif
+void acpi_arch_init(void);
 
 #ifdef CONFIG_ACPI_PCC
 void acpi_init_pcc(void);

---
base-commit: 43fb83c17ba2d63dfb798f0be7453ed55ca3f9c2
change-id: 20240807-intro-acpi-arch-init-fc99fe33e62d

Best regards,
-- 
Miao Wang <shankerwangmiao at gmail.com>




From samuel.holland at sifive.com  Thu Nov 21 14:41:05 2024
From: samuel.holland at sifive.com (Samuel Holland)
Date: Thu, 21 Nov 2024 16:41:05 -0600
Subject: [PATCH v2] riscv: Call secondary mmu notifier when flushing the
 tlb
In-Reply-To: <0456b6b4-1453-444d-8cd8-38715dc9f845@ghiti.fr>
References: <20240328073838.8776-1-alexghiti@rivosinc.com>
 <20241121-e97820f8c09de9bcedfe885d@orel>
 <0456b6b4-1453-444d-8cd8-38715dc9f845@ghiti.fr>
Message-ID: <4141beba-3310-49a0-9163-538b89c0e6fb@sifive.com>

Hi Alex,

On 2024-11-21 4:36 AM, Alexandre Ghiti wrote:
> Hi Andrew,
> 
> On 21/11/2024 10:32, Andrew Jones wrote:
>> On Thu, Mar 28, 2024 at 08:38:38AM +0100, Alexandre Ghiti wrote:
>>> This is required to allow the IOMMU driver to correctly flush its own
>>> TLB.
>>>
>>> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
>>> ---
>>>
>>> Changes in v2:
>>> - Rebase on top of 6.9-rc1
>>>
>>> ? arch/riscv/mm/tlbflush.c | 39 +++++++++++++++++++++++----------------
>>> ? 1 file changed, 23 insertions(+), 16 deletions(-)
>>>
>> Hi Alex,
>>
>> Is this patch still something we need?
>>
>> Thanks,
>> drew
> 
> 
> Yes I think so, hopefully it gets merged.

Please rebase and resend this patch. It conflicts with two other changes merged
since you sent v2 (038ac18aae93 and f58e5dc45fa9), in addition to the one you
sent the resolution for.

Regards,
Samuel



From ajones at ventanamicro.com  Fri Nov 22 07:11:36 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Fri, 22 Nov 2024 16:11:36 +0100
Subject: [RFC PATCH 08/15] iommu/riscv: Add IRQ domain for interrupt
 remapping
In-Reply-To: <20241119153622.GD559636@ziepe.ca>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-25-ajones@ventanamicro.com>
 <20241118184336.GB559636@ziepe.ca>
 <20241119-62ff49fc1eedba051838dba2@orel>
 <20241119140047.GC559636@ziepe.ca>
 <DE13E1DF-7C68-461D-ADCD-8141B1ACEA5E@ventanamicro.com>
 <20241119153622.GD559636@ziepe.ca>
Message-ID: <20241121-4e637c492d554280dec3b077@orel>

On Tue, Nov 19, 2024 at 11:36:22AM -0400, Jason Gunthorpe wrote:
> On Tue, Nov 19, 2024 at 04:03:05PM +0100, Andrew Jones wrote:
> 
> > >This is the wrong thinking entirely. There is no such thing as a "VFIO
> > >domain".
> > >
> > >Default VFIO created domains should act excatly the same as a DMA API
> > >domain.
> > >
> > >If you want your system to have irq remapping, then it should be on by
> > >default and DMA API gets remapping too. There would need to be a very
> > >strong reason not to do that in order to make something special for
> > >riscv. If so you'd need to add some kind of flag to select it.
> > >
> > >Until you reach nested translation there is no "need" for VFIO to use
> > >any particular stage. The design is that default VFIO uses the same
> > >stage as the DMA API because it is doing the same basic default
> > >translation function.
> > 
> > The RISC-V IOMMU needs to use g-stage for device assignment, if we
> > also want to enable irqbypass, because the IOMMU is specified to
> > only look at the MSI table when g-stage is in use. This is actually
> > another reason the irq domain only makes sense for device
> > assignment.
> 
> Most HW has enablable interrupt remapping and typically Linux just
> turns it always on.
> 
> Is there a reason the DMA API shouldn't use this translation mode too?
> That seems to be the main issue here, you are trying to avoid
> interrupt remapping for DMA API and use it only for VFIO, and haven't
> explained why we need such complexity. Just use it always?

The reason is that the RISC-V IOMMU only checks the MSI table, i.e.
enables its support for MSI remapping, when the g-stage (second-stage)
page table is in use. However, the expected virtual memory scheme for an
OS to use for DMA would be to have s-stage (first-stage) in use and the
g-stage set to 'Bare' (not in use). OIOW, it doesn't appear the spec
authors expected MSI remapping to be enabled for the host DMA use case.
That does make some sense, since it's actually not necessary. For the
host DMA use case, providing mappings for each s-mode interrupt file
which the device is allowed to write to in the s-stage page table
sufficiently enables MSIs to be delivered.

> 
> > >Nested translation has a control to select the stage, and you can
> > >then force the g-stage for VFIO users at that point.
> > 
> > We could force riscv device assignment to always be nested, and when
> > not providing an iommu to the guest, it will still be single-stage,
> > but g-stage, but I don't think that's currently possible with VFIO,
> > is it?
> 
> That isn't what I mean, I mean you should not be forcing the kind of
> domain being created until you get to special cases like nested.
> 
> Default VFIO should work the same as the DMA API.

If "default VFIO" means VFIO without irqbypass, then it would work the
same as the DMA API, assuming all mappings for all necessary s-mode
interrupt files are created (something the DMA API needs as well).
However, VFIO would also need 'vfio_iommu_type1.allow_unsafe_interrupts=1'
to be set for this no-irqbypass configuration.

> 
> > >> The IRQ domain will only be useful for device assignment, as that's when
> > >> an MSI translation will be needed. I can't think of any problems that
> > >> could arise from only creating the IRQ domain when probing assigned
> > >> devices, but I could certainly be missing something. Do you have some
> > >> potential problems in mind?
> > >
> > >I'm not an expert in the interrupt subsystem, but my understanding was
> > >we expect the interrupt domains/etc to be static once a device driver
> > >is probed. Changing things during iommu domain attach is after drivers
> > >are probed. I don't really expect it to work correctly in all corner
> > >cases.
> > 
> > With VFIO the iommu domain attach comes after an unbind/bind, so the
> > new driver is probed.
> 
> That's the opposite of what I mean. The irq domain should be setup
> *before* VFIO binds to the driver.
> 
> Changing the active irq_domain while VFIO is already probed to the
> device is highly unlikely to work right in all cases.
> 
> > I think that's a safe time. However, if there
> > could be cases where the attach does not follow an unbind/bind, then
> > I agree that wouldn't be safe.
> 
> These cases exist.
> 
> > I'll consider always creating an IRQ
> > domain, even if it won't provide any additional functionality unless
> > the device is assigned.
> 
> That isn't ideal, the translation under the IRQs shouldn't really be
> changing as the translation under the IOMMU changes.

Unless the device is assigned to a guest, then the IRQ domain wouldn't
do anything at all (it'd just sit between the device and the device's
old MSI parent domain), but it also wouldn't come and go, risking issues
with anything sensitive to changes in the IRQ domain hierarchy.

> 
> Further, VFIO assumes iommu_group_has_isolated_msi(), ie
> IRQ_DOMAIN_FLAG_ISOLATED_MSI, is fixed while it is is bound. Will that
> be true if the iommu is flapping all about? What will you do when VFIO
> has it attached to a blocked domain?
> 
> It just doesn't make sense to change something so fundamental as the
> interrupt path on an iommu domain attachement. :\

Yes, it does appear I should be doing this at iommu device probe time
instead. It won't provide any additional functionality to use cases which
aren't assigning devices to guests, but it also won't hurt, and it should
avoid the risks you point out.

> 
> > >VFIO is allowed to change the translation as it operates and we expect
> > >that interrupts are not disturbed.
> > 
> > The IRQ domain stays the same during operation, the only changes are
> > the mappings from what the guest believes are its s-mode interrupt
> > files to the hypervisor selected guest interrupt files, and these
> > changes are made possible by the IRQ domain's vcpu-affinity support.
> 
> That is only the case when talking about kvm, this all still has to
> work fully for non-kvm VFIO uses cases too.
> 

I'll rework the irq domain creation to be at iommu device probe time for
the next version.

Thanks,
drew


From jgg at ziepe.ca  Fri Nov 22 07:33:40 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Fri, 22 Nov 2024 11:33:40 -0400
Subject: [RFC PATCH 08/15] iommu/riscv: Add IRQ domain for interrupt
 remapping
In-Reply-To: <20241121-4e637c492d554280dec3b077@orel>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-25-ajones@ventanamicro.com>
 <20241118184336.GB559636@ziepe.ca>
 <20241119-62ff49fc1eedba051838dba2@orel>
 <20241119140047.GC559636@ziepe.ca>
 <DE13E1DF-7C68-461D-ADCD-8141B1ACEA5E@ventanamicro.com>
 <20241119153622.GD559636@ziepe.ca>
 <20241121-4e637c492d554280dec3b077@orel>
Message-ID: <20241122153340.GC773835@ziepe.ca>

On Fri, Nov 22, 2024 at 04:11:36PM +0100, Andrew Jones wrote:

> The reason is that the RISC-V IOMMU only checks the MSI table, i.e.
> enables its support for MSI remapping, when the g-stage (second-stage)
> page table is in use. However, the expected virtual memory scheme for an
> OS to use for DMA would be to have s-stage (first-stage) in use and the
> g-stage set to 'Bare' (not in use). 

That isn't really a technical reason.

> OIOW, it doesn't appear the spec authors expected MSI remapping to
> be enabled for the host DMA use case.  That does make some sense,
> since it's actually not necessary. For the host DMA use case,
> providing mappings for each s-mode interrupt file which the device
> is allowed to write to in the s-stage page table sufficiently
> enables MSIs to be delivered.

Well, that seems to be the main problem here. You are grappling with a
spec design that doesn't match the SW expecations. Since it has
deviated from what everyone else has done you now have extra
challenges to resolve in some way.

Just always using interrupt remapping if the HW is capable of
interrupt remapping and ignoring the spec "expectation" is a nice a
simple way to make things work with existing Linux.

> If "default VFIO" means VFIO without irqbypass, then it would work the
> same as the DMA API, assuming all mappings for all necessary s-mode
> interrupt files are created (something the DMA API needs as well).
> However, VFIO would also need 'vfio_iommu_type1.allow_unsafe_interrupts=1'
> to be set for this no-irqbypass configuration.

Which isn't what anyone wants, you need to make the DMA API domain be
fully functional so that VFIO works.

> > That isn't ideal, the translation under the IRQs shouldn't really be
> > changing as the translation under the IOMMU changes.
> 
> Unless the device is assigned to a guest, then the IRQ domain wouldn't
> do anything at all (it'd just sit between the device and the device's
> old MSI parent domain), but it also wouldn't come and go, risking issues
> with anything sensitive to changes in the IRQ domain hierarchy.

VFIO isn't restricted to such a simple use model. You have to support
all the generality, which includes fully supporting changing the iommu
translation on the fly.

> > Further, VFIO assumes iommu_group_has_isolated_msi(), ie
> > IRQ_DOMAIN_FLAG_ISOLATED_MSI, is fixed while it is is bound. Will that
> > be true if the iommu is flapping all about? What will you do when VFIO
> > has it attached to a blocked domain?
> > 
> > It just doesn't make sense to change something so fundamental as the
> > interrupt path on an iommu domain attachement. :\
> 
> Yes, it does appear I should be doing this at iommu device probe time
> instead. It won't provide any additional functionality to use cases which
> aren't assigning devices to guests, but it also won't hurt, and it should
> avoid the risks you point out.

Even if you statically create the domain you can't change the value of
IRQ_DOMAIN_FLAG_ISOLATED_MSI depending on what is currently attached
to the IOMMU.

What you are trying to do is not supported by the software stack right
now. You need to make much bigger, more intrusive changes, if you
really want to make interrupt remapping dynamic.

Jason


From ajones at ventanamicro.com  Fri Nov 22 09:07:59 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Fri, 22 Nov 2024 18:07:59 +0100
Subject: [RFC PATCH 08/15] iommu/riscv: Add IRQ domain for interrupt
 remapping
In-Reply-To: <20241122153340.GC773835@ziepe.ca>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-25-ajones@ventanamicro.com>
 <20241118184336.GB559636@ziepe.ca>
 <20241119-62ff49fc1eedba051838dba2@orel>
 <20241119140047.GC559636@ziepe.ca>
 <DE13E1DF-7C68-461D-ADCD-8141B1ACEA5E@ventanamicro.com>
 <20241119153622.GD559636@ziepe.ca>
 <20241121-4e637c492d554280dec3b077@orel>
 <20241122153340.GC773835@ziepe.ca>
Message-ID: <20241122-8c00551e2383787346c5249f@orel>

On Fri, Nov 22, 2024 at 11:33:40AM -0400, Jason Gunthorpe wrote:
> On Fri, Nov 22, 2024 at 04:11:36PM +0100, Andrew Jones wrote:
> 
> > The reason is that the RISC-V IOMMU only checks the MSI table, i.e.
> > enables its support for MSI remapping, when the g-stage (second-stage)
> > page table is in use. However, the expected virtual memory scheme for an
> > OS to use for DMA would be to have s-stage (first-stage) in use and the
> > g-stage set to 'Bare' (not in use). 
> 
> That isn't really a technical reason.
> 
> > OIOW, it doesn't appear the spec authors expected MSI remapping to
> > be enabled for the host DMA use case.  That does make some sense,
> > since it's actually not necessary. For the host DMA use case,
> > providing mappings for each s-mode interrupt file which the device
> > is allowed to write to in the s-stage page table sufficiently
> > enables MSIs to be delivered.
> 
> Well, that seems to be the main problem here. You are grappling with a
> spec design that doesn't match the SW expecations. Since it has
> deviated from what everyone else has done you now have extra
> challenges to resolve in some way.
> 
> Just always using interrupt remapping if the HW is capable of
> interrupt remapping and ignoring the spec "expectation" is a nice a
> simple way to make things work with existing Linux.
> 
> > If "default VFIO" means VFIO without irqbypass, then it would work the
> > same as the DMA API, assuming all mappings for all necessary s-mode
> > interrupt files are created (something the DMA API needs as well).
> > However, VFIO would also need 'vfio_iommu_type1.allow_unsafe_interrupts=1'
> > to be set for this no-irqbypass configuration.
> 
> Which isn't what anyone wants, you need to make the DMA API domain be
> fully functional so that VFIO works.
> 
> > > That isn't ideal, the translation under the IRQs shouldn't really be
> > > changing as the translation under the IOMMU changes.
> > 
> > Unless the device is assigned to a guest, then the IRQ domain wouldn't
> > do anything at all (it'd just sit between the device and the device's
> > old MSI parent domain), but it also wouldn't come and go, risking issues
> > with anything sensitive to changes in the IRQ domain hierarchy.
> 
> VFIO isn't restricted to such a simple use model. You have to support
> all the generality, which includes fully supporting changing the iommu
> translation on the fly.
> 
> > > Further, VFIO assumes iommu_group_has_isolated_msi(), ie
> > > IRQ_DOMAIN_FLAG_ISOLATED_MSI, is fixed while it is is bound. Will that
> > > be true if the iommu is flapping all about? What will you do when VFIO
> > > has it attached to a blocked domain?
> > > 
> > > It just doesn't make sense to change something so fundamental as the
> > > interrupt path on an iommu domain attachement. :\
> > 
> > Yes, it does appear I should be doing this at iommu device probe time
> > instead. It won't provide any additional functionality to use cases which
> > aren't assigning devices to guests, but it also won't hurt, and it should
> > avoid the risks you point out.
> 
> Even if you statically create the domain you can't change the value of
> IRQ_DOMAIN_FLAG_ISOLATED_MSI depending on what is currently attached
> to the IOMMU.
> 
> What you are trying to do is not supported by the software stack right
> now. You need to make much bigger, more intrusive changes, if you
> really want to make interrupt remapping dynamic.
>

Let the fun begin. I'll look into this more. It also looks like I need to
collect some test cases to ensure I can support all use cases with
whatever I propose next. Pointers for those would be welcome.

Thanks,
drew


From rafael at kernel.org  Fri Nov 22 12:33:55 2024
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Fri, 22 Nov 2024 21:33:55 +0100
Subject: [PATCH v4] ACPI: introduce acpi_arch_init
In-Reply-To: <20241121-intro-acpi-arch-init-v4-1-b1fb517e7d8b@gmail.com>
References: <20241121-intro-acpi-arch-init-v4-1-b1fb517e7d8b@gmail.com>
Message-ID: <CAJZ5v0gmDghrLAx_ZpFS0oK8UAPLE8A2Mzt4yVJG7CtYYy0VUw@mail.gmail.com>

On Thu, Nov 21, 2024 at 3:25?PM Miao Wang via B4 Relay
<devnull+shankerwangmiao.gmail.com at kernel.org> wrote:
>
> From: Miao Wang <shankerwangmiao at gmail.com>
>
> To avoid arch-specific code in general ACPI initialization flow,
> we introduce a weak symbol acpi_arch_init. Currently, arm64 and
> riscv can utillize this to insert their arch-specific flow. In
> the future, other architectures can also have chance to define
> their own arch-specific acpi initialization process if necessary.
>
> Reviewed-by: Sunil V L <sunilvl at ventanamicro.com>
> Reviewed-by: Sudeep Holla <sudeep.holla at arm.com>
> Acked-by: Hanjun Guo <guohanjun at huawei.com>
> Signed-off-by: Miao Wang <shankerwangmiao at gmail.com>
> ---
> Changes from v1
> - Change acpi_arch_init from a static inline stub to a weak function
>   according to Haijun Guo's advice
> ---
> Changes from v2:
> - Add __init attribute to the weak acpi_arch_init stub
> - Link to v2: https://lore.kernel.org/r/20240807-intro-acpi-arch-init-v2-1-9231e23a7721 at gmail.com
> ---
> Changes in v4:
> - Rebased to recent Linus's tree
> - Consolidate acpi_arm_init and acpi_riscv_init into acpi_arch_init
> - Link to v3: https://lore.kernel.org/r/20240808-intro-acpi-arch-init-v3-1-ba510859baff at gmail.com
> ---
>  drivers/acpi/arm64/init.c |  2 +-
>  drivers/acpi/bus.c        |  5 +++--
>  drivers/acpi/riscv/init.c |  2 +-
>  include/linux/acpi.h      | 12 +-----------
>  4 files changed, 6 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/acpi/arm64/init.c b/drivers/acpi/arm64/init.c
> index d0c8aed90fd16f9a7fe62b8c551c0cd091cb91ec..7a47d8095a7dd5f3dac6e0754d6271bf6de269ff 100644
> --- a/drivers/acpi/arm64/init.c
> +++ b/drivers/acpi/arm64/init.c
> @@ -2,7 +2,7 @@
>  #include <linux/acpi.h>
>  #include "init.h"
>
> -void __init acpi_arm_init(void)
> +void __init acpi_arch_init(void)
>  {
>         if (IS_ENABLED(CONFIG_ACPI_AGDI))
>                 acpi_agdi_init();
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index 16917dc3ad604cc537d05bb2c0034ff5a9181fd0..058910af82bca689577909e8967073ca3198b3c8 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -1434,6 +1434,8 @@ static int __init acpi_bus_init(void)
>  struct kobject *acpi_kobj;
>  EXPORT_SYMBOL_GPL(acpi_kobj);
>
> +void __weak __init acpi_arch_init(void) { }
> +
>  static int __init acpi_init(void)
>  {
>         int result;
> @@ -1461,8 +1463,7 @@ static int __init acpi_init(void)
>         acpi_viot_early_init();
>         acpi_hest_init();
>         acpi_ghes_init();
> -       acpi_arm_init();
> -       acpi_riscv_init();
> +       acpi_arch_init();
>         acpi_scan_init();
>         acpi_ec_init();
>         acpi_debugfs_init();
> diff --git a/drivers/acpi/riscv/init.c b/drivers/acpi/riscv/init.c
> index 5ef97905a72759ea2aab3195e56b7ee580eded96..673e4d5dd752719ae7ed0017c8b5b1c688cf9b4b 100644
> --- a/drivers/acpi/riscv/init.c
> +++ b/drivers/acpi/riscv/init.c
> @@ -7,7 +7,7 @@
>  #include <linux/acpi.h>
>  #include "init.h"
>
> -void __init acpi_riscv_init(void)
> +void __init acpi_arch_init(void)
>  {
>         riscv_acpi_init_gsi_mapping();
>  }
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 7dd24acd9ffeedbe47ac392bd939309408c0afa3..05f39fbfa4856d2e6b7d45d9580cc82963764d55 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -1530,17 +1530,7 @@ static inline int find_acpi_cpu_topology_hetero_id(unsigned int cpu)
>  }
>  #endif
>
> -#ifdef CONFIG_ARM64
> -void acpi_arm_init(void);
> -#else
> -static inline void acpi_arm_init(void) { }
> -#endif
> -
> -#ifdef CONFIG_RISCV
> -void acpi_riscv_init(void);
> -#else
> -static inline void acpi_riscv_init(void) { }
> -#endif
> +void acpi_arch_init(void);
>
>  #ifdef CONFIG_ACPI_PCC
>  void acpi_init_pcc(void);
>
> ---

Applied as 6.13-rc material, thanks!


From nathan at kernel.org  Sat Nov 23 18:30:19 2024
From: nathan at kernel.org (Nathan Chancellor)
Date: Sat, 23 Nov 2024 19:30:19 -0700
Subject: [PATCH] riscv: Always inline bitops
Message-ID: <20241123-riscv-always-inline-bitops-v1-1-00e8262ab1cf@kernel.org>

When building allmodconfig + ThinLTO with certain versions of clang,
arch_set_bit() may not be inlined, resulting in a modpost warning:

  WARNING: modpost: vmlinux: section mismatch in reference: arch_set_bit+0x58 (section: .text.arch_set_bit) -> numa_nodes_parsed (section: .init.data)

acpi_numa_rintc_affinity_init() calls arch_set_bit() via __node_set()
with numa_nodes_parsed, which is marked as __initdata. If arch_set_bit()
is not inlined, modpost will flag that it is being called with data that
will be freed after init.

As acpi_numa_rintc_affinity_init() is marked as __init, there is not
actually a functional issue here. However, the bitop functions should be
marked as __always_inline, so that they work consistently for init and
non-init code, which the comment in include/linux/nodemask.h alludes to.
This matches s390 and x86's implementations.

Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 arch/riscv/include/asm/bitops.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
index fae152ea0508d2e1ea490fffd645eab99cf387bf..c6bd3d8354a96b4e7bbef0e98a201da412301b57 100644
--- a/arch/riscv/include/asm/bitops.h
+++ b/arch/riscv/include/asm/bitops.h
@@ -228,7 +228,7 @@ static __always_inline int variable_fls(unsigned int x)
  *
  * This operation may be reordered on other architectures than x86.
  */
-static inline int arch_test_and_set_bit(int nr, volatile unsigned long *addr)
+static __always_inline int arch_test_and_set_bit(int nr, volatile unsigned long *addr)
 {
 	return __test_and_op_bit(or, __NOP, nr, addr);
 }
@@ -240,7 +240,7 @@ static inline int arch_test_and_set_bit(int nr, volatile unsigned long *addr)
  *
  * This operation can be reordered on other architectures other than x86.
  */
-static inline int arch_test_and_clear_bit(int nr, volatile unsigned long *addr)
+static __always_inline int arch_test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
 	return __test_and_op_bit(and, __NOT, nr, addr);
 }
@@ -253,7 +253,7 @@ static inline int arch_test_and_clear_bit(int nr, volatile unsigned long *addr)
  * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
-static inline int arch_test_and_change_bit(int nr, volatile unsigned long *addr)
+static __always_inline int arch_test_and_change_bit(int nr, volatile unsigned long *addr)
 {
 	return __test_and_op_bit(xor, __NOP, nr, addr);
 }
@@ -270,7 +270,7 @@ static inline int arch_test_and_change_bit(int nr, volatile unsigned long *addr)
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-static inline void arch_set_bit(int nr, volatile unsigned long *addr)
+static __always_inline void arch_set_bit(int nr, volatile unsigned long *addr)
 {
 	__op_bit(or, __NOP, nr, addr);
 }
@@ -284,7 +284,7 @@ static inline void arch_set_bit(int nr, volatile unsigned long *addr)
  * on non x86 architectures, so if you are writing portable code,
  * make sure not to rely on its reordering guarantees.
  */
-static inline void arch_clear_bit(int nr, volatile unsigned long *addr)
+static __always_inline void arch_clear_bit(int nr, volatile unsigned long *addr)
 {
 	__op_bit(and, __NOT, nr, addr);
 }
@@ -298,7 +298,7 @@ static inline void arch_clear_bit(int nr, volatile unsigned long *addr)
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-static inline void arch_change_bit(int nr, volatile unsigned long *addr)
+static __always_inline void arch_change_bit(int nr, volatile unsigned long *addr)
 {
 	__op_bit(xor, __NOP, nr, addr);
 }
@@ -311,7 +311,7 @@ static inline void arch_change_bit(int nr, volatile unsigned long *addr)
  * This operation is atomic and provides acquire barrier semantics.
  * It can be used to implement bit locks.
  */
-static inline int arch_test_and_set_bit_lock(
+static __always_inline int arch_test_and_set_bit_lock(
 	unsigned long nr, volatile unsigned long *addr)
 {
 	return __test_and_op_bit_ord(or, __NOP, nr, addr, .aq);
@@ -324,7 +324,7 @@ static inline int arch_test_and_set_bit_lock(
  *
  * This operation is atomic and provides release barrier semantics.
  */
-static inline void arch_clear_bit_unlock(
+static __always_inline void arch_clear_bit_unlock(
 	unsigned long nr, volatile unsigned long *addr)
 {
 	__op_bit_ord(and, __NOT, nr, addr, .rl);
@@ -345,13 +345,13 @@ static inline void arch_clear_bit_unlock(
  * non-atomic property here: it's a lot more instructions and we still have to
  * provide release semantics anyway.
  */
-static inline void arch___clear_bit_unlock(
+static __always_inline void arch___clear_bit_unlock(
 	unsigned long nr, volatile unsigned long *addr)
 {
 	arch_clear_bit_unlock(nr, addr);
 }
 
-static inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,
+static __always_inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,
 		volatile unsigned long *addr)
 {
 	unsigned long res;

---
base-commit: 0eb512779d642b21ced83778287a0f7a3ca8f2a1
change-id: 20241123-riscv-always-inline-bitops-0021c4dae36b

Best regards,
-- 
Nathan Chancellor <nathan at kernel.org>



From dlan at gentoo.org  Sun Nov 24 07:32:13 2024
From: dlan at gentoo.org (Yixun Lan)
Date: Sun, 24 Nov 2024 23:32:13 +0800
Subject: [PATCH v3 2/2] i2c: spacemit: add support for SpacemiT K1 SoC
In-Reply-To: <46a81098-3092-44a0-a625-bd17b4ba0e2b@gmail.com>
References: <20241112-k1-i2c-master-v3-0-5005b70dc208@gmail.com>
 <20241112-k1-i2c-master-v3-2-5005b70dc208@gmail.com>
 <20241114064943-GYA998060@gentoo>
 <46a81098-3092-44a0-a625-bd17b4ba0e2b@gmail.com>
Message-ID: <20241124153213-GYA3212048@gentoo>

Hi Troy:

On 12:11 Thu 21 Nov     , Troy Mitchell wrote:
> Hi, Yixun. thanks for ur review.
> 
> On 2024/11/14 14:49, Yixun Lan wrote:
> > On 11:07 Tue 12 Nov     , Troy Mitchell wrote:
> >> From: Troy Mitchell <troymitchell988 at gmail.com>
> >>
> >> This patch introduces basic I2C support for the SpacemiT K1 SoC,
> >> utilizing interrupts for transfers.
> >>
> >> The driver has been tested using i2c-tools on a Bananapi-F3 board,
> >> and basic I2C read/write operations have been confirmed to work.
> >>
> >> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
> >> ---
> >>  drivers/i2c/busses/Kconfig  |  19 ++
> >>  drivers/i2c/busses/Makefile |   1 +
> >>  drivers/i2c/busses/i2c-k1.c | 656 ++++++++++++++++++++++++++++++++++++++++++++
> >>  3 files changed, 676 insertions(+)
> >>
...
> >> +
> >> +static int spacemit_i2c_probe(struct platform_device *pdev)
> >> +{
> >> +	struct spacemit_i2c_dev *i2c;
> >> +	struct device_node *of_node = pdev->dev.of_node;
> >> +	struct clk *clk;
> >> +	int ret = 0;
> >> +
> >> +	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
> >> +	if (!i2c)
> >> +		return -ENOMEM;
> >> +
> >> +	i2c->dev = &pdev->dev;
> >> +
> >> +	i2c->base = devm_platform_ioremap_resource(pdev, 0);
> >> +	if (IS_ERR(i2c->base))
> >> +		return dev_err_probe(&pdev->dev, PTR_ERR(i2c->base), "failed to do ioremap");
> >> +
> >> +	i2c->irq = platform_get_irq(pdev, 0);
> >> +	if (i2c->irq < 0)
> >> +		return dev_err_probe(&pdev->dev, i2c->irq, "failed to get irq resource");
> >> +
> >> +	ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
> >> +			       IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(i2c->dev), i2c);
> >> +	if (ret)
> >> +		return dev_err_probe(&pdev->dev, ret, "failed to request irq");
> >> +
> >> +	disable_irq(i2c->irq);
> >> +
> >> +	clk = devm_clk_get_enabled(&pdev->dev, NULL);
> >> +	if (IS_ERR(clk))
> >> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk), "failed to enable clock");
> >> +
> > I'd suggest also to handle pin request here, since pinctrl driver is merged
> > 
> > https://lore.kernel.org/all/CACRpkdYnaJsKKfcdhHeMGTTp86M+wNODzZx2e=OYbxQ4Jc4Rjw at mail.gmail.com/
> sry, I don't understand what pin I need to request?
> > 

I was suggesting to add devm_pinctrl_get(), but after checking,
this is not needed anymore since it's already handled by device core,
so no need to change here..

check drivers/core/pinctrl.c -> pinctrl_bind_pins()

> >> +	i2c_set_adapdata(&i2c->adapt, i2c);
> >> +	i2c->adapt.owner = THIS_MODULE;
> >> +	i2c->adapt.algo = &spacemit_i2c_algo;
> >> +	i2c->adapt.dev.parent = i2c->dev;
> >> +	i2c->adapt.nr = pdev->id;
> >> +
> >> +	i2c->adapt.dev.of_node = of_node;
> >> +	i2c->adapt.algo_data = i2c;
> >> +
> >> +	strscpy(i2c->adapt.name, "spacemit-i2c-adapter", sizeof(i2c->adapt.name));
> >> +
> >> +	init_completion(&i2c->complete);
> >> +
> >> +	ret = i2c_add_numbered_adapter(&i2c->adapt);
> >> +	if (ret)
> >> +		return dev_err_probe(&pdev->dev, ret, "failed to add i2c adapter");
> >> +
> >> +	platform_set_drvdata(pdev, i2c);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static void spacemit_i2c_remove(struct platform_device *pdev)
> >> +{
> >> +	struct spacemit_i2c_dev *i2c = platform_get_drvdata(pdev);
> >> +
> >> +	i2c_del_adapter(&i2c->adapt);
> >> +}
> >> +
> >> +static const struct of_device_id spacemit_i2c_of_match[] = {
> >> +	{ .compatible = "spacemit,k1-i2c", },
> >> +	{ /* sentinel */ }
> >> +};
> >> +MODULE_DEVICE_TABLE(of, spacemit_i2c_of_match);
> >> +
> >> +static struct platform_driver spacemit_i2c_driver = {
> >> +	.probe = spacemit_i2c_probe,
> >> +	.remove = spacemit_i2c_remove,
> >> +	.driver = {
> >> +		.name = "i2c-k1",
> >> +		.of_match_table = spacemit_i2c_of_match,
> >> +	},
> >> +};
> >> +module_platform_driver(spacemit_i2c_driver);
> >> +
> >> +MODULE_LICENSE("GPL");
> >> +MODULE_DESCRIPTION("I2C bus driver for SpacemiT K1 SoC");
> >>
> >> -- 
> >> 2.34.1
> >>
> > 
> 
> -- 
> Troy Mitchell

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55


From heylenay at 4d2.org  Sun Nov 24 11:18:59 2024
From: heylenay at 4d2.org (Haylen Chu)
Date: Sun, 24 Nov 2024 19:18:59 +0000
Subject: [PATCH v2 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <a9f59ffb-23e9-4c83-8d44-4c766e32b3bf@sifive.com>
References: <20241028053220.346283-1-TroyMitchell988@gmail.com>
 <20241028053220.346283-2-TroyMitchell988@gmail.com>
 <846b4f2a-602e-431e-affc-0e995db5eee5@sifive.com>
 <9dfb250c-d8a1-4536-8658-48b3a2585abd@gmail.com>
 <a9f59ffb-23e9-4c83-8d44-4c766e32b3bf@sifive.com>
Message-ID: <Z0N8I2zv2vl9f8Y1@ketchup>

On Wed, Nov 06, 2024 at 06:29:56PM -0600, Samuel Holland wrote:
Hi Samuel,

I'm working on the clock driver for Spacemit K1.

> On 2024-11-06 1:58 AM, Troy Mitchell wrote:
> > On 2024/11/2 11:48, Samuel Holland wrote:
> >> On 2024-10-28 12:32 AM, Troy Mitchell wrote:
> >>> The I2C of K1 supports fast-speed-mode and high-speed-mode,
> >>> and supports FIFO transmission.
> >>>
> >>> Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
> >>> ---
> >>>  .../bindings/i2c/spacemit,k1-i2c.yaml         | 51 +++++++++++++++++++
> >>>  1 file changed, 51 insertions(+)
> >>>  create mode 100644 Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> >>> new file mode 100644
> >>> index 000000000000..57af66f494e7
> >>> --- /dev/null
> >>> +++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
> >>> @@ -0,0 +1,51 @@
> >>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >>> +%YAML 1.2
> >>> +---
> >>> +$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
> >>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >>> +
> >>> +title: I2C controller embedded in SpacemiT's K1 SoC
> >>> +
> >>> +maintainers:
> >>> +  - Troy Mitchell <troymitchell988 at gmail.com>
> >>> +
> >>> +properties:
> >>> +  compatible:
> >>> +    const: spacemit,k1-i2c
> >>> +
> >>> +  reg:
> >>> +    maxItems: 2
> >>> +
> >>> +  interrupts:
> >>> +    maxItems: 1
> >>> +
> >>> +  clocks:
> >>> +    maxItems: 1
> >>
> >> Looking at the K1 user manual (9.1.4.77 RCPU I2C0 CLOCK RESET CONTROL
> >> REGISTER(RCPU_I2C0_CLK_RST)), I see two clocks (pclk, fclk) and a reset, which
> >> looks to be standard across the peripherals in this SoC. Please be sure that the
> >> binding covers all resources needed to use this peripheral.
> >
> > RCPU stands for Real-time CPU, which is typically used for low power consumption
> > applications.
> > We should be using the APBC_TWSIx_CLK_RST register, but it's not listed in the
> > user manual.

The vendor missed the register definition of APBC_TWSIx_CLK_RST in the
documentation. There'll be an update soon.

> > However, you can find this register referenced in the K1 clock patch:
> > https://lore.kernel.org/all/SEYPR01MB4221AA2CA9C91A695FEFA777D7602 at SEYPR01MB4221.apcprd01.prod.exchangelabs.com/
> 
> Ah, well that driver is missing most of the bus clocks. For example, from a
> quick comparison with the manual, the driver includes sdh_axi_aclk, but misses
> all of the PWM APB clocks at APBC_PWMx_CLK_RST bit 0.

Thanks for pointing this out. Indeeded, the v2 of clock driver is
missing some bus clocks. I'm fixing them and working for a v3.

As for the I2C controller, I've confirmed with the vendor that both bus
and function clocks are required for normal operation. This applies for
all I2C controllers on the SoC, regardless of the region it belongs to
(RCPU/APBC).

> 
> If the clock gate exists in the hardware, even if it is enabled by default, it
> needs to be modeled in the devicetree.
> 
> > Also, to see how to enable the I2C clock in the device tree (note that the
> > spacemit,apb_clock property is unused in the driver), check out the example here:
> > https://gitee.com/bianbu-linux/linux-6.1/blob/bl-v1.0.y/arch/riscv/boot/dts/spacemit/k1-x.dtsi#L1048
> 
> The devicetree describes the hardware, irrespective of which features the driver
> may or may not use.

Best regards,
Haylen Chu


From michaelneuling at tenstorrent.com  Sun Nov 24 14:14:58 2024
From: michaelneuling at tenstorrent.com (Michael Neuling)
Date: Sun, 24 Nov 2024 22:14:58 +0000
Subject: [PATCH] RISC-V: KVM: Fix csr_write -> csr_set for HVIEN PMU overflow bit
Message-ID: <20241124221458.347464-1-michaelneuling@tenstorrent.com>

This doesn't cause a problem currently as HVIEN isn't used elsewhere
yet. Found by inspection.

Signed-off-by: Michael Neuling <michaelneuling at tenstorrent.com>
---
 arch/riscv/kvm/aia.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
index 2967d305c4..9f3b527596 100644
--- a/arch/riscv/kvm/aia.c
+++ b/arch/riscv/kvm/aia.c
@@ -552,7 +552,7 @@ void kvm_riscv_aia_enable(void)
 	csr_set(CSR_HIE, BIT(IRQ_S_GEXT));
 	/* Enable IRQ filtering for overflow interrupt only if sscofpmf is present */
 	if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
-		csr_write(CSR_HVIEN, BIT(IRQ_PMU_OVF));
+		csr_set(CSR_HVIEN, BIT(IRQ_PMU_OVF));
 }
 
 void kvm_riscv_aia_disable(void)
-- 
2.34.1



From anup at brainfault.org  Sun Nov 24 20:32:19 2024
From: anup at brainfault.org (Anup Patel)
Date: Mon, 25 Nov 2024 10:02:19 +0530
Subject: [PATCH] RISC-V: KVM: Fix csr_write -> csr_set for HVIEN PMU
 overflow bit
In-Reply-To: <20241124221458.347464-1-michaelneuling@tenstorrent.com>
References: <20241124221458.347464-1-michaelneuling@tenstorrent.com>
Message-ID: <CAAhSdy2Qq61qSLkuFkgiT2o5wXNDp3qO=U40AU1CFkcY6iNYhw@mail.gmail.com>

On Mon, Nov 25, 2024 at 3:45?AM Michael Neuling
<michaelneuling at tenstorrent.com> wrote:
>
> This doesn't cause a problem currently as HVIEN isn't used elsewhere
> yet. Found by inspection.
>

Fixes tag ?

> Signed-off-by: Michael Neuling <michaelneuling at tenstorrent.com>

Otherwise it looks good to me.

Reviewed-by: Anup Patel <anup at brainfault.org>

Regards,
Anup

> ---
>  arch/riscv/kvm/aia.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
> index 2967d305c4..9f3b527596 100644
> --- a/arch/riscv/kvm/aia.c
> +++ b/arch/riscv/kvm/aia.c
> @@ -552,7 +552,7 @@ void kvm_riscv_aia_enable(void)
>         csr_set(CSR_HIE, BIT(IRQ_S_GEXT));
>         /* Enable IRQ filtering for overflow interrupt only if sscofpmf is present */
>         if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
> -               csr_write(CSR_HVIEN, BIT(IRQ_PMU_OVF));
> +               csr_set(CSR_HVIEN, BIT(IRQ_PMU_OVF));
>  }
>
>  void kvm_riscv_aia_disable(void)
> --
> 2.34.1
>


From MichaelNeuling at tenstorrent.com  Sun Nov 24 20:41:09 2024
From: MichaelNeuling at tenstorrent.com (Michael Neuling)
Date: Mon, 25 Nov 2024 15:41:09 +1100
Subject: [PATCH] RISC-V: KVM: Fix csr_write -> csr_set for HVIEN PMU
 overflow bit
In-Reply-To: <CAAhSdy2Qq61qSLkuFkgiT2o5wXNDp3qO=U40AU1CFkcY6iNYhw@mail.gmail.com>
References: <20241124221458.347464-1-michaelneuling@tenstorrent.com> <CAAhSdy2Qq61qSLkuFkgiT2o5wXNDp3qO=U40AU1CFkcY6iNYhw@mail.gmail.com>
Message-ID: <CAAQMj+ojdJ3iQ7HHpPudai=yuKwKwhT4VFCdAnrAGA11oSPgcw@mail.gmail.com>

> > This doesn't cause a problem currently as HVIEN isn't used elsewhere
> > yet. Found by inspection.
> >
>
> Fixes tag ?

I'll resend in a few days but it's:

Fixes: 16b0bde9a37c ("RISC-V: KVM: Add perf sampling support for guests")

(I've also added Atish to CC who was the original author)

> > Signed-off-by: Michael Neuling <michaelneuling at tenstorrent.com>
>
> Otherwise it looks good to me.
>
> Reviewed-by: Anup Patel <anup at brainfault.org>

Thanks.

Mikey


From troymitchell988 at gmail.com  Sun Nov 24 22:49:52 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Mon, 25 Nov 2024 14:49:52 +0800
Subject: [PATCH v4 0/2] riscv: spacemit: add i2c support to K1 SoC
Message-ID: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com>

Hi all,

This patch implements I2C driver for the SpacemiT K1 SoC,
providing basic support for I2C read/write communication which
compatible with standard I2C bus specifications.

In this version, the driver defaults to use fast-speed-mode and
interrupts for transmission, and does not support DMA, high-speed mode, or FIFO.

The docs of I2C can be found here, in chapter 16.1 I2C [1]

Link: https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#part5 [1]
---
Change in v4:
- Patch #1:
	- Change the default value of clock-frequency from 100000 to
	  400000. This is to correspond to the driver's default value.
	- Drop the minimum of clock-frequency
	- Modify the description of clock-frequency
- Patch #2:
	- Drop the `inline` qualifier from the `spacemit_i2c_xfer_core` function
	- Drop the initialization of `ret` to 0 in `spacemit_i2c_xfer_core` function
	- Drop useless wrap
Link to v3:
https://lore.kernel.org/all/20241112-k1-i2c-master-v3-0-5005b70dc208 at gmail.com/

Change in v3:
- Patch #1:
	- Change the maxItems of reg from 2 to 1 in properties
	- Modify reg in dts example 
	- Changed the enum selection for clock-frequency to a range,
	  setting a minimum value of 1 and a maximum value of 3,300,000.
- Patch #2:
	- Drop unused judgement in `spacemit_i2c_xfer_msg`
	- Fix the dangling else warning in `spacemit_i2c_is_last_msg`
	- Fix the error check for `i2c->base`
	- Modify Kconfig dependencies
Link to v2:
https://lore.kernel.org/all/20241028053220.346283-1-TroyMitchell988 at gmail.com/

Change in v2:
- Patch #1:
	- Change the maxItems of reg from 1 to 2 in properties
	- Change 'i2c' to 'I2C' in the commit message.
	- Drop fifo-disable property
	- Drop alias in dts example
	- Move `unevaluatedProperties` after `required:` block
- Patch #2:
	- Alphabetize Makefile and Kconfig
	- Change `.remove_new` to `.remove` in `struct platform_driver`
	- Change `dev_alert` to `dev_warn_ratelimited` in `spacemit_i2c_bus_reset`
	- Change `spacemit_i2c_read/write_reg` to `read/writel`
	- Change `spacemit_i2c_dt_match` to `spacemit_i2c_of_match`
	- Clean up code flow
	- Fix unnecessary line wraps
	- Move `spacemit_i2c_handle_err` to a suitable location
	- Modify Kconfig dependencies
	- Use `PTR_ERR(i2c->base)` directly as the `dev_err_probe` parameter instead of
	  the intermediate variable
Link to v1:
https://lore.kernel.org/all/20241015075134.1449458-1-TroyMitchell988 at gmail.com/
---

Troy Mitchell (2):
  dt-bindings: i2c: spacemit: add support for K1 SoC
  i2c: spacemit: add support for SpacemiT K1 SoC

 .../bindings/i2c/spacemit,k1-i2c.yaml         |  51 ++
 drivers/i2c/busses/Kconfig                    |  18 +
 drivers/i2c/busses/Makefile                   |   1 +
 drivers/i2c/busses/i2c-k1.c                   | 658 ++++++++++++++++++
 4 files changed, 728 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
 create mode 100644 drivers/i2c/busses/i2c-k1.c

--
2.34.1

---
Changes in v4:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v3: https://lore.kernel.org/r/20241112-k1-i2c-master-v3-0-5005b70dc208 at gmail.com

---
Troy Mitchell (2):
      dt-bindings: i2c: spacemit: add support for K1 SoC
      i2c: spacemit: add support for SpacemiT K1 SoC

 .../devicetree/bindings/i2c/spacemit,k1-i2c.yaml   |  53 ++
 drivers/i2c/busses/Kconfig                         |  19 +
 drivers/i2c/busses/Makefile                        |   1 +
 drivers/i2c/busses/i2c-k1.c                        | 655 +++++++++++++++++++++
 4 files changed, 728 insertions(+)
---
base-commit: 8e929cb546ee42c9a61d24fae60605e9e3192354
change-id: 20241031-k1-i2c-master-fe7f7b0dce93
prerequisite-change-id: 20240626-k1-01-basic-dt-1aa31eeebcd2:v5
prerequisite-patch-id: 47dcf6861f7d434d25855b379e6d7ef4ce369c9c
prerequisite-patch-id: 77787fe82911923aff15ccf565e8fa451538c3a6
prerequisite-patch-id: b0bdb1742d96c5738f05262c3b0059102761390b
prerequisite-patch-id: 3927d39d8d77e35d5bfe53d9950da574ff8f2054
prerequisite-patch-id: a98039136a4796252a6029e474f03906f2541643
prerequisite-patch-id: c95f6dc0547a2a63a76e3cba0cf5c623b212b4e6
prerequisite-patch-id: 66e750e438ee959ddc2a6f0650814a2d8c989139
prerequisite-patch-id: 29a0fd8c36c1a4340f0d0b68a4c34d2b8abfb1ab
prerequisite-patch-id: 0bdfff661c33c380d1cf00a6c68688e05f88c0b3
prerequisite-patch-id: 99f15718e0bfbb7ed1a96dfa19f35841b004dae9

Best regards,
-- 
Troy Mitchell <TroyMitchell988 at gmail.com>



From troymitchell988 at gmail.com  Sun Nov 24 22:49:53 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Mon, 25 Nov 2024 14:49:53 +0800
Subject: [PATCH v4 1/2] dt-bindings: i2c: spacemit: add support for K1 SoC
In-Reply-To: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com>
References: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com>
Message-ID: <20241125-k1-i2c-master-v4-1-0f3d5886336b@gmail.com>

From: Troy Mitchell <troymitchell988 at gmail.com>

The I2C of K1 supports fast-speed-mode and high-speed-mode,
and supports FIFO transmission.

Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
---
 .../devicetree/bindings/i2c/spacemit,k1-i2c.yaml   | 53 ++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
new file mode 100644
index 000000000000..e7cc62f39e28
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/spacemit,k1-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: I2C controller embedded in SpacemiT's K1 SoC
+
+maintainers:
+  - Troy Mitchell <troymitchell988 at gmail.com>
+
+properties:
+  compatible:
+    const: spacemit,k1-i2c
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-frequency:
+    description: |
+      K1 support three different modes which running different frequencies
+      standard speed mode: up to 100000 (100Hz)
+      fast speed mode    : up to 400000 (400Hz)
+      high speed mode    : up to 3300000 (3.3Mhz)
+    default: 400000
+    maximum: 3300000
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c at d4010800 {
+        compatible = "spacemit,k1-i2c";
+        reg = <0xd4010800 0x38>;
+        interrupt-parent = <&plic>;
+        interrupts = <36>;
+        clocks = <&ccu 90>;
+        clock-frequency = <100000>;
+    };
+
+...

-- 
2.34.1



From troymitchell988 at gmail.com  Sun Nov 24 22:49:54 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Mon, 25 Nov 2024 14:49:54 +0800
Subject: [PATCH v4 2/2] i2c: spacemit: add support for SpacemiT K1 SoC
In-Reply-To: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com>
References: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com>
Message-ID: <20241125-k1-i2c-master-v4-2-0f3d5886336b@gmail.com>

From: Troy Mitchell <troymitchell988 at gmail.com>

This patch introduces basic I2C support for the SpacemiT K1 SoC,
utilizing interrupts for transfers.

The driver has been tested using i2c-tools on a Bananapi-F3 board,
and basic I2C read/write operations have been confirmed to work.

Signed-off-by: Troy Mitchell <TroyMitchell988 at gmail.com>
---
 drivers/i2c/busses/Kconfig  |  19 ++
 drivers/i2c/busses/Makefile |   1 +
 drivers/i2c/busses/i2c-k1.c | 655 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 675 insertions(+)

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 6b3ba7e5723a..91630f55667f 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -779,6 +779,25 @@ config I2C_JZ4780
 
 	 If you don't know what to do here, say N.
 
+config I2C_K1
+	tristate "Spacemit K1 I2C adapter"
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	depends on OF
+	help
+	  This option enables support for the I2C interface on the Spacemit K1
+	  platform.
+
+	  If you enable this configuration, the kernel will include support for
+	  the I2C adapter specific to the Spacemit K1 platform. This driver ca
+	  be used to manage I2C bus transactions, which are necessary for
+	  interfacing with I2C peripherals such as sensors, EEPROMs, and other
+	  devices.
+
+	  This driver can also be compiled as a module. If you choose to build
+	  it as a module, the resulting kernel module will be named `i2c-k1`.
+	  Loading this module will enable the I2C functionality for the K1
+	  platform dynamically, without requiring a rebuild of the kernel.
+
 config I2C_KEBA
 	tristate "KEBA I2C controller support"
 	depends on HAS_IOMEM
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index ecc07c50f2a0..9744b0e58598 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
 obj-$(CONFIG_I2C_IMX_LPI2C)	+= i2c-imx-lpi2c.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_JZ4780)	+= i2c-jz4780.o
+obj-$(CONFIG_I2C_K1)		+= i2c-k1.o
 obj-$(CONFIG_I2C_KEBA)		+= i2c-keba.o
 obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
 obj-$(CONFIG_I2C_LPC2K)		+= i2c-lpc2k.o
diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c
new file mode 100644
index 000000000000..5812296bfc32
--- /dev/null
+++ b/drivers/i2c/busses/i2c-k1.c
@@ -0,0 +1,655 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Troy Mitchell <troymitchell988 at gmail.com>
+ */
+
+ #include <linux/clk.h>
+ #include <linux/i2c.h>
+ #include <linux/iopoll.h>
+ #include <linux/module.h>
+ #include <linux/of_address.h>
+ #include <linux/platform_device.h>
+
+/* spacemit i2c registers */
+#define ICR          0x0		/* Control Register */
+#define ISR          0x4		/* Status Register */
+#define ISAR         0x8		/* Slave Address Register */
+#define IDBR         0xc		/* Data Buffer Register */
+#define ILCR         0x10		/* Load Count Register */
+#define IWCR         0x14		/* Wait Count Register */
+#define IRST_CYC     0x18		/* Bus reset cycle counter */
+#define IBMR         0x1c		/* Bus monitor register */
+#define IWFIFO       0x20		/* Write FIFO Register */
+#define IWFIFO_WPTR  0x24		/* Write FIFO Write Pointer Register */
+#define IWFIFO_RPTR  0x28		/* Write FIFO Read Pointer Register */
+#define IRFIFO       0x2c		/* Read FIFO Register */
+#define IRFIFO_WPTR  0x30		/* Read FIFO Write Pointer Register */
+#define IRFIFO_RPTR  0x34		/* Read FIFO Read Pointer Register */
+
+/* register ICR fields */
+#define CR_START        BIT(0)		/* start bit */
+#define CR_STOP         BIT(1)		/* stop bit */
+#define CR_ACKNAK       BIT(2)		/* send ACK(0) or NAK(1) */
+#define CR_TB           BIT(3)		/* transfer byte bit */
+#define CR_TXBEGIN      BIT(4)		/* transaction begin */
+#define CR_FIFOEN       BIT(5)		/* enable FIFO mode */
+#define CR_GPIOEN       BIT(6)		/* enable GPIO mode for SCL in HS */
+#define CR_DMAEN        BIT(7)		/* enable DMA for TX and RX FIFOs */
+#define CR_MODE_FAST    BIT(8)		/* bus mode (master operation) */
+#define CR_MODE_HIGH    BIT(9)		/* bus mode (master operation) */
+#define CR_UR           BIT(10)		/* unit reset */
+#define CR_RSTREQ       BIT(11)		/* i2c bus reset request */
+#define CR_MA           BIT(12)		/* master abort */
+#define CR_SCLE         BIT(13)		/* master clock enable */
+#define CR_IUE          BIT(14)		/* unit enable */
+#define CR_HS_STRETCH   BIT(16)		/* I2C hs stretch */
+#define CR_ALDIE        BIT(18)		/* enable arbitration interrupt */
+#define CR_DTEIE        BIT(19)		/* enable tx interrupts */
+#define CR_DRFIE        BIT(20)		/* enable rx interrupts */
+#define CR_GCD          BIT(21)		/* general call disable */
+#define CR_BEIE         BIT(22)		/* enable bus error ints */
+#define CR_SADIE        BIT(23)		/* slave address detected int enable */
+#define CR_SSDIE        BIT(24)		/* slave STOP detected int enable */
+#define CR_MSDIE        BIT(25)		/* master STOP detected int enable */
+#define CR_MSDE         BIT(26)		/* master STOP detected enable */
+#define CR_TXDONEIE     BIT(27)		/* transaction done int enable */
+#define CR_TXEIE        BIT(28)		/* transmit FIFO empty int enable */
+#define CR_RXHFIE       BIT(29)		/* receive FIFO half-full int enable */
+#define CR_RXFIE        BIT(30)		/* receive FIFO full int enable */
+#define CR_RXOVIE       BIT(31)		/* receive FIFO overrun int enable */
+
+/* register ISR fields */
+#define SR_RWM          BIT(13)		/* read/write mode */
+#define SR_ACKNAK       BIT(14)		/* ACK/NACK status */
+#define SR_UB           BIT(15)		/* unit busy */
+#define SR_IBB          BIT(16)		/* i2c bus busy */
+#define SR_EBB          BIT(17)		/* early bus busy */
+#define SR_ALD          BIT(18)		/* arbitration loss detected */
+#define SR_ITE          BIT(19)		/* tx buffer empty */
+#define SR_IRF          BIT(20)		/* rx buffer full */
+#define SR_GCAD         BIT(21)		/* general call address detected */
+#define SR_BED          BIT(22)		/* bus error no ACK/NAK */
+#define SR_SAD          BIT(23)		/* slave address detected */
+#define SR_SSD          BIT(24)		/* slave stop detected */
+#define SR_MSD          BIT(26)		/* master stop detected */
+#define SR_TXDONE       BIT(27)		/* transaction done */
+#define SR_TXE          BIT(28)		/* tx FIFO empty */
+#define SR_RXHF         BIT(29)		/* rx FIFO half-full */
+#define SR_RXF          BIT(30)		/* rx FIFO full */
+#define SR_RXOV         BIT(31)		/* RX FIFO overrun */
+
+/* register ILCR fields */
+#define LCR_SLV         0x000001FF	/* SLV: bit[8:0] */
+#define LCR_FLV         0x0003FE00	/* FLV: bit[17:9] */
+#define LCR_HLVH        0x07FC0000	/* HLVH: bit[26:18] */
+#define LCR_HLVL        0xF8000000	/* HLVL: bit[31:27] */
+
+/* register IWCR fields */
+#define WCR_COUNT       0x0000001F	/* COUNT: bit[4:0] */
+#define WCR_COUNT1      0x000003E0	/* HS_COUNT1: bit[9:5] */
+#define WCR_COUNT2      0x00007C00	/* HS_COUNT2: bit[14:10] */
+
+/* register IBMR fields */
+#define BMR_SDA         BIT(0)		/* SDA line level */
+#define BMR_SCL         BIT(1)		/* SCL line level */
+
+/* register IWFIFO fields */
+#define WFIFO_DATA_MSK      0x000000FF  /* data: bit[7:0] */
+#define WFIFO_CTRL_MSK      0x000003E0  /* control: bit[11:8] */
+#define WFIFO_CTRL_START    BIT(8)      /* start bit */
+#define WFIFO_CTRL_STOP     BIT(9)      /* stop bit */
+#define WFIFO_CTRL_ACKNAK   BIT(10)     /* send ACK(0) or NAK(1) */
+#define WFIFO_CTRL_TB       BIT(11)     /* transfer byte bit */
+
+/* status register init value */
+#define I2C_INT_STATUS_MASK    0xfffc0000  /* SR bits[31:18] */
+#define I2C_INT_CTRL_MASK      (CR_ALDIE | CR_DTEIE | CR_DRFIE | \
+				CR_BEIE | CR_TXDONEIE | CR_TXEIE | \
+				CR_RXHFIE | CR_RXFIE | CR_RXOVIE | \
+				CR_MSDIE)
+
+/* i2c bus recover timeout: us */
+#define I2C_BUS_RECOVER_TIMEOUT		(100000)
+
+#define I2C_FAST_MODE_FREQ		(400000)
+
+enum spacemit_i2c_state {
+	STATE_IDLE,
+	STATE_START,
+	STATE_READ,
+	STATE_WRITE,
+};
+
+enum spacemit_i2c_dir {
+	DIR_WRITE,
+	DIR_READ
+};
+
+/* i2c-spacemit driver's main struct */
+struct spacemit_i2c_dev {
+	struct device *dev;
+	struct i2c_adapter adapt;
+
+	/* hardware resources */
+	void __iomem *base;
+	int irq;
+
+	struct i2c_msg *msgs;
+	int msg_num;
+	struct i2c_msg *cur_msg;
+
+	/* index of the current message being processed */
+	int msg_idx;
+	u8 *msg_buf;
+	/* the number of unprocessed bytes remaining in each message  */
+	size_t unprocessed;
+
+	enum spacemit_i2c_state state;
+	enum spacemit_i2c_dir dir;
+	struct completion complete;
+	u32 status;
+	u32 err;
+};
+
+static void spacemit_i2c_enable(struct spacemit_i2c_dev *i2c)
+{
+	u32 val;
+
+	val = readl(i2c->base + ICR);
+	writel(val | CR_IUE, i2c->base + ICR);
+}
+
+static void spacemit_i2c_disable(struct spacemit_i2c_dev *i2c)
+{
+	u32 val;
+
+	val = readl(i2c->base + ICR);
+	val &= ~CR_IUE;
+	writel(val, i2c->base + ICR);
+}
+
+static void spacemit_i2c_reset(struct spacemit_i2c_dev *i2c)
+{
+	writel(CR_UR, i2c->base + ICR);
+	udelay(5);
+	writel(0, i2c->base + ICR);
+}
+
+static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c);
+
+static void spacemit_i2c_bus_reset(struct spacemit_i2c_dev *i2c)
+{
+	u32 status;
+
+	/* if bus is locked, reset unit. 0: locked */
+	status = readl(i2c->base + IBMR);
+	if ((status & BMR_SDA) && (status & BMR_SCL))
+		return;
+
+	spacemit_i2c_reset(i2c);
+	usleep_range(10, 20);
+
+	/* check scl status again */
+	status = readl(i2c->base + IBMR);
+	if (!(status & BMR_SCL))
+		dev_warn_ratelimited(i2c->dev, "unit reset failed\n");
+}
+
+static int spacemit_i2c_recover_bus_busy(struct spacemit_i2c_dev *i2c)
+{
+	int ret = 0;
+	u32 val;
+
+	val = readl(i2c->base + ISR);
+	if (likely(!(val & (SR_UB | SR_IBB))))
+		return 0;
+
+	ret = readl_poll_timeout(i2c->base + ISR, val, !(val & (SR_UB | SR_IBB)),
+				 1500, I2C_BUS_RECOVER_TIMEOUT);
+	if (unlikely(ret)) {
+		spacemit_i2c_reset(i2c);
+		ret = -EAGAIN;
+	}
+
+	return ret;
+}
+
+static void spacemit_i2c_check_bus_release(struct spacemit_i2c_dev *i2c)
+{
+	/* in case bus is not released after transfer completes */
+	if (unlikely(readl(i2c->base + ISR) & SR_EBB)) {
+		spacemit_i2c_bus_reset(i2c);
+		usleep_range(90, 150);
+	}
+}
+
+static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c)
+{
+	u32 val = 0;
+
+	/*
+	 * Unmask interrupt bits for all xfer mode:
+	 * bus error, arbitration loss detected.
+	 * For transaction complete signal, we use master stop
+	 * interrupt, so we don't need to unmask CR_TXDONEIE.
+	 */
+	val |= CR_BEIE | CR_ALDIE;
+
+	/*
+	 * Unmask interrupt bits for interrupt xfer mode:
+	 * DBR rx full.
+	 * For tx empty interrupt CR_DTEIE, we only
+	 * need to enable when trigger byte transfer to start
+	 * data sending.
+	 */
+	val |= CR_DRFIE;
+
+	/* set speed bits: default fast mode */
+	val |= CR_MODE_FAST;
+
+	/* disable response to general call */
+	val |= CR_GCD;
+
+	/* enable SCL clock output */
+	val |= CR_SCLE;
+
+	/* enable master stop detected */
+	val |= CR_MSDE | CR_MSDIE;
+
+	writel(val, i2c->base + ICR);
+}
+
+static inline void
+spacemit_i2c_clear_int_status(struct spacemit_i2c_dev *i2c, u32 mask)
+{
+	writel(mask & I2C_INT_STATUS_MASK, i2c->base + ISR);
+}
+
+static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c)
+{
+	u32 slave_addr_rw, val;
+
+	i2c->dir = i2c->cur_msg->flags & I2C_M_RD;
+	i2c->state = STATE_START;
+
+	if (i2c->cur_msg->flags & I2C_M_RD)
+		slave_addr_rw = ((i2c->cur_msg->addr & 0x7f) << 1) | 1;
+	else
+		slave_addr_rw = (i2c->cur_msg->addr & 0x7f) << 1;
+
+	writel(slave_addr_rw, i2c->base + IDBR);
+
+	val = readl(i2c->base + ICR);
+
+	/* send start pulse */
+	val &= ~CR_STOP;
+	val |= CR_START | CR_TB | CR_DTEIE;
+	writel(val, i2c->base + ICR);
+}
+
+static void spacemit_i2c_stop(struct spacemit_i2c_dev *i2c)
+{
+	u32 val;
+
+	val = readl(i2c->base + ICR);
+
+	val |= CR_STOP | CR_ALDIE | CR_TB;
+
+	if (i2c->dir == DIR_READ)
+		val |= CR_ACKNAK;
+
+	writel(val, i2c->base + ICR);
+}
+
+static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
+{
+	unsigned long time_left;
+
+	for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) {
+		i2c->cur_msg = i2c->msgs + i2c->msg_idx;
+		i2c->msg_buf = i2c->cur_msg->buf;
+		i2c->err = 0;
+		i2c->status = 0;
+		i2c->unprocessed = i2c->cur_msg->len;
+
+		reinit_completion(&i2c->complete);
+
+		spacemit_i2c_start(i2c);
+
+		time_left = wait_for_completion_timeout(&i2c->complete,
+							i2c->adapt.timeout);
+		if (unlikely(time_left == 0)) {
+			dev_alert(i2c->dev, "msg completion timeout\n");
+			spacemit_i2c_bus_reset(i2c);
+			spacemit_i2c_reset(i2c);
+			return -ETIMEDOUT;
+		}
+
+		if (unlikely(i2c->err))
+			return spacemit_i2c_handle_err(i2c);
+	}
+
+	return 0;
+}
+
+static int spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c)
+{
+	if (i2c->dir == DIR_READ) {
+		if (i2c->unprocessed == 1 && i2c->msg_idx == i2c->msg_num - 1)
+			return 1;
+	} else if (i2c->dir == DIR_WRITE) {
+		if (!i2c->unprocessed && i2c->msg_idx == i2c->msg_num - 1)
+			return 1;
+	}
+
+	return 0;
+}
+
+static void spacemit_i2c_handle_write(struct spacemit_i2c_dev *i2c)
+{
+	/* if transfer completes, ISR will handle it */
+	if (i2c->status & SR_MSD)
+		return;
+
+	if (i2c->unprocessed) {
+		writel(*i2c->msg_buf++, i2c->base + IDBR);
+		i2c->unprocessed--;
+		return;
+	}
+
+	/* STATE_IDLE avoids trigger next byte */
+	i2c->state = STATE_IDLE;
+	complete(&i2c->complete);
+}
+
+static void spacemit_i2c_handle_read(struct spacemit_i2c_dev *i2c)
+{
+	if (i2c->unprocessed) {
+		*i2c->msg_buf++ = readl(i2c->base + IDBR);
+		i2c->unprocessed--;
+	}
+
+	/* if transfer completes, ISR will handle it */
+	if (i2c->status & (SR_MSD | SR_ACKNAK))
+		return;
+
+	/* it has to append stop bit in icr that read last byte */
+	if (i2c->unprocessed)
+		return;
+
+	/* STATE_IDLE avoids trigger next byte */
+	i2c->state = STATE_IDLE;
+	complete(&i2c->complete);
+}
+
+static void spacemit_i2c_handle_start(struct spacemit_i2c_dev *i2c)
+{
+	if (i2c->dir == DIR_READ) {
+		i2c->state = STATE_READ;
+		return;
+	}
+
+	if (i2c->dir == DIR_WRITE) {
+		i2c->state = STATE_WRITE;
+		spacemit_i2c_handle_write(i2c);
+	}
+}
+
+static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c)
+{
+	if (!i2c->err)
+		return 0;
+
+	dev_dbg(i2c->dev, "i2c error status: 0x%08x\n",	i2c->status);
+
+	if (i2c->err & (SR_BED | SR_ALD))
+		spacemit_i2c_reset(i2c);
+
+	if (i2c->err & (SR_RXOV | SR_ALD))
+		return -EAGAIN;
+
+	return (i2c->status & SR_ACKNAK) ? -ENXIO : -EIO;
+}
+
+static void spacemit_i2c_err_check(struct spacemit_i2c_dev *i2c)
+{
+	u32 val;
+	/*
+	 * send transaction complete signal:
+	 * error happens, detect master stop
+	 */
+	if (likely(i2c->err || (i2c->status & SR_MSD))) {
+		/*
+		 * Here the transaction is already done, we don't need any
+		 * other interrupt signals from now, in case any interrupt
+		 * happens before spacemit_i2c_xfer to disable irq and i2c unit,
+		 * we mask all the interrupt signals and clear the interrupt
+		 * status.
+		 */
+		val = readl(i2c->base + ICR);
+		val &= ~I2C_INT_CTRL_MASK;
+		writel(val, i2c->base + ICR);
+
+		spacemit_i2c_clear_int_status(i2c, I2C_INT_STATUS_MASK);
+
+		i2c->state = STATE_IDLE;
+		complete(&i2c->complete);
+	}
+}
+
+static irqreturn_t spacemit_i2c_irq_handler(int irq, void *devid)
+{
+	struct spacemit_i2c_dev *i2c = devid;
+	u32 status, val;
+
+	status = readl(i2c->base + ISR);
+	if (!status)
+		return IRQ_HANDLED;
+
+	i2c->status = status;
+
+	i2c->err = status & (SR_BED | SR_RXOV | SR_ALD);
+
+	spacemit_i2c_clear_int_status(i2c, status);
+
+	if (unlikely(i2c->err))
+		goto err_out;
+
+	val = readl(i2c->base + ICR);
+
+	val &= ~(CR_TB | CR_ACKNAK | CR_STOP | CR_START);
+	writel(val, i2c->base + ICR);
+
+	switch (i2c->state) {
+	case STATE_START:
+		spacemit_i2c_handle_start(i2c);
+		break;
+	case STATE_READ:
+		spacemit_i2c_handle_read(i2c);
+		break;
+	case STATE_WRITE:
+		spacemit_i2c_handle_write(i2c);
+		break;
+	default:
+		break;
+	}
+
+	if (i2c->state != STATE_IDLE) {
+		if (spacemit_i2c_is_last_msg(i2c)) {
+			/* trigger next byte with stop */
+			spacemit_i2c_stop(i2c);
+		} else {
+			/* trigger next byte */
+			val |= CR_ALDIE | CR_TB;
+			writel(val, i2c->base + ICR);
+		}
+	}
+
+err_out:
+	spacemit_i2c_err_check(i2c);
+	return IRQ_HANDLED;
+}
+
+static void spacemit_i2c_calc_timeout(struct spacemit_i2c_dev *i2c)
+{
+	unsigned long timeout;
+	int idx = 0, cnt = 0, freq;
+
+	while (idx < i2c->msg_num) {
+		cnt += (i2c->msgs + idx)->len + 1;
+		idx++;
+	}
+
+	freq = I2C_FAST_MODE_FREQ;
+	/*
+	 * multiply by 9 because each byte in I2C transmission requires
+	 * 9 clock cycles: 8 bits of data plus 1 ACK/NACK bit.
+	 */
+	timeout = cnt * 9 * USEC_PER_SEC / freq;
+
+	i2c->adapt.timeout = usecs_to_jiffies(timeout + USEC_PER_SEC / 2) / i2c->msg_num;
+}
+
+static int spacemit_i2c_xfer_core(struct spacemit_i2c_dev *i2c)
+{
+	int ret;
+
+	spacemit_i2c_reset(i2c);
+
+	spacemit_i2c_calc_timeout(i2c);
+
+	spacemit_i2c_init(i2c);
+
+	spacemit_i2c_enable(i2c);
+	enable_irq(i2c->irq);
+
+	/* i2c wait for bus busy */
+	ret = spacemit_i2c_recover_bus_busy(i2c);
+	if (unlikely(ret))
+		return ret;
+
+	ret = spacemit_i2c_xfer_msg(i2c);
+	if (unlikely(ret < 0)) {
+		dev_dbg(i2c->dev, "i2c transfer error\n");
+		/* timeout error should not be overridden, and the transfer
+		 * error will be confirmed by err handle function latter,
+		 * the reset should be invalid argument error.
+		 */
+		if (ret != -ETIMEDOUT)
+			ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int spacemit_i2c_xfer(struct i2c_adapter *adapt, struct i2c_msg msgs[], int num)
+{
+	struct spacemit_i2c_dev *i2c = i2c_get_adapdata(adapt);
+	int ret;
+
+	i2c->msgs = msgs;
+	i2c->msg_num = num;
+
+	ret = spacemit_i2c_xfer_core(i2c);
+	if (likely(!ret))
+		spacemit_i2c_check_bus_release(i2c);
+
+	disable_irq(i2c->irq);
+
+	spacemit_i2c_disable(i2c);
+
+	if (unlikely((ret == -ETIMEDOUT || ret == -EAGAIN)))
+		dev_alert(i2c->dev, "i2c transfer failed, ret %d err 0x%x\n", ret, i2c->err);
+
+	return ret < 0 ? ret : num;
+}
+
+static u32 spacemit_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+}
+
+static const struct i2c_algorithm spacemit_i2c_algo = {
+	.xfer = spacemit_i2c_xfer,
+	.functionality = spacemit_i2c_func,
+};
+
+static int spacemit_i2c_probe(struct platform_device *pdev)
+{
+	struct spacemit_i2c_dev *i2c;
+	struct device_node *of_node = pdev->dev.of_node;
+	struct clk *clk;
+	int ret = 0;
+
+	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
+
+	i2c->dev = &pdev->dev;
+
+	i2c->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(i2c->base))
+		return dev_err_probe(&pdev->dev, PTR_ERR(i2c->base), "failed to do ioremap");
+
+	i2c->irq = platform_get_irq(pdev, 0);
+	if (i2c->irq < 0)
+		return dev_err_probe(&pdev->dev, i2c->irq, "failed to get irq resource");
+
+	ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
+			       IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(i2c->dev), i2c);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to request irq");
+
+	disable_irq(i2c->irq);
+
+	clk = devm_clk_get_enabled(&pdev->dev, NULL);
+	if (IS_ERR(clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(clk), "failed to enable clock");
+
+	i2c_set_adapdata(&i2c->adapt, i2c);
+	i2c->adapt.owner = THIS_MODULE;
+	i2c->adapt.algo = &spacemit_i2c_algo;
+	i2c->adapt.dev.parent = i2c->dev;
+	i2c->adapt.nr = pdev->id;
+
+	i2c->adapt.dev.of_node = of_node;
+	i2c->adapt.algo_data = i2c;
+
+	strscpy(i2c->adapt.name, "spacemit-i2c-adapter", sizeof(i2c->adapt.name));
+
+	init_completion(&i2c->complete);
+
+	ret = i2c_add_numbered_adapter(&i2c->adapt);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to add i2c adapter");
+
+	platform_set_drvdata(pdev, i2c);
+
+	return 0;
+}
+
+static void spacemit_i2c_remove(struct platform_device *pdev)
+{
+	struct spacemit_i2c_dev *i2c = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&i2c->adapt);
+}
+
+static const struct of_device_id spacemit_i2c_of_match[] = {
+	{ .compatible = "spacemit,k1-i2c", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, spacemit_i2c_of_match);
+
+static struct platform_driver spacemit_i2c_driver = {
+	.probe = spacemit_i2c_probe,
+	.remove = spacemit_i2c_remove,
+	.driver = {
+		.name = "i2c-k1",
+		.of_match_table = spacemit_i2c_of_match,
+	},
+};
+module_platform_driver(spacemit_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("I2C bus driver for SpacemiT K1 SoC");

-- 
2.34.1



From krzk at kernel.org  Mon Nov 25 00:06:02 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 25 Nov 2024 09:06:02 +0100
Subject: [PATCH v4 0/2] riscv: spacemit: add i2c support to K1 SoC
In-Reply-To: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com>
References: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com>
Message-ID: <5d69e1db-2ec5-445d-9336-9345c918722a@kernel.org>

On 25/11/2024 07:49, Troy Mitchell wrote:
> Hi all,
> 
> This patch implements I2C driver for the SpacemiT K1 SoC,
> providing basic support for I2C read/write communication which
> compatible with standard I2C bus specifications.
> 
> In this version, the driver defaults to use fast-speed-mode and
> interrupts for transmission, and does not support DMA, high-speed mode, or FIFO.
> 
> The docs of I2C can be found here, in chapter 16.1 I2C [1]
> 
> Link: https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#part5 [1]
> ---
> Change in v4:
> - Patch #1:
> 	- Change the default value of clock-frequency from 100000 to
> 	  400000. This is to correspond to the driver's default value.
> 	- Drop the minimum of clock-frequency
> 	- Modify the description of clock-frequency

Explain why do you request re-review.

<form letter>
This is a friendly reminder during the review process.

It looks like you received a tag and forgot to add it.

If you do not know the process, here is a short explanation:
Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions, under or above your Signed-off-by tag. Tag is "received", when
provided in a message replied to you on the mailing list. Tools like b4
can help here. However, there's no need to repost patches *only* to add
the tags. The upstream maintainer will do that for tags received on the
version they apply.

https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577

If a tag was not added on purpose, please state why and what changed.
</form letter>

Best regards,
Krzysztof


From patryk.wysocki at sharpwise.pl  Mon Nov 25 01:10:51 2024
From: patryk.wysocki at sharpwise.pl (Patryk Wysocki)
Date: Mon, 25 Nov 2024 09:10:51 GMT
Subject: Zapytanie ofertowe 
Message-ID: <20241125084501-0.1.82.1akrp.0.m7pyflcjaj@sharpwise.pl>

Dzie? dobry,

Pozwoli?em sobie na kontakt, poniewa? jestem zainteresowany weryfikacj? mo?liwo?ci nawi?zania wsp??pracy.

Wspieramy firmy w pozyskiwaniu nowych klient?w biznesowych.

Czy mo?emy porozmawia? w celu przedstawienia szczeg??owych informacji?


Pozdrawiam
Patryk Wysocki


From troymitchell988 at gmail.com  Mon Nov 25 02:05:58 2024
From: troymitchell988 at gmail.com (Troy Mitchell)
Date: Mon, 25 Nov 2024 18:05:58 +0800
Subject: [PATCH v4 0/2] riscv: spacemit: add i2c support to K1 SoC
In-Reply-To: <5d69e1db-2ec5-445d-9336-9345c918722a@kernel.org>
References: <20241125-k1-i2c-master-v4-0-0f3d5886336b@gmail.com>
 <5d69e1db-2ec5-445d-9336-9345c918722a@kernel.org>
Message-ID: <062192c5-4482-4c83-b127-fae0942ab114@gmail.com>


On 2024/11/25 16:06, Krzysztof Kozlowski wrote:
> On 25/11/2024 07:49, Troy Mitchell wrote:
>> Hi all,
>>
>> This patch implements I2C driver for the SpacemiT K1 SoC,
>> providing basic support for I2C read/write communication which
>> compatible with standard I2C bus specifications.
>>
>> In this version, the driver defaults to use fast-speed-mode and
>> interrupts for transmission, and does not support DMA, high-speed mode, or FIFO.
>>
>> The docs of I2C can be found here, in chapter 16.1 I2C [1]
>>
>> Link: https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#part5 [1]
>> ---
>> Change in v4:
>> - Patch #1:
>> 	- Change the default value of clock-frequency from 100000 to
>> 	  400000. This is to correspond to the driver's default value.
>> 	- Drop the minimum of clock-frequency
>> 	- Modify the description of clock-frequency
> 
> Explain why do you request re-review.
> 
> <form letter>
> This is a friendly reminder during the review process.
> 
> It looks like you received a tag and forgot to add it.
> 
> If you do not know the process, here is a short explanation:
> Please add Acked-by/Reviewed-by/Tested-by tags when posting new
> versions, under or above your Signed-off-by tag. Tag is "received", when
> provided in a message replied to you on the mailing list. Tools like b4
> can help here. However, there's no need to repost patches *only* to add
> the tags. The upstream maintainer will do that for tags received on the
> version they apply.
> 
> https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577
> 
> If a tag was not added on purpose, please state why and what changed.
> </form letter>
> 
> Best regards,
> Krzysztof
Thank you, I accidentally forgot to add it, and it was not intentional.

-- 
Troy Mitchell


From ajones at ventanamicro.com  Mon Nov 25 04:08:47 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Mon, 25 Nov 2024 13:08:47 +0100
Subject: [PATCH RFC v3 3/3] riscv: KVM: Add Svukte extension support for
 Guest/VM
In-Reply-To: <20241120-dev-maxh-svukte-v3-v3-3-1e533d41ae15@sifive.com>
References: <20241120-dev-maxh-svukte-v3-v3-0-1e533d41ae15@sifive.com>
 <20241120-dev-maxh-svukte-v3-v3-3-1e533d41ae15@sifive.com>
Message-ID: <20241125-7cfad4185ec1a66fa08ff0f0@orel>

On Wed, Nov 20, 2024 at 10:09:34PM +0800, Max Hsu wrote:
> Add KVM_RISCV_ISA_EXT_SVUKTE for VMM to detect the enablement
> or disablement the Svukte extension for Guest/VM
> 
> Reviewed-by: Samuel Holland <samuel.holland at sifive.com>
> Signed-off-by: Max Hsu <max.hsu at sifive.com>
> ---
>  arch/riscv/include/uapi/asm/kvm.h | 1 +
>  arch/riscv/kvm/vcpu_onereg.c      | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
> index 4f24201376b17215315cf1fb8888d0a562dc76ac..158f9253658c4c28a533b2bda179fb48bf41e1fc 100644
> --- a/arch/riscv/include/uapi/asm/kvm.h
> +++ b/arch/riscv/include/uapi/asm/kvm.h
> @@ -177,6 +177,7 @@ enum KVM_RISCV_ISA_EXT_ID {
>  	KVM_RISCV_ISA_EXT_ZAWRS,
>  	KVM_RISCV_ISA_EXT_SMNPM,
>  	KVM_RISCV_ISA_EXT_SSNPM,
> +	KVM_RISCV_ISA_EXT_SVUKTE,
>  	KVM_RISCV_ISA_EXT_MAX,
>  };
>  
> diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
> index 5b68490ad9b75fef6a18289d8c5cf9291594e01e..4c3a77cdeed0956e21e53d1ab4e948a170ac5c5c 100644
> --- a/arch/riscv/kvm/vcpu_onereg.c
> +++ b/arch/riscv/kvm/vcpu_onereg.c
> @@ -43,6 +43,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
>  	KVM_ISA_EXT_ARR(SVINVAL),
>  	KVM_ISA_EXT_ARR(SVNAPOT),
>  	KVM_ISA_EXT_ARR(SVPBMT),
> +	KVM_ISA_EXT_ARR(SVUKTE),
>  	KVM_ISA_EXT_ARR(ZACAS),
>  	KVM_ISA_EXT_ARR(ZAWRS),
>  	KVM_ISA_EXT_ARR(ZBA),
> 
> -- 
> 2.43.2

Anup raised the missing entry in kvm_riscv_vcpu_isa_disable_allowed() in
the last review. An additional paragraph was added to the cover letter for
this review, but I think there's still a misunderstanding. If the guest
can always use the extension (whether it's advertised in its ISA string
or not), then that means it cannot be disabled from the perspective of
the VMM. The only ISA extensions which may be disabled are the ones that
trap on their use, allowing KVM to emulate responses which a physical hart
without the extension would produce.

Thanks,
drew


From bjorn at kernel.org  Mon Nov 25 05:13:17 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Mon, 25 Nov 2024 14:13:17 +0100
Subject: [PATCH v3 25/25] Revert "riscv: mm: Add support for ZONE_DEVICE"
In-Reply-To: <f511de7cb9817e2e2fdd274ee842c228d699abea.1732239628.git-series.apopple@nvidia.com>
References: <cover.e1ebdd6cab9bde0d232c1810deacf0bae25e6707.1732239628.git-series.apopple@nvidia.com>
 <f511de7cb9817e2e2fdd274ee842c228d699abea.1732239628.git-series.apopple@nvidia.com>
Message-ID: <878qt7zcb6.fsf@all.your.base.are.belong.to.us>

Alistair Popple <apopple at nvidia.com> writes:

> DEVMAP PTEs are no longer required to support ZONE_DEVICE so remove
> them.
>
> Signed-off-by: Alistair Popple <apopple at nvidia.com>
> Suggested-by: Chunyan Zhang <zhang.lyra at gmail.com>

Oh, we're getting the bit back! Thanks!

Reviewed-by: Bj?rn T?pel <bjorn at rivosinc.com>


From jgg at ziepe.ca  Mon Nov 25 07:07:27 2024
From: jgg at ziepe.ca (Jason Gunthorpe)
Date: Mon, 25 Nov 2024 11:07:27 -0400
Subject: [RFC PATCH 08/15] iommu/riscv: Add IRQ domain for interrupt
 remapping
In-Reply-To: <20241122-8c00551e2383787346c5249f@orel>
References: <20241114161845.502027-17-ajones@ventanamicro.com>
 <20241114161845.502027-25-ajones@ventanamicro.com>
 <20241118184336.GB559636@ziepe.ca>
 <20241119-62ff49fc1eedba051838dba2@orel>
 <20241119140047.GC559636@ziepe.ca>
 <DE13E1DF-7C68-461D-ADCD-8141B1ACEA5E@ventanamicro.com>
 <20241119153622.GD559636@ziepe.ca>
 <20241121-4e637c492d554280dec3b077@orel>
 <20241122153340.GC773835@ziepe.ca>
 <20241122-8c00551e2383787346c5249f@orel>
Message-ID: <20241125150727.GD773835@ziepe.ca>

On Fri, Nov 22, 2024 at 06:07:59PM +0100, Andrew Jones wrote:

> > What you are trying to do is not supported by the software stack right
> > now. You need to make much bigger, more intrusive changes, if you
> > really want to make interrupt remapping dynamic.
> >
> 
> Let the fun begin. I'll look into this more. It also looks like I need to
> collect some test cases to ensure I can support all use cases with
> whatever I propose next. Pointers for those would be welcome.

Sorry, I don't really have anything.. But iommufd allows changing the
translation at will and we expect this to happen in normal VMM
scenarios. So blocking, paging, nesting are all expected to be
dynamically selectable and non-disruptive to interrupts.

So, you can't decide if remapping is enabled or not for a device based
only on the domain attachment.

I think you'd need to create a way for VFIO to request dynamic
interrupt remapping be enabled for the device very, very early in it's
process and that would remain fixed while VFIO is using the device.

The dynamic state of interrupt remapping would constrain what iommu
attachment configurations are permitted.

Jason


From valentina.fernandezalanis at microchip.com  Mon Nov 25 09:58:14 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Mon, 25 Nov 2024 17:58:14 +0000
Subject: [PATCH v4 0/4] Add Microchip IPC mailbox
Message-ID: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>

Hello all,

This series adds support for the Microchip Inter-Processor Communication
(IPC) mailbox driver.

Microchip's family of RISC-V SoCs typically has one or more clusters
that can be configured to run in Asymmetric Multi-Processing (AMP) mode.

The Microchip IPC is used to send messages between processors using
an interrupt signaling mechanism. The driver uses the RISC-V Supervisor
Binary Interface (SBI) to communicate with software running in machine
mode (M-mode) to access the IPC hardware block.

Additional details on the Microchip vendor extension and the IPC
function IDs described in the driver can be found in the following
documentation:

https://github.com/linux4microchip/microchip-sbi-ecall-extension

The PIC64GX MPU has a Mi-V IHC block, this will be added to the PIC64GX
dts after the initial upstreaming [1].

[1] https://patchwork.kernel.org/project/linux-riscv/patch/20240725121609.13101-18-pierre-henry.moussay at microchip.com/

Changes in v4:
- specify that microchip,miv-ihc-rtl-v2 is intended for use with MIV IHC Soft IP
- drop items array and use const value for compatible strings
- add a contraint to microchip,ihc-chan-disabled-mask property
- minor improvements to "'#mbox-cells' description

Changes in v3:
- Fix incorrent formatting around '=' in dt binding examples
- Add per compatible descriptions in dt binding
- Add '>' in certain dt binding descriptions to keep paragraphs maintained
- export __cpuid_to_hartid_map to compile mailbox driver as module
- Drop unused enum ipc_irq_type
- rename struct mchp_ipc_probe to mchp_ipc_mbox_info
- rename struct ipc_chan_info to mchp_ipc_sbi_chan
- rename struct microchip_ipc to mchp_ipc_sbi_mbox
- use phys_addr_t for __pa()
- drop mchp_ipc_get_chan_id function
- use num_chans in mbox_controller
- Fix buf_base_tx and buf_base_rx sizes using max and kmalloc

Changes in v2:
- use kmalloc and __pa() instead of DMA API
- fix size of buf_base to avoid potential buffer overflow
- add kernel doc for exported functions (mchp_ipc_get_chan_id)
- use EXPORT_SYMBOL_GPL instead of EXPORT_SYMBOL
- drop unnecessary blank line and fix alignment issues
- drop of_match_ptr
- move MODULE_DEVICE_TABLE next to the definition
- reword subject from riscv: asm: vendorid_list to riscv: sbi: vendorid_list
- remove the word "driver" from dt-binding commit subject
- make interrupt-names a required property for all cases
- add dependency on COMPILE_TEST and ARCH_MICROCHIP

Regards,
Valentina

Valentina Fernandez (4):
  riscv: sbi: vendorid_list: Add Microchip Technology to the vendor list
  riscv: export __cpuid_to_hartid_map
  dt-bindings: mailbox: add binding for Microchip IPC mailbox controller
  mailbox: add Microchip IPC support

 .../bindings/mailbox/microchip,sbi-ipc.yaml   | 111 ++++
 arch/riscv/include/asm/vendorid_list.h        |   1 +
 arch/riscv/kernel/smp.c                       |   1 +
 drivers/mailbox/Kconfig                       |  13 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mailbox-mchp-ipc-sbi.c        | 504 ++++++++++++++++++
 include/linux/mailbox/mchp-ipc.h              |  33 ++
 7 files changed, 665 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
 create mode 100644 drivers/mailbox/mailbox-mchp-ipc-sbi.c
 create mode 100644 include/linux/mailbox/mchp-ipc.h

-- 
2.34.1



From valentina.fernandezalanis at microchip.com  Mon Nov 25 09:58:15 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Mon, 25 Nov 2024 17:58:15 +0000
Subject: [PATCH v4 1/4] riscv: sbi: vendorid_list: Add Microchip Technology to the vendor list
In-Reply-To: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
References: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
Message-ID: <20241125175818.213108-2-valentina.fernandezalanis@microchip.com>

Add Microchip Technology to the RISC-V vendor list.

Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
---
 arch/riscv/include/asm/vendorid_list.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h
index 2f2bb0c84f9a..a5150cdf34d8 100644
--- a/arch/riscv/include/asm/vendorid_list.h
+++ b/arch/riscv/include/asm/vendorid_list.h
@@ -6,6 +6,7 @@
 #define ASM_VENDOR_LIST_H
 
 #define ANDES_VENDOR_ID		0x31e
+#define MICROCHIP_VENDOR_ID	0x029
 #define SIFIVE_VENDOR_ID	0x489
 #define THEAD_VENDOR_ID		0x5b7
 
-- 
2.34.1



From valentina.fernandezalanis at microchip.com  Mon Nov 25 09:58:16 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Mon, 25 Nov 2024 17:58:16 +0000
Subject: [PATCH v4 2/4] riscv: export __cpuid_to_hartid_map
In-Reply-To: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
References: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
Message-ID: <20241125175818.213108-3-valentina.fernandezalanis@microchip.com>

EXPORT_SYMBOL_GPL() is missing for __cpuid_to_hartid_map array.
Export this symbol to allow drivers compiled as modules to use
cpuid_to_hartid_map().

Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
---
 arch/riscv/kernel/smp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index c180a647a30e..d58b5e751286 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -43,6 +43,7 @@ enum ipi_message_type {
 unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = {
 	[0 ... NR_CPUS-1] = INVALID_HARTID
 };
+EXPORT_SYMBOL_GPL(__cpuid_to_hartid_map);
 
 void __init smp_setup_processor_id(void)
 {
-- 
2.34.1



From valentina.fernandezalanis at microchip.com  Mon Nov 25 09:58:18 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Mon, 25 Nov 2024 17:58:18 +0000
Subject: [PATCH v4 4/4] mailbox: add Microchip IPC support
In-Reply-To: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
References: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
Message-ID: <20241125175818.213108-5-valentina.fernandezalanis@microchip.com>

Add a mailbox controller driver for the Microchip Inter-processor
Communication (IPC), which is used to send and receive data between
processors.

The driver uses the RISC-V Supervisor Binary Interface (SBI) to
communicate with software running in machine mode (M-mode) to access
the IPC hardware block.

Additional details on the Microchip vendor extension and the IPC
function IDs described in the driver can be found in the following
documentation:

https://github.com/linux4microchip/microchip-sbi-ecall-extension

This SBI interface in this driver is compatible with the Mi-V Inter-hart
Communication (IHC) IP.

Transmitting and receiving data through the mailbox framework is done
through struct mchp_ipc_msg.

Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
---
 drivers/mailbox/Kconfig                |  13 +
 drivers/mailbox/Makefile               |   2 +
 drivers/mailbox/mailbox-mchp-ipc-sbi.c | 504 +++++++++++++++++++++++++
 include/linux/mailbox/mchp-ipc.h       |  33 ++
 4 files changed, 552 insertions(+)
 create mode 100644 drivers/mailbox/mailbox-mchp-ipc-sbi.c
 create mode 100644 include/linux/mailbox/mchp-ipc.h

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 6fb995778636..a61b3b0c5da3 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -177,6 +177,19 @@ config POLARFIRE_SOC_MAILBOX
 
 	  If unsure, say N.
 
+config MCHP_SBI_IPC_MBOX
+	tristate "Microchip Inter-processor Communication (IPC) SBI driver"
+	depends on RISCV_SBI || COMPILE_TEST
+	depends on ARCH_MICROCHIP
+	help
+	  Mailbox implementation for Microchip devices with an
+	  Inter-process communication (IPC) controller.
+
+	  To compile this driver as a module, choose M here. the
+	  module will be called mailbox-mchp-ipc-sbi.
+
+	  If unsure, say N.
+
 config QCOM_APCS_IPC
 	tristate "Qualcomm APCS IPC driver"
 	depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 3c3c27d54c13..a78d1948e331 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -45,6 +45,8 @@ obj-$(CONFIG_BCM_FLEXRM_MBOX)	+= bcm-flexrm-mailbox.o
 
 obj-$(CONFIG_POLARFIRE_SOC_MAILBOX)	+= mailbox-mpfs.o
 
+obj-$(CONFIG_MCHP_SBI_IPC_MBOX)		+= mailbox-mchp-ipc-sbi.o
+
 obj-$(CONFIG_QCOM_APCS_IPC)	+= qcom-apcs-ipc-mailbox.o
 
 obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
diff --git a/drivers/mailbox/mailbox-mchp-ipc-sbi.c b/drivers/mailbox/mailbox-mchp-ipc-sbi.c
new file mode 100644
index 000000000000..a6e52009a424
--- /dev/null
+++ b/drivers/mailbox/mailbox-mchp-ipc-sbi.c
@@ -0,0 +1,504 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Microchip Inter-Processor communication (IPC) driver
+ *
+ * Copyright (c) 2021 - 2024 Microchip Technology Inc. All rights reserved.
+ *
+ * Author: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/of_device.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mailbox/mchp-ipc.h>
+#include <asm/sbi.h>
+#include <asm/vendorid_list.h>
+
+#define IRQ_STATUS_BITS			12
+#define NUM_CHANS_PER_CLUSTER		5
+#define IPC_DMA_BIT_MASK		32
+#define SBI_EXT_MICROCHIP_TECHNOLOGY	(SBI_EXT_VENDOR_START | \
+					 MICROCHIP_VENDOR_ID)
+
+enum {
+	SBI_EXT_IPC_PROBE = 0x100,
+	SBI_EXT_IPC_CH_INIT,
+	SBI_EXT_IPC_SEND,
+	SBI_EXT_IPC_RECEIVE,
+	SBI_EXT_IPC_STATUS,
+};
+
+enum ipc_hw {
+	MIV_IHC,
+};
+
+/**
+ * struct mchp_ipc_mbox_info - IPC probe message format
+ *
+ * @hw_type:		IPC implementation available in the hardware
+ * @num_channels:	number of IPC channels available in the hardware
+ *
+ * Used to retrieve information on the IPC implementation
+ * using the SBI_EXT_IPC_PROBE SBI function id.
+ */
+struct mchp_ipc_mbox_info {
+	enum ipc_hw hw_type;
+	u8 num_channels;
+};
+
+/**
+ * struct mchp_ipc_init - IPC channel init message format
+ *
+ * @max_msg_size:	maxmimum message size in bytes of a given channel
+ *
+ * struct used by the SBI_EXT_IPC_CH_INIT SBI function id to get
+ * the max message size in bytes of the initialized channel.
+ */
+struct mchp_ipc_init {
+	u16 max_msg_size;
+};
+
+/**
+ * struct mchp_ipc_status - IPC status message format
+ *
+ * @status:	interrupt status for all channels associated to a cluster
+ * @cluster:	specifies the cluster instance that originated an irq
+ *
+ * struct used by the SBI_EXT_IPC_STATUS SBI function id to get
+ * the message present and message clear interrupt status for all the
+ * channels associated to a cluster.
+ */
+struct mchp_ipc_status {
+	u32 status;
+	u8 cluster;
+};
+
+/**
+ * struct mchp_ipc_sbi_msg - IPC SBI payload message
+ *
+ * @buf_addr:	physical address where the received data should be copied to
+ * @size:	maximum size(in bytes) that can be stored in the buffer pointed to by `buf`
+ * @irq_type:	mask representing the irq types that triggered an irq
+ *
+ * struct used by the SBI_EXT_IPC_SEND/SBI_EXT_IPC_RECEIVE SBI function
+ * ids to send/receive a message from an associated processor using
+ * the IPC.
+ */
+struct mchp_ipc_sbi_msg {
+	u64 buf_addr;
+	u16 size;
+	u8 irq_type;
+};
+
+struct mchp_ipc_cluster_cfg {
+	void *buf_base;
+	phys_addr_t buf_base_addr;
+	int irq;
+};
+
+struct mchp_ipc_sbi_mbox {
+	struct device *dev;
+	struct mbox_chan *chans;
+	struct mchp_ipc_cluster_cfg *cluster_cfg;
+	void *buf_base;
+	unsigned long buf_base_addr;
+	struct mbox_controller controller;
+	enum ipc_hw hw_type;
+};
+
+static int mchp_ipc_sbi_chan_send(u32 command, u32 channel, unsigned long address)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_MICROCHIP_TECHNOLOGY, command, channel,
+			address, 0, 0, 0, 0);
+
+	if (ret.error)
+		return sbi_err_map_linux_errno(ret.error);
+	else
+		return ret.value;
+}
+
+static int mchp_ipc_sbi_send(u32 command, unsigned long address)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_MICROCHIP_TECHNOLOGY, command, address,
+			0, 0, 0, 0, 0);
+
+	if (ret.error)
+		return sbi_err_map_linux_errno(ret.error);
+	else
+		return ret.value;
+}
+
+static struct mchp_ipc_sbi_mbox *to_mchp_ipc_mbox(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mchp_ipc_sbi_mbox, controller);
+}
+
+static inline void mchp_ipc_prepare_receive_req(struct mbox_chan *chan)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+	struct mchp_ipc_sbi_msg request;
+
+	request.buf_addr = chan_info->msg_buf_rx_addr;
+	request.size = chan_info->max_msg_size;
+	memcpy(chan_info->buf_base_rx, &request, sizeof(struct mchp_ipc_sbi_msg));
+}
+
+static inline void mchp_ipc_process_received_data(struct mbox_chan *chan,
+						  struct mchp_ipc_msg *ipc_msg)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+	struct mchp_ipc_sbi_msg sbi_msg;
+
+	memcpy(&sbi_msg, chan_info->buf_base_rx, sizeof(struct mchp_ipc_sbi_msg));
+	ipc_msg->buf = (u32 *)chan_info->msg_buf_rx;
+	ipc_msg->size = sbi_msg.size;
+}
+
+static irqreturn_t mchp_ipc_cluster_aggr_isr(int irq, void *data)
+{
+	struct mbox_chan *chan;
+	struct mchp_ipc_sbi_chan *chan_info;
+	struct mchp_ipc_sbi_mbox *ipc = (struct mchp_ipc_sbi_mbox *)data;
+	struct mchp_ipc_msg ipc_msg;
+	struct mchp_ipc_status status_msg;
+	int ret;
+	unsigned long hartid;
+	u32 i, chan_index, chan_id;
+
+	/* Find out the hart that originated the irq */
+	for_each_online_cpu(i) {
+		hartid = cpuid_to_hartid_map(i);
+		if (irq == ipc->cluster_cfg[hartid].irq)
+			break;
+	}
+
+	status_msg.cluster = hartid;
+	memcpy(ipc->cluster_cfg[hartid].buf_base, &status_msg, sizeof(struct mchp_ipc_status));
+
+	ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[hartid].buf_base_addr);
+	if (ret < 0) {
+		dev_err_ratelimited(ipc->dev, "could not get IHC irq status ret=%d\n", ret);
+		return IRQ_HANDLED;
+	}
+
+	memcpy(&status_msg, ipc->cluster_cfg[hartid].buf_base, sizeof(struct mchp_ipc_status));
+
+	/*
+	 * Iterate over each bit set in the IHC interrupt status register (IRQ_STATUS) to identify
+	 * the channel(s) that have a message to be processed/acknowledged.
+	 * The bits are organized in alternating format, where each pair of bits represents
+	 * the status of the message present and message clear interrupts for each cluster/hart
+	 * (from hart 0 to hart 5). Each cluster can have up to 5 fixed channels associated.
+	 */
+
+	for_each_set_bit(i, (unsigned long *)&status_msg.status, IRQ_STATUS_BITS) {
+		/* Find out the destination hart that triggered the interrupt */
+		chan_index = i / 2;
+
+		/*
+		 * The IP has no loopback channels, so we need to decrement the index when
+		 * the target hart has a greater index than our own
+		 */
+		if (chan_index >= status_msg.cluster)
+			chan_index--;
+
+		/*
+		 * Calculate the channel id given the hart and channel index. Channel IDs
+		 * are unique across all clusters of an IPC, and iterate contiguously
+		 * across all clusters.
+		 */
+		chan_id = status_msg.cluster * (NUM_CHANS_PER_CLUSTER + chan_index);
+
+		chan = &ipc->chans[chan_id];
+		chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+
+		if (i % 2 == 0) {
+			mchp_ipc_prepare_receive_req(chan);
+			ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_RECEIVE, chan_id,
+						     chan_info->buf_base_rx_addr);
+			if (ret < 0)
+				continue;
+
+			mchp_ipc_process_received_data(chan, &ipc_msg);
+			mbox_chan_received_data(&ipc->chans[chan_id], (void *)&ipc_msg);
+
+		} else {
+			ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_RECEIVE, chan_id,
+						     chan_info->buf_base_rx_addr);
+			mbox_chan_txdone(&ipc->chans[chan_id], ret);
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static int mchp_ipc_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+	const struct mchp_ipc_msg *msg = data;
+	struct mchp_ipc_sbi_msg sbi_payload;
+
+	memcpy(chan_info->msg_buf_tx, msg->buf, msg->size);
+	sbi_payload.buf_addr = chan_info->msg_buf_tx_addr;
+	sbi_payload.size = msg->size;
+	memcpy(chan_info->buf_base_tx, &sbi_payload, sizeof(sbi_payload));
+
+	return mchp_ipc_sbi_chan_send(SBI_EXT_IPC_SEND, chan_info->id, chan_info->buf_base_tx_addr);
+}
+
+static int mchp_ipc_startup(struct mbox_chan *chan)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+	struct mchp_ipc_sbi_mbox *ipc = to_mchp_ipc_mbox(chan->mbox);
+	struct mchp_ipc_init ch_init_msg;
+	int ret;
+
+	/*
+	 * The TX base buffer is used to transmit two types of messages:
+	 * - struct mchp_ipc_init to initialize the channel
+	 * - struct mchp_ipc_sbi_msg to transmit user data/payload
+	 * Ensure the TX buffer size is large enough to accommodate either message type.
+	 */
+	size_t max_size = max(sizeof(struct mchp_ipc_init), sizeof(struct mchp_ipc_sbi_msg));
+
+	chan_info->buf_base_tx = kmalloc(max_size, GFP_KERNEL);
+	if (!chan_info->buf_base_tx) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	chan_info->buf_base_tx_addr = __pa(chan_info->buf_base_tx);
+
+	chan_info->buf_base_rx = kmalloc(max_size, GFP_KERNEL);
+	if (!chan_info->buf_base_rx) {
+		ret = -ENOMEM;
+		goto fail_free_buf_base_tx;
+	}
+
+	chan_info->buf_base_rx_addr = __pa(chan_info->buf_base_rx);
+
+	ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_CH_INIT, chan_info->id,
+				     chan_info->buf_base_tx_addr);
+	if (ret < 0) {
+		dev_err(ipc->dev, "channel %u init failed\n", chan_info->id);
+		goto fail_free_buf_base_rx;
+	}
+
+	memcpy(&ch_init_msg, chan_info->buf_base_tx, sizeof(struct mchp_ipc_init));
+	chan_info->max_msg_size = ch_init_msg.max_msg_size;
+
+	chan_info->msg_buf_tx = kmalloc(chan_info->max_msg_size, GFP_KERNEL);
+	if (!chan_info->msg_buf_tx) {
+		ret = -ENOMEM;
+		goto fail_free_buf_base_rx;
+	}
+
+	chan_info->msg_buf_tx_addr = __pa(chan_info->msg_buf_tx);
+
+	chan_info->msg_buf_rx = kmalloc(chan_info->max_msg_size, GFP_KERNEL);
+	if (!chan_info->msg_buf_rx) {
+		ret = -ENOMEM;
+		goto fail_free_buf_msg_tx;
+	}
+
+	chan_info->msg_buf_rx_addr = __pa(chan_info->msg_buf_rx);
+
+	switch (ipc->hw_type) {
+	case MIV_IHC:
+		return 0;
+	default:
+		goto fail_free_buf_msg_rx;
+	}
+
+	if (ret) {
+		dev_err(ipc->dev, "failed to register interrupt(s)\n");
+		goto fail_free_buf_msg_rx;
+	}
+
+	return ret;
+
+fail_free_buf_msg_rx:
+	kfree(chan_info->msg_buf_rx);
+fail_free_buf_msg_tx:
+	kfree(chan_info->msg_buf_tx);
+fail_free_buf_base_rx:
+	kfree(chan_info->buf_base_rx);
+fail_free_buf_base_tx:
+	kfree(chan_info->buf_base_tx);
+fail:
+	return ret;
+}
+
+static void mchp_ipc_shutdown(struct mbox_chan *chan)
+{
+	struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv;
+
+	kfree(chan_info->buf_base_tx);
+	kfree(chan_info->buf_base_rx);
+	kfree(chan_info->msg_buf_tx);
+	kfree(chan_info->msg_buf_rx);
+}
+
+static const struct mbox_chan_ops mchp_ipc_ops = {
+	.startup = mchp_ipc_startup,
+	.send_data = mchp_ipc_send_data,
+	.shutdown = mchp_ipc_shutdown,
+};
+
+static struct mbox_chan *mchp_ipc_mbox_xlate(struct mbox_controller *controller,
+					     const struct of_phandle_args *spec)
+{
+	struct mchp_ipc_sbi_mbox *ipc = to_mchp_ipc_mbox(controller);
+	unsigned int chan_id = spec->args[0];
+
+	if (chan_id >= ipc->controller.num_chans) {
+		dev_err(ipc->dev, "invalid channel id %d\n", chan_id);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return &ipc->chans[chan_id];
+}
+
+static int mchp_ipc_get_cluster_aggr_irq(struct mchp_ipc_sbi_mbox *ipc)
+{
+	struct platform_device *pdev = to_platform_device(ipc->dev);
+	char *irq_name;
+	int cpuid, ret;
+	unsigned long hartid;
+	bool irq_found = false;
+
+	for_each_online_cpu(cpuid) {
+		hartid = cpuid_to_hartid_map(cpuid);
+		irq_name = devm_kasprintf(ipc->dev, GFP_KERNEL, "hart-%lu", hartid);
+		ret = platform_get_irq_byname_optional(pdev, irq_name);
+		if (ret <= 0)
+			continue;
+
+		ipc->cluster_cfg[hartid].irq = ret;
+		ret = devm_request_irq(ipc->dev, ipc->cluster_cfg[hartid].irq,
+				       mchp_ipc_cluster_aggr_isr, IRQF_SHARED,
+				       "miv-ihc-irq", ipc);
+		if (ret)
+			return ret;
+
+		ipc->cluster_cfg[hartid].buf_base = devm_kmalloc(ipc->dev,
+								 sizeof(struct mchp_ipc_status),
+								 GFP_KERNEL);
+
+		if (!ipc->cluster_cfg[hartid].buf_base)
+			return -ENOMEM;
+
+		ipc->cluster_cfg[hartid].buf_base_addr = __pa(ipc->cluster_cfg[hartid].buf_base);
+
+		irq_found = true;
+	}
+
+	return irq_found;
+}
+
+static int mchp_ipc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mchp_ipc_mbox_info ipc_info;
+	struct mchp_ipc_sbi_mbox *ipc;
+	struct mchp_ipc_sbi_chan *priv;
+	bool irq_avail = false;
+	int ret;
+	u32 chan_id;
+
+	ret = sbi_probe_extension(SBI_EXT_MICROCHIP_TECHNOLOGY);
+	if (ret <= 0)
+		return dev_err_probe(dev, ret, "Microchip SBI extension not detected\n");
+
+	ipc = devm_kzalloc(dev, sizeof(*ipc), GFP_KERNEL);
+	if (!ipc)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ipc);
+
+	ipc->buf_base = devm_kmalloc(dev, sizeof(struct mchp_ipc_mbox_info), GFP_KERNEL);
+	if (!ipc->buf_base)
+		return -ENOMEM;
+
+	ipc->buf_base_addr = __pa(ipc->buf_base);
+
+	ret = mchp_ipc_sbi_send(SBI_EXT_IPC_PROBE, ipc->buf_base_addr);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "could not probe IPC SBI service\n");
+
+	memcpy(&ipc_info, ipc->buf_base, sizeof(struct mchp_ipc_mbox_info));
+	ipc->controller.num_chans = ipc_info.num_channels;
+	ipc->hw_type = ipc_info.hw_type;
+
+	ipc->chans = devm_kcalloc(dev, ipc->controller.num_chans, sizeof(*ipc->chans), GFP_KERNEL);
+	if (!ipc->chans)
+		return -ENOMEM;
+
+	ipc->dev = dev;
+	ipc->controller.txdone_irq = true;
+	ipc->controller.dev = ipc->dev;
+	ipc->controller.ops = &mchp_ipc_ops;
+	ipc->controller.chans = ipc->chans;
+	ipc->controller.of_xlate = mchp_ipc_mbox_xlate;
+
+	for (chan_id = 0; chan_id < ipc->controller.num_chans; chan_id++) {
+		priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
+		if (!priv)
+			return -ENOMEM;
+
+		ipc->chans[chan_id].con_priv = priv;
+		priv->id = chan_id;
+	}
+
+	if (ipc->hw_type == MIV_IHC) {
+		ipc->cluster_cfg = devm_kcalloc(dev, num_online_cpus(),
+						sizeof(struct mchp_ipc_cluster_cfg),
+						GFP_KERNEL);
+		if (!ipc->cluster_cfg)
+			return -ENOMEM;
+
+		if (mchp_ipc_get_cluster_aggr_irq(ipc))
+			irq_avail = true;
+	}
+
+	if (!irq_avail)
+		return dev_err_probe(dev, -ENODEV, "missing interrupt property\n");
+
+	ret = devm_mbox_controller_register(dev, &ipc->controller);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				    "Inter-Processor communication (IPC) registration failed\n");
+
+	return 0;
+}
+
+static const struct of_device_id mchp_ipc_of_match[] = {
+	{.compatible = "microchip,sbi-ipc", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, mchp_ipc_of_match);
+
+static struct platform_driver mchp_ipc_driver = {
+	.driver = {
+		.name = "microchip_ipc",
+		.of_match_table = mchp_ipc_of_match,
+	},
+	.probe = mchp_ipc_probe,
+};
+
+module_platform_driver(mchp_ipc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Valentina Fernandez <valentina.fernandezalanis at microchip.com>");
+MODULE_DESCRIPTION("Microchip Inter-Processor Communication (IPC) driver");
diff --git a/include/linux/mailbox/mchp-ipc.h b/include/linux/mailbox/mchp-ipc.h
new file mode 100644
index 000000000000..f084ac9e291b
--- /dev/null
+++ b/include/linux/mailbox/mchp-ipc.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *Copyright (c) 2024 Microchip Technology Inc. All rights reserved.
+ */
+
+#ifndef _LINUX_MCHP_IPC_H_
+#define _LINUX_MCHP_IPC_H_
+
+#include <linux/mailbox_controller.h>
+#include <linux/types.h>
+
+struct mchp_ipc_msg {
+	u32 *buf;
+	u16 size;
+};
+
+struct mchp_ipc_sbi_chan {
+	void *buf_base_tx;
+	void *buf_base_rx;
+	void *msg_buf_tx;
+	void *msg_buf_rx;
+	phys_addr_t buf_base_tx_addr;
+	phys_addr_t buf_base_rx_addr;
+	phys_addr_t msg_buf_tx_addr;
+	phys_addr_t msg_buf_rx_addr;
+	int chan_aggregated_irq;
+	int mp_irq;
+	int mc_irq;
+	u32 id;
+	u32 max_msg_size;
+};
+
+#endif /* _LINUX_MCHP_IPC_H_ */
-- 
2.34.1



From valentina.fernandezalanis at microchip.com  Mon Nov 25 09:58:17 2024
From: valentina.fernandezalanis at microchip.com (Valentina Fernandez)
Date: Mon, 25 Nov 2024 17:58:17 +0000
Subject: [PATCH v4 3/4] dt-bindings: mailbox: add binding for Microchip IPC mailbox controller
In-Reply-To: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
References: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
Message-ID: <20241125175818.213108-4-valentina.fernandezalanis@microchip.com>

Add a dt-binding for the Microchip Inter-Processor Communication (IPC)
mailbox controller.

Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
---
 .../bindings/mailbox/microchip,sbi-ipc.yaml   | 111 ++++++++++++++++++
 1 file changed, 111 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml b/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
new file mode 100644
index 000000000000..b69af85ec608
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
@@ -0,0 +1,111 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/microchip,sbi-ipc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip Inter-processor communication (IPC) mailbox controller
+
+maintainers:
+  - Valentina Fernandez <valentina.fernandezalanis at microchip.com>
+
+description:
+  The Microchip Inter-processor Communication (IPC) facilitates
+  message passing between processors using an interrupt signaling
+  mechanism.
+
+properties:
+  compatible:
+    oneOf:
+      - description:
+          Intended for use by software running in supervisor privileged
+          mode (s-mode). This SBI interface is compatible with the Mi-V
+          Inter-hart Communication (IHC) IP.
+        const: microchip,sbi-ipc
+
+      - description:
+          Intended for use by the SBI implementation in machine mode
+          (m-mode), this compatible string is for the MIV_IHC Soft-IP.
+        const: microchip,miv-ihc-rtl-v2
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 5
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 5
+    items:
+      pattern: "^hart-[0-5]+$"
+
+  "#mbox-cells":
+    description: >
+      For "microchip,sbi-ipc", the cell represents the global "logical"
+      channel IDs. The meaning of channel IDs are platform firmware dependent.
+
+      For "microchip,miv-ihc-rtl-v2", the cell represents the physical
+      channel and does not vary based on the platform firmware.
+    const: 1
+
+  microchip,ihc-chan-disabled-mask:
+    description: >
+      Represents the enable/disable state of the bi-directional IHC
+      channels within the MIV-IHC IP configuration.
+
+      A bit set to '1' indicates that the corresponding channel is disabled,
+      and any read or write operations to that channel will return zero.
+
+      A bit set to '0' indicates that the corresponding channel is enabled
+      and will be accessible through its dedicated address range registers.
+
+      The actual enable/disable state of each channel is determined by the
+      IP block?s configuration.
+    $ref: /schemas/types.yaml#/definitions/uint16
+    maximum: 0x7fff
+    default: 0
+
+required:
+  - compatible
+  - interrupts
+  - interrupt-names
+  - "#mbox-cells"
+
+additionalProperties: false
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: microchip,sbi-ipc
+    then:
+      properties:
+        reg: false
+        microchip,ihc-chan-disabled-mask: false
+    else:
+      required:
+        - reg
+        - microchip,ihc-chan-disabled-mask
+
+examples:
+  - |
+    mailbox {
+      compatible = "microchip,sbi-ipc";
+      interrupt-parent = <&plic>;
+      interrupts = <180>, <179>, <178>;
+      interrupt-names = "hart-1", "hart-2", "hart-3";
+      #mbox-cells = <1>;
+    };
+  - |
+    mailbox at 50000000 {
+      compatible = "microchip,miv-ihc-rtl-v2";
+      microchip,ihc-chan-disabled-mask = /bits/ 16 <0>;
+      reg = <0x50000000 0x1C000>;
+      interrupt-parent = <&plic>;
+      interrupts = <180>, <179>, <178>;
+      interrupt-names = "hart-1", "hart-2", "hart-3";
+      #mbox-cells = <1>;
+    };
-- 
2.34.1



From advaitdhamorikar at gmail.com  Mon Nov 25 11:10:09 2024
From: advaitdhamorikar at gmail.com (Advait Dhamorikar)
Date: Tue, 26 Nov 2024 00:40:09 +0530
Subject: [PATCH-next] mailbox: th1520: Fix out of bounds write
Message-ID: <20241125191009.28535-1-advaitdhamorikar@gmail.com>

The loop in the function iterates up to `TH_1520_MBOX_CHANS`,
but the `ctx->intr_mask` array only has 3 elements. When 
`TH_1520_MBOX_CHANS` is set to a value larger than 3, this
causes an out-of-bounds write at `ctx->intr_mask[3]`.
This could cause an immediate crash or incorrect computations.

Signed-off-by: Advait Dhamorikar <advaitdhamorikar at gmail.com>
---
 drivers/mailbox/mailbox-th1520.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mailbox/mailbox-th1520.c b/drivers/mailbox/mailbox-th1520.c
index 4e84640ac3b8..759634a4fb72 100644
--- a/drivers/mailbox/mailbox-th1520.c
+++ b/drivers/mailbox/mailbox-th1520.c
@@ -532,6 +532,9 @@ static int __maybe_unused th1520_mbox_suspend_noirq(struct device *dev)
 	 * INFO data all assumed to be lost.
 	 */
 	for (i = 0; i < TH_1520_MBOX_CHANS; i++) {
+		if (i >= ARRAY_SIZE(ctx->intr_mask))
+			break;
+
 		ctx->intr_mask[i] =
 			ioread32(priv->local_icu[i] + TH_1520_MBOX_MASK);
 	}
-- 
2.34.1



From debug at rivosinc.com  Mon Nov 25 16:08:23 2024
From: debug at rivosinc.com (Deepak Gupta)
Date: Mon, 25 Nov 2024 16:08:23 -0800
Subject: [PATCH v2 3/7] riscv: convert bottom half of exception handling
 to C
In-Reply-To: <20240720171232.1753-4-jszhang@kernel.org>
References: <20240720171232.1753-1-jszhang@kernel.org>
 <20240720171232.1753-4-jszhang@kernel.org>
Message-ID: <Z0URd1oF6FnJGXa8@debug.ba.rivosinc.com>

On Sun, Jul 21, 2024 at 01:12:28AM +0800, Jisheng Zhang wrote:
>For readability, maintainability and future scalability, convert the
>bottom half of the exception handling to C.
>
>Mostly the assembly code is converted to C in a relatively
>straightforward manner.
>
>However, there are two modifications I need to mention:
>
>1. the cause I.E the CSR_CAUSE value is passed to do_traps() via. 2nd
>param, do_traps() doesn't get it from pt_regs because this way an extra
>memory load is needed, the exception handling sits in hot code path,
>every instruction matters.
>
>2.To cope with SIFIVE_CIP_453 errata, it looks like we don't need
>alternative mechanism any more after the asm->c conversion. Just
>replace the excp_vect_table two entries.
>
>Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
>---
> arch/riscv/errata/sifive/errata.c       | 25 ++++++++---
> arch/riscv/include/asm/asm-prototypes.h |  1 +
> arch/riscv/include/asm/errata_list.h    |  5 +--
> arch/riscv/kernel/entry.S               | 57 +------------------------
> arch/riscv/kernel/traps.c               | 37 ++++++++++++++++
> 5 files changed, 61 insertions(+), 64 deletions(-)
>
Sorry for noticing it so late. And thanks to Bjorn for pointing it out.
lgtm.

Reviewed-by: Deepak Gupta <debug at rivosinc.com>



From krzk at kernel.org  Mon Nov 25 23:04:38 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Nov 2024 08:04:38 +0100
Subject: [PATCH v4 3/4] dt-bindings: mailbox: add binding for Microchip
 IPC mailbox controller
In-Reply-To: <20241125175818.213108-4-valentina.fernandezalanis@microchip.com>
References: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
 <20241125175818.213108-4-valentina.fernandezalanis@microchip.com>
Message-ID: <vkw7o25szfn2upi5776xdojg5n5fxxaxwynth5kynjwjqzrgua@5lwrjqgzlxzi>

On Mon, Nov 25, 2024 at 05:58:17PM +0000, Valentina Fernandez wrote:
> Add a dt-binding for the Microchip Inter-Processor Communication (IPC)
> mailbox controller.
> 
> Signed-off-by: Valentina Fernandez <valentina.fernandezalanis at microchip.com>
> ---
>  .../bindings/mailbox/microchip,sbi-ipc.yaml   | 111 ++++++++++++++++++
>  1 file changed, 111 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml b/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
> new file mode 100644
> index 000000000000..b69af85ec608
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.yaml
> @@ -0,0 +1,111 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mailbox/microchip,sbi-ipc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Microchip Inter-processor communication (IPC) mailbox controller
> +
> +maintainers:
> +  - Valentina Fernandez <valentina.fernandezalanis at microchip.com>
> +
> +description:
> +  The Microchip Inter-processor Communication (IPC) facilitates
> +  message passing between processors using an interrupt signaling
> +  mechanism.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - description:
> +          Intended for use by software running in supervisor privileged
> +          mode (s-mode). This SBI interface is compatible with the Mi-V
> +          Inter-hart Communication (IHC) IP.
> +        const: microchip,sbi-ipc
> +
> +      - description:
> +          Intended for use by the SBI implementation in machine mode
> +          (m-mode), this compatible string is for the MIV_IHC Soft-IP.
> +        const: microchip,miv-ihc-rtl-v2
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    minItems: 1
> +    maxItems: 5
> +
> +  interrupt-names:
> +    minItems: 1
> +    maxItems: 5
> +    items:
> +      pattern: "^hart-[0-5]+$"

Why hart-0 and hart-5555 are allowed? I thought you have only 5
interrupts. List them instead of pattern, five is small enough still.

> +
> +  "#mbox-cells":
> +    description: >
> +      For "microchip,sbi-ipc", the cell represents the global "logical"
> +      channel IDs. The meaning of channel IDs are platform firmware dependent.
> +
> +      For "microchip,miv-ihc-rtl-v2", the cell represents the physical
> +      channel and does not vary based on the platform firmware.
> +    const: 1
> +
> +  microchip,ihc-chan-disabled-mask:
> +    description: >
> +      Represents the enable/disable state of the bi-directional IHC
> +      channels within the MIV-IHC IP configuration.
> +
> +      A bit set to '1' indicates that the corresponding channel is disabled,
> +      and any read or write operations to that channel will return zero.
> +
> +      A bit set to '0' indicates that the corresponding channel is enabled
> +      and will be accessible through its dedicated address range registers.
> +
> +      The actual enable/disable state of each channel is determined by the
> +      IP block?s configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint16
> +    maximum: 0x7fff
> +    default: 0
> +
> +required:
> +  - compatible
> +  - interrupts
> +  - interrupt-names
> +  - "#mbox-cells"
> +
> +additionalProperties: false

This goes after allOf: block

> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: microchip,sbi-ipc
> +    then:
> +      properties:
> +        reg: false

What does this mean in reality? Device does not have IO address space?
Then it is completely different programming model, isn't it?

> +        microchip,ihc-chan-disabled-mask: false
> +    else:
> +      required:
> +        - reg
> +        - microchip,ihc-chan-disabled-mask
> +
> +examples:
> +  - |
> +    mailbox {
> +      compatible = "microchip,sbi-ipc";
> +      interrupt-parent = <&plic>;
> +      interrupts = <180>, <179>, <178>;
> +      interrupt-names = "hart-1", "hart-2", "hart-3";
> +      #mbox-cells = <1>;
> +    };
> +  - |
> +    mailbox at 50000000 {
> +      compatible = "microchip,miv-ihc-rtl-v2";
> +      microchip,ihc-chan-disabled-mask = /bits/ 16 <0>;
> +      reg = <0x50000000 0x1C000>;

Lowercase hex.

> +      interrupt-parent = <&plic>;
> +      interrupts = <180>, <179>, <178>;
> +      interrupt-names = "hart-1", "hart-2", "hart-3";
> +      #mbox-cells = <1>;
> +    };
> -- 
> 2.34.1
> 


From e at freeshell.de  Mon Nov 25 23:38:17 2024
From: e at freeshell.de (E Shattow)
Date: Mon, 25 Nov 2024 23:38:17 -0800
Subject: [PATCH v3 1/1] riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function
In-Reply-To: <20241126073836.17208-1-e@freeshell.de>
References: <20241126073836.17208-1-e@freeshell.de>
Message-ID: <20241126073836.17208-2-e@freeshell.de>

Pine64 Star64 set JH7110 on-chip USB host mode and vbus pin assignment

Signed-off-by: E Shattow <e at freeshell.de>
---
 .../boot/dts/starfive/jh7110-pine64-star64.dts | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
index fe4a490ecc61..b764d4d92fd9 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
@@ -80,7 +80,23 @@ &spi0 {
 	status = "okay";
 };
 
+&sysgpio {
+	usb0_pins: usb0-0 {
+		vbus-pins {
+			pinmux = <GPIOMUX(25,  GPOUT_SYS_USB_DRIVE_VBUS,
+					       GPOEN_ENABLE,
+					       GPI_NONE)>;
+			bias-disable;
+			input-disable;
+			input-schmitt-disable;
+			slew-rate = <0>;
+		};
+	};
+};
+
 &usb0 {
-	dr_mode = "peripheral";
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins>;
 	status = "okay";
 };
-- 
2.45.2



From e at freeshell.de  Mon Nov 25 23:38:16 2024
From: e at freeshell.de (E Shattow)
Date: Mon, 25 Nov 2024 23:38:16 -0800
Subject: [PATCH v3 0/1] riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function
Message-ID: <20241126073836.17208-1-e@freeshell.de>

Enable host mode JH7110 on-chip USB for Pine64 Star64 by setting host mode 
and connect vbus pinctrl.

This functionality depends on setting the USB over-current register to 
disable at bootloader phase, for example U-Boot:
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no 
change in functional outcome with this patch applied; there is an error 
visible to the user and this usb configuration fails (same as it is now).

Changes since v2:
 - Rebase on latest master

Changes since v1:
 - Rebase on linux-next/master
 - use tabs for code indent

E Shattow (1):
  riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function

 .../boot/dts/starfive/jh7110-pine64-star64.dts | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

-- 
2.45.2



From e at freeshell.de  Mon Nov 25 23:57:24 2024
From: e at freeshell.de (E Shattow)
Date: Mon, 25 Nov 2024 23:57:24 -0800
Subject: [PATCH v5 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
Message-ID: <20241126075740.17419-1-e@freeshell.de>

Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host mode
and connect vbus pinctrl.

This functionality depends on setting the USB over-current register to 
disable at bootloader phase, for example U-Boot:
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no 
change in functional outcome with this patch applied; there is an error 
visible to the user and this additional usb configuration fails (same as
it is now). On Milk-V Mars with four USB-A ports this applies to one of the 
ports and the remaining three VL805-connected ports via PCIe are not changed.

Changes since v4:
 - Rebase on latest master

Changes since v3:
 - Rebase on linux-next/master
 - use tabs for code indent

Changes since v2:
 - Rebase on 6.12

E Shattow (1):
  riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function

 .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

-- 
2.45.2



From e at freeshell.de  Mon Nov 25 23:57:25 2024
From: e at freeshell.de (E Shattow)
Date: Mon, 25 Nov 2024 23:57:25 -0800
Subject: [PATCH v5 1/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
In-Reply-To: <20241126075740.17419-1-e@freeshell.de>
References: <20241126075740.17419-1-e@freeshell.de>
Message-ID: <20241126075740.17419-2-e@freeshell.de>

Milk-V Mars set JH7110 on-chip USB host mode and vbus pin assignment

Signed-off-by: E Shattow <e at freeshell.de>
---
 .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
index 0d248b671d4b..3bd62ab78523 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -53,7 +53,23 @@ &spi0 {
 	status = "okay";
 };
 
+&sysgpio {
+	usb0_pins: usb0-0 {
+		vbus-pins {
+			pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS,
+					      GPOEN_ENABLE,
+					      GPI_NONE)>;
+			bias-disable;
+			input-disable;
+			input-schmitt-disable;
+			slew-rate = <0>;
+		};
+	};
+};
+
 &usb0 {
-	dr_mode = "peripheral";
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins>;
 	status = "okay";
 };
-- 
2.45.2



From heylenay at 4d2.org  Tue Nov 26 06:31:23 2024
From: heylenay at 4d2.org (Haylen Chu)
Date: Tue, 26 Nov 2024 14:31:23 +0000
Subject: [PATCH v3 0/3] Add clock controller support for Spacemit K1
Message-ID: <20241126143125.9980-2-heylenay@4d2.org>

The clock tree of Spacemit K1 is managed by several independent
controllers in different SoC parts. In this series, all clock hardwares
in APBS, MPMU, APBC and APMU, are implemented. With some changes to UART
driver, CPU cores and UARTs could be brought up (see below). More clocks
will be implemented later soon.

No device tree changes are included since Spacemit K1 UART needs two
clocks to operate, but for now the driver gets only one. I would like to
defer the changes until this is resolved.

This driver has been tested on BananaPi-F3 board and successfully
brought up I2C, RTC, mmc and ethernet controllers. A clock tree dump
could be obtained here[1].

[1]: https://gist.github.com/heylenayy/ebc6316692dd3aff56575dbf0eb4f1a9

Link: https://developer.spacemit.com/documentation?token=LCrKwWDasiJuROkVNusc2pWTnEb

Changed from v2
- dt-binding fixes
- misc improvements in code
- drop unnecessary spinlock in the driver
- implement missing bus clocks
- Link to v2: https://lore.kernel.org/all/SEYPR01MB4221829A2CD4D4C1704BABD7D7602 at SEYPR01MB4221.apcprd01.prod.exchangelabs.com/

Changed from v1
- add SoC prefix (k1)
- relicense dt-binding header
- misc fixes and style improvements for dt-binding
- document spacemit,k1-syscon
- implement all APBS, MPMU, APBC and APMU clocks
- code cleanup
- Link to v1: https://lore.kernel.org/all/SEYPR01MB4221B3178F5233EAB5149E41D7902 at SEYPR01MB4221.apcprd01.prod.exchangelabs.com/

Haylen Chu (3):
  dt-bindings: clock: spacemit: Add clock controllers of Spacemit K1 SoC
  dt-bindings: soc: spacemit: Add spacemit,k1-syscon
  clk: spacemit: Add clock support for Spacemit K1 SoC

 .../bindings/clock/spacemit,k1-ccu.yaml       |   57 +
 .../soc/spacemit/spacemit,k1-syscon.yaml      |   86 +
 drivers/clk/Kconfig                           |    1 +
 drivers/clk/Makefile                          |    1 +
 drivers/clk/spacemit/Kconfig                  |   20 +
 drivers/clk/spacemit/Makefile                 |    5 +
 drivers/clk/spacemit/ccu-k1.c                 | 1747 +++++++++++++++++
 drivers/clk/spacemit/ccu_common.h             |   62 +
 drivers/clk/spacemit/ccu_ddn.c                |  146 ++
 drivers/clk/spacemit/ccu_ddn.h                |   85 +
 drivers/clk/spacemit/ccu_mix.c                |  296 +++
 drivers/clk/spacemit/ccu_mix.h                |  336 ++++
 drivers/clk/spacemit/ccu_pll.c                |  198 ++
 drivers/clk/spacemit/ccu_pll.h                |   80 +
 include/dt-bindings/clock/spacemit,k1-ccu.h   |  246 +++
 15 files changed, 3366 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
 create mode 100644 drivers/clk/spacemit/Kconfig
 create mode 100644 drivers/clk/spacemit/Makefile
 create mode 100644 drivers/clk/spacemit/ccu-k1.c
 create mode 100644 drivers/clk/spacemit/ccu_common.h
 create mode 100644 drivers/clk/spacemit/ccu_ddn.c
 create mode 100644 drivers/clk/spacemit/ccu_ddn.h
 create mode 100644 drivers/clk/spacemit/ccu_mix.c
 create mode 100644 drivers/clk/spacemit/ccu_mix.h
 create mode 100644 drivers/clk/spacemit/ccu_pll.c
 create mode 100644 drivers/clk/spacemit/ccu_pll.h
 create mode 100644 include/dt-bindings/clock/spacemit,k1-ccu.h


base-commit: 2d5404caa8c7bb5c4e0435f94b28834ae5456623
prerequisite-patch-id: 47dcf6861f7d434d25855b379e6d7ef4ce369c9c
prerequisite-patch-id: 77787fe82911923aff15ccf565e8fa451538c3a6
prerequisite-patch-id: b0bdb1742d96c5738f05262c3b0059102761390b
prerequisite-patch-id: 3927d39d8d77e35d5bfe53d9950da574ff8f2054
prerequisite-patch-id: a98039136a4796252a6029e474f03906f2541643
prerequisite-patch-id: c95f6dc0547a2a63a76e3cba0cf5c623b212b4e6
prerequisite-patch-id: 66e750e438ee959ddc2a6f0650814a2d8c989139
prerequisite-patch-id: 29a0fd8c36c1a4340f0d0b68a4c34d2b8abfb1ab
prerequisite-patch-id: 0bdfff661c33c380d1cf00a6c68688e05f88c0b3
prerequisite-patch-id: 99f15718e0bfbb7ed1a96dfa19f35841b004dae9
-- 
2.47.0



From heylenay at 4d2.org  Tue Nov 26 06:31:24 2024
From: heylenay at 4d2.org (Haylen Chu)
Date: Tue, 26 Nov 2024 14:31:24 +0000
Subject: [PATCH v3 1/3] dt-bindings: clock: spacemit: Add clock controllers of Spacemit K1 SoC
In-Reply-To: <20241126143125.9980-2-heylenay@4d2.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
Message-ID: <20241126143125.9980-3-heylenay@4d2.org>

Add definition for the clock controllers of Spacemit K1 SoC. The clock
tree is managed by several SoC parts thus different compatible strings
are introduced for each.

Signed-off-by: Haylen Chu <heylenay at 4d2.org>
---
 .../bindings/clock/spacemit,k1-ccu.yaml       |  57 ++++
 include/dt-bindings/clock/spacemit,k1-ccu.h   | 246 ++++++++++++++++++
 2 files changed, 303 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml
 create mode 100644 include/dt-bindings/clock/spacemit,k1-ccu.h

diff --git a/Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml b/Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml
new file mode 100644
index 000000000000..9a12ac29c6e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/spacemit,k1-ccu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Spacemit K1 SoC Clock Controller
+
+maintainers:
+  - Haylen Chu <heylenay at 4d2.org>
+
+properties:
+  compatible:
+    enum:
+      - spacemit,k1-ccu-apbs
+      - spacemit,k1-ccu-mpmu
+      - spacemit,k1-ccu-apbc
+      - spacemit,k1-ccu-apmu
+
+  clocks:
+    maxItems: 4
+
+  clock-names:
+    items:
+      - const: osc_32k
+      - const: vctcxo_1m
+      - const: vctcxo_3m
+      - const: vctcxo_24m
+
+  spacemit,mpmu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon managing "Main PMU (MPMU)" registers. It is used to
+      check PLL lock status.
+
+  "#clock-cells":
+    const: 1
+    description:
+      See <dt-bindings/clock/spacemit,k1-ccu.h> for valid indices.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: spacemit,k1-ccu-apbs
+    then:
+      required:
+        - spacemit,mpmu
+
+additionalProperties: false
diff --git a/include/dt-bindings/clock/spacemit,k1-ccu.h b/include/dt-bindings/clock/spacemit,k1-ccu.h
new file mode 100644
index 000000000000..71760355b304
--- /dev/null
+++ b/include/dt-bindings/clock/spacemit,k1-ccu.h
@@ -0,0 +1,246 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2024 Haylen Chu <heylenay at outlook.com>
+ */
+
+#ifndef _DT_BINDINGS_SPACEMIT_CCU_H_
+#define _DT_BINDINGS_SPACEMIT_CCU_H_
+
+/*	APBS clocks	*/
+#define CLK_PLL1		0
+#define CLK_PLL2		1
+#define CLK_PLL3		2
+#define CLK_PLL1_D2		3
+#define CLK_PLL1_D3		4
+#define CLK_PLL1_D4		5
+#define CLK_PLL1_D5		6
+#define CLK_PLL1_D6		7
+#define CLK_PLL1_D7		8
+#define CLK_PLL1_D8		9
+#define CLK_PLL1_D11		10
+#define CLK_PLL1_D13		11
+#define CLK_PLL1_D23		12
+#define CLK_PLL1_D64		13
+#define CLK_PLL1_D10_AUD	14
+#define CLK_PLL1_D100_AUD	15
+#define CLK_PLL2_D1		16
+#define CLK_PLL2_D2		17
+#define CLK_PLL2_D3		18
+#define CLK_PLL2_D4		19
+#define CLK_PLL2_D5		20
+#define CLK_PLL2_D6		21
+#define CLK_PLL2_D7		22
+#define CLK_PLL2_D8		23
+#define CLK_PLL3_D1		24
+#define CLK_PLL3_D2		25
+#define CLK_PLL3_D3		26
+#define CLK_PLL3_D4		27
+#define CLK_PLL3_D5		28
+#define CLK_PLL3_D6		29
+#define CLK_PLL3_D7		30
+#define CLK_PLL3_D8		31
+#define CLK_PLL3_80		32
+#define CLK_PLL3_40		33
+#define CLK_PLL3_20		34
+#define CLK_APBS_NUM		35
+
+/*	MPMU clocks	*/
+#define CLK_PLL1_307P2		0
+#define CLK_PLL1_76P8		1
+#define CLK_PLL1_61P44		2
+#define CLK_PLL1_153P6		3
+#define CLK_PLL1_102P4		4
+#define CLK_PLL1_51P2		5
+#define CLK_PLL1_51P2_AP	6
+#define CLK_PLL1_57P6		7
+#define CLK_PLL1_25P6		8
+#define CLK_PLL1_12P8		9
+#define CLK_PLL1_12P8_WDT	10
+#define CLK_PLL1_6P4		11
+#define CLK_PLL1_3P2		12
+#define CLK_PLL1_1P6		13
+#define CLK_PLL1_0P8		14
+#define CLK_PLL1_351		15
+#define CLK_PLL1_409P6		16
+#define CLK_PLL1_204P8		17
+#define CLK_PLL1_491		18
+#define CLK_PLL1_245P76		19
+#define CLK_PLL1_614		20
+#define CLK_PLL1_47P26		21
+#define CLK_PLL1_31P5		22
+#define CLK_PLL1_819		23
+#define CLK_PLL1_1228		24
+#define CLK_SLOW_UART		25
+#define CLK_SLOW_UART1		26
+#define CLK_SLOW_UART2		27
+#define CLK_WDT			28
+#define CLK_RIPC		29
+#define CLK_I2S_SYSCLK		30
+#define CLK_I2S_BCLK		31
+#define CLK_APB			32
+#define CLK_WDT_BUS		33
+#define CLK_MPMU_NUM		34
+
+/*	APBC clocks	*/
+#define CLK_UART0		0
+#define CLK_UART2		1
+#define CLK_UART3		2
+#define CLK_UART4		3
+#define CLK_UART5		4
+#define CLK_UART6		5
+#define CLK_UART7		6
+#define CLK_UART8		7
+#define CLK_UART9		8
+#define CLK_GPIO		9
+#define CLK_PWM0		10
+#define CLK_PWM1		11
+#define CLK_PWM2		12
+#define CLK_PWM3		13
+#define CLK_PWM4		14
+#define CLK_PWM5		15
+#define CLK_PWM6		16
+#define CLK_PWM7		17
+#define CLK_PWM8		18
+#define CLK_PWM9		19
+#define CLK_PWM10		20
+#define CLK_PWM11		21
+#define CLK_PWM12		22
+#define CLK_PWM13		23
+#define CLK_PWM14		24
+#define CLK_PWM15		25
+#define CLK_PWM16		26
+#define CLK_PWM17		27
+#define CLK_PWM18		28
+#define CLK_PWM19		29
+#define CLK_SSP3		30
+#define CLK_RTC			31
+#define CLK_TWSI0		32
+#define CLK_TWSI1		33
+#define CLK_TWSI2		34
+#define CLK_TWSI4		35
+#define CLK_TWSI5		36
+#define CLK_TWSI6		37
+#define CLK_TWSI7		38
+#define CLK_TWSI8		39
+#define CLK_TIMERS1		40
+#define CLK_TIMERS2		41
+#define CLK_AIB			42
+#define CLK_ONEWIRE		43
+#define CLK_SSPA0		44
+#define CLK_SSPA1		45
+#define CLK_DRO			46
+#define CLK_IR			47
+#define CLK_TSEN		48
+#define CLK_IPC_AP2AUD		49
+#define CLK_CAN0		50
+#define CLK_CAN0_BUS		51
+#define CLK_UART0_BUS		52
+#define CLK_UART2_BUS		53
+#define CLK_UART3_BUS		54
+#define CLK_UART4_BUS		55
+#define CLK_UART5_BUS		56
+#define CLK_UART6_BUS		57
+#define CLK_UART7_BUS		58
+#define CLK_UART8_BUS		59
+#define CLK_UART9_BUS		60
+#define CLK_GPIO_BUS		61
+#define CLK_PWM0_BUS		62
+#define CLK_PWM1_BUS		63
+#define CLK_PWM2_BUS		64
+#define CLK_PWM3_BUS		65
+#define CLK_PWM4_BUS		66
+#define CLK_PWM5_BUS		67
+#define CLK_PWM6_BUS		68
+#define CLK_PWM7_BUS		69
+#define CLK_PWM8_BUS		70
+#define CLK_PWM9_BUS		71
+#define CLK_PWM10_BUS		72
+#define CLK_PWM11_BUS		73
+#define CLK_PWM12_BUS		74
+#define CLK_PWM13_BUS		75
+#define CLK_PWM14_BUS		76
+#define CLK_PWM15_BUS		77
+#define CLK_PWM16_BUS		78
+#define CLK_PWM17_BUS		79
+#define CLK_PWM18_BUS		80
+#define CLK_PWM19_BUS		81
+#define CLK_SSP3_BUS		82
+#define CLK_RTC_BUS		83
+#define CLK_TWSI0_BUS		84
+#define CLK_TWSI1_BUS		85
+#define CLK_TWSI2_BUS		86
+#define CLK_TWSI4_BUS		87
+#define CLK_TWSI5_BUS		88
+#define CLK_TWSI6_BUS		89
+#define CLK_TWSI7_BUS		90
+#define CLK_TWSI8_BUS		91
+#define CLK_TIMERS1_BUS		92
+#define CLK_TIMERS2_BUS		93
+#define CLK_AIB_BUS		94
+#define CLK_ONEWIRE_BUS		95
+#define CLK_SSPA0_BUS		96
+#define CLK_SSPA1_BUS		97
+#define CLK_TSEN_BUS		98
+#define CLK_IPC_AP2AUD_BUS	99
+#define CLK_APBC_NUM		100
+
+/*	APMU clocks	*/
+#define CLK_CCI550		0
+#define CLK_CPU_C0_HI		1
+#define CLK_CPU_C0_CORE		2
+#define CLK_CPU_C0_ACE		3
+#define CLK_CPU_C0_TCM		4
+#define CLK_CPU_C1_HI		5
+#define CLK_CPU_C1_CORE		6
+#define CLK_CPU_C1_ACE		7
+#define CLK_CCIC_4X		8
+#define CLK_CCIC1PHY		9
+#define CLK_SDH_AXI		10
+#define CLK_SDH0		11
+#define CLK_SDH1		12
+#define CLK_SDH2		13
+#define CLK_USB_P1		14
+#define CLK_USB_AXI		15
+#define CLK_USB30		16
+#define CLK_QSPI		17
+#define CLK_QSPI_BUS		18
+#define CLK_DMA			19
+#define CLK_AES			20
+#define CLK_VPU			21
+#define CLK_GPU			22
+#define CLK_EMMC		23
+#define CLK_EMMC_X		24
+#define CLK_AUDIO		25
+#define CLK_HDMI		26
+#define CLK_PMUA_ACLK		27
+#define CLK_PCIE0		28
+#define CLK_PCIE1		29
+#define CLK_PCIE2		30
+#define CLK_EMAC0_BUS		31
+#define CLK_EMAC0_PTP		32
+#define CLK_EMAC1_BUS		33
+#define CLK_EMAC1_PTP		34
+#define CLK_JPG			35
+#define CLK_CCIC2PHY		36
+#define CLK_CCIC3PHY		37
+#define CLK_CSI			38
+#define CLK_CAMM0		39
+#define CLK_CAMM1		40
+#define CLK_CAMM2		41
+#define CLK_ISP_CPP		42
+#define CLK_ISP_BUS		43
+#define CLK_ISP			44
+#define CLK_DPU_MCLK		45
+#define CLK_DPU_ESC		46
+#define CLK_DPU_BIT		47
+#define CLK_DPU_PXCLK		48
+#define CLK_DPU_HCLK		49
+#define CLK_DPU_SPI		50
+#define CLK_DPU_SPI_HBUS	51
+#define CLK_DPU_SPIBUS		52
+#define CLK_DPU_SPI_ACLK	53
+#define CLK_V2D			54
+#define CLK_EMMC_BUS		55
+#define CLK_APMU_NUM		56
+
+#endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */
-- 
2.47.0



From heylenay at 4d2.org  Tue Nov 26 06:31:26 2024
From: heylenay at 4d2.org (Haylen Chu)
Date: Tue, 26 Nov 2024 14:31:26 +0000
Subject: [PATCH v3 2/3] dt-bindings: soc: spacemit: Add spacemit,k1-syscon
In-Reply-To: <20241126143125.9980-2-heylenay@4d2.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
Message-ID: <20241126143125.9980-5-heylenay@4d2.org>

Add documentation to describe Spacemit K1 system controller registers.

Signed-off-by: Haylen Chu <heylenay at 4d2.org>
---
 .../soc/spacemit/spacemit,k1-syscon.yaml      | 86 +++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml

diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
new file mode 100644
index 000000000000..b9f20190a70a
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/spacemit/spacemit,k1-syscon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Spacemit K1 SoC System Controller
+
+maintainers:
+  - Haylen Chu <heylenay at 4d2.org>
+
+description:
+  The Spacemit K1 SoC system controller provides access to shared register files
+  for related SoC modules, such as clock controller and reset controller.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - spacemit,k1-apbc-syscon
+          - spacemit,k1-apbs-syscon
+          - spacemit,k1-apmu-syscon
+          - spacemit,k1-mpmu-syscon
+      - const: syscon
+      - const: simple-mfd
+
+  reg:
+    maxItems: 1
+
+  clock-controller:
+    $ref: /schemas/clock/spacemit,k1-ccu.yaml#
+    type: object
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+    osc_32k: clock-32k {
+        compatible = "fixed-clock";
+        clock-frequency = <32000>;
+        clock-output-names = "osc_32k";
+        #clock-cells = <0>;
+    };
+
+    vctcxo_1m: clock-1m {
+        compatible = "fixed-clock";
+        clock-frequency = <1000000>;
+        clock-output-names = "vctcxo_1m";
+        #clock-cells = <0>;
+    };
+
+    vctcxo_3m: clock-3m {
+        compatible = "fixed-clock";
+        clock-frequency = <3000000>;
+        clock-output-names = "vctcxo_3m";
+        #clock-cells = <0>;
+    };
+
+    vctcxo_24m: clock-24m {
+        compatible = "fixed-clock";
+        clock-frequency = <24000000>;
+        clock-output-names = "vctcxo_24m";
+        #clock-cells = <0>;
+    };
+
+    system-controller at d4050000 {
+        compatible = "spacemit,k1-mpmu-syscon", "syscon", "simple-mfd";
+        reg = <0xd4050000 0x209c>;
+
+        clock-controller {
+            compatible = "spacemit,k1-ccu-mpmu";
+            clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, <&vctcxo_24m>;
+            clock-names = "osc_32k", "vctcxo_1m", "vctcxo_3m", "vctcxo_24m";
+            #clock-cells = <1>;
+        };
+    };
-- 
2.47.0



From heylenay at 4d2.org  Tue Nov 26 06:31:28 2024
From: heylenay at 4d2.org (Haylen Chu)
Date: Tue, 26 Nov 2024 14:31:28 +0000
Subject: [PATCH v3 3/3] clk: spacemit: Add clock support for Spacemit K1 SoC
In-Reply-To: <20241126143125.9980-2-heylenay@4d2.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
Message-ID: <20241126143125.9980-7-heylenay@4d2.org>

The clock tree of K1 SoC contains three main types of clock hardware
(PLL/DDN/MIX) and is managed by several independent controllers in
different SoC parts (APBC, APBS and etc.), thus different compatible
strings are added to distinguish them.

Some controllers may share IO region with reset controller and other low
speed peripherals like watchdog, so all register operations are done
through regmap to avoid competition.

Signed-off-by: Haylen Chu <heylenay at 4d2.org>
---
 drivers/clk/Kconfig               |    1 +
 drivers/clk/Makefile              |    1 +
 drivers/clk/spacemit/Kconfig      |   20 +
 drivers/clk/spacemit/Makefile     |    5 +
 drivers/clk/spacemit/ccu-k1.c     | 1747 +++++++++++++++++++++++++++++
 drivers/clk/spacemit/ccu_common.h |   62 +
 drivers/clk/spacemit/ccu_ddn.c    |  146 +++
 drivers/clk/spacemit/ccu_ddn.h    |   85 ++
 drivers/clk/spacemit/ccu_mix.c    |  296 +++++
 drivers/clk/spacemit/ccu_mix.h    |  336 ++++++
 drivers/clk/spacemit/ccu_pll.c    |  198 ++++
 drivers/clk/spacemit/ccu_pll.h    |   80 ++
 12 files changed, 2977 insertions(+)
 create mode 100644 drivers/clk/spacemit/Kconfig
 create mode 100644 drivers/clk/spacemit/Makefile
 create mode 100644 drivers/clk/spacemit/ccu-k1.c
 create mode 100644 drivers/clk/spacemit/ccu_common.h
 create mode 100644 drivers/clk/spacemit/ccu_ddn.c
 create mode 100644 drivers/clk/spacemit/ccu_ddn.h
 create mode 100644 drivers/clk/spacemit/ccu_mix.c
 create mode 100644 drivers/clk/spacemit/ccu_mix.h
 create mode 100644 drivers/clk/spacemit/ccu_pll.c
 create mode 100644 drivers/clk/spacemit/ccu_pll.h

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 299bc678ed1b..fa8b5e8f2926 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -498,6 +498,7 @@ source "drivers/clk/samsung/Kconfig"
 source "drivers/clk/sifive/Kconfig"
 source "drivers/clk/socfpga/Kconfig"
 source "drivers/clk/sophgo/Kconfig"
+source "drivers/clk/spacemit/Kconfig"
 source "drivers/clk/sprd/Kconfig"
 source "drivers/clk/starfive/Kconfig"
 source "drivers/clk/sunxi/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index fb8878a5d7d9..e82ece2d0095 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -129,6 +129,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG)	+= samsung/
 obj-$(CONFIG_CLK_SIFIVE)		+= sifive/
 obj-y					+= socfpga/
 obj-y					+= sophgo/
+obj-y					+= spacemit/
 obj-$(CONFIG_PLAT_SPEAR)		+= spear/
 obj-y					+= sprd/
 obj-$(CONFIG_ARCH_STI)			+= st/
diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig
new file mode 100644
index 000000000000..76090cd85668
--- /dev/null
+++ b/drivers/clk/spacemit/Kconfig
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config SPACEMIT_CCU
+	tristate "Clock support for Spacemit SoCs"
+	default y
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	select MFD_SYSCON
+	help
+	  Say Y to enable clock controller unit support for Spacemit SoCs.
+
+if SPACEMIT_CCU
+
+config SPACEMIT_K1_CCU
+	tristate "Support for Spacemit K1 SoC"
+	default y
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	help
+	  Support for clock controller unit in Spacemit K1 SoC.
+
+endif
diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile
new file mode 100644
index 000000000000..9d1d5f759eb1
--- /dev/null
+++ b/drivers/clk/spacemit/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SPACEMIT_CCU)	+= ccu_pll.o ccu_mix.o ccu_ddn.o
+
+obj-$(CONFIG_SPACEMIT_K1_CCU)	+= ccu-k1.o
diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
new file mode 100644
index 000000000000..0b003fba4a8b
--- /dev/null
+++ b/drivers/clk/spacemit/ccu-k1.c
@@ -0,0 +1,1747 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay at outlook.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_pll.h"
+#include "ccu_mix.h"
+#include "ccu_ddn.h"
+
+#include <dt-bindings/clock/spacemit,k1-ccu.h>
+
+/*	APBS register offset	*/
+/*	pll1	*/
+#define APB_SPARE1_REG			0x100
+#define APB_SPARE2_REG			0x104
+#define APB_SPARE3_REG			0x108
+/*	pll2	*/
+#define APB_SPARE7_REG			0x118
+#define APB_SPARE8_REG			0x11c
+#define APB_SPARE9_REG			0x120
+/*	pll3	*/
+#define APB_SPARE10_REG			0x124
+#define APB_SPARE11_REG			0x128
+#define APB_SPARE12_REG			0x12c
+
+/* MPMU register offset */
+#define MPMU_POSR			0x10
+#define POSR_PLL1_LOCK			BIT(27)
+#define POSR_PLL2_LOCK			BIT(28)
+#define POSR_PLL3_LOCK			BIT(29)
+
+#define MPMU_WDTPCR			0x200
+#define MPMU_RIPCCR			0x210
+#define MPMU_ACGR			0x1024
+#define MPMU_SUCCR			0x14
+#define MPMU_ISCCR			0x44
+#define MPMU_SUCCR_1			0x10b0
+#define MPMU_APBCSCR			0x1050
+
+/* APBC register offset */
+#define APBC_UART1_CLK_RST		0x0
+#define APBC_UART2_CLK_RST		0x4
+#define APBC_GPIO_CLK_RST		0x8
+#define APBC_PWM0_CLK_RST		0xc
+#define APBC_PWM1_CLK_RST		0x10
+#define APBC_PWM2_CLK_RST		0x14
+#define APBC_PWM3_CLK_RST		0x18
+#define APBC_TWSI8_CLK_RST		0x20
+#define APBC_UART3_CLK_RST		0x24
+#define APBC_RTC_CLK_RST		0x28
+#define APBC_TWSI0_CLK_RST		0x2c
+#define APBC_TWSI1_CLK_RST		0x30
+#define APBC_TIMERS1_CLK_RST		0x34
+#define APBC_TWSI2_CLK_RST		0x38
+#define APBC_AIB_CLK_RST		0x3c
+#define APBC_TWSI4_CLK_RST		0x40
+#define APBC_TIMERS2_CLK_RST		0x44
+#define APBC_ONEWIRE_CLK_RST		0x48
+#define APBC_TWSI5_CLK_RST		0x4c
+#define APBC_DRO_CLK_RST		0x58
+#define APBC_IR_CLK_RST			0x5c
+#define APBC_TWSI6_CLK_RST		0x60
+#define APBC_COUNTER_CLK_SEL		0x64
+#define APBC_TWSI7_CLK_RST		0x68
+#define APBC_TSEN_CLK_RST		0x6c
+#define APBC_UART4_CLK_RST		0x70
+#define APBC_UART5_CLK_RST		0x74
+#define APBC_UART6_CLK_RST		0x78
+#define APBC_SSP3_CLK_RST		0x7c
+#define APBC_SSPA0_CLK_RST		0x80
+#define APBC_SSPA1_CLK_RST		0x84
+#define APBC_IPC_AP2AUD_CLK_RST		0x90
+#define APBC_UART7_CLK_RST		0x94
+#define APBC_UART8_CLK_RST		0x98
+#define APBC_UART9_CLK_RST		0x9c
+#define APBC_CAN0_CLK_RST		0xa0
+#define APBC_PWM4_CLK_RST		0xa8
+#define APBC_PWM5_CLK_RST		0xac
+#define APBC_PWM6_CLK_RST		0xb0
+#define APBC_PWM7_CLK_RST		0xb4
+#define APBC_PWM8_CLK_RST		0xb8
+#define APBC_PWM9_CLK_RST		0xbc
+#define APBC_PWM10_CLK_RST		0xc0
+#define APBC_PWM11_CLK_RST		0xc4
+#define APBC_PWM12_CLK_RST		0xc8
+#define APBC_PWM13_CLK_RST		0xcc
+#define APBC_PWM14_CLK_RST		0xd0
+#define APBC_PWM15_CLK_RST		0xd4
+#define APBC_PWM16_CLK_RST		0xd8
+#define APBC_PWM17_CLK_RST		0xdc
+#define APBC_PWM18_CLK_RST		0xe0
+#define APBC_PWM19_CLK_RST		0xe4
+
+/* APMU register offset */
+#define APMU_CCI550_CLK_CTRL		0x300
+#define APMU_CPU_C0_CLK_CTRL		0x38C
+#define APMU_CPU_C1_CLK_CTRL		0x390
+#define APMU_JPG_CLK_RES_CTRL		0x20
+#define APMU_CSI_CCIC2_CLK_RES_CTRL	0x24
+#define APMU_ISP_CLK_RES_CTRL		0x38
+#define APMU_LCD_CLK_RES_CTRL1		0x44
+#define APMU_LCD_SPI_CLK_RES_CTRL	0x48
+#define APMU_LCD_CLK_RES_CTRL2		0x4c
+#define APMU_CCIC_CLK_RES_CTRL		0x50
+#define APMU_SDH0_CLK_RES_CTRL		0x54
+#define APMU_SDH1_CLK_RES_CTRL		0x58
+#define APMU_USB_CLK_RES_CTRL		0x5c
+#define APMU_QSPI_CLK_RES_CTRL		0x60
+#define APMU_USB_CLK_RES_CTRL		0x5c
+#define APMU_DMA_CLK_RES_CTRL		0x64
+#define APMU_AES_CLK_RES_CTRL		0x68
+#define APMU_VPU_CLK_RES_CTRL		0xa4
+#define APMU_GPU_CLK_RES_CTRL		0xcc
+#define APMU_SDH2_CLK_RES_CTRL		0xe0
+#define APMU_PMUA_MC_CTRL		0xe8
+#define APMU_PMU_CC2_AP			0x100
+#define APMU_PMUA_EM_CLK_RES_CTRL	0x104
+#define APMU_AUDIO_CLK_RES_CTRL		0x14c
+#define APMU_HDMI_CLK_RES_CTRL		0x1B8
+#define APMU_CCI550_CLK_CTRL		0x300
+#define APMU_ACLK_CLK_CTRL		0x388
+#define APMU_CPU_C0_CLK_CTRL		0x38C
+#define APMU_CPU_C1_CLK_CTRL		0x390
+#define APMU_PCIE_CLK_RES_CTRL_0	0x3cc
+#define APMU_PCIE_CLK_RES_CTRL_1	0x3d4
+#define APMU_PCIE_CLK_RES_CTRL_2	0x3dc
+#define APMU_EMAC0_CLK_RES_CTRL		0x3e4
+#define APMU_EMAC1_CLK_RES_CTRL		0x3ec
+
+/*	APBS clocks start	*/
+
+/* Frequency of pll{1,2} should not be updated at runtime */
+static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = {
+	CCU_PLL_RATE(2457600000UL, 0x64, 0xdd, 0x50, 0x00, 0x33, 0x0ccccd),
+};
+
+static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = {
+	CCU_PLL_RATE(3000000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3f, 0xe00000),
+};
+
+static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = {
+	CCU_PLL_RATE(3000000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3f, 0xe00000),
+	CCU_PLL_RATE(3200000000UL, 0x67, 0xdd, 0x50, 0x00, 0x43, 0xeaaaab),
+	CCU_PLL_RATE(2457600000UL, 0x64, 0xdd, 0x50, 0x00, 0x33, 0x0ccccd),
+};
+
+static CCU_PLL_DEFINE(pll1, "pll1", pll1_rate_tbl,
+		      APB_SPARE1_REG, APB_SPARE2_REG, APB_SPARE3_REG,
+		      MPMU_POSR, POSR_PLL1_LOCK, 0);
+static CCU_PLL_DEFINE(pll2, "pll2", pll2_rate_tbl,
+		      APB_SPARE7_REG, APB_SPARE8_REG, APB_SPARE9_REG,
+		      MPMU_POSR, POSR_PLL2_LOCK, 0);
+static CCU_PLL_DEFINE(pll3, "pll3", pll3_rate_tbl,
+		      APB_SPARE10_REG, APB_SPARE11_REG, APB_SPARE12_REG,
+		      MPMU_POSR, POSR_PLL3_LOCK, 0);
+
+static CCU_GATE_FACTOR_DEFINE(pll1_d2, "pll1_d2", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(1), BIT(1), 0, 2, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d3, "pll1_d3", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(2), BIT(2), 0, 3, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d4, "pll1_d4", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(3), BIT(3), 0, 4, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d5, "pll1_d5", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(4), BIT(4), 0, 5, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d6, "pll1_d6", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(5), BIT(5), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d7, "pll1_d7", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(6), BIT(6), 0, 7, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d8, "pll1_d8", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(7), BIT(7), 0, 8, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d11_223p4, "pll1_d11_223p4", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(15), BIT(15), 0, 11, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d13_189, "pll1_d13_189", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(16), BIT(16), 0, 13, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d23_106p8, "pll1_d23_106p8", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(20), BIT(20), 0, 23, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d64_38p4, "pll1_d64_38p4", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(0), BIT(0), 0, 64, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_aud_245p7, "pll1_aud_245p7", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(10), BIT(10), 0, 10, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_aud_24p5, "pll1_aud_24p5", CCU_PARENT_HW(pll1),
+			      APB_SPARE2_REG,
+			      BIT(11), BIT(11), 0, 100, 1, 0);
+
+static CCU_GATE_FACTOR_DEFINE(pll2_d1, "pll2_d1", CCU_PARENT_HW(pll2),
+			      APB_SPARE8_REG,
+			      BIT(0), BIT(0), 0, 1, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d2, "pll2_d2", CCU_PARENT_HW(pll2),
+			      APB_SPARE8_REG,
+			      BIT(1), BIT(1), 0, 2, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d3, "pll2_d3", CCU_PARENT_HW(pll2),
+			      APB_SPARE8_REG,
+			      BIT(2), BIT(2), 0, 3, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d4, "pll2_d4", CCU_PARENT_HW(pll2),
+			      APB_SPARE8_REG,
+			      BIT(3), BIT(3), 0, 4, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d5, "pll2_d5", CCU_PARENT_HW(pll2),
+			      APB_SPARE8_REG,
+			      BIT(4), BIT(4), 0, 5, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d6, "pll2_d6", CCU_PARENT_HW(pll2),
+			      APB_SPARE8_REG,
+			      BIT(5), BIT(5), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d7, "pll2_d7", CCU_PARENT_HW(pll2),
+			      APB_SPARE8_REG,
+			      BIT(6), BIT(6), 0, 7, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d8, "pll2_d8", CCU_PARENT_HW(pll2),
+			      APB_SPARE8_REG,
+			      BIT(7), BIT(7), 0, 8, 1, 0);
+
+static CCU_GATE_FACTOR_DEFINE(pll3_d1, "pll3_d1", CCU_PARENT_HW(pll3),
+			      APB_SPARE11_REG,
+			      BIT(0), BIT(0), 0, 1, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d2, "pll3_d2", CCU_PARENT_HW(pll3),
+			      APB_SPARE11_REG,
+			      BIT(1), BIT(1), 0, 2, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d3, "pll3_d3", CCU_PARENT_HW(pll3),
+			      APB_SPARE11_REG,
+			      BIT(2), BIT(2), 0, 3, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d4, "pll3_d4", CCU_PARENT_HW(pll3),
+			      APB_SPARE11_REG,
+			      BIT(3), BIT(3), 0, 4, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d5, "pll3_d5", CCU_PARENT_HW(pll3),
+			      APB_SPARE11_REG,
+			      BIT(4), BIT(4), 0, 5, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d6, "pll3_d6", CCU_PARENT_HW(pll3),
+			      APB_SPARE11_REG,
+			      BIT(5), BIT(5), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d7, "pll3_d7", CCU_PARENT_HW(pll3),
+			      APB_SPARE11_REG,
+			      BIT(6), BIT(6), 0, 7, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d8, "pll3_d8", CCU_PARENT_HW(pll3),
+			      APB_SPARE11_REG,
+			      BIT(7), BIT(7), 0, 8, 1, 0);
+
+static CCU_FACTOR_DEFINE(pll3_20, "pll3_20", CCU_PARENT_HW(pll3_d8), 20, 1);
+static CCU_FACTOR_DEFINE(pll3_40, "pll3_40", CCU_PARENT_HW(pll3_d8), 10, 1);
+static CCU_FACTOR_DEFINE(pll3_80, "pll3_80", CCU_PARENT_HW(pll3_d8), 5, 1);
+
+/*	APBS clocks end		*/
+
+/*	MPMU clocks start	*/
+static CCU_GATE_DEFINE(pll1_d8_307p2, "pll1_d8_307p2", CCU_PARENT_HW(pll1_d8),
+		       MPMU_ACGR,
+		       BIT(13), BIT(13), 0, 0);
+static CCU_FACTOR_DEFINE(pll1_d32_76p8, "pll1_d32_76p8", CCU_PARENT_HW(pll1_d8_307p2),
+			 4, 1);
+static CCU_FACTOR_DEFINE(pll1_d40_61p44, "pll1_d40_61p44", CCU_PARENT_HW(pll1_d8_307p2),
+			 5, 1);
+static CCU_FACTOR_DEFINE(pll1_d16_153p6, "pll1_d16_153p6", CCU_PARENT_HW(pll1_d8),
+			 2, 1);
+static CCU_GATE_FACTOR_DEFINE(pll1_d24_102p4, "pll1_d24_102p4", CCU_PARENT_HW(pll1_d8),
+			      MPMU_ACGR,
+			      BIT(12), BIT(12), 0, 3, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d48_51p2, "pll1_d48_51p2", CCU_PARENT_HW(pll1_d8),
+			      MPMU_ACGR,
+			      BIT(7), BIT(7), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d48_51p2_ap, "pll1_d48_51p2_ap", CCU_PARENT_HW(pll1_d8),
+			      MPMU_ACGR,
+			      BIT(11), BIT(11), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_m3d128_57p6, "pll1_m3d128_57p6", CCU_PARENT_HW(pll1_d8),
+			      MPMU_ACGR,
+			      BIT(8), BIT(8), 0, 16, 3, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d96_25p6, "pll1_d96_25p6", CCU_PARENT_HW(pll1_d8),
+			      MPMU_ACGR,
+			      BIT(4), BIT(4), 0, 12, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d192_12p8, "pll1_d192_12p8", CCU_PARENT_HW(pll1_d8),
+			      MPMU_ACGR,
+			      BIT(3), BIT(3), 0, 24, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d192_12p8_wdt, "pll1_d192_12p8_wdt", CCU_PARENT_HW(pll1_d8),
+			      MPMU_ACGR,
+			      BIT(19), BIT(19), 0x0, 24, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d384_6p4, "pll1_d384_6p4", CCU_PARENT_HW(pll1_d8),
+			      MPMU_ACGR,
+			      BIT(2), BIT(2), 0, 48, 1, 0);
+static CCU_FACTOR_DEFINE(pll1_d768_3p2, "pll1_d768_3p2", CCU_PARENT_HW(pll1_d384_6p4),
+			 2, 1);
+static CCU_FACTOR_DEFINE(pll1_d1536_1p6, "pll1_d1536_1p6", CCU_PARENT_HW(pll1_d384_6p4),
+			 4, 1);
+static CCU_FACTOR_DEFINE(pll1_d3072_0p8, "pll1_d3072_0p8", CCU_PARENT_HW(pll1_d384_6p4),
+			 8, 1);
+
+static CCU_FACTOR_DEFINE(pll1_d7_351p08, "pll1_d7_351p08", CCU_PARENT_HW(pll1_d7),
+			 1, 1);
+
+static CCU_GATE_DEFINE(pll1_d6_409p6, "pll1_d6_409p6", CCU_PARENT_HW(pll1_d6),
+		       MPMU_ACGR,
+		       BIT(0), BIT(0), 0, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d12_204p8, "pll1_d12_204p8", CCU_PARENT_HW(pll1_d6),
+			      MPMU_ACGR,
+			      BIT(5), BIT(5), 0, 2, 1, 0);
+
+static CCU_GATE_DEFINE(pll1_d5_491p52, "pll1_d5_491p52", CCU_PARENT_HW(pll1_d5),
+		       MPMU_ACGR,
+		       BIT(21), BIT(21), 0, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d10_245p76, "pll1_d10_245p76", CCU_PARENT_HW(pll1_d5),
+			      MPMU_ACGR,
+			      BIT(18), BIT(18), 0, 2, 1, 0);
+
+static CCU_GATE_DEFINE(pll1_d4_614p4, "pll1_d4_614p4", CCU_PARENT_HW(pll1_d4),
+		       MPMU_ACGR,
+		       BIT(15), BIT(15), 0, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d52_47p26, "pll1_d52_47p26", CCU_PARENT_HW(pll1_d4),
+			      MPMU_ACGR,
+			      BIT(10), BIT(10), 0, 13, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d78_31p5, "pll1_d78_31p5", CCU_PARENT_HW(pll1_d4),
+			      MPMU_ACGR,
+			      BIT(6), BIT(6), 0, 39, 2, 0);
+
+static CCU_GATE_DEFINE(pll1_d3_819p2, "pll1_d3_819p2", CCU_PARENT_HW(pll1_d3),
+		       MPMU_ACGR,
+		       BIT(14), BIT(14), 0, 0);
+
+static CCU_GATE_DEFINE(pll1_d2_1228p8, "pll1_d2_1228p8", CCU_PARENT_HW(pll1_d2),
+		       MPMU_ACGR,
+		       BIT(16), BIT(16), 0, 0);
+
+static struct ccu_ddn_info uart_ddn_mask_info = {
+	.factor		= 2,
+	.num_mask	= 0x1fff,
+	.den_mask	= 0x1fff,
+	.num_shift	= 16,
+	.den_shift	= 0,
+};
+static struct ccu_ddn_tbl slow_uart1_tbl[] = {
+	{ .num = 125, .den = 24 },
+};
+static struct ccu_ddn_tbl slow_uart2_tbl[] = {
+	{ .num = 6144, .den = 960 },
+};
+static CCU_GATE_DEFINE(slow_uart, "slow_uart", CCU_PARENT_NAME(osc_32k),
+		       MPMU_ACGR,
+		       BIT(1), BIT(1), 0, CLK_IGNORE_UNUSED);
+static CCU_DDN_DEFINE(slow_uart1_14p74, "slow_uart1_14p74", pll1_d16_153p6,
+		      &uart_ddn_mask_info, slow_uart1_tbl,
+		      MPMU_SUCCR, 0);
+static CCU_DDN_DEFINE(slow_uart2_48, "slow_uart2_48", pll1_d4_614p4,
+		      &uart_ddn_mask_info, slow_uart2_tbl,
+		      MPMU_SUCCR_1, 0);
+
+static CCU_GATE_DEFINE(wdt_clk, "wdt_clk", CCU_PARENT_HW(pll1_d96_25p6),
+		       MPMU_WDTPCR,
+		       BIT(1), BIT(1), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(ripc_clk, "ripc_clk", CCU_PARENT_NAME(vctcxo_24m),
+		       MPMU_RIPCCR,
+		       0x3, 0x3, 0x0,
+		       0);
+
+static CCU_GATE_FACTOR_DEFINE(i2s_sysclk, "i2s_sysclk", CCU_PARENT_HW(pll1_d16_153p6),
+			      MPMU_ISCCR,
+			      BIT(31), BIT(31), 0x0, 50, 1,
+			      0);
+static CCU_GATE_FACTOR_DEFINE(i2s_bclk, "i2s_bclk", CCU_PARENT_HW(i2s_sysclk),
+			      MPMU_ISCCR,
+			      BIT(29), BIT(29), 0x0, 1, 1,
+			      0);
+
+static const struct clk_parent_data apb_parents[] = {
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d48_51p2),
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d24_102p4),
+};
+static CCU_MUX_DEFINE(apb_clk, "apb_clk", apb_parents,
+		      MPMU_APBCSCR,
+		      0, 2,
+		      0);
+
+static CCU_GATE_DEFINE(wdt_bus_clk, "wdt_bus_clk", CCU_PARENT_HW(apb_clk),
+		       MPMU_WDTPCR,
+		       BIT(2), BIT(2), 0x0,
+		       0);
+/*	MPMU clocks end		*/
+
+/*	APBC clocks start	*/
+static const struct clk_parent_data uart_clk_parents[] = {
+	CCU_PARENT_HW(pll1_m3d128_57p6),
+	CCU_PARENT_HW(slow_uart1_14p74),
+	CCU_PARENT_HW(slow_uart2_48),
+};
+static CCU_MUX_GATE_DEFINE(uart0_clk, "uart0_clk", uart_clk_parents,
+			   APBC_UART1_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   CLK_IS_CRITICAL);
+static CCU_MUX_GATE_DEFINE(uart2_clk, "uart2_clk", uart_clk_parents,
+			   APBC_UART2_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart3_clk, "uart3_clk", uart_clk_parents,
+			   APBC_UART3_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart4_clk, "uart4_clk", uart_clk_parents,
+			   APBC_UART4_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart5_clk, "uart5_clk", uart_clk_parents,
+			   APBC_UART5_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart6_clk, "uart6_clk", uart_clk_parents,
+			   APBC_UART6_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart7_clk, "uart7_clk", uart_clk_parents,
+			   APBC_UART7_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart8_clk, "uart8_clk", uart_clk_parents,
+			   APBC_UART8_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart9_clk, "uart9_clk", uart_clk_parents,
+			   APBC_UART9_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+
+static CCU_GATE_DEFINE(gpio_clk, "gpio_clk", CCU_PARENT_NAME(vctcxo_24m),
+		       APBC_GPIO_CLK_RST,
+		       BIT(1), BIT(1), 0x0,
+		       0);
+
+static const struct clk_parent_data pwm_parents[] = {
+	CCU_PARENT_HW(pll1_d192_12p8),
+	CCU_PARENT_NAME(osc_32k),
+};
+static CCU_MUX_GATE_DEFINE(pwm0_clk, "pwm0_clk", pwm_parents,
+			   APBC_PWM0_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm1_clk, "pwm1_clk", pwm_parents,
+			   APBC_PWM1_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm2_clk, "pwm2_clk", pwm_parents,
+			   APBC_PWM2_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm3_clk, "pwm3_clk", pwm_parents,
+			   APBC_PWM3_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm4_clk, "pwm4_clk", pwm_parents,
+			   APBC_PWM4_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm5_clk, "pwm5_clk", pwm_parents,
+			   APBC_PWM5_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm6_clk, "pwm6_clk", pwm_parents,
+			   APBC_PWM6_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm7_clk, "pwm7_clk", pwm_parents,
+			   APBC_PWM7_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm8_clk, "pwm8_clk", pwm_parents,
+			   APBC_PWM8_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm9_clk, "pwm9_clk", pwm_parents,
+			   APBC_PWM9_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm10_clk, "pwm10_clk", pwm_parents,
+			   APBC_PWM10_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm11_clk, "pwm11_clk", pwm_parents,
+			   APBC_PWM11_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm12_clk, "pwm12_clk", pwm_parents,
+			   APBC_PWM12_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm13_clk, "pwm13_clk", pwm_parents,
+			   APBC_PWM13_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm14_clk, "pwm14_clk", pwm_parents,
+			   APBC_PWM14_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm15_clk, "pwm15_clk", pwm_parents,
+			   APBC_PWM15_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm16_clk, "pwm16_clk", pwm_parents,
+			   APBC_PWM16_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm17_clk, "pwm17_clk", pwm_parents,
+			   APBC_PWM17_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm18_clk, "pwm18_clk", pwm_parents,
+			   APBC_PWM18_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(pwm19_clk, "pwm19_clk", pwm_parents,
+			   APBC_PWM19_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+
+static const struct clk_parent_data ssp_parents[] = {
+	CCU_PARENT_HW(pll1_d384_6p4),
+	CCU_PARENT_HW(pll1_d192_12p8),
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d48_51p2),
+	CCU_PARENT_HW(pll1_d768_3p2),
+	CCU_PARENT_HW(pll1_d1536_1p6),
+	CCU_PARENT_HW(pll1_d3072_0p8),
+};
+static CCU_MUX_GATE_DEFINE(ssp3_clk, "ssp3_clk", ssp_parents,
+			   APBC_SSP3_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+
+static CCU_GATE_DEFINE(rtc_clk, "rtc_clk", CCU_PARENT_NAME(osc_32k),
+		       APBC_RTC_CLK_RST,
+		       0x82, 0x82, 0x0,
+		       0);
+
+static const struct clk_parent_data twsi_parents[] = {
+	CCU_PARENT_HW(pll1_d78_31p5),
+	CCU_PARENT_HW(pll1_d48_51p2),
+	CCU_PARENT_HW(pll1_d40_61p44),
+};
+static CCU_MUX_GATE_DEFINE(twsi0_clk, "twsi0_clk", twsi_parents,
+			   APBC_TWSI0_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(twsi1_clk, "twsi1_clk", twsi_parents,
+			   APBC_TWSI1_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(twsi2_clk, "twsi2_clk", twsi_parents,
+			   APBC_TWSI2_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(twsi4_clk, "twsi4_clk", twsi_parents,
+			   APBC_TWSI4_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(twsi5_clk, "twsi5_clk", twsi_parents,
+			   APBC_TWSI5_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(twsi6_clk, "twsi6_clk", twsi_parents,
+			   APBC_TWSI6_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(twsi7_clk, "twsi7_clk", twsi_parents,
+			   APBC_TWSI7_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(twsi8_clk, "twsi8_clk", twsi_parents,
+			   APBC_TWSI8_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+
+static const struct clk_parent_data timer_parents[] = {
+	CCU_PARENT_HW(pll1_d192_12p8),
+	CCU_PARENT_NAME(osc_32k),
+	CCU_PARENT_HW(pll1_d384_6p4),
+	CCU_PARENT_NAME(vctcxo_3m),
+	CCU_PARENT_NAME(vctcxo_1m),
+};
+static CCU_MUX_GATE_DEFINE(timers1_clk, "timers1_clk", timer_parents,
+			   APBC_TIMERS1_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(timers2_clk, "timers2_clk", timer_parents,
+			   APBC_TIMERS2_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+
+static CCU_GATE_DEFINE(aib_clk, "aib_clk", CCU_PARENT_NAME(vctcxo_24m),
+		       APBC_AIB_CLK_RST,
+		       BIT(1), BIT(1), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(onewire_clk, "onewire_clk", CCU_PARENT_NAME(vctcxo_24m),
+		       APBC_ONEWIRE_CLK_RST,
+		       BIT(1), BIT(1), 0x0,
+		       0);
+
+static const struct clk_parent_data sspa_parents[] = {
+	CCU_PARENT_HW(pll1_d384_6p4),
+	CCU_PARENT_HW(pll1_d192_12p8),
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d48_51p2),
+	CCU_PARENT_HW(pll1_d768_3p2),
+	CCU_PARENT_HW(pll1_d1536_1p6),
+	CCU_PARENT_HW(pll1_d3072_0p8),
+	CCU_PARENT_HW(i2s_bclk),
+};
+static CCU_MUX_GATE_DEFINE(sspa0_clk, "sspa0_clk", sspa_parents,
+			   APBC_SSPA0_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(sspa1_clk, "sspa1_clk", sspa_parents,
+			   APBC_SSPA1_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_GATE_DEFINE(dro_clk, "dro_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_DRO_CLK_RST,
+		       BIT(1), BIT(1), 0x0,
+		       0);
+static CCU_GATE_DEFINE(ir_clk, "ir_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_IR_CLK_RST,
+		       BIT(1), BIT(1), 0x0,
+		       0);
+static CCU_GATE_DEFINE(tsen_clk, "tsen_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TSEN_CLK_RST,
+		       BIT(1), BIT(1), 0x0,
+		       0);
+static CCU_GATE_DEFINE(ipc_ap2aud_clk, "ipc_ap2aud_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_IPC_AP2AUD_CLK_RST,
+		       BIT(1), BIT(1), 0x0,
+		       0);
+
+static const struct clk_parent_data can_parents[] = {
+	CCU_PARENT_HW(pll3_20),
+	CCU_PARENT_HW(pll3_40),
+	CCU_PARENT_HW(pll3_80),
+};
+static CCU_MUX_GATE_DEFINE(can0_clk, "can0_clk", can_parents,
+			   APBC_CAN0_CLK_RST,
+			   4, 3, BIT(1), BIT(1), 0x0,
+			   0);
+static CCU_GATE_DEFINE(can0_bus_clk, "can0_bus_clk", CCU_PARENT_NAME(vctcxo_24m),
+		       APBC_CAN0_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(uart0_bus_clk, "uart0_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_UART1_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       CLK_IS_CRITICAL);
+static CCU_GATE_DEFINE(uart2_bus_clk, "uart2_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_UART2_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(uart3_bus_clk, "uart3_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_UART3_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(uart4_bus_clk, "uart4_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_UART4_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(uart5_bus_clk, "uart5_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_UART5_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(uart6_bus_clk, "uart6_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_UART6_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(uart7_bus_clk, "uart7_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_UART7_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(uart8_bus_clk, "uart8_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_UART8_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(uart9_bus_clk, "uart9_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_UART9_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(gpio_bus_clk, "gpio_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_GPIO_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(pwm0_bus_clk, "pwm0_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM0_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm1_bus_clk, "pwm1_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM1_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm2_bus_clk, "pwm2_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM2_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm3_bus_clk, "pwm3_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM3_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm4_bus_clk, "pwm4_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM4_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm5_bus_clk, "pwm5_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM5_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm6_bus_clk, "pwm6_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM6_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm7_bus_clk, "pwm7_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM7_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm8_bus_clk, "pwm8_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM8_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm9_bus_clk, "pwm9_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM9_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm10_bus_clk, "pwm10_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM10_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm11_bus_clk, "pwm11_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM11_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm12_bus_clk, "pwm12_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM12_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm13_bus_clk, "pwm13_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM13_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm14_bus_clk, "pwm14_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM14_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm15_bus_clk, "pwm15_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM15_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm16_bus_clk, "pwm16_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM16_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm17_bus_clk, "pwm17_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM17_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm18_bus_clk, "pwm18_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM18_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(pwm19_bus_clk, "pwm19_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_PWM19_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(ssp3_bus_clk, "ssp3_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_SSP3_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(rtc_bus_clk, "rtc_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_RTC_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(twsi0_bus_clk, "twsi0_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TWSI0_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(twsi1_bus_clk, "twsi1_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TWSI1_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(twsi2_bus_clk, "twsi2_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TWSI2_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(twsi4_bus_clk, "twsi4_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TWSI4_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(twsi5_bus_clk, "twsi5_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TWSI5_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(twsi6_bus_clk, "twsi6_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TWSI6_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(twsi7_bus_clk, "twsi7_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TWSI7_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(twsi8_bus_clk, "twsi8_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TWSI8_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(timers1_bus_clk, "timers1_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TIMERS1_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(timers2_bus_clk, "timers2_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TIMERS2_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(aib_bus_clk, "aib_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_AIB_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(onewire_bus_clk, "onewire_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_ONEWIRE_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(sspa0_bus_clk, "sspa0_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_SSPA0_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(sspa1_bus_clk, "sspa1_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_SSPA1_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(tsen_bus_clk, "tsen_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_TSEN_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(ipc_ap2aud_bus_clk, "ipc_ap2aud_bus_clk", CCU_PARENT_HW(apb_clk),
+		       APBC_IPC_AP2AUD_CLK_RST,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+/*	APBC clocks end		*/
+
+/*	APMU clocks start	*/
+static const struct clk_parent_data pmua_aclk_parents[] = {
+	CCU_PARENT_HW(pll1_d10_245p76),
+	CCU_PARENT_HW(pll1_d8_307p2),
+};
+static CCU_DIV_FC_MUX_DEFINE(pmua_aclk, "pmua_aclk", pmua_aclk_parents,
+			     APMU_ACLK_CLK_CTRL,
+			     1, 2, BIT(4),
+			     0, 1,
+			     0);
+
+static const struct clk_parent_data cci550_clk_parents[] = {
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll2_d3),
+};
+static CCU_DIV_FC_MUX_DEFINE(cci550_clk, "cci550_clk", cci550_clk_parents,
+			     APMU_CCI550_CLK_CTRL,
+			     8, 3, BIT(12), 0, 2, CLK_IS_CRITICAL);
+
+static const struct clk_parent_data cpu_c0_hi_clk_parents[] = {
+	CCU_PARENT_HW(pll3_d2),
+	CCU_PARENT_HW(pll3_d1),
+};
+static CCU_MUX_DEFINE(cpu_c0_hi_clk, "cpu_c0_hi_clk", cpu_c0_hi_clk_parents,
+		      APMU_CPU_C0_CLK_CTRL,
+		      13, 1, 0);
+static const struct clk_parent_data cpu_c0_clk_parents[] = {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+	CCU_PARENT_HW(pll3_d3),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(cpu_c0_hi_clk),
+};
+static CCU_MUX_FC_DEFINE(cpu_c0_core_clk, "cpu_c0_core_clk", cpu_c0_clk_parents,
+			 APMU_CPU_C0_CLK_CTRL,
+			 BIT(12), 0, 3, CLK_IS_CRITICAL);
+static CCU_DIV_DEFINE(cpu_c0_ace_clk, "cpu_c0_ace_clk", CCU_PARENT_HW(cpu_c0_core_clk),
+		      APMU_CPU_C0_CLK_CTRL,
+		      6, 3, CLK_IS_CRITICAL);
+static CCU_DIV_DEFINE(cpu_c0_tcm_clk, "cpu_c0_tcm_clk", CCU_PARENT_HW(cpu_c0_core_clk),
+		      APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL);
+
+static const struct clk_parent_data cpu_c1_hi_clk_parents[] = {
+	CCU_PARENT_HW(pll3_d2),
+	CCU_PARENT_HW(pll3_d1),
+};
+static CCU_MUX_DEFINE(cpu_c1_hi_clk, "cpu_c1_hi_clk", cpu_c1_hi_clk_parents,
+		      APMU_CPU_C1_CLK_CTRL,
+		      13, 1, CLK_IS_CRITICAL);
+static const struct clk_parent_data cpu_c1_clk_parents[] = {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+	CCU_PARENT_HW(pll3_d3),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(cpu_c1_hi_clk),
+};
+static CCU_MUX_FC_DEFINE(cpu_c1_core_clk, "cpu_c1_core_clk", cpu_c1_clk_parents,
+			 APMU_CPU_C1_CLK_CTRL,
+			 BIT(12), 0, 3, CLK_IS_CRITICAL);
+static CCU_DIV_DEFINE(cpu_c1_ace_clk, "cpu_c1_ace_clk", CCU_PARENT_HW(cpu_c1_core_clk),
+		      APMU_CPU_C1_CLK_CTRL,
+		      6, 3, CLK_IS_CRITICAL);
+
+static const struct clk_parent_data jpg_parents[] = {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll2_d3),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(jpg_clk, "jpg_clk", jpg_parents,
+				  APMU_JPG_CLK_RES_CTRL,
+				  5, 3, BIT(15),
+				  2, 3, BIT(1), BIT(1), 0x0,
+				  0);
+
+static const struct clk_parent_data ccic2phy_parents[] = {
+	CCU_PARENT_HW(pll1_d24_102p4),
+	CCU_PARENT_HW(pll1_d48_51p2_ap),
+};
+static CCU_MUX_GATE_DEFINE(ccic2phy_clk, "ccic2phy_clk", ccic2phy_parents,
+			   APMU_CSI_CCIC2_CLK_RES_CTRL,
+			   7, 1, BIT(5), BIT(5), 0x0,
+			   0);
+
+static const struct clk_parent_data ccic3phy_parents[] = {
+	CCU_PARENT_HW(pll1_d24_102p4),
+	CCU_PARENT_HW(pll1_d48_51p2_ap),
+};
+static CCU_MUX_GATE_DEFINE(ccic3phy_clk, "ccic3phy_clk", ccic3phy_parents,
+			   APMU_CSI_CCIC2_CLK_RES_CTRL,
+			   31, 1, BIT(30), BIT(30), 0x0,
+			   0);
+
+static const struct clk_parent_data csi_parents[] = {
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll2_d2),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(csi_clk, "csi_clk", csi_parents,
+				  APMU_CSI_CCIC2_CLK_RES_CTRL,
+				  20, 3, BIT(15),
+				  16, 3, BIT(4), BIT(4), 0x0,
+				  0);
+
+static const struct clk_parent_data camm_parents[] = {
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll2_d5),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_NAME(vctcxo_24m),
+};
+static CCU_DIV_MUX_GATE_DEFINE(camm0_clk, "camm0_clk", camm_parents,
+			       APMU_CSI_CCIC2_CLK_RES_CTRL,
+			       23, 4, 8, 2,
+			       BIT(28), BIT(28), 0x0,
+			       0);
+static CCU_DIV_MUX_GATE_DEFINE(camm1_clk, "camm1_clk", camm_parents,
+			       APMU_CSI_CCIC2_CLK_RES_CTRL,
+			       23, 4, 8, 2, BIT(6), BIT(6), 0x0,
+			       0);
+static CCU_DIV_MUX_GATE_DEFINE(camm2_clk, "camm2_clk", camm_parents,
+			       APMU_CSI_CCIC2_CLK_RES_CTRL,
+			       23, 4, 8, 2, BIT(3), BIT(3), 0x0,
+			       0);
+
+static const struct clk_parent_data isp_cpp_parents[] = {
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+};
+static CCU_DIV_MUX_GATE_DEFINE(isp_cpp_clk, "isp_cpp_clk", isp_cpp_parents,
+			       APMU_ISP_CLK_RES_CTRL,
+			       24, 2, 26, 1, BIT(28), BIT(28), 0x0,
+			       0);
+static const struct clk_parent_data isp_bus_parents[] = {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d10_245p76),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(isp_bus_clk, "isp_bus_clk", isp_bus_parents,
+				  APMU_ISP_CLK_RES_CTRL,
+				  18, 3, BIT(23),
+				  21, 2, BIT(17), BIT(17), 0x0,
+				  0);
+static const struct clk_parent_data isp_parents[] = {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d8_307p2),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(isp_clk, "isp_clk", isp_parents,
+				  APMU_ISP_CLK_RES_CTRL,
+				  4, 3, BIT(7),
+				  8, 2, BIT(1), BIT(1), 0x0,
+				  0);
+
+static const struct clk_parent_data dpumclk_parents[] = {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d8_307p2),
+};
+static CCU_DIV2_FC_MUX_GATE_DEFINE(dpu_mclk, "dpu_mclk", dpumclk_parents,
+				   APMU_LCD_CLK_RES_CTRL1,
+				   APMU_LCD_CLK_RES_CTRL2,
+				   1, 4, BIT(29),
+				   5, 3, BIT(0), BIT(0), 0x0,
+				   0);
+
+static const struct clk_parent_data dpuesc_parents[] = {
+	CCU_PARENT_HW(pll1_d48_51p2_ap),
+	CCU_PARENT_HW(pll1_d52_47p26),
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d32_76p8),
+};
+static CCU_MUX_GATE_DEFINE(dpu_esc_clk, "dpu_esc_clk", dpuesc_parents,
+			   APMU_LCD_CLK_RES_CTRL1,
+			   0, 2, BIT(2), BIT(2), 0x0,
+			   0);
+
+static const struct clk_parent_data dpubit_parents[] = {
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll2_d2),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll2_d5),
+	CCU_PARENT_HW(pll2_d8),
+	CCU_PARENT_HW(pll2_d8),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(dpu_bit_clk, "dpu_bit_clk", dpubit_parents,
+				  APMU_LCD_CLK_RES_CTRL1,
+				  17, 3, BIT(31),
+				  20, 3, BIT(16), BIT(16), 0x0,
+				  0);
+
+static const struct clk_parent_data dpupx_parents[] = {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll2_d7),
+	CCU_PARENT_HW(pll2_d8),
+};
+static CCU_DIV2_FC_MUX_GATE_DEFINE(dpu_pxclk, "dpu_pxclk", dpupx_parents,
+				  APMU_LCD_CLK_RES_CTRL1,
+				  APMU_LCD_CLK_RES_CTRL2,
+				  17, 4, BIT(30),
+				  21, 3, BIT(16), BIT(16), 0x0,
+				  0);
+
+static CCU_GATE_DEFINE(dpu_hclk, "dpu_hclk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_LCD_CLK_RES_CTRL1,
+		       BIT(5), BIT(5), 0x0,
+		       0);
+
+static const struct clk_parent_data dpu_spi_parents[] = {
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d10_245p76),
+	CCU_PARENT_HW(pll1_d11_223p4),
+	CCU_PARENT_HW(pll1_d13_189),
+	CCU_PARENT_HW(pll1_d23_106p8),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d5),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(dpu_spi_clk, "dpu_spi_clk", dpu_spi_parents,
+				  APMU_LCD_SPI_CLK_RES_CTRL,
+				  8, 3, BIT(7),
+				  12, 3, BIT(1), BIT(1), 0x0,
+				  0);
+static CCU_GATE_DEFINE(dpu_spi_hbus_clk, "dpu_spi_hbus_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_LCD_SPI_CLK_RES_CTRL,
+		       BIT(3), BIT(3), 0x0,
+		       0);
+static CCU_GATE_DEFINE(dpu_spi_bus_clk, "dpu_spi_bus_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_LCD_SPI_CLK_RES_CTRL,
+		       BIT(5), BIT(5), 0x0,
+		       0);
+static CCU_GATE_DEFINE(dpu_spi_aclk, "dpu_spi_aclk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_LCD_SPI_CLK_RES_CTRL,
+		       BIT(6), BIT(6), 0x0,
+		       0);
+
+static const struct clk_parent_data v2d_parents[] = {
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d4_614p4),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(v2d_clk, "v2d_clk", v2d_parents,
+				  APMU_LCD_CLK_RES_CTRL1,
+				  9, 3, BIT(28),
+				  12, 2, BIT(8), BIT(8), 0x0,
+				  0);
+
+static const struct clk_parent_data ccic_4x_parents[] = {
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll2_d2),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(ccic_4x_clk, "ccic_4x_clk", ccic_4x_parents,
+				  APMU_CCIC_CLK_RES_CTRL,
+				  18, 3, BIT(15),
+				  23, 2, BIT(4), BIT(4), 0x0,
+				  0);
+
+static const struct clk_parent_data ccic1phy_parents[] = {
+	CCU_PARENT_HW(pll1_d24_102p4),
+	CCU_PARENT_HW(pll1_d48_51p2_ap),
+};
+static CCU_MUX_GATE_DEFINE(ccic1phy_clk, "ccic1phy_clk", ccic1phy_parents,
+			   APMU_CCIC_CLK_RES_CTRL,
+			   7, 1, BIT(5), BIT(5), 0x0,
+			   0);
+
+static CCU_GATE_DEFINE(sdh_axi_aclk, "sdh_axi_aclk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_SDH0_CLK_RES_CTRL,
+		       BIT(3), BIT(3), 0x0,
+		       0);
+static const struct clk_parent_data sdh01_parents[] = {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll2_d8),
+	CCU_PARENT_HW(pll2_d5),
+	CCU_PARENT_HW(pll1_d11_223p4),
+	CCU_PARENT_HW(pll1_d13_189),
+	CCU_PARENT_HW(pll1_d23_106p8),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(sdh0_clk, "sdh0_clk", sdh01_parents,
+				  APMU_SDH0_CLK_RES_CTRL,
+				  8, 3, BIT(11),
+				  5, 3, BIT(4), BIT(4), 0x0,
+				  0);
+static CCU_DIV_FC_MUX_GATE_DEFINE(sdh1_clk, "sdh1_clk", sdh01_parents,
+				  APMU_SDH1_CLK_RES_CTRL,
+				  8, 3, BIT(11),
+				  5, 3, BIT(4), BIT(4), 0x0,
+				  0);
+static const struct clk_parent_data sdh2_parents[] = {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll2_d8),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d11_223p4),
+	CCU_PARENT_HW(pll1_d13_189),
+	CCU_PARENT_HW(pll1_d23_106p8),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(sdh2_clk, "sdh2_clk", sdh2_parents,
+				  APMU_SDH2_CLK_RES_CTRL,
+				  8, 3, BIT(11),
+				  5, 3, BIT(4), BIT(4), 0x0,
+				  0);
+
+static CCU_GATE_DEFINE(usb_axi_clk, "usb_axi_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_USB_CLK_RES_CTRL,
+		       BIT(1), BIT(1), 0x0,
+		       0);
+static CCU_GATE_DEFINE(usb_p1_aclk, "usb_p1_aclk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_USB_CLK_RES_CTRL,
+		       BIT(5), BIT(5), 0x0,
+		       0);
+static CCU_GATE_DEFINE(usb30_clk, "usb30_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_USB_CLK_RES_CTRL,
+		       BIT(8), BIT(8), 0x0,
+		       0);
+
+static const struct clk_parent_data qspi_parents[] = {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll2_d8),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d10_245p76),
+	CCU_PARENT_HW(pll1_d11_223p4),
+	CCU_PARENT_HW(pll1_d23_106p8),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d13_189),
+};
+static CCU_DIV_MFC_MUX_GATE_DEFINE(qspi_clk, "qspi_clk", qspi_parents,
+				   APMU_QSPI_CLK_RES_CTRL,
+				   9, 3, BIT(12),
+				   6, 3, BIT(4), BIT(4), 0x0,
+				   0);
+static CCU_GATE_DEFINE(qspi_bus_clk, "qspi_bus_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_QSPI_CLK_RES_CTRL,
+		       BIT(3), BIT(3), 0x0,
+		       0);
+static CCU_GATE_DEFINE(dma_clk, "dma_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_DMA_CLK_RES_CTRL,
+		       BIT(3), BIT(3), 0x0,
+		       0);
+
+static const struct clk_parent_data aes_parents[] = {
+	CCU_PARENT_HW(pll1_d12_204p8),
+	CCU_PARENT_HW(pll1_d24_102p4),
+};
+static CCU_MUX_GATE_DEFINE(aes_clk, "aes_clk", aes_parents,
+			   APMU_AES_CLK_RES_CTRL,
+			   6, 1, BIT(5), BIT(5), 0x0,
+			   0);
+
+static const struct clk_parent_data vpu_parents[] = {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll3_d6),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll2_d5),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(vpu_clk, "vpu_clk", vpu_parents,
+				  APMU_VPU_CLK_RES_CTRL,
+				  13, 3, BIT(21),
+				  10, 3,
+				  BIT(3), BIT(3), 0x0,
+				  0);
+
+static const struct clk_parent_data gpu_parents[] = {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll3_d6),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll2_d5),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(gpu_clk, "gpu_clk", gpu_parents,
+				  APMU_GPU_CLK_RES_CTRL,
+				  12, 3, BIT(15),
+				  18, 3,
+				  BIT(4), BIT(4), 0x0,
+				  0);
+
+static const struct clk_parent_data emmc_parents[] = {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d52_47p26),
+	CCU_PARENT_HW(pll1_d3_819p2),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(emmc_clk, "emmc_clk", emmc_parents,
+				  APMU_PMUA_EM_CLK_RES_CTRL,
+				  8, 3, BIT(11),
+				  6, 2,
+				  BIT(4), BIT(4), 0x0,
+				  0);
+static CCU_DIV_GATE_DEFINE(emmc_x_clk, "emmc_x_clk", CCU_PARENT_HW(pll1_d2_1228p8),
+			   APMU_PMUA_EM_CLK_RES_CTRL,
+			   12, 3, BIT(15), BIT(15), 0x0,
+			   0);
+
+static const struct clk_parent_data audio_parents[] = {
+	CCU_PARENT_HW(pll1_aud_245p7),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(audio_clk, "audio_clk", audio_parents,
+				  APMU_AUDIO_CLK_RES_CTRL,
+				  4, 3, BIT(15),
+				  7, 3,
+				  BIT(12), BIT(12), 0x0,
+				  0);
+
+static const struct clk_parent_data hdmi_parents[] = {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d8_307p2),
+};
+static CCU_DIV_FC_MUX_GATE_DEFINE(hdmi_mclk, "hdmi_mclk", hdmi_parents,
+				  APMU_HDMI_CLK_RES_CTRL,
+				  1, 4, BIT(29),
+				  5, 3,
+				  BIT(0), BIT(0), 0x0,
+				  0);
+
+static CCU_GATE_DEFINE(pcie0_clk, "pcie0_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_PCIE_CLK_RES_CTRL_0,
+		       0x7, 0x7, 0x0,
+		       0);
+static CCU_GATE_DEFINE(pcie1_clk, "pcie1_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_PCIE_CLK_RES_CTRL_1,
+		       0x7, 0x7, 0x0,
+		       0);
+static CCU_GATE_DEFINE(pcie2_clk, "pcie2_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_PCIE_CLK_RES_CTRL_2,
+		       0x7, 0x7, 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(emac0_bus_clk, "emac0_bus_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_EMAC0_CLK_RES_CTRL,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(emac0_ptp_clk, "emac0_ptp_clk", CCU_PARENT_HW(pll2_d6),
+		       APMU_EMAC0_CLK_RES_CTRL,
+		       BIT(15), BIT(15), 0x0,
+		       0);
+static CCU_GATE_DEFINE(emac1_bus_clk, "emac1_bus_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_EMAC1_CLK_RES_CTRL,
+		       BIT(0), BIT(0), 0x0,
+		       0);
+static CCU_GATE_DEFINE(emac1_ptp_clk, "emac1_ptp_clk", CCU_PARENT_HW(pll2_d6),
+		       APMU_EMAC1_CLK_RES_CTRL,
+		       BIT(15), BIT(15), 0x0,
+		       0);
+
+static CCU_GATE_DEFINE(emmc_bus_clk, "emmc_bus_clk", CCU_PARENT_HW(pmua_aclk),
+		       APMU_PMUA_EM_CLK_RES_CTRL,
+		       BIT(3), BIT(3), 0,
+		       0);
+/*	APMU clocks end		*/
+
+static struct clk_hw_onecell_data k1_ccu_apbs_clks = {
+	.hws = {
+		[CLK_PLL1]		= &pll1.common.hw,
+		[CLK_PLL2]		= &pll2.common.hw,
+		[CLK_PLL3]		= &pll3.common.hw,
+		[CLK_PLL1_D2]		= &pll1_d2.common.hw,
+		[CLK_PLL1_D3]		= &pll1_d3.common.hw,
+		[CLK_PLL1_D4]		= &pll1_d4.common.hw,
+		[CLK_PLL1_D5]		= &pll1_d5.common.hw,
+		[CLK_PLL1_D6]		= &pll1_d6.common.hw,
+		[CLK_PLL1_D7]		= &pll1_d7.common.hw,
+		[CLK_PLL1_D8]		= &pll1_d8.common.hw,
+		[CLK_PLL1_D11]		= &pll1_d11_223p4.common.hw,
+		[CLK_PLL1_D13]		= &pll1_d13_189.common.hw,
+		[CLK_PLL1_D23]		= &pll1_d23_106p8.common.hw,
+		[CLK_PLL1_D64]		= &pll1_d64_38p4.common.hw,
+		[CLK_PLL1_D10_AUD]	= &pll1_aud_245p7.common.hw,
+		[CLK_PLL1_D100_AUD]	= &pll1_aud_24p5.common.hw,
+		[CLK_PLL2_D1]		= &pll2_d1.common.hw,
+		[CLK_PLL2_D2]		= &pll2_d2.common.hw,
+		[CLK_PLL2_D3]		= &pll2_d3.common.hw,
+		[CLK_PLL2_D3]		= &pll2_d4.common.hw,
+		[CLK_PLL2_D5]		= &pll2_d5.common.hw,
+		[CLK_PLL2_D6]		= &pll2_d6.common.hw,
+		[CLK_PLL2_D7]		= &pll2_d7.common.hw,
+		[CLK_PLL2_D8]		= &pll2_d8.common.hw,
+		[CLK_PLL3_D1]		= &pll3_d1.common.hw,
+		[CLK_PLL3_D2]		= &pll3_d2.common.hw,
+		[CLK_PLL3_D3]		= &pll3_d3.common.hw,
+		[CLK_PLL3_D4]		= &pll3_d4.common.hw,
+		[CLK_PLL3_D5]		= &pll3_d5.common.hw,
+		[CLK_PLL3_D6]		= &pll3_d6.common.hw,
+		[CLK_PLL3_D7]		= &pll3_d7.common.hw,
+		[CLK_PLL3_D8]		= &pll3_d8.common.hw,
+		[CLK_PLL3_80]		= &pll3_80.common.hw,
+		[CLK_PLL3_40]		= &pll3_40.common.hw,
+		[CLK_PLL3_20]		= &pll3_20.common.hw,
+
+	},
+	.num = CLK_APBS_NUM,
+};
+
+static struct clk_hw_onecell_data k1_ccu_mpmu_clks = {
+	.hws = {
+		[CLK_PLL1_307P2]	= &pll1_d8_307p2.common.hw,
+		[CLK_PLL1_76P8]		= &pll1_d32_76p8.common.hw,
+		[CLK_PLL1_61P44]	= &pll1_d40_61p44.common.hw,
+		[CLK_PLL1_153P6]	= &pll1_d16_153p6.common.hw,
+		[CLK_PLL1_102P4]	= &pll1_d24_102p4.common.hw,
+		[CLK_PLL1_51P2]		= &pll1_d48_51p2.common.hw,
+		[CLK_PLL1_51P2_AP]	= &pll1_d48_51p2_ap.common.hw,
+		[CLK_PLL1_57P6]		= &pll1_m3d128_57p6.common.hw,
+		[CLK_PLL1_25P6]		= &pll1_d96_25p6.common.hw,
+		[CLK_PLL1_12P8]		= &pll1_d192_12p8.common.hw,
+		[CLK_PLL1_12P8_WDT]	= &pll1_d192_12p8_wdt.common.hw,
+		[CLK_PLL1_6P4]		= &pll1_d384_6p4.common.hw,
+		[CLK_PLL1_3P2]		= &pll1_d768_3p2.common.hw,
+		[CLK_PLL1_1P6]		= &pll1_d1536_1p6.common.hw,
+		[CLK_PLL1_0P8]		= &pll1_d3072_0p8.common.hw,
+		[CLK_PLL1_351]		= &pll1_d7_351p08.common.hw,
+		[CLK_PLL1_409P6]	= &pll1_d6_409p6.common.hw,
+		[CLK_PLL1_204P8]	= &pll1_d12_204p8.common.hw,
+		[CLK_PLL1_491]		= &pll1_d5_491p52.common.hw,
+		[CLK_PLL1_245P76]	= &pll1_d10_245p76.common.hw,
+		[CLK_PLL1_614]		= &pll1_d4_614p4.common.hw,
+		[CLK_PLL1_47P26]	= &pll1_d52_47p26.common.hw,
+		[CLK_PLL1_31P5]		= &pll1_d78_31p5.common.hw,
+		[CLK_PLL1_819]		= &pll1_d3_819p2.common.hw,
+		[CLK_PLL1_1228]		= &pll1_d2_1228p8.common.hw,
+		[CLK_SLOW_UART]		= &slow_uart.common.hw,
+		[CLK_SLOW_UART1]	= &slow_uart1_14p74.common.hw,
+		[CLK_SLOW_UART2]	= &slow_uart2_48.common.hw,
+		[CLK_WDT]		= &wdt_clk.common.hw,
+		[CLK_RIPC]		= &ripc_clk.common.hw,
+		[CLK_I2S_SYSCLK]	= &i2s_sysclk.common.hw,
+		[CLK_I2S_BCLK]		= &i2s_bclk.common.hw,
+		[CLK_APB]		= &apb_clk.common.hw,
+		[CLK_WDT_BUS]		= &wdt_bus_clk.common.hw,
+	},
+	.num = CLK_MPMU_NUM,
+};
+
+static struct clk_hw_onecell_data k1_ccu_apbc_clks = {
+	.hws = {
+		[CLK_UART0]		= &uart0_clk.common.hw,
+		[CLK_UART2]		= &uart2_clk.common.hw,
+		[CLK_UART3]		= &uart3_clk.common.hw,
+		[CLK_UART4]		= &uart4_clk.common.hw,
+		[CLK_UART5]		= &uart5_clk.common.hw,
+		[CLK_UART6]		= &uart6_clk.common.hw,
+		[CLK_UART7]		= &uart7_clk.common.hw,
+		[CLK_UART8]		= &uart8_clk.common.hw,
+		[CLK_UART9]		= &uart9_clk.common.hw,
+		[CLK_GPIO]		= &gpio_clk.common.hw,
+		[CLK_PWM0]		= &pwm0_clk.common.hw,
+		[CLK_PWM1]		= &pwm1_clk.common.hw,
+		[CLK_PWM2]		= &pwm2_clk.common.hw,
+		[CLK_PWM3]		= &pwm3_clk.common.hw,
+		[CLK_PWM4]		= &pwm4_clk.common.hw,
+		[CLK_PWM5]		= &pwm5_clk.common.hw,
+		[CLK_PWM6]		= &pwm6_clk.common.hw,
+		[CLK_PWM7]		= &pwm7_clk.common.hw,
+		[CLK_PWM8]		= &pwm8_clk.common.hw,
+		[CLK_PWM9]		= &pwm9_clk.common.hw,
+		[CLK_PWM10]		= &pwm10_clk.common.hw,
+		[CLK_PWM11]		= &pwm11_clk.common.hw,
+		[CLK_PWM12]		= &pwm12_clk.common.hw,
+		[CLK_PWM13]		= &pwm13_clk.common.hw,
+		[CLK_PWM14]		= &pwm14_clk.common.hw,
+		[CLK_PWM15]		= &pwm15_clk.common.hw,
+		[CLK_PWM16]		= &pwm16_clk.common.hw,
+		[CLK_PWM17]		= &pwm17_clk.common.hw,
+		[CLK_PWM18]		= &pwm18_clk.common.hw,
+		[CLK_PWM19]		= &pwm19_clk.common.hw,
+		[CLK_SSP3]		= &ssp3_clk.common.hw,
+		[CLK_RTC]		= &rtc_clk.common.hw,
+		[CLK_TWSI0]		= &twsi0_clk.common.hw,
+		[CLK_TWSI1]		= &twsi1_clk.common.hw,
+		[CLK_TWSI2]		= &twsi2_clk.common.hw,
+		[CLK_TWSI4]		= &twsi4_clk.common.hw,
+		[CLK_TWSI5]		= &twsi5_clk.common.hw,
+		[CLK_TWSI6]		= &twsi6_clk.common.hw,
+		[CLK_TWSI7]		= &twsi7_clk.common.hw,
+		[CLK_TWSI8]		= &twsi8_clk.common.hw,
+		[CLK_TIMERS1]		= &timers1_clk.common.hw,
+		[CLK_TIMERS2]		= &timers2_clk.common.hw,
+		[CLK_AIB]		= &aib_clk.common.hw,
+		[CLK_ONEWIRE]		= &onewire_clk.common.hw,
+		[CLK_SSPA0]		= &sspa0_clk.common.hw,
+		[CLK_SSPA1]		= &sspa1_clk.common.hw,
+		[CLK_DRO]		= &dro_clk.common.hw,
+		[CLK_IR]		= &ir_clk.common.hw,
+		[CLK_TSEN]		= &tsen_clk.common.hw,
+		[CLK_IPC_AP2AUD]	= &ipc_ap2aud_clk.common.hw,
+		[CLK_CAN0]		= &can0_clk.common.hw,
+		[CLK_CAN0_BUS]		= &can0_bus_clk.common.hw,
+		[CLK_UART0_BUS]		= &uart0_bus_clk.common.hw,
+		[CLK_UART2_BUS]		= &uart2_bus_clk.common.hw,
+		[CLK_UART3_BUS]		= &uart3_bus_clk.common.hw,
+		[CLK_UART4_BUS]		= &uart4_bus_clk.common.hw,
+		[CLK_UART5_BUS]		= &uart5_bus_clk.common.hw,
+		[CLK_UART6_BUS]		= &uart6_bus_clk.common.hw,
+		[CLK_UART7_BUS]		= &uart7_bus_clk.common.hw,
+		[CLK_UART8_BUS]		= &uart8_bus_clk.common.hw,
+		[CLK_UART9_BUS]		= &uart9_bus_clk.common.hw,
+		[CLK_GPIO_BUS]		= &gpio_bus_clk.common.hw,
+		[CLK_PWM0_BUS]		= &pwm0_bus_clk.common.hw,
+		[CLK_PWM1_BUS]		= &pwm1_bus_clk.common.hw,
+		[CLK_PWM2_BUS]		= &pwm2_bus_clk.common.hw,
+		[CLK_PWM3_BUS]		= &pwm3_bus_clk.common.hw,
+		[CLK_PWM4_BUS]		= &pwm4_bus_clk.common.hw,
+		[CLK_PWM5_BUS]		= &pwm5_bus_clk.common.hw,
+		[CLK_PWM6_BUS]		= &pwm6_bus_clk.common.hw,
+		[CLK_PWM7_BUS]		= &pwm7_bus_clk.common.hw,
+		[CLK_PWM8_BUS]		= &pwm8_bus_clk.common.hw,
+		[CLK_PWM9_BUS]		= &pwm9_bus_clk.common.hw,
+		[CLK_PWM10_BUS]		= &pwm10_bus_clk.common.hw,
+		[CLK_PWM11_BUS]		= &pwm11_bus_clk.common.hw,
+		[CLK_PWM12_BUS]		= &pwm12_bus_clk.common.hw,
+		[CLK_PWM13_BUS]		= &pwm13_bus_clk.common.hw,
+		[CLK_PWM14_BUS]		= &pwm14_bus_clk.common.hw,
+		[CLK_PWM15_BUS]		= &pwm15_bus_clk.common.hw,
+		[CLK_PWM16_BUS]		= &pwm16_bus_clk.common.hw,
+		[CLK_PWM17_BUS]		= &pwm17_bus_clk.common.hw,
+		[CLK_PWM18_BUS]		= &pwm18_bus_clk.common.hw,
+		[CLK_PWM19_BUS]		= &pwm19_bus_clk.common.hw,
+		[CLK_SSP3_BUS]		= &ssp3_bus_clk.common.hw,
+		[CLK_RTC_BUS]		= &rtc_bus_clk.common.hw,
+		[CLK_TWSI0_BUS]		= &twsi0_bus_clk.common.hw,
+		[CLK_TWSI1_BUS]		= &twsi1_bus_clk.common.hw,
+		[CLK_TWSI2_BUS]		= &twsi2_bus_clk.common.hw,
+		[CLK_TWSI4_BUS]		= &twsi4_bus_clk.common.hw,
+		[CLK_TWSI5_BUS]		= &twsi5_bus_clk.common.hw,
+		[CLK_TWSI6_BUS]		= &twsi6_bus_clk.common.hw,
+		[CLK_TWSI7_BUS]		= &twsi7_bus_clk.common.hw,
+		[CLK_TWSI8_BUS]		= &twsi8_bus_clk.common.hw,
+		[CLK_TIMERS1_BUS]	= &timers1_bus_clk.common.hw,
+		[CLK_TIMERS2_BUS]	= &timers2_bus_clk.common.hw,
+		[CLK_AIB_BUS]		= &aib_bus_clk.common.hw,
+		[CLK_ONEWIRE_BUS]	= &onewire_bus_clk.common.hw,
+		[CLK_SSPA0_BUS]		= &sspa0_bus_clk.common.hw,
+		[CLK_SSPA1_BUS]		= &sspa1_bus_clk.common.hw,
+		[CLK_TSEN_BUS]		= &tsen_bus_clk.common.hw,
+		[CLK_IPC_AP2AUD_BUS]	= &ipc_ap2aud_bus_clk.common.hw,
+	},
+	.num = CLK_APBC_NUM,
+};
+
+static struct clk_hw_onecell_data k1_ccu_apmu_clks = {
+	.hws = {
+		[CLK_CCI550]		= &cci550_clk.common.hw,
+		[CLK_CPU_C0_HI]		= &cpu_c0_hi_clk.common.hw,
+		[CLK_CPU_C0_CORE]	= &cpu_c0_core_clk.common.hw,
+		[CLK_CPU_C0_ACE]	= &cpu_c0_ace_clk.common.hw,
+		[CLK_CPU_C0_TCM]	= &cpu_c0_tcm_clk.common.hw,
+		[CLK_CPU_C1_HI]		= &cpu_c1_hi_clk.common.hw,
+		[CLK_CPU_C1_CORE]	= &cpu_c1_core_clk.common.hw,
+		[CLK_CPU_C1_ACE]	= &cpu_c1_ace_clk.common.hw,
+		[CLK_CCIC_4X]		= &ccic_4x_clk.common.hw,
+		[CLK_CCIC1PHY]		= &ccic1phy_clk.common.hw,
+		[CLK_SDH_AXI]		= &sdh_axi_aclk.common.hw,
+		[CLK_SDH0]		= &sdh0_clk.common.hw,
+		[CLK_SDH1]		= &sdh1_clk.common.hw,
+		[CLK_SDH2]		= &sdh2_clk.common.hw,
+		[CLK_USB_P1]		= &usb_p1_aclk.common.hw,
+		[CLK_USB_AXI]		= &usb_axi_clk.common.hw,
+		[CLK_USB30]		= &usb30_clk.common.hw,
+		[CLK_QSPI]		= &qspi_clk.common.hw,
+		[CLK_QSPI_BUS]		= &qspi_bus_clk.common.hw,
+		[CLK_DMA]		= &dma_clk.common.hw,
+		[CLK_AES]		= &aes_clk.common.hw,
+		[CLK_VPU]		= &vpu_clk.common.hw,
+		[CLK_GPU]		= &gpu_clk.common.hw,
+		[CLK_EMMC]		= &emmc_clk.common.hw,
+		[CLK_EMMC_X]		= &emmc_x_clk.common.hw,
+		[CLK_AUDIO]		= &audio_clk.common.hw,
+		[CLK_HDMI]		= &hdmi_mclk.common.hw,
+		[CLK_PMUA_ACLK]		= &pmua_aclk.common.hw,
+		[CLK_PCIE0]		= &pcie0_clk.common.hw,
+		[CLK_PCIE1]		= &pcie1_clk.common.hw,
+		[CLK_PCIE2]		= &pcie2_clk.common.hw,
+		[CLK_EMAC0_BUS]		= &emac0_bus_clk.common.hw,
+		[CLK_EMAC0_PTP]		= &emac0_ptp_clk.common.hw,
+		[CLK_EMAC1_BUS]		= &emac1_bus_clk.common.hw,
+		[CLK_EMAC1_PTP]		= &emac1_ptp_clk.common.hw,
+		[CLK_JPG]		= &jpg_clk.common.hw,
+		[CLK_CCIC2PHY]		= &ccic2phy_clk.common.hw,
+		[CLK_CCIC3PHY]		= &ccic3phy_clk.common.hw,
+		[CLK_CSI]		= &csi_clk.common.hw,
+		[CLK_CAMM0]		= &camm0_clk.common.hw,
+		[CLK_CAMM1]		= &camm1_clk.common.hw,
+		[CLK_CAMM2]		= &camm2_clk.common.hw,
+		[CLK_ISP_CPP]		= &isp_cpp_clk.common.hw,
+		[CLK_ISP_BUS]		= &isp_bus_clk.common.hw,
+		[CLK_ISP]		= &isp_clk.common.hw,
+		[CLK_DPU_MCLK]		= &dpu_mclk.common.hw,
+		[CLK_DPU_ESC]		= &dpu_esc_clk.common.hw,
+		[CLK_DPU_BIT]		= &dpu_bit_clk.common.hw,
+		[CLK_DPU_PXCLK]		= &dpu_pxclk.common.hw,
+		[CLK_DPU_HCLK]		= &dpu_hclk.common.hw,
+		[CLK_DPU_SPI]		= &dpu_spi_clk.common.hw,
+		[CLK_DPU_SPI_HBUS]	= &dpu_spi_hbus_clk.common.hw,
+		[CLK_DPU_SPIBUS]	= &dpu_spi_bus_clk.common.hw,
+		[CLK_DPU_SPI_ACLK]	= &dpu_spi_aclk.common.hw,
+		[CLK_V2D]		= &v2d_clk.common.hw,
+		[CLK_EMMC_BUS]		= &emmc_bus_clk.common.hw,
+	},
+	.num = CLK_APMU_NUM
+};
+
+struct spacemit_ccu_data {
+	struct clk_hw_onecell_data *hw_clks;
+	bool need_pll_lock;
+};
+
+struct spacemit_ccu_priv {
+	const struct spacemit_ccu_data *data;
+	struct regmap *base;
+	struct regmap *lock_base;
+};
+
+static int spacemit_ccu_register(struct device *dev,
+				 struct spacemit_ccu_priv *priv)
+{
+	const struct spacemit_ccu_data *data = priv->data;
+	int i, ret;
+
+	for (i = 0; i < data->hw_clks->num; i++) {
+		struct clk_hw *hw = data->hw_clks->hws[i];
+		struct ccu_common *common;
+		const char *name;
+
+		if (!hw)
+			continue;
+
+		common = hw_to_ccu_common(hw);
+		name = hw->init->name;
+
+		common->base		= priv->base;
+		common->lock_base	= priv->lock_base;
+
+		ret = devm_clk_hw_register(dev, hw);
+		if (ret) {
+			dev_err(dev, "Cannot register clock %d - %s\n",
+				i, name);
+			return ret;
+		}
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   data->hw_clks);
+}
+
+static int k1_ccu_probe(struct platform_device *pdev)
+{
+	const struct spacemit_ccu_data *data;
+	struct regmap *base_map, *lock_map;
+	struct device *dev = &pdev->dev;
+	struct spacemit_ccu_priv *priv;
+	struct device_node *parent;
+	int ret;
+
+	data = of_device_get_match_data(dev);
+	if (WARN_ON(!data))
+		return -EINVAL;
+
+	parent   = of_get_parent(dev->of_node);
+	base_map = syscon_node_to_regmap(parent);
+	of_node_put(parent);
+
+	if (IS_ERR(base_map))
+		return dev_err_probe(dev, PTR_ERR(base_map),
+				     "failed to get regmap\n");
+
+	if (data->need_pll_lock) {
+		lock_map = syscon_regmap_lookup_by_phandle(dev->of_node,
+							   "spacemit,mpmu");
+		if (IS_ERR(lock_map))
+			return dev_err_probe(dev, PTR_ERR(lock_map),
+					     "failed to get lock regmap\n");
+	}
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->data	= data;
+	priv->base	= base_map;
+	priv->lock_base	= lock_map;
+
+	ret = spacemit_ccu_register(dev, priv);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register clocks\n");
+
+	return 0;
+}
+
+static const struct spacemit_ccu_data k1_ccu_apbs_data = {
+	.need_pll_lock	= true,
+	.hw_clks	= &k1_ccu_apbs_clks,
+};
+
+static const struct spacemit_ccu_data k1_ccu_mpmu_data = {
+	.need_pll_lock	= false,
+	.hw_clks	= &k1_ccu_mpmu_clks,
+};
+
+static const struct spacemit_ccu_data k1_ccu_apbc_data = {
+	.need_pll_lock	= false,
+	.hw_clks	= &k1_ccu_apbc_clks,
+};
+
+static const struct spacemit_ccu_data k1_ccu_apmu_data = {
+	.need_pll_lock	= false,
+	.hw_clks	= &k1_ccu_apmu_clks,
+};
+
+static const struct of_device_id of_k1_ccu_match[] = {
+	{
+		.compatible	= "spacemit,k1-ccu-apbs",
+		.data		= &k1_ccu_apbs_data,
+	},
+	{
+		.compatible	= "spacemit,k1-ccu-mpmu",
+		.data		= &k1_ccu_mpmu_data,
+	},
+	{
+		.compatible	= "spacemit,k1-ccu-apbc",
+		.data		= &k1_ccu_apbc_data,
+	},
+	{
+		.compatible	= "spacemit,k1-ccu-apmu",
+		.data		= &k1_ccu_apmu_data,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, of_k1_ccu_match);
+
+static struct platform_driver k1_ccu_driver = {
+	.driver = {
+		.name		= "spacemit,k1-ccu",
+		.of_match_table = of_k1_ccu_match,
+	},
+	.probe	= k1_ccu_probe,
+};
+module_platform_driver(k1_ccu_driver);
+
+MODULE_DESCRIPTION("Spacemit K1 CCU driver");
+MODULE_AUTHOR("Haylen Chu <heylenay at outlook.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/spacemit/ccu_common.h b/drivers/clk/spacemit/ccu_common.h
new file mode 100644
index 000000000000..9910fb69bc9e
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_common.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay at outlook.com>
+ */
+
+#ifndef _CCU_COMMON_H_
+#define _CCU_COMMON_H_
+
+#include <linux/regmap.h>
+
+enum ccu_div_type {
+	CLK_DIV_TYPE_1REG_NOFC_V1 = 0,
+	CLK_DIV_TYPE_1REG_FC_V2,
+	CLK_DIV_TYPE_2REG_NOFC_V3,
+	CLK_DIV_TYPE_2REG_FC_V4,
+	CLK_DIV_TYPE_1REG_FC_DIV_V5,
+	CLK_DIV_TYPE_1REG_FC_MUX_V6,
+};
+
+struct ccu_common {
+	struct regmap *base;
+	struct regmap *lock_base;
+
+	enum ccu_div_type reg_type;
+
+	union {
+		struct {
+			u32 reg_ctrl;
+			u32 reg_sel;
+			u32 reg_xtc;
+			u32 fc;
+		};
+		struct {
+			u32 reg_swcr1;
+			u32 reg_swcr2;
+			u32 reg_swcr3;
+		};
+	};
+
+	unsigned long flags;
+	const char *name;
+	const char * const *parent_names;
+	int num_parents;
+
+	struct clk_hw hw;
+};
+
+static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw)
+{
+	return container_of(hw, struct ccu_common, hw);
+}
+
+#define ccu_read(reg, c, val)	regmap_read((c)->base, (c)->reg_##reg, val)
+#define ccu_write(reg, c, val)	regmap_write((c)->base, (c)->reg_##reg, val)
+#define ccu_update(reg, c, mask, val) \
+	regmap_update_bits((c)->base, (c)->reg_##reg, mask, val)
+#define ccu_poll(reg, c, tmp, cond, sleep, timeout) \
+	regmap_read_poll_timeout_atomic((c)->base, (c)->reg_##reg,	\
+					tmp, cond, sleep, timeout)
+
+#endif /* _CCU_COMMON_H_ */
diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c
new file mode 100644
index 000000000000..7a68652676ce
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_ddn.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Spacemit clock type ddn
+ *
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay at outlook.com>
+ */
+
+#include <linux/clk-provider.h>
+
+#include "ccu_ddn.h"
+
+/*
+ * It is M/N clock
+ *
+ * Fout from synthesizer can be given from two equations:
+ * numerator/denominator = Fin / (Fout * factor)
+ */
+static void ccu_ddn_disable(struct clk_hw *hw)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_common *common = &ddn->common;
+
+	if (!ddn->gate)
+		return;
+
+	ccu_update(sel, common, ddn->gate, 0);
+}
+
+static int ccu_ddn_enable(struct clk_hw *hw)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_common *common = &ddn->common;
+
+	if (!ddn->gate)
+		return 0;
+
+	ccu_update(sel, common, ddn->gate, ddn->gate);
+
+	return 0;
+}
+
+static int ccu_ddn_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_common *common = &ddn->common;
+	u32 tmp;
+
+	if (!ddn->gate)
+		return 1;
+
+	ccu_read(sel, common, &tmp);
+
+	return tmp & ddn->gate;
+}
+
+static long clk_ddn_round_rate(struct clk_hw *hw, unsigned long drate,
+			       unsigned long *prate)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_ddn_config *params = &ddn->ddn;
+	unsigned long rate = 0, prev_rate;
+	unsigned long result;
+	int i;
+
+	for (i = 0; i < params->tbl_size; i++) {
+		prev_rate = rate;
+		rate = (((*prate / 10000) * params->tbl[i].den) /
+			(params->tbl[i].num * params->info->factor)) * 10000;
+		if (rate > drate)
+			break;
+	}
+
+	if ((i == 0) || (i == params->tbl_size)) {
+		result = rate;
+	} else {
+		if ((drate - prev_rate) > (rate - drate))
+			result = rate;
+		else
+			result = prev_rate;
+	}
+
+	return result;
+}
+
+static unsigned long clk_ddn_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_ddn_config *params = &ddn->ddn;
+	unsigned int val, num, den;
+	unsigned long rate;
+
+	ccu_read(ctrl, &ddn->common, &val);
+
+	num = (val >> params->info->num_shift) & params->info->num_mask;
+	den = (val >> params->info->den_shift) & params->info->den_mask;
+
+	if (!den)
+		return 0;
+
+	rate = ((parent_rate / 10000)  * den) / (num * params->info->factor);
+	rate *= 10000;
+
+	return rate;
+}
+
+/* Configures new clock rate*/
+static int clk_ddn_set_rate(struct clk_hw *hw, unsigned long drate,
+			    unsigned long prate)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_ddn_config *params = &ddn->ddn;
+	struct ccu_ddn_info *info = params->info;
+	unsigned long prev_rate, rate = 0;
+	int i;
+
+	for (i = 0; i < params->tbl_size; i++) {
+		prev_rate = rate;
+		rate = ((prate / 10000) * params->tbl[i].den) /
+		       (params->tbl[i].num * info->factor);
+		rate *= 10000;
+
+		if (rate > drate)
+			break;
+	}
+
+	if (i > 0)
+		i--;
+
+	ccu_update(ctrl, &ddn->common,
+		   info->num_mask | info->den_mask,
+		   (params->tbl[i].num << info->num_shift) |
+		   (params->tbl[i].den << info->den_shift));
+
+	return 0;
+}
+
+const struct clk_ops spacemit_ccu_ddn_ops = {
+	.disable	= ccu_ddn_disable,
+	.enable		= ccu_ddn_enable,
+	.is_enabled	= ccu_ddn_is_enabled,
+	.recalc_rate	= clk_ddn_recalc_rate,
+	.round_rate	= clk_ddn_round_rate,
+	.set_rate	= clk_ddn_set_rate,
+};
diff --git a/drivers/clk/spacemit/ccu_ddn.h b/drivers/clk/spacemit/ccu_ddn.h
new file mode 100644
index 000000000000..4d369f41404c
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_ddn.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenayy at outlook.com>
+ */
+
+#ifndef _CCU_DDN_H_
+#define _CCU_DDN_H_
+
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+
+struct ccu_ddn_tbl {
+	unsigned int num;
+	unsigned int den;
+};
+
+struct ccu_ddn_info {
+	unsigned int factor;
+	unsigned int num_mask;
+	unsigned int den_mask;
+	unsigned int num_shift;
+	unsigned int den_shift;
+};
+
+struct ccu_ddn_config {
+	struct ccu_ddn_info *info;
+	struct ccu_ddn_tbl *tbl;
+	u32 tbl_size;
+};
+
+struct ccu_ddn {
+	struct ccu_ddn_config  ddn;
+	struct ccu_common	common;
+	u32 gate;
+};
+
+#define CCU_DDN_CONFIG(_info, _table)					\
+	{								\
+		.info		= (struct ccu_ddn_info *)_info,		\
+		.tbl		= (struct ccu_ddn_tbl *)&_table,	\
+		.tbl_size	= ARRAY_SIZE(_table),			\
+	}
+
+#define CCU_DDN_INIT(_name, _parent, _flags) \
+	CLK_HW_INIT_HW(_name, &_parent.common.hw,			\
+		       &spacemit_ccu_ddn_ops, _flags)
+
+#define CCU_DDN_DEFINE(_struct, _name, _parent, _info, _table,		\
+		       _reg_ctrl, _flags)				\
+	struct ccu_ddn _struct = {					\
+		.ddn	= CCU_DDN_CONFIG(_info, _table),		\
+		.common = {						\
+			.reg_ctrl = _reg_ctrl,				\
+			.hw.init  = CCU_DDN_INIT(_name, _parent,	\
+						 _flags),		\
+		}							\
+	}
+
+#define CCU_DDN_GATE_DEFINE(_struct, _name, _parent, _info, _table,	\
+			    _reg_ddn, _reg_gate, _gate_mask, _flags)	\
+	struct ccu_ddn _struct = {					\
+		.ddn	= CCU_DDN_CONFIG(_info, _table),		\
+		.common = {						\
+			.reg_ctrl	= _reg_ddn,			\
+			.reg_sel	= _reg_gate,			\
+			.hw.init = CLK_HW_INIT(_name, _parent,		\
+					       &spacemit_ccu_ddn_ops,	\
+					       _flags),			\
+		}							\
+		.gate	= _gate_mask,					\
+	}
+
+
+static inline struct ccu_ddn *hw_to_ccu_ddn(struct clk_hw *hw)
+{
+	struct ccu_common *common = hw_to_ccu_common(hw);
+
+	return container_of(common, struct ccu_ddn, common);
+}
+
+extern const struct clk_ops spacemit_ccu_ddn_ops;
+
+#endif
diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c
new file mode 100644
index 000000000000..de343405fcc7
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_mix.c
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Spacemit clock type mix(div/mux/gate/factor)
+ *
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay at outlook.com>
+ */
+
+#include <linux/clk-provider.h>
+
+#include "ccu_mix.h"
+
+#define MIX_TIMEOUT	10000
+
+#define mix_hwparam_in_sel(c) \
+	((c)->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || \
+	 (c)->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
+
+static void ccu_mix_disable(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_gate_config *gate = mix->gate;
+
+	if (!gate)
+		return;
+
+	if (mix_hwparam_in_sel(common))
+		ccu_update(sel, common, gate->gate_mask, gate->val_disable);
+	else
+		ccu_update(ctrl, common, gate->gate_mask, gate->val_disable);
+}
+
+static int ccu_mix_enable(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_gate_config *gate = mix->gate;
+	u32 val_enable, mask;
+	u32 tmp;
+
+	if (!gate)
+		return 0;
+
+	val_enable	= gate->val_enable;
+	mask		= gate->gate_mask;
+
+	if (mix_hwparam_in_sel(common))
+		ccu_update(sel, common, mask, val_enable);
+	else
+		ccu_update(ctrl, common, mask, val_enable);
+
+	if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
+	    common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
+		return ccu_poll(sel, common, tmp, (tmp & mask) == val_enable,
+				10, MIX_TIMEOUT);
+	else
+		return ccu_poll(ctrl, common, tmp, (tmp & mask) == val_enable,
+				10, MIX_TIMEOUT);
+}
+
+static int ccu_mix_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_gate_config *gate = mix->gate;
+	u32 tmp;
+
+	if (!gate)
+		return 1;
+
+	if (mix_hwparam_in_sel(common))
+		ccu_read(sel, common, &tmp);
+	else
+		ccu_read(ctrl, common, &tmp);
+
+	return (tmp & gate->gate_mask) == gate->val_enable;
+}
+
+static unsigned long ccu_mix_recalc_rate(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_div_config *div = mix->div;
+	unsigned long val;
+	u32 reg;
+
+	if (!div) {
+		if (mix->factor)
+			return parent_rate * mix->factor->mul / mix->factor->div;
+
+		return parent_rate;
+	}
+
+	if (mix_hwparam_in_sel(common))
+		ccu_read(sel, common, &reg);
+	else
+		ccu_read(ctrl, common, &reg);
+
+	val = reg >> div->shift;
+	val &= (1 << div->width) - 1;
+
+	val = divider_recalc_rate(hw, parent_rate, val, div->table,
+				  div->flags, div->width);
+
+	return val;
+}
+
+
+static int ccu_mix_trigger_fc(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	unsigned int val = 0;
+	int ret = 0;
+
+	if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 ||
+	    common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 ||
+	    common->reg_type == CLK_DIV_TYPE_1REG_FC_DIV_V5 ||
+	    common->reg_type == CLK_DIV_TYPE_1REG_FC_MUX_V6) {
+		ccu_update(ctrl, common, common->fc, common->fc);
+
+		ret = ccu_poll(ctrl, common, val, !(val & common->fc),
+			       5, MIX_TIMEOUT);
+	}
+
+	return ret;
+}
+
+static int ccu_mix_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	return 0;
+}
+
+static unsigned long
+ccu_mix_calc_best_rate(struct clk_hw *hw, unsigned long rate, u32 *mux_val,
+		       u32 *div_val)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_div_config *div = mix->div ? mix->div : NULL;
+	struct clk_hw *parent;
+	unsigned long parent_rate = 0, best_rate = 0;
+	u32 i, j, div_max;
+
+	for (i = 0; i < common->num_parents; i++) {
+		parent = clk_hw_get_parent_by_index(hw, i);
+		if (!parent)
+			continue;
+
+		parent_rate = clk_hw_get_rate(parent);
+
+		if (div)
+			div_max = 1 << div->width;
+		else
+			div_max = 1;
+
+		for (j = 1; j <= div_max; j++) {
+			if (abs(parent_rate/j - rate) < abs(best_rate - rate)) {
+				best_rate = DIV_ROUND_UP_ULL(parent_rate, j);
+				*mux_val = i;
+				*div_val = j - 1;
+			}
+		}
+	}
+
+	return best_rate;
+}
+
+static int ccu_mix_set_rate(struct clk_hw *hw, unsigned long rate,
+			   unsigned long parent_rate)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_div_config *div = mix->div;
+	struct ccu_mux_config *mux = mix->mux;
+	u32 cur_mux, cur_div, mux_val = 0, div_val = 0;
+	unsigned long best_rate = 0;
+	int ret = 0, tmp = 0;
+
+	if (!div && !mux)
+		return 0;
+
+	best_rate = ccu_mix_calc_best_rate(hw, rate, &mux_val, &div_val);
+
+	if (mix_hwparam_in_sel(common))
+		ccu_read(sel, common, &tmp);
+	else
+		ccu_read(ctrl, common, &tmp);
+
+	if (mux) {
+		cur_mux = tmp >> mux->shift;
+		cur_mux &= (1 << mux->width) - 1;
+
+		if (cur_mux != mux_val)
+			clk_hw_set_parent(hw, clk_hw_get_parent_by_index(hw, mux_val));
+	}
+
+	if (div) {
+		cur_div = tmp >> div->shift;
+		cur_div &= (1 << div->width) - 1;
+
+		if (cur_div == div_val)
+			return 0;
+	} else {
+		return 0;
+	}
+
+	tmp = GENMASK(div->width + div->shift - 1, div->shift);
+
+	if (mix_hwparam_in_sel(common))
+		ccu_update(sel, common, tmp, div_val << div->shift);
+	else
+		ccu_update(ctrl, common, tmp, div_val << div->shift);
+
+	if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 ||
+	    common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 ||
+	    common->reg_type == CLK_DIV_TYPE_1REG_FC_DIV_V5)
+		ret = ccu_mix_trigger_fc(hw);
+
+	return ret;
+}
+
+static u8 ccu_mix_get_parent(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_mux_config *mux = mix->mux;
+	u32 reg;
+	u8 parent;
+
+	if (!mux)
+		return 0;
+
+	if (mix_hwparam_in_sel(common))
+		ccu_read(sel, common, &reg);
+	else
+		ccu_read(ctrl, common, &reg);
+
+	parent = reg >> mux->shift;
+	parent &= (1 << mux->width) - 1;
+
+	if (mux->table) {
+		int num_parents = clk_hw_get_num_parents(&common->hw);
+		int i;
+
+		for (i = 0; i < num_parents; i++)
+			if (mux->table[i] == parent)
+				return i;
+	}
+
+	return parent;
+}
+
+static int ccu_mix_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_mux_config *mux = mix->mux;
+	int ret = 0;
+	u32 mask;
+
+	if (!mux)
+		return 0;
+
+	if (mux->table)
+		index = mux->table[index];
+
+	mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
+
+	if (mix_hwparam_in_sel(common))
+		ccu_update(sel, common, mask, index << mux->shift);
+	else
+		ccu_update(ctrl, common, mask, index << mux->shift);
+
+	if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 ||
+	    common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 ||
+	    common->reg_type == CLK_DIV_TYPE_1REG_FC_MUX_V6)
+		ret = ccu_mix_trigger_fc(hw);
+
+	return ret;
+}
+
+const struct clk_ops spacemit_ccu_mix_ops = {
+	.disable	 = ccu_mix_disable,
+	.enable		 = ccu_mix_enable,
+	.is_enabled	 = ccu_mix_is_enabled,
+	.get_parent	 = ccu_mix_get_parent,
+	.set_parent	 = ccu_mix_set_parent,
+	.determine_rate  = ccu_mix_determine_rate,
+	.recalc_rate	 = ccu_mix_recalc_rate,
+	.set_rate	 = ccu_mix_set_rate,
+};
+
diff --git a/drivers/clk/spacemit/ccu_mix.h b/drivers/clk/spacemit/ccu_mix.h
new file mode 100644
index 000000000000..c7d91e1c03fd
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_mix.h
@@ -0,0 +1,336 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay at outlook.com>
+ */
+
+#ifndef _CCU_MIX_H_
+#define _CCU_MIX_H_
+
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+
+struct ccu_gate_config {
+	u32 gate_mask;
+	u32 val_enable;
+	u32 val_disable;
+	u32 flags;
+};
+
+struct ccu_factor_config {
+	u32 div;
+	u32 mul;
+};
+
+struct ccu_mux_config {
+	const u8 *table;
+	u32 flags;
+	u8 shift;
+	u8 width;
+};
+
+struct ccu_div_config {
+	struct clk_div_table *table;
+	u32 max;
+	u32 offset;
+	u32 flags;
+	u8 shift;
+	u8 width;
+};
+
+struct ccu_mix {
+	struct ccu_factor_config *factor;
+	struct ccu_gate_config *gate;
+	struct ccu_div_config *div;
+	struct ccu_mux_config *mux;
+	struct ccu_common common;
+};
+
+#define CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, _flags)		\
+	(&(struct ccu_gate_config) {						\
+		.gate_mask   = _gate_mask,					\
+		.val_enable  = _val_enable,					\
+		.val_disable = _val_disable,					\
+		.flags	     = _flags,						\
+	})
+
+#define CCU_FACTOR_INIT(_div, _mul)					\
+	(&(struct ccu_factor_config) {					\
+		.div = _div,						\
+		.mul = _mul,						\
+	})
+
+
+#define CCU_MUX_INIT(_shift, _width, _table, _flags)			\
+	(&(struct ccu_mux_config) {					\
+		.shift	= _shift,					\
+		.width	= _width,					\
+		.table	= _table,					\
+		.flags	= _flags,					\
+	})
+
+#define CCU_DIV_INIT(_shift, _width, _table, _flags)			\
+	(&(struct ccu_div_config) {					\
+		.shift	= _shift,					\
+		.width	= _width,					\
+		.flags	= _flags,					\
+		.table	= _table,					\
+	})
+
+#define CCU_PARENT_HW(_parent)		{ .hw = &_parent.common.hw }
+#define CCU_PARENT_NAME(_name)		{ .fw_name = #_name }
+
+#define CCU_MIX_INITHW(_name, _parent, _flags)				\
+	(&(struct clk_init_data) {					\
+		.flags		= _flags,				\
+		.name		= _name,				\
+		.parent_data	= (const struct clk_parent_data[])	\
+					{ _parent },			\
+		.num_parents	= 1,					\
+		.ops		= &spacemit_ccu_mix_ops,		\
+	})
+
+#define CCU_MIX_INITHW_PARENTS(_name, _parents, _flags)			\
+	CLK_HW_INIT_PARENTS_DATA(_name, _parents,			\
+				 &spacemit_ccu_mix_ops, _flags)
+
+#define CCU_GATE_DEFINE(_struct, _name, _parent, _reg, _gate_mask,	\
+			 _val_enable, _val_disable, _flags)		\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.common	= {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init	= CCU_MIX_INITHW(_name, _parent,	\
+						 _flags),		\
+	}								\
+}
+
+#define CCU_FACTOR_DEFINE(_struct, _name, _parent, _div, _mul)		\
+struct ccu_mix _struct = {						\
+	.factor	= CCU_FACTOR_INIT(_div, _mul),				\
+	.common = {							\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init	= CCU_MIX_INITHW(_name, _parent, 0),	\
+	}								\
+}
+
+#define CCU_MUX_DEFINE(_struct, _name, _parents, _reg, _shift, _width,	\
+		       _flags)						\
+struct ccu_mix _struct = {						\
+	.mux	= CCU_MUX_INIT(_shift, _width, NULL, 0),		\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	}								\
+}
+
+#define CCU_DIV_DEFINE(_struct, _name, _parent, _reg, _shift, _width,	\
+		       _flags)						\
+struct ccu_mix _struct = {						\
+	.div	= CCU_DIV_INIT(_shift, _width, NULL, 0),		\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init = CCU_MIX_INITHW(_name, _parent, _flags)	\
+	}								\
+}
+
+#define CCU_GATE_FACTOR_DEFINE(_struct, _name, _parent, _reg,		\
+			       _gate_mask, _val_enable, _val_disable,	\
+			       _div, _mul, _flags)			\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.factor	= CCU_FACTOR_INIT(_div, _mul),				\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init = CCU_MIX_INITHW(_name, _parent, _flags)	\
+	}								\
+}
+
+
+#define CCU_MUX_GATE_DEFINE(_struct, _name, _parents, _reg, _shift,	\
+			    _width, _gate_mask, _val_enable,		\
+			    _val_disable, _flags)			\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.mux	= CCU_MUX_INIT(_shift, _width, NULL, 0),		\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	}								\
+}
+
+#define CCU_DIV_GATE_DEFINE(_struct, _name, _parent, _reg, _shift,	\
+			    _width, _gate_mask, _val_enable,		\
+			    _val_disable, _flags)			\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_shift, _width, NULL, 0),		\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init	= CCU_MIX_INITHW(_name, _parent,	\
+						 _flags),		\
+	}								\
+}
+
+
+#define CCU_DIV_MUX_GATE_DEFINE(_struct, _name, _parents,  _reg_ctrl,	\
+				_mshift, _mwidth, _muxshift, _muxwidth,	\
+				_gate_mask, _val_enable, _val_disable,	\
+				_flags)					\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common	= {							\
+		.reg_ctrl	= _reg_ctrl,				\
+		.name		= _name,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	},								\
+}
+
+#define CCU_DIV2_FC_MUX_GATE_DEFINE(_struct, _name, _parents,		\
+				    _reg_ctrl, _reg_sel, _mshift,	\
+				    _mwidth, _fc, _muxshift, _muxwidth,	\
+				    _gate_mask, _val_enable,		\
+				    _val_disable, _flags)		\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+	    .reg_type = CLK_DIV_TYPE_2REG_FC_V4,			\
+		.reg_ctrl	= _reg_ctrl,				\
+		.reg_sel	= _reg_sel,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	},								\
+}
+
+
+#define CCU_DIV_FC_MUX_GATE_DEFINE(_struct, _name, _parents, _reg_ctrl,	\
+				   _mshift, _mwidth, _fc, _muxshift,	\
+				   _muxwidth, _gate_mask, _val_enable,	\
+				   _val_disable, _flags)		\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type	= CLK_DIV_TYPE_1REG_FC_V2,		\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	},								\
+}
+
+#define CCU_DIV_MFC_MUX_GATE_DEFINE(_struct, _name, _parents,		\
+				    _reg_ctrl, _mshift, _mwidth, _fc,	\
+				    _muxshift, _muxwidth, _gate_mask,	\
+				    _val_enable, _val_disable, _flags)	\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type = CLK_DIV_TYPE_1REG_FC_MUX_V6,		\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	},								\
+}
+
+#define CCU_DIV_FC_WITH_GATE_DEFINE(_struct, _name, _parent, _reg_ctrl,	\
+				    _mshift, _mwidth, _fc, _gate_mask,	\
+				    _val_enable, _val_disable, _flags)	\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type = CLK_DIV_TYPE_1REG_FC_V2,			\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init	= CCU_MIXINITHW(_name, _parent,		\
+						_flags),		\
+	},								\
+}
+
+#define CCU_DIV_FC_MUX_DEFINE(_struct, _name, _parents, _reg_ctrl,	\
+			      _mshift, _mwidth, _fc, _muxshift,		\
+			      _muxwidth, _flags)			\
+struct ccu_mix _struct = {						\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type	= CLK_DIV_TYPE_1REG_FC_V2,		\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	},								\
+}
+
+#define CCU_MUX_FC_DEFINE(_struct, _name, _parents, _reg_ctrl, _fc,	\
+			  _muxshift, _muxwidth, _flags)			\
+struct ccu_mix _struct = {						\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type	= CLK_DIV_TYPE_1REG_FC_V2,		\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags)		\
+	},								\
+}
+
+static inline struct ccu_mix *hw_to_ccu_mix(struct clk_hw *hw)
+{
+	struct ccu_common *common = hw_to_ccu_common(hw);
+
+	return container_of(common, struct ccu_mix, common);
+}
+
+extern const struct clk_ops spacemit_ccu_mix_ops;
+
+#endif /* _CCU_DIV_H_ */
diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c
new file mode 100644
index 000000000000..cf6e547f073b
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_pll.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Spacemit clock type pll
+ *
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay at outlook.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+
+#include "ccu_common.h"
+#include "ccu_pll.h"
+
+#define PLL_MIN_FREQ	600000000
+#define PLL_MAX_FREQ	3400000000
+#define PLL_DELAY_TIME	3000
+
+#define PLL_SWCR1_REG5_OFF	0
+#define PLL_SWCR1_REG5_MASK	GENMASK(7, 0)
+#define PLL_SWCR1_REG6_OFF	8
+#define PLL_SWCR1_REG6_MASK	GENMASK(15, 8)
+#define PLL_SWCR1_REG7_OFF	16
+#define PLL_SWCR1_REG7_MASK	GENMASK(23, 16)
+#define PLL_SWCR1_REG8_OFF	24
+#define PLL_SWCR1_REG8_MASK	GENMASK(31, 24)
+
+#define PLL_SWCR2_DIVn_EN(n)	BIT(n + 1)
+#define PLL_SWCR2_ATEST_EN	BIT(12)
+#define PLL_SWCR2_CKTEST_EN	BIT(13)
+#define PLL_SWCR2_DTEST_EN	BIT(14)
+
+#define PLL_SWCR3_DIV_FRC_OFF	0
+#define PLL_SWCR3_DIV_FRC_MASK	GENMASK(23, 0)
+#define PLL_SWCR3_DIV_INT_OFF	24
+#define PLL_SWCR3_DIV_INT_MASK	GENMASK(30, 24)
+#define PLL_SWCR3_EN		BIT(31)
+
+static int ccu_pll_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	u32 tmp;
+
+	ccu_read(swcr3, &p->common, &tmp);
+
+	return tmp & PLL_SWCR3_EN;
+}
+
+/* frequency unit Mhz, return pll vco freq */
+static unsigned long __get_vco_freq(struct clk_hw *hw)
+{
+	unsigned int reg5, reg6, reg7, reg8, size, i;
+	unsigned int div_int, div_frc;
+	struct ccu_pll_rate_tbl *freq_pll_regs_table;
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_common *common = &p->common;
+	u32 tmp;
+
+	ccu_read(swcr1, common, &tmp);
+	reg5 = (tmp & PLL_SWCR1_REG5_MASK) >> PLL_SWCR1_REG5_OFF;
+	reg6 = (tmp & PLL_SWCR1_REG6_MASK) >> PLL_SWCR1_REG6_OFF;
+	reg7 = (tmp & PLL_SWCR1_REG7_MASK) >> PLL_SWCR1_REG7_OFF;
+	reg8 = (tmp & PLL_SWCR1_REG8_MASK) >> PLL_SWCR1_REG8_OFF;
+
+	ccu_read(swcr3, common, &tmp);
+	div_int = (tmp & PLL_SWCR3_DIV_INT_MASK) >> PLL_SWCR3_DIV_INT_OFF;
+	div_frc = (tmp & PLL_SWCR3_DIV_FRC_MASK) >> PLL_SWCR3_DIV_FRC_OFF;
+
+	freq_pll_regs_table = p->pll.rate_tbl;
+	size = p->pll.tbl_size;
+
+	for (i = 0; i < size; i++)
+		if ((freq_pll_regs_table[i].reg5 == reg5) &&
+		    (freq_pll_regs_table[i].reg6 == reg6) &&
+		    (freq_pll_regs_table[i].reg7 == reg7) &&
+		    (freq_pll_regs_table[i].reg8 == reg8) &&
+		    (freq_pll_regs_table[i].div_int == div_int) &&
+		    (freq_pll_regs_table[i].div_frac == div_frc))
+			return freq_pll_regs_table[i].rate;
+
+	WARN_ON_ONCE(1);
+
+	return 0;
+}
+
+static int ccu_pll_enable(struct clk_hw *hw)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_common *common = &p->common;
+	unsigned int tmp;
+	int ret;
+
+	if (ccu_pll_is_enabled(hw))
+		return 0;
+
+	ccu_update(swcr3, common, PLL_SWCR3_EN, PLL_SWCR3_EN);
+
+	/* check lock status */
+	ret = regmap_read_poll_timeout_atomic(common->lock_base,
+					      p->pll.reg_lock,
+					      tmp,
+					      tmp & p->pll.lock_enable_bit,
+					      5, PLL_DELAY_TIME);
+
+	return ret;
+}
+
+static void ccu_pll_disable(struct clk_hw *hw)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_common *common = &p->common;
+
+	ccu_update(swcr3, common, PLL_SWCR3_EN, 0);
+}
+
+/*
+ * pll rate change requires sequence:
+ * clock off -> change rate setting -> clock on
+ * This function doesn't really change rate, but cache the config
+ */
+static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long parent_rate)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_common *common = &p->common;
+	struct ccu_pll_config *params = &p->pll;
+	struct ccu_pll_rate_tbl *entry;
+	unsigned long old_rate;
+	bool found = false;
+	u32 mask, val;
+	int i;
+
+	if (ccu_pll_is_enabled(hw)) {
+		pr_err("%s %s is enabled, ignore the setrate!\n",
+		       __func__, __clk_get_name(hw->clk));
+		return 0;
+	}
+
+	old_rate = __get_vco_freq(hw);
+
+	for (i = 0; i < params->tbl_size; i++) {
+		if (rate == params->rate_tbl[i].rate) {
+			found = true;
+			entry = &params->rate_tbl[i];
+			break;
+		}
+	}
+	WARN_ON_ONCE(!found);
+
+	mask = PLL_SWCR1_REG5_MASK | PLL_SWCR1_REG6_MASK;
+	mask |= PLL_SWCR1_REG7_MASK | PLL_SWCR1_REG8_MASK;
+	val |= entry->reg5 << PLL_SWCR1_REG5_OFF;
+	val |= entry->reg6 << PLL_SWCR1_REG6_OFF;
+	val |= entry->reg7 << PLL_SWCR1_REG7_OFF;
+	val |= entry->reg8 << PLL_SWCR1_REG8_OFF;
+	ccu_update(swcr1, common, mask, val);
+
+	mask = PLL_SWCR3_DIV_INT_MASK | PLL_SWCR3_DIV_FRC_MASK;
+	val = entry->div_int << PLL_SWCR3_DIV_INT_OFF;
+	val |= entry->div_frac << PLL_SWCR3_DIV_FRC_OFF;
+	ccu_update(swcr3, common, mask, val);
+
+	return 0;
+}
+
+static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	return __get_vco_freq(hw);
+}
+
+static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *prate)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_pll_config *params = &p->pll;
+	unsigned long max_rate = 0;
+	unsigned int i;
+
+	for (i = 0; i < params->tbl_size; i++) {
+		if (params->rate_tbl[i].rate <= rate) {
+			if (max_rate < params->rate_tbl[i].rate)
+				max_rate = params->rate_tbl[i].rate;
+		}
+	}
+
+	return MAX(max_rate, PLL_MIN_FREQ);
+}
+
+const struct clk_ops spacemit_ccu_pll_ops = {
+	.enable		= ccu_pll_enable,
+	.disable	= ccu_pll_disable,
+	.set_rate	= ccu_pll_set_rate,
+	.recalc_rate	= ccu_pll_recalc_rate,
+	.round_rate	= ccu_pll_round_rate,
+	.is_enabled	= ccu_pll_is_enabled,
+};
+
diff --git a/drivers/clk/spacemit/ccu_pll.h b/drivers/clk/spacemit/ccu_pll.h
new file mode 100644
index 000000000000..a2252e79ff4a
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_pll.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay at outlook.com>
+ */
+
+#ifndef _CCU_PLL_H_
+#define _CCU_PLL_H_
+
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+
+struct ccu_pll_rate_tbl {
+	unsigned long long rate;
+	u32 reg5;
+	u32 reg6;
+	u32 reg7;
+	u32 reg8;
+	unsigned int div_int;
+	unsigned int div_frac;
+};
+
+struct ccu_pll_config {
+	struct ccu_pll_rate_tbl *rate_tbl;
+	u32 tbl_size;
+	u32 reg_lock;
+	u32 lock_enable_bit;
+};
+
+#define CCU_PLL_RATE(_rate, _reg5, _reg6, _reg7, _reg8, _div_int, _div_frac) \
+	{									\
+		.rate		= (_rate),					\
+		.reg5		= (_reg5),					\
+		.reg6		= (_reg6),					\
+		.reg7		= (_reg7),					\
+		.reg8		= (_reg8),					\
+		.div_int	= (_div_int),				\
+		.div_frac	= (_div_frac),				\
+	}
+
+struct ccu_pll {
+	struct ccu_pll_config	pll;
+	struct ccu_common	common;
+};
+
+#define CCU_PLL_CONFIG(_table, _reg_lock, _lock_enable_bit) \
+	{									\
+		.rate_tbl	 = (struct ccu_pll_rate_tbl *)&(_table),	\
+		.tbl_size	 = ARRAY_SIZE(_table),				\
+		.reg_lock	 = (_reg_lock),					\
+		.lock_enable_bit = (_lock_enable_bit),				\
+	}
+
+#define CCU_PLL_HWINIT(_name, _flags) \
+	CLK_HW_INIT_NO_PARENT(_name, &spacemit_ccu_pll_ops, _flags)
+
+#define CCU_PLL_DEFINE(_struct, _name, _table, _reg_swcr1, _reg_swcr2,	\
+		       _reg_swcr3, _reg_lock, _lock_enable_bit, _flags)		\
+										\
+	struct ccu_pll _struct = {						\
+		.pll	= CCU_PLL_CONFIG(_table, _reg_lock, _lock_enable_bit),	\
+		.common = {							\
+			.reg_swcr1	= _reg_swcr1,				\
+			.reg_swcr2	= _reg_swcr2,				\
+			.reg_swcr3	= _reg_swcr3,				\
+			.hw.init	= CCU_PLL_HWINIT(_name, _flags)		\
+		}								\
+	}
+
+static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw)
+{
+	struct ccu_common *common = hw_to_ccu_common(hw);
+
+	return container_of(common, struct ccu_pll, common);
+}
+
+extern const struct clk_ops spacemit_ccu_pll_ops;
+
+#endif
-- 
2.47.0




From palmer at rivosinc.com  Tue Nov 26 06:32:50 2024
From: palmer at rivosinc.com (Palmer Dabbelt)
Date: Tue, 26 Nov 2024 06:32:50 -0800
Subject: [PATCH] RISC-V: Remove unnecessary include from compat.h
Message-ID: <20241126143250.29708-1-palmer@rivosinc.com>

Without this I get a bunch of build errors like

    In file included from ./include/linux/sched/task_stack.h:12,
                     from ./arch/riscv/include/asm/compat.h:12,
                     from ./arch/riscv/include/asm/pgtable.h:115,
                     from ./include/linux/pgtable.h:6,
                     from ./include/linux/mm.h:30,
                     from arch/riscv/kernel/asm-offsets.c:8:
    ./include/linux/kasan.h:50:37: error: ?MAX_PTRS_PER_PTE? undeclared here (not in a function); did you mean ?PTRS_PER_PTE??
       50 | extern pte_t kasan_early_shadow_pte[MAX_PTRS_PER_PTE + PTE_HWTABLE_PTRS];
          |                                     ^~~~~~~~~~~~~~~~
          |                                     PTRS_PER_PTE
    ./include/linux/kasan.h:51:8: error: unknown type name ?pmd_t?; did you mean ?pgd_t??
       51 | extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD];
          |        ^~~~~
          |        pgd_t
    ./include/linux/kasan.h:51:37: error: ?MAX_PTRS_PER_PMD? undeclared here (not in a function); did you mean ?PTRS_PER_PGD??
       51 | extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD];
          |                                     ^~~~~~~~~~~~~~~~
          |                                     PTRS_PER_PGD
    ./include/linux/kasan.h:52:8: error: unknown type name ?pud_t?; did you mean ?pgd_t??
       52 | extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD];
          |        ^~~~~
          |        pgd_t
    ./include/linux/kasan.h:52:37: error: ?MAX_PTRS_PER_PUD? undeclared here (not in a function); did you mean ?PTRS_PER_PGD??
       52 | extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD];
          |                                     ^~~~~~~~~~~~~~~~
          |                                     PTRS_PER_PGD
    ./include/linux/kasan.h:53:8: error: unknown type name ?p4d_t?; did you mean ?pgd_t??
       53 | extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
          |        ^~~~~
          |        pgd_t
    ./include/linux/kasan.h:53:37: error: ?MAX_PTRS_PER_P4D? undeclared here (not in a function); did you mean ?PTRS_PER_PGD??
       53 | extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
          |                                     ^~~~~~~~~~~~~~~~
          |                                     PTRS_PER_PGD

Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>

Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>
---
 arch/riscv/include/asm/compat.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/riscv/include/asm/compat.h b/arch/riscv/include/asm/compat.h
index aa103530a5c8..6081327e55f5 100644
--- a/arch/riscv/include/asm/compat.h
+++ b/arch/riscv/include/asm/compat.h
@@ -9,7 +9,6 @@
  */
 #include <linux/types.h>
 #include <linux/sched.h>
-#include <linux/sched/task_stack.h>
 #include <asm-generic/compat.h>
 
 static inline int is_compat_task(void)
-- 
2.45.2



From krzk at kernel.org  Tue Nov 26 06:44:20 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Nov 2024 15:44:20 +0100
Subject: [PATCH v3 0/3] Add clock controller support for Spacemit K1
In-Reply-To: <20241126143125.9980-2-heylenay@4d2.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
Message-ID: <015ca99c-e3bd-4e45-8d92-0e0f4de6aacc@kernel.org>

On 26/11/2024 15:31, Haylen Chu wrote:
> The clock tree of Spacemit K1 is managed by several independent
> controllers in different SoC parts. In this series, all clock hardwares
> in APBS, MPMU, APBC and APMU, are implemented. With some changes to UART
> driver, CPU cores and UARTs could be brought up (see below). More clocks
> will be implemented later soon.
> 
> No device tree changes are included since Spacemit K1 UART needs two
> clocks to operate, but for now the driver gets only one. I would like to
> defer the changes until this is resolved.
> 
> This driver has been tested on BananaPi-F3 board and successfully
> brought up I2C, RTC, mmc and ethernet controllers. A clock tree dump
> could be obtained here[1].
> 
> [1]: https://gist.github.com/heylenayy/ebc6316692dd3aff56575dbf0eb4f1a9
> 
> Link: https://developer.spacemit.com/documentation?token=LCrKwWDasiJuROkVNusc2pWTnEb
> 
> Changed from v2
> - dt-binding fixes
What fixes? Be specific, what did you change?

Best regards,
Krzysztof


From krzk at kernel.org  Tue Nov 26 06:46:23 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Nov 2024 15:46:23 +0100
Subject: [PATCH v3 2/3] dt-bindings: soc: spacemit: Add spacemit,k1-syscon
In-Reply-To: <20241126143125.9980-5-heylenay@4d2.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
 <20241126143125.9980-5-heylenay@4d2.org>
Message-ID: <550d80c9-3a7a-4db4-96fa-758cb34dc746@kernel.org>

On 26/11/2024 15:31, Haylen Chu wrote:
> Add documentation to describe Spacemit K1 system controller registers.
> 
> Signed-off-by: Haylen Chu <heylenay at 4d2.org>
> ---
>  .../soc/spacemit/spacemit,k1-syscon.yaml      | 86 +++++++++++++++++++
>  1 file changed, 86 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> 
> diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> new file mode 100644
> index 000000000000..b9f20190a70a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> @@ -0,0 +1,86 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/spacemit/spacemit,k1-syscon.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Spacemit K1 SoC System Controller
> +
> +maintainers:
> +  - Haylen Chu <heylenay at 4d2.org>
> +
> +description:
> +  The Spacemit K1 SoC system controller provides access to shared register files
> +  for related SoC modules, such as clock controller and reset controller.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - spacemit,k1-apbc-syscon
> +          - spacemit,k1-apbs-syscon
> +          - spacemit,k1-apmu-syscon
> +          - spacemit,k1-mpmu-syscon
> +      - const: syscon
> +      - const: simple-mfd
> +
> +  reg:
> +    maxItems: 1
> +
> +  clock-controller:
> +    $ref: /schemas/clock/spacemit,k1-ccu.yaml#
> +    type: object
> +
> +  "#address-cells":
> +    const: 1
> +
> +  "#size-cells":
> +    const: 1
Nothing improved. That's a no-go.

<form letter>
This is a friendly reminder during the review process.

It seems my or other reviewer's previous comments were not fully
addressed. Maybe the feedback got lost between the quotes, maybe you
just forgot to apply it. Please go back to the previous discussion and
either implement all requested changes or keep discussing them.

Thank you.
</form letter>

Best regards,
Krzysztof


From krzk at kernel.org  Tue Nov 26 06:48:33 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Nov 2024 15:48:33 +0100
Subject: [PATCH v3 1/3] dt-bindings: clock: spacemit: Add clock
 controllers of Spacemit K1 SoC
In-Reply-To: <20241126143125.9980-3-heylenay@4d2.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
 <20241126143125.9980-3-heylenay@4d2.org>
Message-ID: <64bf96a3-e28c-4c47-b7b3-e227bbaa7aee@kernel.org>

On 26/11/2024 15:31, Haylen Chu wrote:
> +
> +properties:
> +  compatible:
> +    enum:
> +      - spacemit,k1-ccu-apbs
> +      - spacemit,k1-ccu-mpmu
> +      - spacemit,k1-ccu-apbc
> +      - spacemit,k1-ccu-apmu
> +
> +  clocks:
> +    maxItems: 4
> +
> +  clock-names:
> +    items:
> +      - const: osc_32k

osc

> +      - const: vctcxo_1m
> +      - const: vctcxo_3m
> +      - const: vctcxo_24m
> +
> +  spacemit,mpmu:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon managing "Main PMU (MPMU)" registers. It is used to
> +      check PLL lock status.

Why your example does not have it? Example code is supposed to be complete.

Best regards,
Krzysztof


From krzk at kernel.org  Tue Nov 26 06:50:30 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 26 Nov 2024 15:50:30 +0100
Subject: [PATCH v3 2/3] dt-bindings: soc: spacemit: Add spacemit,k1-syscon
In-Reply-To: <20241126143125.9980-5-heylenay@4d2.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
 <20241126143125.9980-5-heylenay@4d2.org>
Message-ID: <711362cf-5f4c-49e3-b771-38dfb441bc4c@kernel.org>

On 26/11/2024 15:31, Haylen Chu wrote:
> +examples:
> +  - |
> +    osc_32k: clock-32k {
> +        compatible = "fixed-clock";
> +        clock-frequency = <32000>;
> +        clock-output-names = "osc_32k";
> +        #clock-cells = <0>;
> +    };
> +
> +    vctcxo_1m: clock-1m {
> +        compatible = "fixed-clock";
> +        clock-frequency = <1000000>;
> +        clock-output-names = "vctcxo_1m";
> +        #clock-cells = <0>;
> +    };
> +
> +    vctcxo_3m: clock-3m {
> +        compatible = "fixed-clock";
> +        clock-frequency = <3000000>;
> +        clock-output-names = "vctcxo_3m";
> +        #clock-cells = <0>;
> +    };
> +
> +    vctcxo_24m: clock-24m {
> +        compatible = "fixed-clock";
> +        clock-frequency = <24000000>;
> +        clock-output-names = "vctcxo_24m";
> +        #clock-cells = <0>;
> +    };

Drop all above. Your changelog is poor - does not explain this at all.
Write changelogs which detail what you did and why.

Best regards,
Krzysztof


From conor at kernel.org  Tue Nov 26 08:21:13 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 26 Nov 2024 16:21:13 +0000
Subject: [PATCH v4 3/4] dt-bindings: mailbox: add binding for Microchip
 IPC mailbox controller
In-Reply-To: <vkw7o25szfn2upi5776xdojg5n5fxxaxwynth5kynjwjqzrgua@5lwrjqgzlxzi>
References: <20241125175818.213108-1-valentina.fernandezalanis@microchip.com>
 <20241125175818.213108-4-valentina.fernandezalanis@microchip.com>
 <vkw7o25szfn2upi5776xdojg5n5fxxaxwynth5kynjwjqzrgua@5lwrjqgzlxzi>
Message-ID: <20241126-pulmonary-krypton-30da3faa8482@spud>

On Tue, Nov 26, 2024 at 08:04:38AM +0100, Krzysztof Kozlowski wrote:
> On Mon, Nov 25, 2024 at 05:58:17PM +0000, Valentina Fernandez wrote:
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - description:
> > +          Intended for use by software running in supervisor privileged
> > +          mode (s-mode). This SBI interface is compatible with the Mi-V
> > +          Inter-hart Communication (IHC) IP.
> > +        const: microchip,sbi-ipc
> > +
> > +      - description:
> > +          Intended for use by the SBI implementation in machine mode
> > +          (m-mode), this compatible string is for the MIV_IHC Soft-IP.
> > +        const: microchip,miv-ihc-rtl-v2

> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: microchip,sbi-ipc
> > +    then:
> > +      properties:
> > +        reg: false
> 
> What does this mean in reality? Device does not have IO address space?
> Then it is completely different programming model, isn't it?

Ye, different programming models. Two compatibles for the same hardware,
but one represents the m-mode/firmware programming model that has MMIO
access and is the SBI implementation and the other the s-mode/OS
programming model that uses ecalls provided by the SBI implementation.

> > +        microchip,ihc-chan-disabled-mask: false
> > +    else:
> > +      required:
> > +        - reg
> > +        - microchip,ihc-chan-disabled-mask

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241126/490264cf/attachment.sig>

From atishp at rivosinc.com  Tue Nov 26 09:53:42 2024
From: atishp at rivosinc.com (Atish Kumar Patra)
Date: Tue, 26 Nov 2024 09:53:42 -0800
Subject: [PATCH] RISC-V: KVM: Fix csr_write -> csr_set for HVIEN PMU
 overflow bit
In-Reply-To: <CAAQMj+ojdJ3iQ7HHpPudai=yuKwKwhT4VFCdAnrAGA11oSPgcw@mail.gmail.com>
References: <20241124221458.347464-1-michaelneuling@tenstorrent.com>
 <CAAhSdy2Qq61qSLkuFkgiT2o5wXNDp3qO=U40AU1CFkcY6iNYhw@mail.gmail.com> <CAAQMj+ojdJ3iQ7HHpPudai=yuKwKwhT4VFCdAnrAGA11oSPgcw@mail.gmail.com>
Message-ID: <CAHBxVyH+nhZoJtZityYh42wjv7fHHqOQtCv-zJ6n1s8sg2uiaw@mail.gmail.com>

On Sun, Nov 24, 2024 at 8:41?PM Michael Neuling
<MichaelNeuling at tenstorrent.com> wrote:
>
> > > This doesn't cause a problem currently as HVIEN isn't used elsewhere
> > > yet. Found by inspection.
> > >
> >
> > Fixes tag ?
>
> I'll resend in a few days but it's:
>
> Fixes: 16b0bde9a37c ("RISC-V: KVM: Add perf sampling support for guests")
>

Thanks for catching this.
Reviewed-by: Atish Patra <atishp at rivosinc.com>

> (I've also added Atish to CC who was the original author)
>
> > > Signed-off-by: Michael Neuling <michaelneuling at tenstorrent.com>
> >
> > Otherwise it looks good to me.
> >
> > Reviewed-by: Anup Patel <anup at brainfault.org>
>
> Thanks.
>
> Mikey


From conor at kernel.org  Tue Nov 26 09:55:55 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 26 Nov 2024 17:55:55 +0000
Subject: [PATCH v5 1/1] riscv: dts: starfive: jh7110-milkv-mars: enable
 usb0 host function
In-Reply-To: <20241126075740.17419-2-e@freeshell.de>
References: <20241126075740.17419-1-e@freeshell.de>
 <20241126075740.17419-2-e@freeshell.de>
Message-ID: <20241126-overlying-estranged-97adaac4d1aa@spud>

Emil,

On Mon, Nov 25, 2024 at 11:57:25PM -0800, E Shattow wrote:
> Milk-V Mars set JH7110 on-chip USB host mode and vbus pin assignment
> 
> Signed-off-by: E Shattow <e at freeshell.de>

Could you look at this please?

Thanks,
Conor.

> ---
>  .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
> index 0d248b671d4b..3bd62ab78523 100644
> --- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
> +++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
> @@ -53,7 +53,23 @@ &spi0 {
>  	status = "okay";
>  };
>  
> +&sysgpio {
> +	usb0_pins: usb0-0 {
> +		vbus-pins {
> +			pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS,
> +					      GPOEN_ENABLE,
> +					      GPI_NONE)>;
> +			bias-disable;
> +			input-disable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +	};
> +};
> +
>  &usb0 {
> -	dr_mode = "peripheral";
> +	dr_mode = "host";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&usb0_pins>;
>  	status = "okay";
>  };
> -- 
> 2.45.2
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241126/6116c6c3/attachment.sig>

From conor at kernel.org  Tue Nov 26 09:59:23 2024
From: conor at kernel.org (Conor Dooley)
Date: Tue, 26 Nov 2024 17:59:23 +0000
Subject: [PATCH v3 1/1] riscv: dts: starfive: jh7110-pine64-star64:
 enable usb0 host function
In-Reply-To: <20241126073836.17208-2-e@freeshell.de>
References: <20241126073836.17208-1-e@freeshell.de>
 <20241126073836.17208-2-e@freeshell.de>
Message-ID: <20241126-unbraided-underhand-680b9482a24f@spud>

Emil,

On Mon, Nov 25, 2024 at 11:38:17PM -0800, E Shattow wrote:
> Pine64 Star64 set JH7110 on-chip USB host mode and vbus pin assignment
> 

Looks like the same thing here, so same thing here :)

Thanks,
Conor.

> Signed-off-by: E Shattow <e at freeshell.de>
> ---
>  .../boot/dts/starfive/jh7110-pine64-star64.dts | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
> index fe4a490ecc61..b764d4d92fd9 100644
> --- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
> +++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
> @@ -80,7 +80,23 @@ &spi0 {
>  	status = "okay";
>  };
>  
> +&sysgpio {
> +	usb0_pins: usb0-0 {
> +		vbus-pins {
> +			pinmux = <GPIOMUX(25,  GPOUT_SYS_USB_DRIVE_VBUS,
> +					       GPOEN_ENABLE,
> +					       GPI_NONE)>;
> +			bias-disable;
> +			input-disable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +	};
> +};
> +
>  &usb0 {
> -	dr_mode = "peripheral";
> +	dr_mode = "host";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&usb0_pins>;
>  	status = "okay";
>  };
> -- 
> 2.45.2
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241126/9d1cbc58/attachment.sig>

From andrii.nakryiko at gmail.com  Tue Nov 26 11:08:36 2024
From: andrii.nakryiko at gmail.com (Andrii Nakryiko)
Date: Tue, 26 Nov 2024 11:08:36 -0800
Subject: [PATCH] tools: Override makefile ARCH variable if defined, but empty
In-Reply-To: <6a960374-0cd2-4de9-8fc6-c8fe21097b6b@kernel.org>
References: <20241106193208.290067-1-bjorn@kernel.org> <87r076nikd.fsf@all.your.base.are.belong.to.us>
 <Zz7Ng9CzrF_ciAz-@google.com> <6a960374-0cd2-4de9-8fc6-c8fe21097b6b@kernel.org>
Message-ID: <CAEf4BzbY6E4cfFKvnjjXYX=03yGdMa6oLAAca8JXSh9e6b-6iw@mail.gmail.com>

On Thu, Nov 21, 2024 at 3:30?AM Quentin Monnet <qmo at kernel.org> wrote:
>
> 2024-11-20 22:04 UTC-0800 ~ Namhyung Kim <namhyung at kernel.org>
> > On Wed, Nov 20, 2024 at 02:25:22PM +0100, Bj?rn T?pel wrote:
> >> Bj?rn T?pel <bjorn at kernel.org> writes:
> >>
> >>> From: Bj?rn T?pel <bjorn at rivosinc.com>
> >>>
> >>> There are a number of tools (bpftool, selftests), that require a
> >>> "bootstrap" build. Here, a bootstrap build is a build host variant of
> >>> a target. E.g., assume that you're performing a bpftool cross-build on
> >>> x86 to riscv, a bootstrap build would then be an x86 variant of
> >>> bpftool. The typical way to perform the host build variant, is to pass
> >>> "ARCH=" in a sub-make. However, if a variable has been set with a
> >>> command argument, then ordinary assignments in the makefile are
> >>> ignored.
> >>>
> >>> This side-effect results in that ARCH, and variables depending on ARCH
> >>> are not set.
> >>>
> >>> Workaround by overriding ARCH to the host arch, if ARCH is empty.
> >>>
> >>> Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
> >>> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
> >
> > Reviewed-by: Namhyung Kim <namhyung at kernel.org>
>
>
> Acked-by: Quentin Monnet <qmo at kernel.org>
>
>
> >> Arnaldo/Palmer/Quentin:
> >>
> >> A bit unsure what tree this patch should go. It's very important for the
> >> RISC-V builds, so maybe via Palmer's RISC-V tree?
> >
> > I think it'd be best to route this through the bpf tree as it seems the
> > main target is bpftool.  But given the size and the scope of the change,
> > it should be fine with perf-tools or RISC-V tree.
>
>
> The bpf tree would make sense to me as well (but I don't merge patches
> myself; let me Cc BPF maintainers).

Doesn't seem like this file is owned by anyone specific, I guess it's
fine to route it through BPF due to bpftool? Should this be bpf or
bpf-next? Also, please resend targeting the right tree, so BPF CI can
test this.

>
> Quentin


From michaelneuling at tenstorrent.com  Tue Nov 26 20:18:40 2024
From: michaelneuling at tenstorrent.com (Michael Neuling)
Date: Wed, 27 Nov 2024 04:18:40 +0000
Subject: [PATCH v2] RISC-V: KVM: Fix csr_write -> csr_set for HVIEN PMU overflow bit
Message-ID: <20241127041840.419940-1-michaelneuling@tenstorrent.com>

This doesn't cause a problem currently as HVIEN isn't used elsewhere
yet. Found by inspection.

Signed-off-by: Michael Neuling <michaelneuling at tenstorrent.com>
Fixes: 16b0bde9a37c ("RISC-V: KVM: Add perf sampling support for guests")
Reviewed-by: Atish Patra <atishp at rivosinc.com>
Reviewed-by: Anup Patel <anup at brainfault.org>
---
v2:
  Added Fixes tag
  Added Reviews
  No code change
---
 arch/riscv/kvm/aia.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
index 2967d305c4..9f3b527596 100644
--- a/arch/riscv/kvm/aia.c
+++ b/arch/riscv/kvm/aia.c
@@ -552,7 +552,7 @@ void kvm_riscv_aia_enable(void)
 	csr_set(CSR_HIE, BIT(IRQ_S_GEXT));
 	/* Enable IRQ filtering for overflow interrupt only if sscofpmf is present */
 	if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
-		csr_write(CSR_HVIEN, BIT(IRQ_PMU_OVF));
+		csr_set(CSR_HVIEN, BIT(IRQ_PMU_OVF));
 }
 
 void kvm_riscv_aia_disable(void)
-- 
2.34.1



From krzk at kernel.org  Wed Nov 27 00:03:11 2024
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 27 Nov 2024 09:03:11 +0100
Subject: [PATCH v3 1/3] dt-bindings: clock: spacemit: Add clock
 controllers of Spacemit K1 SoC
In-Reply-To: <64bf96a3-e28c-4c47-b7b3-e227bbaa7aee@kernel.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
 <20241126143125.9980-3-heylenay@4d2.org>
 <64bf96a3-e28c-4c47-b7b3-e227bbaa7aee@kernel.org>
Message-ID: <hgtrinu32q2jtxb4z5nvjskjlkwwzxhymtf3alvaxlbqxrbzd3@2rw3uy2tqgnf>

On Tue, Nov 26, 2024 at 03:48:33PM +0100, Krzysztof Kozlowski wrote:
> On 26/11/2024 15:31, Haylen Chu wrote:
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - spacemit,k1-ccu-apbs
> > +      - spacemit,k1-ccu-mpmu
> > +      - spacemit,k1-ccu-apbc
> > +      - spacemit,k1-ccu-apmu
> > +
> > +  clocks:
> > +    maxItems: 4
> > +
> > +  clock-names:
> > +    items:
> > +      - const: osc_32k
> 
> osc
> 
> > +      - const: vctcxo_1m
> > +      - const: vctcxo_3m
> > +      - const: vctcxo_24m
> > +
> > +  spacemit,mpmu:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description:
> > +      Phandle to the syscon managing "Main PMU (MPMU)" registers. It is used to
> > +      check PLL lock status.
> 
> Why your example does not have it? Example code is supposed to be complete.

I think I understand why - this is for only one variant? But then this
should be disallowed in your binding for others. Currently your binding
says that it is required for one and allowed for others.

Best regards,
Krzysztof



From cyy at cyyself.name  Wed Nov 27 01:23:24 2024
From: cyy at cyyself.name (Yangyu Chen)
Date: Wed, 27 Nov 2024 17:23:24 +0800
Subject: [PATCH v11 00/14] riscv: Add support for xtheadvector
In-Reply-To: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
References: <20241113-xtheadvector-v11-0-236c22791ef9@rivosinc.com>
Message-ID: <tencent_0D44A7B1860F54D04B7BC7310AB73B863B05@qq.com>

Tested-by: Yangyu Chen <cyy at cyyself.name>

I applied and tested it on Nezha hardware, and it works fine.

Cheers,
Yangyu Chen

On 11/14/24 10:21, Charlie Jenkins wrote:
> xtheadvector is a custom extension that is based upon riscv vector
> version 0.7.1 [1]. All of the vector routines have been modified to
> support this alternative vector version based upon whether xtheadvector
> was determined to be supported at boot.
> 
> vlenb is not supported on the existing xtheadvector hardware, so a
> devicetree property thead,vlenb is added to provide the vlenb to Linux.
> 
> There is a new hwprobe key RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 that is
> used to request which thead vendor extensions are supported on the
> current platform. This allows future vendors to allocate hwprobe keys
> for their vendor.
> 
> Support for xtheadvector is also added to the vector kselftests.
> 
> Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
> 
> [1] https://github.com/T-head-Semi/thead-extension-spec/blob/95358cb2cca9489361c61d335e03d3134b14133f/xtheadvector.adoc
> 
> ---
> This series is a continuation of a different series that was fragmented
> into two other series in an attempt to get part of it merged in the 6.10
> merge window. The split-off series did not get merged due to a NAK on
> the series that added the generic riscv,vlenb devicetree entry. This
> series has converted riscv,vlenb to thead,vlenb to remedy this issue.
> 
> The original series is titled "riscv: Support vendor extensions and
> xtheadvector" [3].
> 
> I have tested this with an Allwinner Nezha board. I used SkiffOS [1] to
> manage building the image, but upgraded the U-Boot version to Samuel
> Holland's more up-to-date version [2] and changed out the device tree
> used by U-Boot with the device trees that are present in upstream linux
> and this series. Thank you Samuel for all of the work you did to make
> this task possible.
> 
> [1] https://github.com/skiffos/SkiffOS/tree/master/configs/allwinner/nezha
> [2] https://github.com/smaeul/u-boot/commit/2e89b706f5c956a70c989cd31665f1429e9a0b48
> [3] https://lore.kernel.org/all/20240503-dev-charlie-support_thead_vector_6_9-v6-0-cb7624e65d82 at rivosinc.com/
> [4] https://lore.kernel.org/lkml/20240719-support_vendor_extensions-v3-4-0af7587bbec0 at rivosinc.com/T/
> 
> ---
> Changes in v11:
> - Fix an issue where the mitigation was not being properly skipped when
>    requested
> - Fix vstate_discard issue
> - Fix issue when -1 was passed into
>    __riscv_isa_vendor_extension_available()
> - Remove some artifacts from being placed in the test directory
> - Link to v10: https://lore.kernel.org/r/20240911-xtheadvector-v10-0-8d3930091246 at rivosinc.com
> 
> Changes in v10:
> - In DT probing disable vector with new function to clear vendor
>    extension bits for xtheadvector
> - Add ghostwrite mitigations for c9xx CPUs. This disables xtheadvector
>    unless mitigations=off is set as a kernel boot arg
> - Link to v9: https://lore.kernel.org/r/20240806-xtheadvector-v9-0-62a56d2da5d0 at rivosinc.com
> 
> Changes in v9:
> - Rebase onto palmer's for-next
> - Fix sparse error in arch/riscv/kernel/vendor_extensions/thead.c
> - Fix maybe-uninitialized warning in arch/riscv/include/asm/vendor_extensions/vendor_hwprobe.h
> - Wrap some long lines
> - Link to v8: https://lore.kernel.org/r/20240724-xtheadvector-v8-0-cf043168e137 at rivosinc.com
> 
> Changes in v8:
> - Rebase onto palmer's for-next
> - Link to v7: https://lore.kernel.org/r/20240724-xtheadvector-v7-0-b741910ada3e at rivosinc.com
> 
> Changes in v7:
> - Add defs for has_xtheadvector_no_alternatives() and has_xtheadvector()
>    when vector disabled. (Palmer)
> - Link to v6: https://lore.kernel.org/r/20240722-xtheadvector-v6-0-c9af0130fa00 at rivosinc.com
> 
> Changes in v6:
> - Fix return type of is_vector_supported()/is_xthead_supported() to be bool
> - Link to v5: https://lore.kernel.org/r/20240719-xtheadvector-v5-0-4b485fc7d55f at rivosinc.com
> 
> Changes in v5:
> - Rebase on for-next
> - Link to v4: https://lore.kernel.org/r/20240702-xtheadvector-v4-0-2bad6820db11 at rivosinc.com
> 
> Changes in v4:
> - Replace inline asm with C (Samuel)
> - Rename VCSRs to CSRs (Samuel)
> - Replace .insn directives with .4byte directives
> - Link to v3: https://lore.kernel.org/r/20240619-xtheadvector-v3-0-bff39eb9668e at rivosinc.com
> 
> Changes in v3:
> - Add back Heiko's signed-off-by (Conor)
> - Mark RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 as a bitmask
> - Link to v2: https://lore.kernel.org/r/20240610-xtheadvector-v2-0-97a48613ad64 at rivosinc.com
> 
> Changes in v2:
> - Removed extraneous references to "riscv,vlenb" (Jess)
> - Moved declaration of "thead,vlenb" into cpus.yaml and added
>    restriction that it's only applicable to thead cores (Conor)
> - Check CONFIG_RISCV_ISA_XTHEADVECTOR instead of CONFIG_RISCV_ISA_V for
>    thead,vlenb (Jess)
> - Fix naming of hwprobe variables (Evan)
> - Link to v1: https://lore.kernel.org/r/20240609-xtheadvector-v1-0-3fe591d7f109 at rivosinc.com
> 
> ---
> Charlie Jenkins (13):
>        dt-bindings: riscv: Add xtheadvector ISA extension description
>        dt-bindings: cpus: add a thead vlen register length property
>        riscv: dts: allwinner: Add xtheadvector to the D1/D1s devicetree
>        riscv: Add thead and xtheadvector as a vendor extension
>        riscv: vector: Use vlenb from DT for thead
>        riscv: csr: Add CSR encodings for CSR_VXRM/CSR_VXSAT
>        riscv: Add xtheadvector instruction definitions
>        riscv: vector: Support xtheadvector save/restore
>        riscv: hwprobe: Add thead vendor extension probing
>        riscv: hwprobe: Document thead vendor extensions and xtheadvector extension
>        selftests: riscv: Fix vector tests
>        selftests: riscv: Support xtheadvector in vector tests
>        riscv: Add ghostwrite vulnerability
> 
> Heiko Stuebner (1):
>        RISC-V: define the elements of the VCSR vector CSR
> 
>   Documentation/arch/riscv/hwprobe.rst               |  10 +
>   Documentation/devicetree/bindings/riscv/cpus.yaml  |  19 ++
>   .../devicetree/bindings/riscv/extensions.yaml      |  10 +
>   arch/riscv/Kconfig.errata                          |  11 +
>   arch/riscv/Kconfig.vendor                          |  26 ++
>   arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi      |   3 +-
>   arch/riscv/errata/thead/errata.c                   |  28 ++
>   arch/riscv/include/asm/bugs.h                      |  22 ++
>   arch/riscv/include/asm/cpufeature.h                |   2 +
>   arch/riscv/include/asm/csr.h                       |  15 +
>   arch/riscv/include/asm/errata_list.h               |   3 +-
>   arch/riscv/include/asm/hwprobe.h                   |   3 +-
>   arch/riscv/include/asm/switch_to.h                 |   2 +-
>   arch/riscv/include/asm/vector.h                    | 222 +++++++++++----
>   arch/riscv/include/asm/vendor_extensions/thead.h   |  47 ++++
>   .../include/asm/vendor_extensions/thead_hwprobe.h  |  19 ++
>   .../include/asm/vendor_extensions/vendor_hwprobe.h |  37 +++
>   arch/riscv/include/uapi/asm/hwprobe.h              |   3 +-
>   arch/riscv/include/uapi/asm/vendor/thead.h         |   3 +
>   arch/riscv/kernel/Makefile                         |   2 +
>   arch/riscv/kernel/bugs.c                           |  60 ++++
>   arch/riscv/kernel/cpufeature.c                     |  59 +++-
>   arch/riscv/kernel/kernel_mode_vector.c             |   8 +-
>   arch/riscv/kernel/process.c                        |   4 +-
>   arch/riscv/kernel/signal.c                         |   6 +-
>   arch/riscv/kernel/sys_hwprobe.c                    |   5 +
>   arch/riscv/kernel/vector.c                         |  24 +-
>   arch/riscv/kernel/vendor_extensions.c              |  10 +
>   arch/riscv/kernel/vendor_extensions/Makefile       |   2 +
>   arch/riscv/kernel/vendor_extensions/thead.c        |  29 ++
>   .../riscv/kernel/vendor_extensions/thead_hwprobe.c |  19 ++
>   drivers/base/cpu.c                                 |   3 +
>   include/linux/cpu.h                                |   1 +
>   tools/testing/selftests/riscv/vector/.gitignore    |   3 +-
>   tools/testing/selftests/riscv/vector/Makefile      |  17 +-
>   .../selftests/riscv/vector/v_exec_initval_nolibc.c |  94 +++++++
>   tools/testing/selftests/riscv/vector/v_helpers.c   |  68 +++++
>   tools/testing/selftests/riscv/vector/v_helpers.h   |   8 +
>   tools/testing/selftests/riscv/vector/v_initval.c   |  22 ++
>   .../selftests/riscv/vector/v_initval_nolibc.c      |  68 -----
>   .../selftests/riscv/vector/vstate_exec_nolibc.c    |  20 +-
>   .../testing/selftests/riscv/vector/vstate_prctl.c  | 305 +++++++++++++--------
>   42 files changed, 1051 insertions(+), 271 deletions(-)
> ---
> base-commit: 0eb512779d642b21ced83778287a0f7a3ca8f2a1
> change-id: 20240530-xtheadvector-833d3d17b423



From bjorn at kernel.org  Wed Nov 27 02:17:46 2024
From: bjorn at kernel.org (=?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?=)
Date: Wed, 27 Nov 2024 11:17:46 +0100
Subject: [PATCH bpf v2] tools: Override makefile ARCH variable if defined, but empty
Message-ID: <20241127101748.165693-1-bjorn@kernel.org>

From: Bj?rn T?pel <bjorn at rivosinc.com>

There are a number of tools (bpftool, selftests), that require a
"bootstrap" build. Here, a bootstrap build is a build host variant of
a target. E.g., assume that you're performing a bpftool cross-build on
x86 to riscv, a bootstrap build would then be an x86 variant of
bpftool. The typical way to perform the host build variant, is to pass
"ARCH=" in a sub-make. However, if a variable has been set with a
command argument, then ordinary assignments in the makefile are
ignored.

This side-effect results in that ARCH, and variables depending on ARCH
are not set.

Workaround by overriding ARCH to the host arch, if ARCH is empty.

Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Tested-by: Alexandre Ghiti <alexghiti at rivosinc.com>
Reviewed-by: Namhyung Kim <namhyung at kernel.org>
Acked-by: Quentin Monnet <qmo at kernel.org>
Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
---
v2: Proper tree tag "bpf".
    Collected *-by tags.

Andrii,

Apologies for missing out the tree tag in the patch. Here's a respin,
and thanks for routing it via the BPF tree.


Bj?rn

---
 tools/scripts/Makefile.arch | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/scripts/Makefile.arch b/tools/scripts/Makefile.arch
index f6a50f06dfc4..eabfe9f411d9 100644
--- a/tools/scripts/Makefile.arch
+++ b/tools/scripts/Makefile.arch
@@ -7,8 +7,8 @@ HOSTARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
                                   -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
                                   -e s/riscv.*/riscv/ -e s/loongarch.*/loongarch/)
 
-ifndef ARCH
-ARCH := $(HOSTARCH)
+ifeq ($(strip $(ARCH)),)
+override ARCH := $(HOSTARCH)
 endif
 
 SRCARCH := $(ARCH)

base-commit: 3448ad23b34e43a2526bd0f9e1221e8de876adec
-- 
2.45.2



From cleger at rivosinc.com  Wed Nov 27 02:30:14 2024
From: cleger at rivosinc.com (=?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?=)
Date: Wed, 27 Nov 2024 11:30:14 +0100
Subject: [PATCH] riscv: module: use a plain variable for list_head instead of a pointer
Message-ID: <20241127103016.2699179-1-cleger@rivosinc.com>

list_head does not need to be allocated, it can be a plain variable.
Remove the pointer which allows to get rid of the allocation as well as
an existing memory leak.

Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>

---
 arch/riscv/kernel/module.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index 1cd461f3d872..47d0ebeec93c 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -23,7 +23,7 @@ struct used_bucket {
 
 struct relocation_head {
 	struct hlist_node node;
-	struct list_head *rel_entry;
+	struct list_head rel_entry;
 	void *location;
 };
 
@@ -634,7 +634,7 @@ process_accumulated_relocations(struct module *me,
 			location = rel_head_iter->location;
 			list_for_each_entry_safe(rel_entry_iter,
 						 rel_entry_iter_tmp,
-						 rel_head_iter->rel_entry,
+						 &rel_head_iter->rel_entry,
 						 head) {
 				curr_type = rel_entry_iter->type;
 				reloc_handlers[curr_type].reloc_handler(
@@ -704,16 +704,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 			return -ENOMEM;
 		}
 
-		rel_head->rel_entry =
-			kmalloc(sizeof(struct list_head), GFP_KERNEL);
-
-		if (!rel_head->rel_entry) {
-			kfree(entry);
-			kfree(rel_head);
-			return -ENOMEM;
-		}
-
-		INIT_LIST_HEAD(rel_head->rel_entry);
+		INIT_LIST_HEAD(&rel_head->rel_entry);
 		rel_head->location = location;
 		INIT_HLIST_NODE(&rel_head->node);
 		if (!current_head->first) {
@@ -722,7 +713,6 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 
 			if (!bucket) {
 				kfree(entry);
-				kfree(rel_head->rel_entry);
 				kfree(rel_head);
 				return -ENOMEM;
 			}
@@ -735,7 +725,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 	}
 
 	/* Add relocation to head of discovered rel_head */
-	list_add_tail(&entry->head, rel_head->rel_entry);
+	list_add_tail(&entry->head, &rel_head->rel_entry);
 
 	return 0;
 }
-- 
2.45.2



From heylenay at 4d2.org  Wed Nov 27 02:37:20 2024
From: heylenay at 4d2.org (Haylen Chu)
Date: Wed, 27 Nov 2024 10:37:20 +0000
Subject: [PATCH v3 1/3] dt-bindings: clock: spacemit: Add clock
 controllers of Spacemit K1 SoC
In-Reply-To: <hgtrinu32q2jtxb4z5nvjskjlkwwzxhymtf3alvaxlbqxrbzd3@2rw3uy2tqgnf>
References: <20241126143125.9980-2-heylenay@4d2.org>
 <20241126143125.9980-3-heylenay@4d2.org>
 <64bf96a3-e28c-4c47-b7b3-e227bbaa7aee@kernel.org>
 <hgtrinu32q2jtxb4z5nvjskjlkwwzxhymtf3alvaxlbqxrbzd3@2rw3uy2tqgnf>
Message-ID: <Z0b2YOdIWfuJINDW@ketchup>

On Wed, Nov 27, 2024 at 09:03:11AM +0100, Krzysztof Kozlowski wrote:
> On Tue, Nov 26, 2024 at 03:48:33PM +0100, Krzysztof Kozlowski wrote:
> > On 26/11/2024 15:31, Haylen Chu wrote:
> > > +
> > > +properties:
> > > +  compatible:
> > > +    enum:
> > > +      - spacemit,k1-ccu-apbs
> > > +      - spacemit,k1-ccu-mpmu
> > > +      - spacemit,k1-ccu-apbc
> > > +      - spacemit,k1-ccu-apmu
> > > +
> > > +  clocks:
> > > +    maxItems: 4
> > > +
> > > +  clock-names:
> > > +    items:
> > > +      - const: osc_32k
> > 
> > osc
> > 
> > > +      - const: vctcxo_1m
> > > +      - const: vctcxo_3m
> > > +      - const: vctcxo_24m
> > > +
> > > +  spacemit,mpmu:
> > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > +    description:
> > > +      Phandle to the syscon managing "Main PMU (MPMU)" registers. It is used to
> > > +      check PLL lock status.
> > 
> > Why your example does not have it? Example code is supposed to be complete.
> 
> I think I understand why - this is for only one variant?

Yes, currently all implemented PLLs are located at APBS region, thus
this property is only meaningful in spacemit,k1-ccu-apbs.

> But then this
> should be disallowed in your binding for others. Currently your binding
> says that it is required for one and allowed for others.

Thanks for the correction. I'm considering moving the definition of
spacemit,mpmu to the if block as well. Is it the correct way to disallow
its usage in other variants?

> 
> Best regards,
> Krzysztof

Thanks,
Haylen Chu


From heylenay at 4d2.org  Wed Nov 27 02:55:42 2024
From: heylenay at 4d2.org (Haylen Chu)
Date: Wed, 27 Nov 2024 10:55:42 +0000
Subject: [PATCH v3 0/3] Add clock controller support for Spacemit K1
In-Reply-To: <015ca99c-e3bd-4e45-8d92-0e0f4de6aacc@kernel.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
 <015ca99c-e3bd-4e45-8d92-0e0f4de6aacc@kernel.org>
Message-ID: <Z0b6rqurcj-gfzjI@ketchup>

On Tue, Nov 26, 2024 at 03:44:20PM +0100, Krzysztof Kozlowski wrote:
> On 26/11/2024 15:31, Haylen Chu wrote:
> > The clock tree of Spacemit K1 is managed by several independent
> > controllers in different SoC parts. In this series, all clock hardwares
> > in APBS, MPMU, APBC and APMU, are implemented. With some changes to UART
> > driver, CPU cores and UARTs could be brought up (see below). More clocks
> > will be implemented later soon.
> > 
> > No device tree changes are included since Spacemit K1 UART needs two
> > clocks to operate, but for now the driver gets only one. I would like to
> > defer the changes until this is resolved.
> > 
> > This driver has been tested on BananaPi-F3 board and successfully
> > brought up I2C, RTC, mmc and ethernet controllers. A clock tree dump
> > could be obtained here[1].
> > 
> > [1]: https://gist.github.com/heylenayy/ebc6316692dd3aff56575dbf0eb4f1a9
> > 
> > Link: https://developer.spacemit.com/documentation?token=LCrKwWDasiJuROkVNusc2pWTnEb
> > 
> > Changed from v2
> > - dt-binding fixes
> What fixes? Be specific, what did you change?

Sorry for the vague changelog about dt-binding changes... I'm willing
to post a more precise one here,

- drop clocks marked as deprecated by the vendor (CLK_JPF_4KAFBC and
  CLK_JPF_2KAFBC)
- add binding of missing bus clocks
- change input clocks to use frequency-aware and more precise names
- mark input clocks and their names as required
- move the example to the (parent) syscon node and complete it
- misc style fixes

> 
> Best regards,
> Krzysztof

Thanks,
Haylen Chu


From emil.renner.berthing at canonical.com  Wed Nov 27 03:00:48 2024
From: emil.renner.berthing at canonical.com (Emil Renner Berthing)
Date: Wed, 27 Nov 2024 03:00:48 -0800
Subject: [PATCH v5 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable
 usb0 host function
In-Reply-To: <20241126075740.17419-1-e@freeshell.de>
References: <20241126075740.17419-1-e@freeshell.de>
Message-ID: <CAJM55Z9wWCaS+FxZ=Gg_RfXXafNEJZC1zHZoPWQ2Y9QYDf9OyA@mail.gmail.com>

E Shattow wrote:
> Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host mode
> and connect vbus pinctrl.
>
> This functionality depends on setting the USB over-current register to
> disable at bootloader phase, for example U-Boot:
> https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

Hi E,

Ideally the JH7110 pinctrl driver would be updated, so Linux can do this itself
and doesn't need to rely on u-boot doing it. I already asked for this here:

https://lore.kernel.org/all/CAJM55Z-+Cxdebcn4MLXfQdOVhx4c2SQ+zMH8cjn-Yq35xO8g0A at mail.gmail.com/

>
> If the over-current register is not prepared for us then the result is no
> change in functional outcome with this patch applied; there is an error
> visible to the user and this additional usb configuration fails (same as
> it is now). On Milk-V Mars with four USB-A ports this applies to one of the
> ports and the remaining three VL805-connected ports via PCIe are not changed.

Thanks for the patches. I don't quite understand when you write "no change in
functional outcome with this patch applied". The USB-C port is already
configured as a peripheral, and I just tried setting up an ethernet gadget on
my VF2 running 6.12 and that works quite well. Does it not work on the Milk-V
Mars board? If it does then these patches would break that functionality.

Here is the script I used for that:
https://paste.c-net.org/BravoLonely

At the very least you'll need to explain in the commit message itself why
changing the USB-C port from peripheral mode to host mode is OK. But ideally
maybe you could make it work in OTG mode, so userspace can choose how they want
to use the port. The same goes for the PINE64 board too.

/Emil

>
> Changes since v4:
>  - Rebase on latest master
>
> Changes since v3:
>  - Rebase on linux-next/master
>  - use tabs for code indent
>
> Changes since v2:
>  - Rebase on 6.12
>
> E Shattow (1):
>   riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
>
>  .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> --
> 2.45.2
>


From heylenay at 4d2.org  Wed Nov 27 03:01:28 2024
From: heylenay at 4d2.org (Haylen Chu)
Date: Wed, 27 Nov 2024 11:01:28 +0000
Subject: [PATCH v3 2/3] dt-bindings: soc: spacemit: Add spacemit,k1-syscon
In-Reply-To: <711362cf-5f4c-49e3-b771-38dfb441bc4c@kernel.org>
References: <20241126143125.9980-2-heylenay@4d2.org>
 <20241126143125.9980-5-heylenay@4d2.org>
 <711362cf-5f4c-49e3-b771-38dfb441bc4c@kernel.org>
Message-ID: <Z0b8CJGrAe_kUeuU@ketchup>

On Tue, Nov 26, 2024 at 03:50:30PM +0100, Krzysztof Kozlowski wrote:
> On 26/11/2024 15:31, Haylen Chu wrote:
> > +examples:
> > +  - |
> > +    osc_32k: clock-32k {
> > +        compatible = "fixed-clock";
> > +        clock-frequency = <32000>;
> > +        clock-output-names = "osc_32k";
> > +        #clock-cells = <0>;
> > +    };
> > +
> > +    vctcxo_1m: clock-1m {
> > +        compatible = "fixed-clock";
> > +        clock-frequency = <1000000>;
> > +        clock-output-names = "vctcxo_1m";
> > +        #clock-cells = <0>;
> > +    };
> > +
> > +    vctcxo_3m: clock-3m {
> > +        compatible = "fixed-clock";
> > +        clock-frequency = <3000000>;
> > +        clock-output-names = "vctcxo_3m";
> > +        #clock-cells = <0>;
> > +    };
> > +
> > +    vctcxo_24m: clock-24m {
> > +        compatible = "fixed-clock";
> > +        clock-frequency = <24000000>;
> > +        clock-output-names = "vctcxo_24m";
> > +        #clock-cells = <0>;
> > +    };
> 
> Drop all above. Your changelog is poor - does not explain this at all.
> Write changelogs which detail what you did and why.

Thanks, I forgot that missing phandle references are acceptable in
dt-binding examples. This and other required changes in v2 that I forgot
to apply will be adapted in v4.

> 
> Best regards,
> Krzysztof

Thanks,
Haylen Chu


From heylenay at 4d2.org  Wed Nov 27 03:20:28 2024
From: heylenay at 4d2.org (Haylen Chu)
Date: Wed, 27 Nov 2024 11:20:28 +0000
Subject: [PATCH v2 3/3] clk: spacemit: Add clock support for Spacemit K1
 SoC
In-Reply-To: <a680b539e815f2e38f23126fede76591.sboyd@kernel.org>
References: <SEYPR01MB4221829A2CD4D4C1704BABD7D7602@SEYPR01MB4221.apcprd01.prod.exchangelabs.com>
 <SEYPR01MB4221AA2CA9C91A695FEFA777D7602@SEYPR01MB4221.apcprd01.prod.exchangelabs.com>
 <a680b539e815f2e38f23126fede76591.sboyd@kernel.org>
Message-ID: <Z0cAfKdexQugojoJ@ketchup>

Hi Stephen,

Sorry for such a late reply. FYI, I have sent a v3 and applied most of
your recommendation.

On Thu, Sep 19, 2024 at 04:08:32PM -0700, Stephen Boyd wrote:
> Quoting Haylen Chu (2024-09-16 15:23:10)
> > +static const char * const apb_parent_names[] = {
> 
> Please don't use strings for parents. Either use struct clk_parent_data
> or clk_hw pointers directly.
> 
> > +       "pll1_d96_25p6", "pll1_d48_51p2", "pll1_d96_25p6", "pll1_d24_102p4"
> > +};

Thanks for the hint, all parents are described with struct
clk_parent_data in v3.

> > +static int k1_ccu_probe(struct platform_device *pdev)
> > +{
> > +       const struct spacemit_ccu_data *data;
> > +       struct regmap *base_map, *lock_map;
> > +       struct device *dev = &pdev->dev;
> > +       struct spacemit_ccu_priv *priv;
> > +       struct device_node *parent;
> > +       int ret;
> > +
> > +       data = of_device_get_match_data(dev);
> > +       if (WARN_ON(!data))
> > +               return -EINVAL;
> > +
> > +       parent   = of_get_parent(dev->of_node);
> > +       base_map = syscon_node_to_regmap(parent);
> > +       of_node_put(parent);
> > +
> > +       if (IS_ERR(base_map))
> > +               return dev_err_probe(dev, PTR_ERR(base_map),
> > +                                    "failed to get regmap\n");
> > +
> > +       if (data->need_pll_lock) {
> > +               lock_map = syscon_regmap_lookup_by_phandle(dev->of_node,
> > +                                                          "spacemit,mpmu");
> > +               if (IS_ERR(lock_map))
> > +                       return dev_err_probe(dev, PTR_ERR(lock_map),
> > +                                            "failed to get lock regmap\n");
> > +       }
> > +
> > +       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +       if (!priv)
> > +               return -ENOMEM;
> > +
> > +       priv->data      = data;
> > +       priv->base      = base_map;
> > +       priv->lock_base = lock_map;
> > +       spin_lock_init(&priv->lock);
> > +
> > +       ret = spacemit_ccu_register(dev, priv);
> > +       if (ret)
> > +               return dev_err_probe(dev, ret, "failed to register clocks");
> 
> Missing newline on printk

Corrected in v3.

> > diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c
> > +static void ccu_ddn_disable(struct clk_hw *hw)
> > +{
> > +       struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
> > +       struct ccu_common *common = &ddn->common;
> > +       unsigned long flags;
> > +
> > +       if (!ddn->gate)
> > +               return;
> > +
> > +       spin_lock_irqsave(common->lock, flags);
> 
> The regmap can have a lock. Can you use that?

Thanks for the hint. This extra lock is dropped in v3. Since all
register operations to shared MMIO regions are performed through
regmap_update_bits(), there cannot be a race.

> > diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c
> > new file mode 100644
> > index 000000000000..750882b6ed93
> > --- /dev/null
> > +++ b/drivers/clk/spacemit/ccu_mix.c
> > +const struct clk_ops spacemit_ccu_mix_ops = {
> > +       .disable         = ccu_mix_disable,
> > +       .enable          = ccu_mix_enable,
> > +       .is_enabled      = ccu_mix_is_enabled,
> > +       .get_parent      = ccu_mix_get_parent,
> > +       .set_parent      = ccu_mix_set_parent,
> > +       .determine_rate  = ccu_mix_determine_rate,
> > +       .round_rate      = ccu_mix_round_rate,
> 
> Only implement determine_rate

Okay, duplicated round_rate is deleted in v3.

> 
> > +       .recalc_rate     = ccu_mix_recalc_rate,
> > +       .set_rate        = ccu_mix_set_rate,
> > +};
> > +
> > diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c
> > new file mode 100644
> > index 000000000000..1f0ece6abcac
> > --- /dev/null
> > +++ b/drivers/clk/spacemit/ccu_pll.c
> > @@ -0,0 +1,226 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Spacemit clock type pll
> > + *
> > + * Copyright (c) 2024 SpacemiT Technology Co. Ltd
> > + * Copyright (c) 2024 Haylen Chu <heylenay at outlook.com>
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/regmap.h>
> > +
> > +#include "ccu_common.h"
> > +#include "ccu_pll.h"
> > +
> > +#define PLL_MIN_FREQ   600000000
> > +#define PLL_MAX_FREQ   3400000000
> > +#define PLL_DELAY_TIME 3000
> > +
> > +#define pll_read_swcr1(c, v)   ccu_read(ctrl, c, v)
> > +#define pll_read_swcr2(c, v)   ccu_read(sel, c, v)
> > +#define pll_read_swcr3(c, v)   ccu_read(xtc, c, v)
> > +
> > +#define pll_update_swcr1(c, m, v)      ccu_update(ctrl, c, m, v)
> > +#define pll_update_swcr2(c, m, v)      ccu_update(sel, c, m, v)
> > +#define pll_update_swcr3(c, m, v)      ccu_update(xtc, c, m, v)
> 
> Please stop wrapping regmap APIs. Just use them directly.

Thanks, I drop the regmap wrappers for each clock type, but keep
ccu_{read,update} in v3 since they save a lot of keystrokes and make
the code easier to read.

> 
> > +
> > +#define PLL_SWCR1_REG5_OFF     0
> > +#define PLL_SWCR1_REG5_MASK    GENMASK(7, 0)
> > +#define PLL_SWCR1_REG6_OFF     8
> > +#define PLL_SWCR1_REG6_MASK    GENMASK(15, 8)
> > +#define PLL_SWCR1_REG7_OFF     16
> > +#define PLL_SWCR1_REG7_MASK    GENMASK(23, 16)
> > +#define PLL_SWCR1_REG8_OFF     24
> > +#define PLL_SWCR1_REG8_MASK    GENMASK(31, 24)
> > +
> > +#define PLL_SWCR2_DIVn_EN(n)   BIT(n + 1)
> > +#define PLL_SWCR2_ATEST_EN     BIT(12)
> > +#define PLL_SWCR2_CKTEST_EN    BIT(13)
> > +#define PLL_SWCR2_DTEST_EN     BIT(14)
> > +
> > +#define PLL_SWCR3_DIV_FRC_OFF  0
> > +#define PLL_SWCR3_DIV_FRC_MASK GENMASK(23, 0)
> > +#define PLL_SWCR3_DIV_INT_OFF  24
> > +#define PLL_SWCR3_DIV_INT_MASK GENMASK(30, 24)
> > +#define PLL_SWCR3_EN           BIT(31)
> > +
> > +static int ccu_pll_is_enabled(struct clk_hw *hw)
> > +{
> > +       struct ccu_pll *p = hw_to_ccu_pll(hw);
> > +       u32 tmp;
> > +
> > +       pll_read_swcr3(&p->common, &tmp);
> > +
> > +       return tmp & PLL_SWCR3_EN;
> > +}
> > +
> > +/* frequency unit Mhz, return pll vco freq */
> > +static unsigned long __get_vco_freq(struct clk_hw *hw)
> > +{
> > +       unsigned int reg5, reg6, reg7, reg8, size, i;
> > +       unsigned int div_int, div_frc;
> > +       struct ccu_pll_rate_tbl *freq_pll_regs_table;
> > +       struct ccu_pll *p = hw_to_ccu_pll(hw);
> > +       struct ccu_common *common = &p->common;
> > +       u32 tmp;
> > +
> > +       pll_read_swcr1(common, &tmp);
> > +       reg5 = (tmp & PLL_SWCR1_REG5_MASK) >> PLL_SWCR1_REG5_OFF;
> > +       reg6 = (tmp & PLL_SWCR1_REG6_MASK) >> PLL_SWCR1_REG6_OFF;
> > +       reg7 = (tmp & PLL_SWCR1_REG7_MASK) >> PLL_SWCR1_REG7_OFF;
> > +       reg8 = (tmp & PLL_SWCR1_REG8_MASK) >> PLL_SWCR1_REG8_OFF;
> > +
> > +       pll_read_swcr3(common, &tmp);
> > +       div_int = (tmp & PLL_SWCR3_DIV_INT_MASK) >> PLL_SWCR3_DIV_INT_OFF;
> > +       div_frc = (tmp & PLL_SWCR3_DIV_FRC_MASK) >> PLL_SWCR3_DIV_FRC_OFF;
> > +
> > +       freq_pll_regs_table = p->pll.rate_tbl;
> > +       size = p->pll.tbl_size;
> > +
> > +       for (i = 0; i < size; i++)
> > +               if ((freq_pll_regs_table[i].reg5 == reg5) &&
> > +                   (freq_pll_regs_table[i].reg6 == reg6) &&
> > +                   (freq_pll_regs_table[i].reg7 == reg7) &&
> > +                   (freq_pll_regs_table[i].reg8 == reg8) &&
> > +                   (freq_pll_regs_table[i].div_int == div_int) &&
> > +                   (freq_pll_regs_table[i].div_frac == div_frc))
> > +                       return freq_pll_regs_table[i].rate;
> > +
> > +       WARN_ON_ONCE(1);
> > +
> > +       return 0;
> > +}
> > +
> > +static int ccu_pll_enable(struct clk_hw *hw)
> > +{
> > +       struct ccu_pll *p = hw_to_ccu_pll(hw);
> > +       struct ccu_common *common = &p->common;
> > +       unsigned long flags;
> > +       unsigned int tmp;
> > +       int ret;
> > +
> > +       if (ccu_pll_is_enabled(hw))
> > +               return 0;
> > +
> > +       spin_lock_irqsave(common->lock, flags);
> > +
> > +       pll_update_swcr3(common, PLL_SWCR3_EN, PLL_SWCR3_EN);
> > +
> > +       spin_unlock_irqrestore(common->lock, flags);
> > +
> > +       /* check lock status */
> > +       ret = regmap_read_poll_timeout_atomic(common->lock_base,
> > +                                             p->pll.reg_lock,
> > +                                             tmp,
> > +                                             tmp & p->pll.lock_enable_bit,
> > +                                             5, PLL_DELAY_TIME);
> > +
> > +       return ret;
> > +}
> > +
> > +static void ccu_pll_disable(struct clk_hw *hw)
> > +{
> > +       struct ccu_pll *p = hw_to_ccu_pll(hw);
> > +       struct ccu_common *common = &p->common;
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(p->common.lock, flags);
> > +
> > +       pll_update_swcr3(common, PLL_SWCR3_EN, 0);
> > +
> > +       spin_unlock_irqrestore(common->lock, flags);
> > +}
> > +
> > +/*
> > + * pll rate change requires sequence:
> > + * clock off -> change rate setting -> clock on
> > + * This function doesn't really change rate, but cache the config
> > + */
> > +static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> > +                              unsigned long parent_rate)
> > +{
> > +       struct ccu_pll *p = hw_to_ccu_pll(hw);
> > +       struct ccu_common *common = &p->common;
> > +       struct ccu_pll_config *params = &p->pll;
> > +       struct ccu_pll_rate_tbl *entry;
> > +       unsigned long old_rate;
> > +       unsigned long flags;
> > +       bool found = false;
> > +       u32 mask, val;
> > +       int i;
> > +
> > +       if (ccu_pll_is_enabled(hw)) {
> > +               pr_err("%s %s is enabled, ignore the setrate!\n",
> > +                      __func__, __clk_get_name(hw->clk));
> > +               return 0;
> > +       }
> > +
> > +       old_rate = __get_vco_freq(hw);
> > +
> > +       for (i = 0; i < params->tbl_size; i++) {
> > +               if (rate == params->rate_tbl[i].rate) {
> > +                       found = true;
> > +                       entry = &params->rate_tbl[i];
> > +                       break;
> > +               }
> > +       }
> > +       WARN_ON_ONCE(!found);
> > +
> > +       spin_lock_irqsave(common->lock, flags);
> > +
> > +       mask = PLL_SWCR1_REG5_MASK | PLL_SWCR1_REG6_MASK;
> > +       mask |= PLL_SWCR1_REG7_MASK | PLL_SWCR1_REG8_MASK;
> > +       val |= entry->reg5 << PLL_SWCR1_REG5_OFF;
> > +       val |= entry->reg6 << PLL_SWCR1_REG6_OFF;
> > +       val |= entry->reg7 << PLL_SWCR1_REG7_OFF;
> > +       val |= entry->reg8 << PLL_SWCR1_REG8_OFF;
> > +       pll_update_swcr1(common, mask, val);
> > +
> > +       mask = PLL_SWCR3_DIV_INT_MASK | PLL_SWCR3_DIV_FRC_MASK;
> > +       val = entry->div_int << PLL_SWCR3_DIV_INT_OFF;
> > +       val |= entry->div_frac << PLL_SWCR3_DIV_FRC_OFF;
> > +       pll_update_swcr3(common, mask, val);
> > +
> > +       spin_unlock_irqrestore(common->lock, flags);
> > +
> > +       return 0;
> > +}
> > +
> > +static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
> > +                                        unsigned long parent_rate)
> > +{
> > +       return __get_vco_freq(hw);
> > +}
> > +
> > +static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > +                              unsigned long *prate)
> > +{
> > +       struct ccu_pll *p = hw_to_ccu_pll(hw);
> > +       struct ccu_pll_config *params = &p->pll;
> > +       unsigned long max_rate = 0;
> > +       unsigned int i;
> > +
> > +       if (rate > PLL_MAX_FREQ || rate < PLL_MIN_FREQ) {
> > +               pr_err("%lu rate out of range!\n", rate);
> 
> We should simply clamp the rate here. It doesn't matter what 'rate' is
> when this function is called. The callback is supposed to determine what
> the clk rate will be if a consumer called clk_set_rate() with 'rate'.
> Don't fail that if the rate is requested to be larger than max, just
> tell clk_round_rate() that if you ask for something larger you'll get
> PLL_MAX_FREQ.

Thanks for explaining the convention. I have adapted ccu_pll_round_rate
to follow this behavior in v3.

> > +               return -EINVAL;
> > +       }
> > +

Thanks again for your review and time.

Best regards,
Haylen Chu


From e at freeshell.de  Wed Nov 27 03:52:10 2024
From: e at freeshell.de (E Shattow)
Date: Wed, 27 Nov 2024 03:52:10 -0800
Subject: [PATCH v5 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable
 usb0 host function
In-Reply-To: <CAJM55Z9wWCaS+FxZ=Gg_RfXXafNEJZC1zHZoPWQ2Y9QYDf9OyA@mail.gmail.com>
References: <20241126075740.17419-1-e@freeshell.de>
 <CAJM55Z9wWCaS+FxZ=Gg_RfXXafNEJZC1zHZoPWQ2Y9QYDf9OyA@mail.gmail.com>
Message-ID: <eb06c8e0-ebda-47b9-94f6-6e6eca21097d@freeshell.de>

Hi Emil, thanks for taking time to review!

Added CC: Minda Chen, Hal Feng

Please Minda and Hal can you follow-up on Emil's comments as well?

On 11/27/24 03:00, Emil Renner Berthing wrote:
> E Shattow wrote:
>> Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host mode
>> and connect vbus pinctrl.
>>
>> This functionality depends on setting the USB over-current register to
>> disable at bootloader phase, for example U-Boot:
>> https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/
> Hi E,
>
> Ideally the JH7110 pinctrl driver would be updated, so Linux can do this itself
> and doesn't need to rely on u-boot doing it. I already asked for this here:
>
> https://lore.kernel.org/all/CAJM55Z-+Cxdebcn4MLXfQdOVhx4c2SQ+zMH8cjn-Yq35xO8g0A at mail.gmail.com/

Yes, I agree, and Linux is not the only consumer of devicetree. I would 
like USB function to work for users of Linux and U-Boot on these boards 
by copying what the vendor Board Support Package does what is shipped 
with the products. If it is more in-depth than this I will defer to Hal 
or Minda.


For some wider context, upstream U-Boot is about to adopt the 
dt-rebasing via Hal's OF_UPSTREAM for JH7110 boards series and then also 
there is a patch set from Minda Chen to add the on-chip JH7110 USB 
support to U-Boot, and so then and there it will depend on these dts 
changes. If you have Milk-V Mars then already there are three of four 
USB-A receptacle ports which are functional on PCIe-connected VL805 USB 
chipset.

>
>> If the over-current register is not prepared for us then the result is no
>> change in functional outcome with this patch applied; there is an error
>> visible to the user and this additional usb configuration fails (same as
>> it is now). On Milk-V Mars with four USB-A ports this applies to one of the
>> ports and the remaining three VL805-connected ports via PCIe are not changed.
> Thanks for the patches. I don't quite understand when you write "no change in
> functional outcome with this patch applied". The USB-C port is already
> configured as a peripheral, and I just tried setting up an ethernet gadget on
> my VF2 running 6.12 and that works quite well. Does it not work on the Milk-V
> Mars board? If it does then these patches would break that functionality.
>
> Here is the script I used for that:
> https://paste.c-net.org/BravoLonely
>
> At the very least you'll need to explain in the commit message itself why
> changing the USB-C port from peripheral mode to host mode is OK. But ideally
> maybe you could make it work in OTG mode, so userspace can choose how they want
> to use the port. The same goes for the PINE64 board too.
>
> /Emil

USB-C port on Mars is not wired for data here, that is only true for 
VisionFive2. If the user wants to use their USB-A receptacle as OTG port 
I will not object to a future improvement, but here we want the basic 
expectations of users covered that they should have four working USB-A 
receptacle ports in U-Boot (and possibly in Linux, depending on the 
overcurrent register wherever it is set). This is what I am meaning, 
there may be somebody using a male-male USB-A USB-A cable for OTG but 
more likely is that people just want to plug in USB peripherals to host 
ports and use their mouse / keyboard / flash memory, I think.


There is no USB-C port on Star64.

>
>> Changes since v4:
>>   - Rebase on latest master
>>
>> Changes since v3:
>>   - Rebase on linux-next/master
>>   - use tabs for code indent
>>
>> Changes since v2:
>>   - Rebase on 6.12
>>
>> E Shattow (1):
>>    riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
>>
>>   .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
>>   1 file changed, 17 insertions(+), 1 deletion(-)
>>
>> --
>> 2.45.2
>>
Thanks again Emil.? -E



From olsajiri at gmail.com  Wed Nov 27 03:53:57 2024
From: olsajiri at gmail.com (Jiri Olsa)
Date: Wed, 27 Nov 2024 12:53:57 +0100
Subject: [PATCH bpf v2] tools: Override makefile ARCH variable if
 defined, but empty
In-Reply-To: <20241127101748.165693-1-bjorn@kernel.org>
References: <20241127101748.165693-1-bjorn@kernel.org>
Message-ID: <Z0cIVfgdU5XDoa7g@krava>

On Wed, Nov 27, 2024 at 11:17:46AM +0100, Bj?rn T?pel wrote:
> From: Bj?rn T?pel <bjorn at rivosinc.com>
> 
> There are a number of tools (bpftool, selftests), that require a
> "bootstrap" build. Here, a bootstrap build is a build host variant of
> a target. E.g., assume that you're performing a bpftool cross-build on
> x86 to riscv, a bootstrap build would then be an x86 variant of
> bpftool. The typical way to perform the host build variant, is to pass
> "ARCH=" in a sub-make. However, if a variable has been set with a
> command argument, then ordinary assignments in the makefile are
> ignored.
> 
> This side-effect results in that ARCH, and variables depending on ARCH
> are not set.
> 
> Workaround by overriding ARCH to the host arch, if ARCH is empty.
> 
> Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
> Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
> Tested-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> Reviewed-by: Namhyung Kim <namhyung at kernel.org>
> Acked-by: Quentin Monnet <qmo at kernel.org>
> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>

Acked-by: Jiri Olsa <jolsa at kernel.org>

jirka

> ---
> v2: Proper tree tag "bpf".
>     Collected *-by tags.
> 
> Andrii,
> 
> Apologies for missing out the tree tag in the patch. Here's a respin,
> and thanks for routing it via the BPF tree.
> 
> 
> Bj?rn
> 
> ---
>  tools/scripts/Makefile.arch | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/scripts/Makefile.arch b/tools/scripts/Makefile.arch
> index f6a50f06dfc4..eabfe9f411d9 100644
> --- a/tools/scripts/Makefile.arch
> +++ b/tools/scripts/Makefile.arch
> @@ -7,8 +7,8 @@ HOSTARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
>                                    -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
>                                    -e s/riscv.*/riscv/ -e s/loongarch.*/loongarch/)
>  
> -ifndef ARCH
> -ARCH := $(HOSTARCH)
> +ifeq ($(strip $(ARCH)),)
> +override ARCH := $(HOSTARCH)
>  endif
>  
>  SRCARCH := $(ARCH)
> 
> base-commit: 3448ad23b34e43a2526bd0f9e1221e8de876adec
> -- 
> 2.45.2
> 
> 


From emil.renner.berthing at canonical.com  Wed Nov 27 05:16:53 2024
From: emil.renner.berthing at canonical.com (Emil Renner Berthing)
Date: Wed, 27 Nov 2024 05:16:53 -0800
Subject: [PATCH v5 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable
 usb0 host function
In-Reply-To: <eb06c8e0-ebda-47b9-94f6-6e6eca21097d@freeshell.de>
References: <20241126075740.17419-1-e@freeshell.de> <CAJM55Z9wWCaS+FxZ=Gg_RfXXafNEJZC1zHZoPWQ2Y9QYDf9OyA@mail.gmail.com>
 <eb06c8e0-ebda-47b9-94f6-6e6eca21097d@freeshell.de>
Message-ID: <CAJM55Z_Cy2aAfWY-6csKBuv3AJ44h4fCCvJ0ZSbLOYcKw6g=bA@mail.gmail.com>

E Shattow wrote:
> Hi Emil, thanks for taking time to review!
>
> Added CC: Minda Chen, Hal Feng
>
> Please Minda and Hal can you follow-up on Emil's comments as well?
>
> On 11/27/24 03:00, Emil Renner Berthing wrote:
> > E Shattow wrote:
> >> Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host mode
> >> and connect vbus pinctrl.
> >>
> >> This functionality depends on setting the USB over-current register to
> >> disable at bootloader phase, for example U-Boot:
> >> https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/
> > Hi E,
> >
> > Ideally the JH7110 pinctrl driver would be updated, so Linux can do this itself
> > and doesn't need to rely on u-boot doing it. I already asked for this here:
> >
> > https://lore.kernel.org/all/CAJM55Z-+Cxdebcn4MLXfQdOVhx4c2SQ+zMH8cjn-Yq35xO8g0A at mail.gmail.com/
>
> Yes, I agree, and Linux is not the only consumer of devicetree. I would
> like USB function to work for users of Linux and U-Boot on these boards
> by copying what the vendor Board Support Package does what is shipped
> with the products. If it is more in-depth than this I will defer to Hal
> or Minda.
>
>
> For some wider context, upstream U-Boot is about to adopt the
> dt-rebasing via Hal's OF_UPSTREAM for JH7110 boards series and then also
> there is a patch set from Minda Chen to add the on-chip JH7110 USB
> support to U-Boot, and so then and there it will depend on these dts
> changes. If you have Milk-V Mars then already there are three of four
> USB-A receptacle ports which are functional on PCIe-connected VL805 USB
> chipset.
>
> >
> >> If the over-current register is not prepared for us then the result is no
> >> change in functional outcome with this patch applied; there is an error
> >> visible to the user and this additional usb configuration fails (same as
> >> it is now). On Milk-V Mars with four USB-A ports this applies to one of the
> >> ports and the remaining three VL805-connected ports via PCIe are not changed.
> > Thanks for the patches. I don't quite understand when you write "no change in
> > functional outcome with this patch applied". The USB-C port is already
> > configured as a peripheral, and I just tried setting up an ethernet gadget on
> > my VF2 running 6.12 and that works quite well. Does it not work on the Milk-V
> > Mars board? If it does then these patches would break that functionality.
> >
> > Here is the script I used for that:
> > https://paste.c-net.org/BravoLonely
> >
> > At the very least you'll need to explain in the commit message itself why
> > changing the USB-C port from peripheral mode to host mode is OK. But ideally
> > maybe you could make it work in OTG mode, so userspace can choose how they want
> > to use the port. The same goes for the PINE64 board too.
> >
> > /Emil
>
> USB-C port on Mars is not wired for data here, that is only true for
> VisionFive2. If the user wants to use their USB-A receptacle as OTG port
> I will not object to a future improvement, but here we want the basic
> expectations of users covered that they should have four working USB-A
> receptacle ports in U-Boot (and possibly in Linux, depending on the
> overcurrent register wherever it is set). This is what I am meaning,
> there may be somebody using a male-male USB-A USB-A cable for OTG but
> more likely is that people just want to plug in USB peripherals to host
> ports and use their mouse / keyboard / flash memory, I think.

You're right, sorry. I'm so used to the JH7110 boards being similar, but this
is actually one of the few differences between the Mars and VF2 that was not
caught when the Mars dts was first upstreamed.

Yes, with 4 similar USB-A ports you'd definitely expect all of them to work in
host mode. With an explanation like the above in the commit message I (now)
think your changes makes sense.

Thanks!
/Emil

>
>
> There is no USB-C port on Star64.
>
> >
> >> Changes since v4:
> >>   - Rebase on latest master
> >>
> >> Changes since v3:
> >>   - Rebase on linux-next/master
> >>   - use tabs for code indent
> >>
> >> Changes since v2:
> >>   - Rebase on 6.12
> >>
> >> E Shattow (1):
> >>    riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
> >>
> >>   .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
> >>   1 file changed, 17 insertions(+), 1 deletion(-)
> >>
> >> --
> >> 2.45.2
> >>
> Thanks again Emil.? -E
>


From emil.renner.berthing at canonical.com  Wed Nov 27 05:23:47 2024
From: emil.renner.berthing at canonical.com (Emil Renner Berthing)
Date: Wed, 27 Nov 2024 05:23:47 -0800
Subject: [PATCH v3 1/1] riscv: dts: starfive: jh7110-pine64-star64: enable
 usb0 host function
In-Reply-To: <20241126073836.17208-2-e@freeshell.de>
References: <20241126073836.17208-1-e@freeshell.de> <20241126073836.17208-2-e@freeshell.de>
Message-ID: <CAJM55Z8---o6_ZxeyUu_M74LA_zKfeksBmRGFkm2C66hRJbPug@mail.gmail.com>

E Shattow wrote:
> Pine64 Star64 set JH7110 on-chip USB host mode and vbus pin assignment

Here I'd like it explained that the Star64 board routes 1 of the 4 USB-A ports
to USB0 on the SoC rather than to the USB 3.0 <-> PCIe chip.

(Confusing for users that 1 of the 4 similar ports only does USB 2.0, but
that's too late to change and not relevant here)

With that fixed:
Reviewed-by: Emil Renner Berthing <emil.renner.berthing at canonical.com>

>
> Signed-off-by: E Shattow <e at freeshell.de>
> ---
>  .../boot/dts/starfive/jh7110-pine64-star64.dts | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
> index fe4a490ecc61..b764d4d92fd9 100644
> --- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
> +++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
> @@ -80,7 +80,23 @@ &spi0 {
>  	status = "okay";
>  };
>
> +&sysgpio {
> +	usb0_pins: usb0-0 {
> +		vbus-pins {
> +			pinmux = <GPIOMUX(25,  GPOUT_SYS_USB_DRIVE_VBUS,
> +					       GPOEN_ENABLE,
> +					       GPI_NONE)>;
> +			bias-disable;
> +			input-disable;
> +			input-schmitt-disable;
> +			slew-rate = <0>;
> +		};
> +	};
> +};
> +
>  &usb0 {
> -	dr_mode = "peripheral";
> +	dr_mode = "host";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&usb0_pins>;
>  	status = "okay";
>  };
> --
> 2.45.2
>


From e at freeshell.de  Wed Nov 27 05:38:39 2024
From: e at freeshell.de (E Shattow)
Date: Wed, 27 Nov 2024 05:38:39 -0800
Subject: [PATCH v3 1/1] riscv: dts: starfive: jh7110-pine64-star64: enable
 usb0 host function
In-Reply-To: <CAJM55Z8---o6_ZxeyUu_M74LA_zKfeksBmRGFkm2C66hRJbPug@mail.gmail.com>
References: <20241126073836.17208-1-e@freeshell.de>
 <20241126073836.17208-2-e@freeshell.de>
 <CAJM55Z8---o6_ZxeyUu_M74LA_zKfeksBmRGFkm2C66hRJbPug@mail.gmail.com>
Message-ID: <dd060a05-9428-4af8-85b1-b6baa756490f@freeshell.de>


On 11/27/24 05:23, Emil Renner Berthing wrote:
> E Shattow wrote:
>> Pine64 Star64 set JH7110 on-chip USB host mode and vbus pin assignment
> Here I'd like it explained that the Star64 board routes 1 of the 4 USB-A ports
> to USB0 on the SoC rather than to the USB 3.0 <-> PCIe chip.
>
> (Confusing for users that 1 of the 4 similar ports only does USB 2.0, but
> that's too late to change and not relevant here)
>
> With that fixed:
> Reviewed-by: Emil Renner Berthing <emil.renner.berthing at canonical.com>


There is no (VL805) USB 3.0 <-> PCIe chip on Star64;? All 4 USB-A ports 
route to USB0 of the SoC. What does not exist I did not write about in 
the cover letter. I will expand the description in the commit message. 
Thank you!? -E


>> Signed-off-by: E Shattow <e at freeshell.de>
>> ---
>>   .../boot/dts/starfive/jh7110-pine64-star64.dts | 18 +++++++++++++++++-
>>   1 file changed, 17 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
>> index fe4a490ecc61..b764d4d92fd9 100644
>> --- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
>> +++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
>> @@ -80,7 +80,23 @@ &spi0 {
>>   	status = "okay";
>>   };
>>
>> +&sysgpio {
>> +	usb0_pins: usb0-0 {
>> +		vbus-pins {
>> +			pinmux = <GPIOMUX(25,  GPOUT_SYS_USB_DRIVE_VBUS,
>> +					       GPOEN_ENABLE,
>> +					       GPI_NONE)>;
>> +			bias-disable;
>> +			input-disable;
>> +			input-schmitt-disable;
>> +			slew-rate = <0>;
>> +		};
>> +	};
>> +};
>> +
>>   &usb0 {
>> -	dr_mode = "peripheral";
>> +	dr_mode = "host";
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&usb0_pins>;
>>   	status = "okay";
>>   };
>> --
>> 2.45.2
>>


From ajones at ventanamicro.com  Wed Nov 27 06:02:35 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Wed, 27 Nov 2024 15:02:35 +0100
Subject: [PATCH] riscv: module: use a plain variable for list_head
 instead of a pointer
In-Reply-To: <20241127103016.2699179-1-cleger@rivosinc.com>
References: <20241127103016.2699179-1-cleger@rivosinc.com>
Message-ID: <20241127-2c074e38cc599c7e2d0da505@orel>

On Wed, Nov 27, 2024 at 11:30:14AM +0100, Cl?ment L?ger wrote:
> list_head does not need to be allocated, it can be a plain variable.

rel_head's list_head member, rel_entry, doesn't need to be allocated,
its storage can just be part of the allocated rel_head.

> Remove the pointer which allows to get rid of the allocation as well as
> an existing memory leak.

It'd be nice to add how the memory leak was found. Inspection or some
tool?

> 
> Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
> 
> ---
>  arch/riscv/kernel/module.c | 18 ++++--------------
>  1 file changed, 4 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
> index 1cd461f3d872..47d0ebeec93c 100644
> --- a/arch/riscv/kernel/module.c
> +++ b/arch/riscv/kernel/module.c
> @@ -23,7 +23,7 @@ struct used_bucket {
>  
>  struct relocation_head {
>  	struct hlist_node node;
> -	struct list_head *rel_entry;
> +	struct list_head rel_entry;
>  	void *location;
>  };
>  
> @@ -634,7 +634,7 @@ process_accumulated_relocations(struct module *me,
>  			location = rel_head_iter->location;
>  			list_for_each_entry_safe(rel_entry_iter,
>  						 rel_entry_iter_tmp,
> -						 rel_head_iter->rel_entry,
> +						 &rel_head_iter->rel_entry,
>  						 head) {
>  				curr_type = rel_entry_iter->type;
>  				reloc_handlers[curr_type].reloc_handler(
> @@ -704,16 +704,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
>  			return -ENOMEM;
>  		}
>  
> -		rel_head->rel_entry =
> -			kmalloc(sizeof(struct list_head), GFP_KERNEL);
> -
> -		if (!rel_head->rel_entry) {
> -			kfree(entry);
> -			kfree(rel_head);
> -			return -ENOMEM;
> -		}
> -
> -		INIT_LIST_HEAD(rel_head->rel_entry);
> +		INIT_LIST_HEAD(&rel_head->rel_entry);
>  		rel_head->location = location;
>  		INIT_HLIST_NODE(&rel_head->node);
>  		if (!current_head->first) {
> @@ -722,7 +713,6 @@ static int add_relocation_to_accumulate(struct module *me, int type,
>  
>  			if (!bucket) {
>  				kfree(entry);
> -				kfree(rel_head->rel_entry);
>  				kfree(rel_head);
>  				return -ENOMEM;
>  			}
> @@ -735,7 +725,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
>  	}
>  
>  	/* Add relocation to head of discovered rel_head */
> -	list_add_tail(&entry->head, rel_head->rel_entry);
> +	list_add_tail(&entry->head, &rel_head->rel_entry);
>  
>  	return 0;
>  }
> -- 
> 2.45.2
> 
>

Other than the commit message change suggestions,

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>


From cleger at rivosinc.com  Wed Nov 27 06:18:25 2024
From: cleger at rivosinc.com (=?UTF-8?B?Q2zDqW1lbnQgTMOpZ2Vy?=)
Date: Wed, 27 Nov 2024 15:18:25 +0100
Subject: [PATCH] riscv: module: use a plain variable for list_head instead
 of a pointer
In-Reply-To: <20241127-2c074e38cc599c7e2d0da505@orel>
References: <20241127103016.2699179-1-cleger@rivosinc.com>
 <20241127-2c074e38cc599c7e2d0da505@orel>
Message-ID: <2a902c69-1115-451d-82b7-dcf7641a7c4b@rivosinc.com>



On 27/11/2024 15:02, Andrew Jones wrote:
> On Wed, Nov 27, 2024 at 11:30:14AM +0100, Cl?ment L?ger wrote:
>> list_head does not need to be allocated, it can be a plain variable.
> 
> rel_head's list_head member, rel_entry, doesn't need to be allocated,
> its storage can just be part of the allocated rel_head.
> 
>> Remove the pointer which allows to get rid of the allocation as well as
>> an existing memory leak.
> 
> It'd be nice to add how the memory leak was found. Inspection or some
> tool?

Yeah sure, it was actually found by Kai Zang, I have added him as Cc but
I can surely give him credit for finding the memleak, I'll add him with
a Reported-by.

Thanks,

Cl?ment

> 
>>
>> Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
>>
>> ---
>>  arch/riscv/kernel/module.c | 18 ++++--------------
>>  1 file changed, 4 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
>> index 1cd461f3d872..47d0ebeec93c 100644
>> --- a/arch/riscv/kernel/module.c
>> +++ b/arch/riscv/kernel/module.c
>> @@ -23,7 +23,7 @@ struct used_bucket {
>>  
>>  struct relocation_head {
>>  	struct hlist_node node;
>> -	struct list_head *rel_entry;
>> +	struct list_head rel_entry;
>>  	void *location;
>>  };
>>  
>> @@ -634,7 +634,7 @@ process_accumulated_relocations(struct module *me,
>>  			location = rel_head_iter->location;
>>  			list_for_each_entry_safe(rel_entry_iter,
>>  						 rel_entry_iter_tmp,
>> -						 rel_head_iter->rel_entry,
>> +						 &rel_head_iter->rel_entry,
>>  						 head) {
>>  				curr_type = rel_entry_iter->type;
>>  				reloc_handlers[curr_type].reloc_handler(
>> @@ -704,16 +704,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
>>  			return -ENOMEM;
>>  		}
>>  
>> -		rel_head->rel_entry =
>> -			kmalloc(sizeof(struct list_head), GFP_KERNEL);
>> -
>> -		if (!rel_head->rel_entry) {
>> -			kfree(entry);
>> -			kfree(rel_head);
>> -			return -ENOMEM;
>> -		}
>> -
>> -		INIT_LIST_HEAD(rel_head->rel_entry);
>> +		INIT_LIST_HEAD(&rel_head->rel_entry);
>>  		rel_head->location = location;
>>  		INIT_HLIST_NODE(&rel_head->node);
>>  		if (!current_head->first) {
>> @@ -722,7 +713,6 @@ static int add_relocation_to_accumulate(struct module *me, int type,
>>  
>>  			if (!bucket) {
>>  				kfree(entry);
>> -				kfree(rel_head->rel_entry);
>>  				kfree(rel_head);
>>  				return -ENOMEM;
>>  			}
>> @@ -735,7 +725,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
>>  	}
>>  
>>  	/* Add relocation to head of discovered rel_head */
>> -	list_add_tail(&entry->head, rel_head->rel_entry);
>> +	list_add_tail(&entry->head, &rel_head->rel_entry);
>>  
>>  	return 0;
>>  }
>> -- 
>> 2.45.2
>>
>>
> 
> Other than the commit message change suggestions,
> 
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>



From cleger at rivosinc.com  Wed Nov 27 06:25:17 2024
From: cleger at rivosinc.com (=?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?=)
Date: Wed, 27 Nov 2024 15:25:17 +0100
Subject: [PATCH v2] riscv: module: use a plain variable for list_head instead of a pointer
Message-ID: <20241127142519.3038691-1-cleger@rivosinc.com>

rel_head's list_head member, rel_entry, doesn't need to be allocated,
its storage can just be part of the allocated rel_head. Remove the
pointer which allows to get rid of the allocation as well as an existing
memory leak found by Kai Zang using kmemleak.

Reported-by: Kai Zhang <zhangkai at iscas.ac.cn>
Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
---

V2:
 - Add Kai Reported-by
 - Reword the commit description (Andrew)

---
 arch/riscv/kernel/module.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index 1cd461f3d872..47d0ebeec93c 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -23,7 +23,7 @@ struct used_bucket {
 
 struct relocation_head {
 	struct hlist_node node;
-	struct list_head *rel_entry;
+	struct list_head rel_entry;
 	void *location;
 };
 
@@ -634,7 +634,7 @@ process_accumulated_relocations(struct module *me,
 			location = rel_head_iter->location;
 			list_for_each_entry_safe(rel_entry_iter,
 						 rel_entry_iter_tmp,
-						 rel_head_iter->rel_entry,
+						 &rel_head_iter->rel_entry,
 						 head) {
 				curr_type = rel_entry_iter->type;
 				reloc_handlers[curr_type].reloc_handler(
@@ -704,16 +704,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 			return -ENOMEM;
 		}
 
-		rel_head->rel_entry =
-			kmalloc(sizeof(struct list_head), GFP_KERNEL);
-
-		if (!rel_head->rel_entry) {
-			kfree(entry);
-			kfree(rel_head);
-			return -ENOMEM;
-		}
-
-		INIT_LIST_HEAD(rel_head->rel_entry);
+		INIT_LIST_HEAD(&rel_head->rel_entry);
 		rel_head->location = location;
 		INIT_HLIST_NODE(&rel_head->node);
 		if (!current_head->first) {
@@ -722,7 +713,6 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 
 			if (!bucket) {
 				kfree(entry);
-				kfree(rel_head->rel_entry);
 				kfree(rel_head);
 				return -ENOMEM;
 			}
@@ -735,7 +725,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 	}
 
 	/* Add relocation to head of discovered rel_head */
-	list_add_tail(&entry->head, rel_head->rel_entry);
+	list_add_tail(&entry->head, &rel_head->rel_entry);
 
 	return 0;
 }
-- 
2.45.2



From e at freeshell.de  Wed Nov 27 07:15:04 2024
From: e at freeshell.de (E Shattow)
Date: Wed, 27 Nov 2024 07:15:04 -0800
Subject: [PATCH v4 0/1] riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function
Message-ID: <20241127151843.70341-1-e@freeshell.de>

Enable host mode JH7110 on-chip USB for Pine64 Star64 by setting host mode 
and connect vbus pinctrl.

This functionality depends on setting the USB over-current register to 
disable at bootloader phase, for example U-Boot:
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no 
change in functional outcome with this patch applied; there is an error 
visible to the user and this usb configuration fails (same as it is now).

Changes since v3:
 - Rebase on latest master
 - Addtional detail to commit description

Changes since v2:
 - Rebase on latest master

Changes since v1:
 - Rebase on linux-next/master
 - use tabs for code indent

E Shattow (1):
  riscv: dts: starfive: jh7110-pine64-star64: enable usb0 host function

 .../boot/dts/starfive/jh7110-pine64-star64.dts | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

-- 
2.45.2



From e at freeshell.de  Wed Nov 27 07:15:05 2024
From: e at freeshell.de (E Shattow)
Date: Wed, 27 Nov 2024 07:15:05 -0800
Subject: [PATCH v4 1/1] riscv: dts: starfive: jh7110-pine64-star64: enable usb0  host function
In-Reply-To: <20241127151843.70341-1-e@freeshell.de>
References: <20241127151843.70341-1-e@freeshell.de>
Message-ID: <20241127151843.70341-2-e@freeshell.de>

Pine64 Star64 board routes all four USB-A ports to USB0 on the SoC.
Set JH7110 on-chip USB host mode and vbus pin assignment accordingly.

Signed-off-by: E Shattow <e at freeshell.de>
Reviewed-by: Emil Renner Berthing <emil.renner.berthing at canonical.com>
---
 .../boot/dts/starfive/jh7110-pine64-star64.dts | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
index fe4a490ecc61..b764d4d92fd9 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
@@ -80,7 +80,23 @@ &spi0 {
 	status = "okay";
 };
 
+&sysgpio {
+	usb0_pins: usb0-0 {
+		vbus-pins {
+			pinmux = <GPIOMUX(25,  GPOUT_SYS_USB_DRIVE_VBUS,
+					       GPOEN_ENABLE,
+					       GPI_NONE)>;
+			bias-disable;
+			input-disable;
+			input-schmitt-disable;
+			slew-rate = <0>;
+		};
+	};
+};
+
 &usb0 {
-	dr_mode = "peripheral";
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins>;
 	status = "okay";
 };
-- 
2.45.2



From patchwork-bot+linux-riscv at kernel.org  Wed Nov 27 07:20:34 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 27 Nov 2024 15:20:34 +0000
Subject: [PATCH] RISC-V: Remove unnecessary include from compat.h
In-Reply-To: <20241126143250.29708-1-palmer@rivosinc.com>
References: <20241126143250.29708-1-palmer@rivosinc.com>
Message-ID: <173272083479.1118426.4000843629538344289.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (for-next)
by Palmer Dabbelt <palmer at rivosinc.com>:

On Tue, 26 Nov 2024 06:32:50 -0800 you wrote:
> Without this I get a bunch of build errors like
> 
>     In file included from ./include/linux/sched/task_stack.h:12,
>                      from ./arch/riscv/include/asm/compat.h:12,
>                      from ./arch/riscv/include/asm/pgtable.h:115,
>                      from ./include/linux/pgtable.h:6,
>                      from ./include/linux/mm.h:30,
>                      from arch/riscv/kernel/asm-offsets.c:8:
>     ./include/linux/kasan.h:50:37: error: ?MAX_PTRS_PER_PTE? undeclared here (not in a function); did you mean ?PTRS_PER_PTE??
>        50 | extern pte_t kasan_early_shadow_pte[MAX_PTRS_PER_PTE + PTE_HWTABLE_PTRS];
>           |                                     ^~~~~~~~~~~~~~~~
>           |                                     PTRS_PER_PTE
>     ./include/linux/kasan.h:51:8: error: unknown type name ?pmd_t?; did you mean ?pgd_t??
>        51 | extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD];
>           |        ^~~~~
>           |        pgd_t
>     ./include/linux/kasan.h:51:37: error: ?MAX_PTRS_PER_PMD? undeclared here (not in a function); did you mean ?PTRS_PER_PGD??
>        51 | extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD];
>           |                                     ^~~~~~~~~~~~~~~~
>           |                                     PTRS_PER_PGD
>     ./include/linux/kasan.h:52:8: error: unknown type name ?pud_t?; did you mean ?pgd_t??
>        52 | extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD];
>           |        ^~~~~
>           |        pgd_t
>     ./include/linux/kasan.h:52:37: error: ?MAX_PTRS_PER_PUD? undeclared here (not in a function); did you mean ?PTRS_PER_PGD??
>        52 | extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD];
>           |                                     ^~~~~~~~~~~~~~~~
>           |                                     PTRS_PER_PGD
>     ./include/linux/kasan.h:53:8: error: unknown type name ?p4d_t?; did you mean ?pgd_t??
>        53 | extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
>           |        ^~~~~
>           |        pgd_t
>     ./include/linux/kasan.h:53:37: error: ?MAX_PTRS_PER_P4D? undeclared here (not in a function); did you mean ?PTRS_PER_PGD??
>        53 | extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
>           |                                     ^~~~~~~~~~~~~~~~
>           |                                     PTRS_PER_PGD
> 
> [...]

Here is the summary with links:
  - RISC-V: Remove unnecessary include from compat.h
    https://git.kernel.org/riscv/c/8d4f1e05ff82

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From farbere at amazon.com  Wed Nov 27 07:22:36 2024
From: farbere at amazon.com (Eliav Farber)
Date: Wed, 27 Nov 2024 15:22:36 +0000
Subject: [PATCH v2] arm64: kexec: Check if IRQ is already masked before masking
Message-ID: <20241127152236.26122-1-farbere@amazon.com>

During machine kexec, the function machine_kexec_mask_interrupts() is
responsible for disabling or masking all interrupts. While the
irq_disable hook ensures that an already-disabled IRQ is not disabled
again, the current implementation unconditionally invokes the irq_mask()
function for every interrupt descriptor, even when the interrupt is
already masked.

A specific issue was observed in the crash kernel flow after unbinding a
device (prior to kexec) that used a GPIO as an IRQ source. The warning
was triggered by the gpiochip_disable_irq() function, which attempted to
clear the FLAG_IRQ_IS_ENABLED flag when FLAG_USED_AS_IRQ was not set:

```
void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset)
{
	struct gpio_desc *desc = gpiochip_get_desc(gc, offset);

	if (!IS_ERR(desc) &&
	    !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags)))
		clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
}
```

The issue emerged after commit a8173820f441 ("gpio: gpiolib: Allow GPIO
IRQs to lazy disable"), which introduced lazy disablement for GPIO IRQs
by replacing disable/enable hooks with mask/unmask hooks in some cases.
While irq_disable guarded against redundant operations, the unguarded
irq_mask in machine_kexec_mask_interrupts() led to warnings when invoked
on already-masked IRQs.

When a GPIO-IRQ-using driver is unbound, the IRQ is released, invoking
__irq_disable() and irq_state_set_masked(). A subsequent call to
machine_kexec_mask_interrupts() reinvoked chip->irq_mask(), leading to a
call chain that included gpiochip_irq_mask() and gpiochip_disable_irq().
Because FLAG_USED_AS_IRQ was cleared earlier, a warning was printed.

This patch replaces the direct invocation of the irq_mask() and
irq_disable() hooks with simplified code that leverages the
irq_disable() kernel infrastructure. This higher-level function checks
the interrupt's state to prevent redundant operations. Additionally, the
IRQ_DISABLE_UNLAZY status flag is set to ensure that, for interrupt
chips lacking an irq_disable callback, the disable operation is handled
using the lazy approach.

As part of this change, the irq_disable() declaration was moved from
kernel/irq/internals.h to include/linux/irq.h to make it accessible
outside the kernel/irq/ directory, as the former can only be included
within that directory.

Signed-off-by: Eliav Farber <farbere at amazon.com>
---
V1 -> V2:
- Implement an alternative solution by utilizing the kernel's
  irq_disable() infrastructure.
- Apply the fix to additional architectures, including ARM, PowerPC,
  and RISC-V.
---
 arch/arm/kernel/machine_kexec.c   | 7 ++-----
 arch/arm64/kernel/machine_kexec.c | 7 ++-----
 arch/powerpc/kexec/core.c         | 7 ++-----
 arch/riscv/kernel/machine_kexec.c | 7 ++-----
 include/linux/irq.h               | 2 ++
 kernel/irq/internals.h            | 1 -
 6 files changed, 10 insertions(+), 21 deletions(-)

diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 80ceb5bd2680..54d0bd1bd449 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -142,11 +142,8 @@ static void machine_kexec_mask_interrupts(void)
 		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
 			chip->irq_eoi(&desc->irq_data);
 
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
+		irq_set_status_flags(i, IRQ_DISABLE_UNLAZY);
+		irq_disable(desc);
 	}
 }
 
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 82e2203d86a3..9b48d952df3e 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -230,11 +230,8 @@ static void machine_kexec_mask_interrupts(void)
 		    chip->irq_eoi)
 			chip->irq_eoi(&desc->irq_data);
 
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
+		irq_set_status_flags(i, IRQ_DISABLE_UNLAZY);
+		irq_disable(desc);
 	}
 }
 
diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
index b8333a49ea5d..3489e50f5017 100644
--- a/arch/powerpc/kexec/core.c
+++ b/arch/powerpc/kexec/core.c
@@ -36,11 +36,8 @@ void machine_kexec_mask_interrupts(void) {
 		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
 			chip->irq_eoi(&desc->irq_data);
 
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
+		irq_set_status_flags(i, IRQ_DISABLE_UNLAZY);
+		irq_disable(desc);
 	}
 }
 
diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
index 3c830a6f7ef4..a9df80e0602c 100644
--- a/arch/riscv/kernel/machine_kexec.c
+++ b/arch/riscv/kernel/machine_kexec.c
@@ -129,11 +129,8 @@ static void machine_kexec_mask_interrupts(void)
 		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
 			chip->irq_eoi(&desc->irq_data);
 
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
+		irq_set_status_flags(i, IRQ_DISABLE_UNLAZY);
+		irq_disable(desc);
 	}
 }
 
diff --git a/include/linux/irq.h b/include/linux/irq.h
index fa711f80957b..176a7f671409 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -600,6 +600,8 @@ enum {
 
 #define IRQ_DEFAULT_INIT_FLAGS	ARCH_IRQ_INIT_FLAGS
 
+extern void irq_disable(struct irq_desc *desc);
+
 struct irqaction;
 extern int setup_percpu_irq(unsigned int irq, struct irqaction *new);
 extern void remove_percpu_irq(unsigned int irq, struct irqaction *act);
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index fe0272cd84a5..d9104d2b26b4 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -91,7 +91,6 @@ extern int irq_startup(struct irq_desc *desc, bool resend, bool force);
 extern void irq_shutdown(struct irq_desc *desc);
 extern void irq_shutdown_and_deactivate(struct irq_desc *desc);
 extern void irq_enable(struct irq_desc *desc);
-extern void irq_disable(struct irq_desc *desc);
 extern void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu);
 extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu);
 extern void mask_irq(struct irq_desc *desc);
-- 
2.40.1



From palmer at rivosinc.com  Wed Nov 27 07:30:53 2024
From: palmer at rivosinc.com (Palmer Dabbelt)
Date: Wed, 27 Nov 2024 07:30:53 -0800 (PST)
Subject: [GIT PULL] RISC-V Paches for the 6.13 Merge Window, Part 1
Message-ID: <mhng-5c0ea89d-908b-4009-ba23-e4fac45618b4@palmer-ri-x1c9>

The following changes since commit 81983758430957d9a5cb3333fe324fd70cf63e7e:

  Linux 6.12-rc5 (2024-10-27 12:52:02 -1000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git tags/riscv-for-linus-6.13-mw1

for you to fetch changes up to 8d4f1e05ff821a5d59116ab8c3a30fcae81d8597:

  RISC-V: Remove unnecessary include from compat.h (2024-11-26 11:48:53 -0800)

----------------------------------------------------------------
RISC-V Paches for the 6.13 Merge Window, Part 1

* Support for pointer masking in userspace,
* Support for probing vector misaligned access performance.
* Support for qspinlock on systems with Zacas and Zabha.

----------------------------------------------------------------
There's a handful of fixes working through other trees (the wait/wound lockdep
failures and a tools build fix), but aside from those everything is clean on my
end.  I don't plan on having a part 2, unless there's something else in flight
that blows up.

----------------------------------------------------------------
Alexandre Ghiti (12):
      riscv: Check that vdso does not contain any dynamic relocations
      riscv: Move cpufeature.h macros into their own header
      riscv: Do not fail to build on byte/halfword operations with Zawrs
      riscv: Implement cmpxchg32/64() using Zacas
      dt-bindings: riscv: Add Zabha ISA extension description
      riscv: Implement cmpxchg8/16() using Zabha
      riscv: Improve zacas fully-ordered cmpxchg()
      riscv: Implement arch_cmpxchg128() using Zacas
      riscv: Implement xchg8/16() using Zabha
      riscv: Add ISA extension parsing for Ziccrse
      dt-bindings: riscv: Add Ziccrse ISA extension description
      riscv: Add qspinlock support

Charlie Jenkins (1):
      riscv: Fix default misaligned access trap

Drew Fustini (1):
      riscv: defconfig: enable gpio support for TH1520

Guo Ren (2):
      asm-generic: ticket-lock: Reuse arch_spinlock_t of qspinlock
      asm-generic: ticket-lock: Add separate ticket-lock.h

Jesse Taube (6):
      RISC-V: Check scalar unaligned access on all CPUs
      RISC-V: Scalar unaligned access emulated on hotplug CPUs
      RISC-V: Replace RISCV_MISALIGNED with RISCV_SCALAR_MISALIGNED
      RISC-V: Detect unaligned vector accesses supported
      RISC-V: Report vector unaligned access speed hwprobe
      RISC-V: hwprobe: Document unaligned vector perf key

Nick Hu (2):
      cpuidle: riscv-sbi: Move sbi_cpuidle_init to arch_initcall
      cpuidle: riscv-sbi: Add cpuidle_disabled() check

Palmer Dabbelt (7):
      Merge patch series "riscv: Per-thread envcfg CSR support"
      Merge patch series "cpuidle: riscv-sbi: Allow cpuidle pd used by other devices"
      Merge patch series "RISC-V: Detect and report speed of unaligned vector accesses"
      Merge patch series "Prevent dynamic relocations in vDSO"
      Merge patch series "riscv: Userspace pointer masking and tagged address ABI"
      Merge patch series "Zacas/Zabha support and qspinlocks"
      RISC-V: Remove unnecessary include from compat.h

Samuel Holland (13):
      riscv: Enable cbo.zero only when all harts support Zicboz
      riscv: Add support for per-thread envcfg CSR values
      riscv: Call riscv_user_isa_enable() only on the boot hart
      dt-bindings: riscv: Add pointer masking ISA extensions
      riscv: Add ISA extension parsing for pointer masking
      riscv: Add CSR definitions for pointer masking
      riscv: Add support for userspace pointer masking
      riscv: Add support for the tagged address ABI
      riscv: Allow ptrace control of the tagged address ABI
      riscv: selftests: Add a pointer masking test
      riscv: hwprobe: Export the Supm ISA extension
      RISC-V: KVM: Allow Smnpm and Ssnpm extensions for guests
      KVM: riscv: selftests: Add Smnpm and Ssnpm to get-reg-list test

 Documentation/arch/riscv/hwprobe.rst               |  19 ++
 Documentation/arch/riscv/uabi.rst                  |  16 +
 .../devicetree/bindings/riscv/extensions.yaml      |  30 ++
 .../locking/queued-spinlocks/arch-support.txt      |   2 +-
 arch/riscv/Kconfig                                 | 138 ++++++++-
 arch/riscv/Makefile                                |   6 +
 arch/riscv/configs/defconfig                       |   1 +
 arch/riscv/include/asm/Kbuild                      |   4 +-
 arch/riscv/include/asm/cmpxchg.h                   | 286 +++++++++++++-----
 arch/riscv/include/asm/compat.h                    |   1 -
 arch/riscv/include/asm/cpufeature-macros.h         |  66 ++++
 arch/riscv/include/asm/cpufeature.h                |  73 +----
 arch/riscv/include/asm/csr.h                       |  16 +
 arch/riscv/include/asm/entry-common.h              |   1 +
 arch/riscv/include/asm/hwcap.h                     |   7 +
 arch/riscv/include/asm/hwprobe.h                   |   2 +-
 arch/riscv/include/asm/mmu.h                       |   7 +
 arch/riscv/include/asm/mmu_context.h               |  13 +
 arch/riscv/include/asm/processor.h                 |   9 +
 arch/riscv/include/asm/spinlock.h                  |  47 +++
 arch/riscv/include/asm/switch_to.h                 |  19 ++
 arch/riscv/include/asm/uaccess.h                   |  43 ++-
 arch/riscv/include/asm/vector.h                    |   2 +
 arch/riscv/include/uapi/asm/hwprobe.h              |   6 +
 arch/riscv/include/uapi/asm/kvm.h                  |   2 +
 arch/riscv/kernel/Makefile                         |   3 +-
 arch/riscv/kernel/copy-unaligned.h                 |   5 +
 arch/riscv/kernel/cpufeature.c                     |  16 +-
 arch/riscv/kernel/fpu.S                            |   4 +-
 arch/riscv/kernel/process.c                        | 154 ++++++++++
 arch/riscv/kernel/ptrace.c                         |  42 +++
 arch/riscv/kernel/setup.c                          |  37 +++
 arch/riscv/kernel/smpboot.c                        |   2 -
 arch/riscv/kernel/suspend.c                        |   4 +-
 arch/riscv/kernel/sys_hwprobe.c                    |  44 +++
 arch/riscv/kernel/traps_misaligned.c               | 139 ++++++++-
 arch/riscv/kernel/unaligned_access_speed.c         | 156 +++++++++-
 arch/riscv/kernel/vdso/Makefile                    |  10 +-
 arch/riscv/kernel/vec-copy-unaligned.S             |  58 ++++
 arch/riscv/kernel/vector.c                         |   2 +-
 arch/riscv/kvm/vcpu_onereg.c                       |   4 +
 drivers/cpuidle/cpuidle-riscv-sbi.c                |  11 +-
 include/asm-generic/qspinlock.h                    |   2 +
 include/asm-generic/spinlock.h                     |  87 +-----
 include/asm-generic/spinlock_types.h               |  12 +-
 include/asm-generic/ticket_spinlock.h              | 105 +++++++
 include/uapi/linux/elf.h                           |   1 +
 include/uapi/linux/prctl.h                         |   5 +-
 tools/testing/selftests/kvm/riscv/get-reg-list.c   |   8 +
 tools/testing/selftests/riscv/Makefile             |   2 +-
 tools/testing/selftests/riscv/abi/.gitignore       |   1 +
 tools/testing/selftests/riscv/abi/Makefile         |  10 +
 .../testing/selftests/riscv/abi/pointer_masking.c  | 332 +++++++++++++++++++++
 53 files changed, 1790 insertions(+), 282 deletions(-)
 create mode 100644 arch/riscv/include/asm/cpufeature-macros.h
 create mode 100644 arch/riscv/include/asm/spinlock.h
 create mode 100644 arch/riscv/kernel/vec-copy-unaligned.S
 create mode 100644 include/asm-generic/ticket_spinlock.h
 create mode 100644 tools/testing/selftests/riscv/abi/.gitignore
 create mode 100644 tools/testing/selftests/riscv/abi/Makefile
 create mode 100644 tools/testing/selftests/riscv/abi/pointer_masking.c


From e at freeshell.de  Wed Nov 27 07:49:22 2024
From: e at freeshell.de (E Shattow)
Date: Wed, 27 Nov 2024 07:49:22 -0800
Subject: [PATCH v6 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
Message-ID: <20241127154958.71094-1-e@freeshell.de>

Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host mode
and connect vbus pinctrl.

This functionality depends on setting the USB over-current register to 
disable at bootloader phase, for example U-Boot:
https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.4268-6-minda.chen at starfivetech.com/

If the over-current register is not prepared for us then the result is no 
change in functional outcome with this patch applied; there is an error 
visible to the user and this additional usb configuration fails (same as
it is now). On Milk-V Mars with four USB-A ports this applies to one of the 
USB-A ports and the remaining three VL805-connected USB-A ports via PCIe are 
not changed.

Changes since v5:
 - Rebase on latest master
 - Addtional detail to commit description

Changes since v4:
 - Rebase on latest master

Changes since v3:
 - Rebase on linux-next/master
 - use tabs for code indent

Changes since v2:
 - Rebase on 6.12

E Shattow (1):
  riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function

 .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

-- 
2.45.2



From e at freeshell.de  Wed Nov 27 07:49:23 2024
From: e at freeshell.de (E Shattow)
Date: Wed, 27 Nov 2024 07:49:23 -0800
Subject: [PATCH v6 1/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host function
In-Reply-To: <20241127154958.71094-1-e@freeshell.de>
References: <20241127154958.71094-1-e@freeshell.de>
Message-ID: <20241127154958.71094-2-e@freeshell.de>

Milk-V Mars board routes one of four USB-A ports to USB0 on the SoC
rather than to the VL805 USB 3.0 <-> PCIe chip.
Set JH7110 on-chip USB host mode and vbus pin assignment accordingly.

Reviewed-by: Emil Renner Berthing <emil.renner.berthing at canonical.com>
Signed-off-by: E Shattow <e at freeshell.de>
---
 .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
index 0d248b671d4b..3bd62ab78523 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
+++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -53,7 +53,23 @@ &spi0 {
 	status = "okay";
 };
 
+&sysgpio {
+	usb0_pins: usb0-0 {
+		vbus-pins {
+			pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS,
+					      GPOEN_ENABLE,
+					      GPI_NONE)>;
+			bias-disable;
+			input-disable;
+			input-schmitt-disable;
+			slew-rate = <0>;
+		};
+	};
+};
+
 &usb0 {
-	dr_mode = "peripheral";
+	dr_mode = "host";
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_pins>;
 	status = "okay";
 };
-- 
2.45.2



From pbonzini at redhat.com  Wed Nov 27 08:38:01 2024
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Wed, 27 Nov 2024 17:38:01 +0100
Subject: [GIT PULL] KVM/riscv changes for 6.13, part #2
In-Reply-To: <CAAhSdy2mLBzE63wpQrOaHtOV0rwqkaxTUMBA9oMZsk68o0EHMg@mail.gmail.com>
References: <CAAhSdy2mLBzE63wpQrOaHtOV0rwqkaxTUMBA9oMZsk68o0EHMg@mail.gmail.com>
Message-ID: <CABgObfacuB-8KN1+Czt5DaXQbaiw9=jP5zYGatw6CGooLnz9Sg@mail.gmail.com>

On Thu, Nov 21, 2024 at 1:55?PM Anup Patel <anup at brainfault.org> wrote:
>
> Hi Paolo,
>
> As mentioned in the last PR, here are the remaining KVM RISC-V
> changes for 6.13 which mainly consists of Svade/Svadu extension
> support for Host and Guest/VM.
>
> Please note that Palmer has not yet sent the RISC-V PR for 6.13
> so these patches will conflict with the RISC-V tree.

The RISC-V PR has not been merged yet (has it been sent?) and I am not
sure what's happening here. If these are merged first, presumably
Linus will bump the arch/riscv/include/asm/hwcap.h constants --
leaving SVADE/SVADU at 87 and 88 and adjusting the others. Should I do
that or is it delayed to 6.14 at this point?

Paolo

> Please pull.
>
> Regards,
> Anup
>
> The following changes since commit 332fa4a802b16ccb727199da685294f85f9880cb:
>
>   riscv: kvm: Fix out-of-bounds array access (2024-11-05 13:27:32 +0530)
>
> are available in the Git repository at:
>
>   https://github.com/kvm-riscv/linux.git tags/kvm-riscv-6.13-2
>
> for you to fetch changes up to c74bfe4ffe8c1ca94e3d60ec7af06cf679e23583:
>
>   KVM: riscv: selftests: Add Svade and Svadu Extension to get-reg-list
> test (2024-11-21 17:40:16 +0530)
>
> ----------------------------------------------------------------
> KVM/riscv changes for 6.13 part #2
>
> - Svade and Svadu extension support for Host and Guest/VM
>
> ----------------------------------------------------------------
> Yong-Xuan Wang (4):
>       RISC-V: Add Svade and Svadu Extensions Support
>       dt-bindings: riscv: Add Svade and Svadu Entries
>       RISC-V: KVM: Add Svade and Svadu Extensions Support for Guest/VM
>       KVM: riscv: selftests: Add Svade and Svadu Extension to get-reg-list test
>
>  .../devicetree/bindings/riscv/extensions.yaml      | 28 ++++++++++++++++++++++
>  arch/riscv/Kconfig                                 |  1 +
>  arch/riscv/include/asm/csr.h                       |  1 +
>  arch/riscv/include/asm/hwcap.h                     |  2 ++
>  arch/riscv/include/asm/pgtable.h                   | 13 +++++++++-
>  arch/riscv/include/uapi/asm/kvm.h                  |  2 ++
>  arch/riscv/kernel/cpufeature.c                     | 12 ++++++++++
>  arch/riscv/kvm/vcpu.c                              |  4 ++++
>  arch/riscv/kvm/vcpu_onereg.c                       | 15 ++++++++++++
>  tools/testing/selftests/kvm/riscv/get-reg-list.c   |  8 +++++++
>  10 files changed, 85 insertions(+), 1 deletion(-)
>



From anup at brainfault.org  Wed Nov 27 08:44:05 2024
From: anup at brainfault.org (Anup Patel)
Date: Wed, 27 Nov 2024 22:14:05 +0530
Subject: [GIT PULL] KVM/riscv changes for 6.13, part #2
In-Reply-To: <CABgObfacuB-8KN1+Czt5DaXQbaiw9=jP5zYGatw6CGooLnz9Sg@mail.gmail.com>
References: <CAAhSdy2mLBzE63wpQrOaHtOV0rwqkaxTUMBA9oMZsk68o0EHMg@mail.gmail.com>
 <CABgObfacuB-8KN1+Czt5DaXQbaiw9=jP5zYGatw6CGooLnz9Sg@mail.gmail.com>
Message-ID: <CAAhSdy1eYZc__ynDrF8sQCk8Rj+CRj+LBBbGnV+Hc4qHfYiEOA@mail.gmail.com>

On Wed, Nov 27, 2024 at 10:08?PM Paolo Bonzini <pbonzini at redhat.com> wrote:
>
> On Thu, Nov 21, 2024 at 1:55?PM Anup Patel <anup at brainfault.org> wrote:
> >
> > Hi Paolo,
> >
> > As mentioned in the last PR, here are the remaining KVM RISC-V
> > changes for 6.13 which mainly consists of Svade/Svadu extension
> > support for Host and Guest/VM.
> >
> > Please note that Palmer has not yet sent the RISC-V PR for 6.13
> > so these patches will conflict with the RISC-V tree.
>
> The RISC-V PR has not been merged yet (has it been sent?) and I am not
> sure what's happening here. If these are merged first, presumably
> Linus will bump the arch/riscv/include/asm/hwcap.h constants --
> leaving SVADE/SVADU at 87 and 88 and adjusting the others. Should I do
> that or is it delayed to 6.14 at this point?

Yes, Palmer send-out RISC-V PR one hour ago.
(subject "[GIT PULL] RISC-V Paches for the 6.13 Merge Window, Part 1")
(git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git
tags/riscv-for-linus-6.13-mw1)

We have already skipped Svade & Svadu support in the 6.12 merge
window. If possible please take it in this merge window.

Regards,
Anup

>
> Paolo
>
> > Please pull.
> >
> > Regards,
> > Anup
> >
> > The following changes since commit 332fa4a802b16ccb727199da685294f85f9880cb:
> >
> >   riscv: kvm: Fix out-of-bounds array access (2024-11-05 13:27:32 +0530)
> >
> > are available in the Git repository at:
> >
> >   https://github.com/kvm-riscv/linux.git tags/kvm-riscv-6.13-2
> >
> > for you to fetch changes up to c74bfe4ffe8c1ca94e3d60ec7af06cf679e23583:
> >
> >   KVM: riscv: selftests: Add Svade and Svadu Extension to get-reg-list
> > test (2024-11-21 17:40:16 +0530)
> >
> > ----------------------------------------------------------------
> > KVM/riscv changes for 6.13 part #2
> >
> > - Svade and Svadu extension support for Host and Guest/VM
> >
> > ----------------------------------------------------------------
> > Yong-Xuan Wang (4):
> >       RISC-V: Add Svade and Svadu Extensions Support
> >       dt-bindings: riscv: Add Svade and Svadu Entries
> >       RISC-V: KVM: Add Svade and Svadu Extensions Support for Guest/VM
> >       KVM: riscv: selftests: Add Svade and Svadu Extension to get-reg-list test
> >
> >  .../devicetree/bindings/riscv/extensions.yaml      | 28 ++++++++++++++++++++++
> >  arch/riscv/Kconfig                                 |  1 +
> >  arch/riscv/include/asm/csr.h                       |  1 +
> >  arch/riscv/include/asm/hwcap.h                     |  2 ++
> >  arch/riscv/include/asm/pgtable.h                   | 13 +++++++++-
> >  arch/riscv/include/uapi/asm/kvm.h                  |  2 ++
> >  arch/riscv/kernel/cpufeature.c                     | 12 ++++++++++
> >  arch/riscv/kvm/vcpu.c                              |  4 ++++
> >  arch/riscv/kvm/vcpu_onereg.c                       | 15 ++++++++++++
> >  tools/testing/selftests/kvm/riscv/get-reg-list.c   |  8 +++++++
> >  10 files changed, 85 insertions(+), 1 deletion(-)
> >
>


From pbonzini at redhat.com  Wed Nov 27 08:47:07 2024
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Wed, 27 Nov 2024 17:47:07 +0100
Subject: [GIT PULL] KVM/riscv changes for 6.13, part #2
In-Reply-To: <CAAhSdy1eYZc__ynDrF8sQCk8Rj+CRj+LBBbGnV+Hc4qHfYiEOA@mail.gmail.com>
References: <CAAhSdy2mLBzE63wpQrOaHtOV0rwqkaxTUMBA9oMZsk68o0EHMg@mail.gmail.com>
 <CABgObfacuB-8KN1+Czt5DaXQbaiw9=jP5zYGatw6CGooLnz9Sg@mail.gmail.com> <CAAhSdy1eYZc__ynDrF8sQCk8Rj+CRj+LBBbGnV+Hc4qHfYiEOA@mail.gmail.com>
Message-ID: <CABgObfbKYc0Dqcq36dHsV=uopV+TAGu9-SuZF+QP=u6x0uMiHg@mail.gmail.com>

On Wed, Nov 27, 2024 at 5:44?PM Anup Patel <anup at brainfault.org> wrote:
>
> On Wed, Nov 27, 2024 at 10:08?PM Paolo Bonzini <pbonzini at redhat.com> wrote:
> >
> > On Thu, Nov 21, 2024 at 1:55?PM Anup Patel <anup at brainfault.org> wrote:
> > >
> > > Hi Paolo,
> > >
> > > As mentioned in the last PR, here are the remaining KVM RISC-V
> > > changes for 6.13 which mainly consists of Svade/Svadu extension
> > > support for Host and Guest/VM.
> > >
> > > Please note that Palmer has not yet sent the RISC-V PR for 6.13
> > > so these patches will conflict with the RISC-V tree.
> >
> > The RISC-V PR has not been merged yet (has it been sent?) and I am not
> > sure what's happening here. If these are merged first, presumably
> > Linus will bump the arch/riscv/include/asm/hwcap.h constants --
> > leaving SVADE/SVADU at 87 and 88 and adjusting the others. Should I do
> > that or is it delayed to 6.14 at this point?
>
> Yes, Palmer send-out RISC-V PR one hour ago.
> (subject "[GIT PULL] RISC-V Paches for the 6.13 Merge Window, Part 1")
> (git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git
> tags/riscv-for-linus-6.13-mw1)
>
> We have already skipped Svade & Svadu support in the 6.12 merge
> window. If possible please take it in this merge window.

Ok, will do. But I'd like to understand if KVM patches needed the bare
metal support. If not, and the only reason to skip it in 6.12 was the
hwcap.h constants, then there was no reason to delay it. Just send the
hwcap.h update as a pull request to both me and Palmer, and we'll
merge it from the same commit into our trees.

Paolo



From anup at brainfault.org  Wed Nov 27 08:51:15 2024
From: anup at brainfault.org (Anup Patel)
Date: Wed, 27 Nov 2024 22:21:15 +0530
Subject: [GIT PULL] KVM/riscv changes for 6.13, part #2
In-Reply-To: <CABgObfbKYc0Dqcq36dHsV=uopV+TAGu9-SuZF+QP=u6x0uMiHg@mail.gmail.com>
References: <CAAhSdy2mLBzE63wpQrOaHtOV0rwqkaxTUMBA9oMZsk68o0EHMg@mail.gmail.com>
 <CABgObfacuB-8KN1+Czt5DaXQbaiw9=jP5zYGatw6CGooLnz9Sg@mail.gmail.com>
 <CAAhSdy1eYZc__ynDrF8sQCk8Rj+CRj+LBBbGnV+Hc4qHfYiEOA@mail.gmail.com> <CABgObfbKYc0Dqcq36dHsV=uopV+TAGu9-SuZF+QP=u6x0uMiHg@mail.gmail.com>
Message-ID: <CAAhSdy1QCeg82kQsPHJx1+Oc=L7BoOUTpeLUNoeApao8rZDE+Q@mail.gmail.com>

On Wed, Nov 27, 2024 at 10:17?PM Paolo Bonzini <pbonzini at redhat.com> wrote:
>
> On Wed, Nov 27, 2024 at 5:44?PM Anup Patel <anup at brainfault.org> wrote:
> >
> > On Wed, Nov 27, 2024 at 10:08?PM Paolo Bonzini <pbonzini at redhat.com> wrote:
> > >
> > > On Thu, Nov 21, 2024 at 1:55?PM Anup Patel <anup at brainfault.org> wrote:
> > > >
> > > > Hi Paolo,
> > > >
> > > > As mentioned in the last PR, here are the remaining KVM RISC-V
> > > > changes for 6.13 which mainly consists of Svade/Svadu extension
> > > > support for Host and Guest/VM.
> > > >
> > > > Please note that Palmer has not yet sent the RISC-V PR for 6.13
> > > > so these patches will conflict with the RISC-V tree.
> > >
> > > The RISC-V PR has not been merged yet (has it been sent?) and I am not
> > > sure what's happening here. If these are merged first, presumably
> > > Linus will bump the arch/riscv/include/asm/hwcap.h constants --
> > > leaving SVADE/SVADU at 87 and 88 and adjusting the others. Should I do
> > > that or is it delayed to 6.14 at this point?
> >
> > Yes, Palmer send-out RISC-V PR one hour ago.
> > (subject "[GIT PULL] RISC-V Paches for the 6.13 Merge Window, Part 1")
> > (git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git
> > tags/riscv-for-linus-6.13-mw1)
> >
> > We have already skipped Svade & Svadu support in the 6.12 merge
> > window. If possible please take it in this merge window.
>
> Ok, will do. But I'd like to understand if KVM patches needed the bare
> metal support. If not, and the only reason to skip it in 6.12 was the
> hwcap.h constants, then there was no reason to delay it. Just send the
> hwcap.h update as a pull request to both me and Palmer, and we'll
> merge it from the same commit into our trees.

It was skipped in 6.12 due to confusion between myself and Palmer
about which tree these patches will go through and we did not resolve
this in time.

Regards,
Anup


From pbonzini at redhat.com  Wed Nov 27 08:59:52 2024
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Wed, 27 Nov 2024 17:59:52 +0100
Subject: [GIT PULL] KVM/riscv changes for 6.13, part #2
In-Reply-To: <CAAhSdy1QCeg82kQsPHJx1+Oc=L7BoOUTpeLUNoeApao8rZDE+Q@mail.gmail.com>
References: <CAAhSdy2mLBzE63wpQrOaHtOV0rwqkaxTUMBA9oMZsk68o0EHMg@mail.gmail.com>
 <CABgObfacuB-8KN1+Czt5DaXQbaiw9=jP5zYGatw6CGooLnz9Sg@mail.gmail.com>
 <CAAhSdy1eYZc__ynDrF8sQCk8Rj+CRj+LBBbGnV+Hc4qHfYiEOA@mail.gmail.com>
 <CABgObfbKYc0Dqcq36dHsV=uopV+TAGu9-SuZF+QP=u6x0uMiHg@mail.gmail.com> <CAAhSdy1QCeg82kQsPHJx1+Oc=L7BoOUTpeLUNoeApao8rZDE+Q@mail.gmail.com>
Message-ID: <CABgObfZ1iqNGqb+MW84_tgZEnSoAjMqzXFcoq0s58iTZDPMKgg@mail.gmail.com>

On Wed, Nov 27, 2024 at 5:51?PM Anup Patel <anup at brainfault.org> wrote:
> > Ok, will do. But I'd like to understand if KVM patches needed the bare
> > metal support. If not, and the only reason to skip it in 6.12 was the
> > hwcap.h constants, then there was no reason to delay it. Just send the
> > hwcap.h update as a pull request to both me and Palmer, and we'll
> > merge it from the same commit into our trees.
>
> It was skipped in 6.12 due to confusion between myself and Palmer
> about which tree these patches will go through and we did not resolve
> this in time.

I still don't understand if KVM patches need any bare metal code though. :)

It's also unclear to me why "RISC-V: KVM: Allow Smnpm and Ssnpm
extensions for guests" came through the RISC-V tree, thus causing
conflicts in the KVM_RISCV_ISA_EXT_ID enum.  It doesn't seem to need
bare metal support, so it should have come through your tree.

This split between patches that you send to me and those that others
send to someone else is not your fault but it's a mess, and the RISC-V
maintainers should not have gone for the least-work option. If
anything has a bare metal and a KVM part it's totally okay that you
send it to me as a separate pull request, but the right way to do it
is to *include a topic branch from the RISC-V tree* and base the KVM
changes on top. Not to let Linus and myself sort out the conflicts.

Paolo



From andybnac at gmail.com  Wed Nov 27 09:29:01 2024
From: andybnac at gmail.com (Andy Chiu)
Date: Thu, 28 Nov 2024 01:29:01 +0800
Subject: [PATCH v3 0/7] riscv: ftrace: atmoic patching and preempt improvements
Message-ID: <20241127172908.17149-1-andybnac@gmail.com>

This series makes atmoic code patching possible in riscv ftrace. A
direct benefit of this is that we can get rid of stop_machine() when
patching function entries. This also makes it possible to run ftrace
with full kernel preemption. Before this series, the kernel initializes
patchable function entries to NOP4 + NOP4. To start tracing, it updates
entries to AUIPC + JALR while holding other cores in stop_machine.
stop_machine() is required because it is impossible to update 2
instructions, and be seen atomically. And preemption must have to be
prevented, as kernel preemption allows process to be scheduled out while
executing on one of these instruction pairs.

This series addresses the problem by initializing the first NOP4 to
AUIPC. So, atmoic patching is possible because the kernel only has to
update one instruction. As long as the instruction is naturally aligned,
then it is expected to be updated atomically.

However, the address range of the ftrace trampoline is limited to +-2K
from ftrace_caller after appplying this series. This issue is expected
to be solved by Puranjay's CALL_OPS, where it adds 8B naturally align
data in front of pacthable functions and can  use it to direct execution
out to any custom trampolines.

The series is composed by three parts. The first part cleans up the
existing issues when the kernel is compiled with clang.The second part
modifies the ftrace code patching mechanism (2-4) as mentioned above.
Then prepare ftrace to be able to run with kernel preemption (5,6)

An ongoing fix:

Since there is no room for marking *kernel_text_address as notrace[1] at
source code level, there is a significant performance regression when
using function_graph with TRACE_IRQFLAGS enabled. There can be as much as
8 graph handler being called in each function-entry. The current
workaround requires us echo "*kernel_text_address" into
set_ftrace_notrace before starting the trace. However, we observed that
the kernel still enables the patch site in some cases even with
*kernel_text_address properly added in the file While the root cause is
still under investagtion, we consider that it should not be the reason
for holding back the code patching, in order to unblock the call_ops
part.

[1]: https://lore.kernel.org/linux-riscv/20240613093233.0b349ed0 at rorschach.local.home/

Changes in v3:
- Add a fix tag for patch 1
- Add a data fence before sending out remote fence.i (6)
- Link to v2: https://lore.kernel.org/all/20240628-dev-andyc-dyn-ftrace-v4-v2-0-1e5f4cb1f049 at sifive.com/

Changes in v2:
- Drop patch 1 as it is merged through fixes.
- Drop patch 2, which converts kernel_text_address into notrace. As
  users can prevent tracing it by configuring the tracefs.
- Use a more generic way in kconfig to align functions.
- Link to v1: https://lore.kernel.org/r/20240613-dev-andyc-dyn-ftrace-v4-v1-0-1a538e12c01e at sifive.com


Andy Chiu (7):
  riscv: ftrace: support fastcc in Clang for WITH_ARGS
  riscv: ftrace: align patchable functions to 4 Byte boundary
  riscv: ftrace: prepare ftrace for atomic code patching
  riscv: ftrace: do not use stop_machine to update code
  riscv: vector: Support calling schedule() for preemptible Vector
  riscv: add a data fence for CMODX in the kernel mode
  riscv: ftrace: support PREEMPT

 arch/riscv/Kconfig                 |   4 +-
 arch/riscv/include/asm/ftrace.h    |  11 +++
 arch/riscv/include/asm/processor.h |   5 ++
 arch/riscv/include/asm/vector.h    |  22 ++++-
 arch/riscv/kernel/asm-offsets.c    |   7 ++
 arch/riscv/kernel/ftrace.c         | 133 ++++++++++++-----------------
 arch/riscv/kernel/mcount-dyn.S     |  25 ++++--
 arch/riscv/mm/cacheflush.c         |  15 +++-
 8 files changed, 135 insertions(+), 87 deletions(-)
---
base-commit: 0eb512779d642b21ced83778287a0f7a3ca8f2a1
-- 
2.39.3 (Apple Git-145)



From andybnac at gmail.com  Wed Nov 27 09:29:02 2024
From: andybnac at gmail.com (Andy Chiu)
Date: Thu, 28 Nov 2024 01:29:02 +0800
Subject: [PATCH v3 1/7] riscv: ftrace: support fastcc in Clang for WITH_ARGS
In-Reply-To: <20241127172908.17149-1-andybnac@gmail.com>
References: <20241127172908.17149-1-andybnac@gmail.com>
Message-ID: <20241127172908.17149-2-andybnac@gmail.com>

From: Andy Chiu <andy.chiu at sifive.com>

Some caller-saved registers which are not defined as function arguments
in the ABI can still be passed as arguments when the kernel is compiled
with Clang. As a result, we must save and restore those registers to
prevent ftrace from clobbering them.

- [1]: https://reviews.llvm.org/D68559

Reported-by: Evgenii Shatokhin <e.shatokhin at yadro.com>
Closes: https://lore.kernel.org/linux-riscv/7e7c7914-445d-426d-89a0-59a9199c45b1 at yadro.com/
Acked-by: Nathan Chancellor <nathan at kernel.org>
Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
---
 arch/riscv/include/asm/ftrace.h |  7 +++++++
 arch/riscv/kernel/asm-offsets.c |  7 +++++++
 arch/riscv/kernel/mcount-dyn.S  | 16 ++++++++++++++--
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
index 2cddd79ff21b..4ca7ce7f34d7 100644
--- a/arch/riscv/include/asm/ftrace.h
+++ b/arch/riscv/include/asm/ftrace.h
@@ -143,6 +143,13 @@ struct ftrace_regs {
 			unsigned long a5;
 			unsigned long a6;
 			unsigned long a7;
+#ifdef CONFIG_CC_IS_CLANG
+			unsigned long t2;
+			unsigned long t3;
+			unsigned long t4;
+			unsigned long t5;
+			unsigned long t6;
+#endif
 		};
 	};
 };
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index e94180ba432f..59789dfb2d5d 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -504,6 +504,13 @@ void asm_offsets(void)
 	DEFINE(FREGS_SP,	    offsetof(struct ftrace_regs, sp));
 	DEFINE(FREGS_S0,	    offsetof(struct ftrace_regs, s0));
 	DEFINE(FREGS_T1,	    offsetof(struct ftrace_regs, t1));
+#ifdef CONFIG_CC_IS_CLANG
+	DEFINE(FREGS_T2,	    offsetof(struct ftrace_regs, t2));
+	DEFINE(FREGS_T3,	    offsetof(struct ftrace_regs, t3));
+	DEFINE(FREGS_T4,	    offsetof(struct ftrace_regs, t4));
+	DEFINE(FREGS_T5,	    offsetof(struct ftrace_regs, t5));
+	DEFINE(FREGS_T6,	    offsetof(struct ftrace_regs, t6));
+#endif
 	DEFINE(FREGS_A0,	    offsetof(struct ftrace_regs, a0));
 	DEFINE(FREGS_A1,	    offsetof(struct ftrace_regs, a1));
 	DEFINE(FREGS_A2,	    offsetof(struct ftrace_regs, a2));
diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S
index 745dd4c4a69c..e988bd26b28b 100644
--- a/arch/riscv/kernel/mcount-dyn.S
+++ b/arch/riscv/kernel/mcount-dyn.S
@@ -96,7 +96,13 @@
 	REG_S	x8,  FREGS_S0(sp)
 #endif
 	REG_S	x6,  FREGS_T1(sp)
-
+#ifdef CONFIG_CC_IS_CLANG
+	REG_S	x7,  FREGS_T2(sp)
+	REG_S	x28, FREGS_T3(sp)
+	REG_S	x29, FREGS_T4(sp)
+	REG_S	x30, FREGS_T5(sp)
+	REG_S	x31, FREGS_T6(sp)
+#endif
 	// save the arguments
 	REG_S	x10, FREGS_A0(sp)
 	REG_S	x11, FREGS_A1(sp)
@@ -115,7 +121,13 @@
 	REG_L	x8, FREGS_S0(sp)
 #endif
 	REG_L	x6,  FREGS_T1(sp)
-
+#ifdef CONFIG_CC_IS_CLANG
+	REG_L	x7,  FREGS_T2(sp)
+	REG_L	x28, FREGS_T3(sp)
+	REG_L	x29, FREGS_T4(sp)
+	REG_L	x30, FREGS_T5(sp)
+	REG_L	x31, FREGS_T6(sp)
+#endif
 	// restore the arguments
 	REG_L	x10, FREGS_A0(sp)
 	REG_L	x11, FREGS_A1(sp)
-- 
2.39.3 (Apple Git-145)



From andybnac at gmail.com  Wed Nov 27 09:29:03 2024
From: andybnac at gmail.com (Andy Chiu)
Date: Thu, 28 Nov 2024 01:29:03 +0800
Subject: [PATCH v3 2/7] riscv: ftrace: align patchable functions to 4 Byte boundary
In-Reply-To: <20241127172908.17149-1-andybnac@gmail.com>
References: <20241127172908.17149-1-andybnac@gmail.com>
Message-ID: <20241127172908.17149-3-andybnac@gmail.com>

From: Andy Chiu <andy.chiu at sifive.com>

We are changing ftrace code patching in order to remove dependency from
stop_machine() and enable kernel preemption. This requires us to align
functions entry at a 4-B align address.

However, -falign-functions on older versions of GCC alone was not strong
enoungh to align all functions. In fact, cold functions are not aligned
after turning on optimizations. We consider this is a bug in GCC and
turn off guess-branch-probility as a workaround to align all functions.

GCC bug id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88345

The option -fmin-function-alignment is able to align all functions
properly on newer versions of gcc. So, we add a cc-option to test if
the toolchain supports it.

Suggested-by: Evgenii Shatokhin <e.shatokhin at yadro.com>
Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
Reviewed-by: Bj?rn T?pel <bjorn at rivosinc.com>
---
 arch/riscv/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5bdda86ada37..75a5ebde4427 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -142,6 +142,7 @@ config RISCV
 	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_DMA_CONTIGUOUS if MMU
 	select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
+	select FUNCTION_ALIGNMENT_4B if HAVE_DYNAMIC_FTRACE && RISCV_ISA_C
 	select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
 	select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE
 	select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
@@ -226,6 +227,7 @@ config CLANG_SUPPORTS_DYNAMIC_FTRACE
 config GCC_SUPPORTS_DYNAMIC_FTRACE
 	def_bool CC_IS_GCC
 	depends on $(cc-option,-fpatchable-function-entry=8)
+	depends on CC_HAS_MIN_FUNCTION_ALIGNMENT || !RISCV_ISA_C
 
 config HAVE_SHADOW_CALL_STACK
 	def_bool $(cc-option,-fsanitize=shadow-call-stack)
-- 
2.39.3 (Apple Git-145)



From andybnac at gmail.com  Wed Nov 27 09:29:04 2024
From: andybnac at gmail.com (Andy Chiu)
Date: Thu, 28 Nov 2024 01:29:04 +0800
Subject: [PATCH v3 3/7] riscv: ftrace: prepare ftrace for atomic code patching
In-Reply-To: <20241127172908.17149-1-andybnac@gmail.com>
References: <20241127172908.17149-1-andybnac@gmail.com>
Message-ID: <20241127172908.17149-4-andybnac@gmail.com>

From: Andy Chiu <andy.chiu at sifive.com>

We use an AUIPC+JALR pair to jump into a ftrace trampoline. Since
instruction fetch can break down to 4 byte at a time, it is impossible
to update two instructions without a race. In order to mitigate it, we
initialize the patchable entry to AUIPC + NOP4. Then, the run-time code
patching can change NOP4 to JALR to eable/disable ftrcae from a
function. This limits the reach of each ftrace entry to +-2KB displacing
from ftrace_caller.

Starting from the trampoline, we add a level of indirection for it to
reach ftrace caller target. Now, it loads the target address from a
memory location, then perform the jump. This enable the kernel to update
the target atomically.

The ordering of reading/updating the targert address should be guarded
by generic ftrace code, where it sends smp_rmb ipi.

Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
---
 arch/riscv/include/asm/ftrace.h |  4 ++
 arch/riscv/kernel/ftrace.c      | 80 +++++++++++++++++++++------------
 arch/riscv/kernel/mcount-dyn.S  |  9 ++--
 3 files changed, 62 insertions(+), 31 deletions(-)

diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
index 4ca7ce7f34d7..36734d285aad 100644
--- a/arch/riscv/include/asm/ftrace.h
+++ b/arch/riscv/include/asm/ftrace.h
@@ -80,6 +80,7 @@ struct dyn_arch_ftrace {
 #define JALR_T0			(0x000282e7)
 #define AUIPC_T0		(0x00000297)
 #define NOP4			(0x00000013)
+#define JALR_RANGE		(JALR_SIGN_MASK - 1)
 
 #define to_jalr_t0(offset)						\
 	(((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_T0)
@@ -117,6 +118,9 @@ do {									\
  * Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here.
  */
 #define MCOUNT_INSN_SIZE 8
+#define MCOUNT_AUIPC_SIZE	4
+#define MCOUNT_JALR_SIZE	4
+#define MCOUNT_NOP4_SIZE	4
 
 #ifndef __ASSEMBLY__
 struct dyn_ftrace;
diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
index 4b95c574fd04..5ebe412280ef 100644
--- a/arch/riscv/kernel/ftrace.c
+++ b/arch/riscv/kernel/ftrace.c
@@ -64,42 +64,64 @@ static int ftrace_check_current_call(unsigned long hook_pos,
 	return 0;
 }
 
-static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target,
-				bool enable, bool ra)
+static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, bool validate)
 {
 	unsigned int call[2];
-	unsigned int nops[2] = {NOP4, NOP4};
+	unsigned int replaced[2];
+
+	make_call_t0(hook_pos, target, call);
 
-	if (ra)
-		make_call_ra(hook_pos, target, call);
-	else
-		make_call_t0(hook_pos, target, call);
+	if (validate) {
+		/*
+		 * Read the text we want to modify;
+		 * return must be -EFAULT on read error
+		 */
+		if (copy_from_kernel_nofault(replaced, (void *)hook_pos,
+					     MCOUNT_INSN_SIZE))
+			return -EFAULT;
+
+		if (replaced[0] != call[0]) {
+			pr_err("%p: expected (%08x) but got (%08x)\n",
+			       (void *)hook_pos, call[0], replaced[0]);
+			return -EINVAL;
+		}
+	}
 
-	/* Replace the auipc-jalr pair at once. Return -EPERM on write error. */
-	if (patch_insn_write((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE))
+	/* Replace the jalr at once. Return -EPERM on write error. */
+	if (patch_insn_write((void *)(hook_pos + MCOUNT_AUIPC_SIZE), call + 1, MCOUNT_JALR_SIZE))
 		return -EPERM;
 
 	return 0;
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+static int __ftrace_modify_call_site(ftrace_func_t *hook_pos, ftrace_func_t target, bool enable)
 {
-	unsigned int call[2];
+	ftrace_func_t call = target;
+	ftrace_func_t nops = &ftrace_stub;
 
-	make_call_t0(rec->ip, addr, call);
-
-	if (patch_insn_write((void *)rec->ip, call, MCOUNT_INSN_SIZE))
-		return -EPERM;
+	WRITE_ONCE(*hook_pos, enable ? call : nops);
 
 	return 0;
 }
 
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+	unsigned long distance, orig_addr;
+
+	orig_addr = (unsigned long)&ftrace_caller;
+	distance = addr > orig_addr ? addr - orig_addr : orig_addr - addr;
+	if (distance > JALR_RANGE)
+		return -EINVAL;
+
+	return __ftrace_modify_call(rec->ip, addr, false);
+}
+
 int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
 		    unsigned long addr)
 {
-	unsigned int nops[2] = {NOP4, NOP4};
+	unsigned int nops[1] = {NOP4};
 
-	if (patch_insn_write((void *)rec->ip, nops, MCOUNT_INSN_SIZE))
+	if (patch_insn_write((void *)(rec->ip + MCOUNT_AUIPC_SIZE), nops, MCOUNT_NOP4_SIZE))
 		return -EPERM;
 
 	return 0;
@@ -114,21 +136,23 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
  */
 int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
 {
+	unsigned int nops[2];
 	int out;
 
+	make_call_t0(rec->ip, &ftrace_caller, nops);
+	nops[1] = NOP4;
+
 	mutex_lock(&text_mutex);
-	out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
+	out = patch_insn_write((void *)rec->ip, nops, MCOUNT_INSN_SIZE);
 	mutex_unlock(&text_mutex);
 
 	return out;
 }
 
+ftrace_func_t ftrace_call_dest = ftrace_stub;
 int ftrace_update_ftrace_func(ftrace_func_t func)
 {
-	int ret = __ftrace_modify_call((unsigned long)&ftrace_call,
-				       (unsigned long)func, true, true);
-
-	return ret;
+	return __ftrace_modify_call_site(&ftrace_call_dest, func, true);
 }
 
 struct ftrace_modify_param {
@@ -182,7 +206,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
 	if (ret)
 		return ret;
 
-	return __ftrace_modify_call(caller, addr, true, false);
+	return __ftrace_modify_call(caller, addr, true);
 }
 #endif
 
@@ -217,17 +241,17 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
 	prepare_ftrace_return(&fregs->ra, ip, fregs->s0);
 }
 #else /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
-extern void ftrace_graph_call(void);
+ftrace_func_t ftrace_graph_call_dest = ftrace_stub;
 int ftrace_enable_ftrace_graph_caller(void)
 {
-	return __ftrace_modify_call((unsigned long)&ftrace_graph_call,
-				    (unsigned long)&prepare_ftrace_return, true, true);
+	return __ftrace_modify_call_site(&ftrace_graph_call_dest,
+					 &prepare_ftrace_return, true);
 }
 
 int ftrace_disable_ftrace_graph_caller(void)
 {
-	return __ftrace_modify_call((unsigned long)&ftrace_graph_call,
-				    (unsigned long)&prepare_ftrace_return, false, true);
+	return __ftrace_modify_call_site(&ftrace_graph_call_dest,
+					 &prepare_ftrace_return, false);
 }
 #endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
 #endif /* CONFIG_DYNAMIC_FTRACE */
diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S
index e988bd26b28b..bc06e8ab81cf 100644
--- a/arch/riscv/kernel/mcount-dyn.S
+++ b/arch/riscv/kernel/mcount-dyn.S
@@ -162,7 +162,8 @@ SYM_FUNC_START(ftrace_caller)
 	mv	a3, sp
 
 SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
-	call	ftrace_stub
+	REG_L	ra, ftrace_call_dest
+	jalr	0(ra)
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	addi	a0, sp, ABI_RA
@@ -172,7 +173,8 @@ SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
 	mv	a2, s0
 #endif
 SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
-	call	ftrace_stub
+	REG_L	ra, ftrace_graph_call_dest
+	jalr	0(ra)
 #endif
 	RESTORE_ABI
 	jr	t0
@@ -185,7 +187,8 @@ SYM_FUNC_START(ftrace_caller)
 	PREPARE_ARGS
 
 SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
-	call	ftrace_stub
+	REG_L	ra, ftrace_call_dest
+	jalr	0(ra)
 
 	RESTORE_ABI_REGS
 	bnez	t1, .Ldirect
-- 
2.39.3 (Apple Git-145)



From andybnac at gmail.com  Wed Nov 27 09:29:05 2024
From: andybnac at gmail.com (Andy Chiu)
Date: Thu, 28 Nov 2024 01:29:05 +0800
Subject: [PATCH v3 4/7] riscv: ftrace: do not use stop_machine to update code
In-Reply-To: <20241127172908.17149-1-andybnac@gmail.com>
References: <20241127172908.17149-1-andybnac@gmail.com>
Message-ID: <20241127172908.17149-5-andybnac@gmail.com>

From: Andy Chiu <andy.chiu at sifive.com>

Now it is safe to remove dependency from stop_machine() for us to patch
code in ftrace.

Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
---
 arch/riscv/kernel/ftrace.c | 53 +++-----------------------------------
 1 file changed, 4 insertions(+), 49 deletions(-)

diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
index 5ebe412280ef..57a6558e212e 100644
--- a/arch/riscv/kernel/ftrace.c
+++ b/arch/riscv/kernel/ftrace.c
@@ -13,23 +13,13 @@
 #include <asm/patch.h>
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-void ftrace_arch_code_modify_prepare(void) __acquires(&text_mutex)
+void arch_ftrace_update_code(int command)
 {
 	mutex_lock(&text_mutex);
-
-	/*
-	 * The code sequences we use for ftrace can't be patched while the
-	 * kernel is running, so we need to use stop_machine() to modify them
-	 * for now.  This doesn't play nice with text_mutex, we use this flag
-	 * to elide the check.
-	 */
-	riscv_patch_in_stop_machine = true;
-}
-
-void ftrace_arch_code_modify_post_process(void) __releases(&text_mutex)
-{
-	riscv_patch_in_stop_machine = false;
+	command |= FTRACE_MAY_SLEEP;
+	ftrace_modify_all_code(command);
 	mutex_unlock(&text_mutex);
+	flush_icache_all();
 }
 
 static int ftrace_check_current_call(unsigned long hook_pos,
@@ -155,41 +145,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
 	return __ftrace_modify_call_site(&ftrace_call_dest, func, true);
 }
 
-struct ftrace_modify_param {
-	int command;
-	atomic_t cpu_count;
-};
-
-static int __ftrace_modify_code(void *data)
-{
-	struct ftrace_modify_param *param = data;
-
-	if (atomic_inc_return(&param->cpu_count) == num_online_cpus()) {
-		ftrace_modify_all_code(param->command);
-		/*
-		 * Make sure the patching store is effective *before* we
-		 * increment the counter which releases all waiting CPUs
-		 * by using the release variant of atomic increment. The
-		 * release pairs with the call to local_flush_icache_all()
-		 * on the waiting CPU.
-		 */
-		atomic_inc_return_release(&param->cpu_count);
-	} else {
-		while (atomic_read(&param->cpu_count) <= num_online_cpus())
-			cpu_relax();
-
-		local_flush_icache_all();
-	}
-
-	return 0;
-}
-
-void arch_ftrace_update_code(int command)
-{
-	struct ftrace_modify_param param = { command, ATOMIC_INIT(0) };
-
-	stop_machine(__ftrace_modify_code, &param, cpu_online_mask);
-}
 #endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
-- 
2.39.3 (Apple Git-145)



From andybnac at gmail.com  Wed Nov 27 09:29:06 2024
From: andybnac at gmail.com (Andy Chiu)
Date: Thu, 28 Nov 2024 01:29:06 +0800
Subject: [PATCH v3 5/7] riscv: vector: Support calling schedule() for preemptible Vector
In-Reply-To: <20241127172908.17149-1-andybnac@gmail.com>
References: <20241127172908.17149-1-andybnac@gmail.com>
Message-ID: <20241127172908.17149-6-andybnac@gmail.com>

From: Andy Chiu <andy.chiu at sifive.com>

Each function entry implies a call to ftrace infrastructure. And it may
call into schedule in some cases. So, it is possible for preemptible
kernel-mode Vector to implicitly call into schedule. Since all V-regs
are caller-saved, it is possible to drop all V context when a thread
voluntarily call schedule(). Besides, we currently don't pass argument
through vector register, so we don't have to save/restore V-regs in
ftrace trampoline.

Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
---
 arch/riscv/include/asm/processor.h |  5 +++++
 arch/riscv/include/asm/vector.h    | 22 +++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 5f56eb9d114a..9c1cc716b891 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -79,6 +79,10 @@ struct pt_regs;
  *       Thus, the task does not own preempt_v. Any use of Vector will have to
  *       save preempt_v, if dirty, and fallback to non-preemptible kernel-mode
  *       Vector.
+ *  - bit 29: The thread voluntarily calls schedule() while holding an active
+ *    preempt_v. All preempt_v context should be dropped in such case because
+ *    V-regs are caller-saved. Only sstatus.VS=ON is persisted across a
+ *    schedule() call.
  *  - bit 30: The in-kernel preempt_v context is saved, and requries to be
  *    restored when returning to the context that owns the preempt_v.
  *  - bit 31: The in-kernel preempt_v context is dirty, as signaled by the
@@ -93,6 +97,7 @@ struct pt_regs;
 #define RISCV_PREEMPT_V			0x00000100
 #define RISCV_PREEMPT_V_DIRTY		0x80000000
 #define RISCV_PREEMPT_V_NEED_RESTORE	0x40000000
+#define RISCV_PREEMPT_V_IN_SCHEDULE	0x20000000
 
 /* CPU-specific state of a task */
 struct thread_struct {
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index c7c023afbacd..c5b6070db99f 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -76,6 +76,11 @@ static __always_inline void riscv_v_disable(void)
 	csr_clear(CSR_SSTATUS, SR_VS);
 }
 
+static __always_inline bool riscv_v_is_on(void)
+{
+	return !!(csr_read(CSR_SSTATUS) & SR_VS);
+}
+
 static __always_inline void __vstate_csr_save(struct __riscv_v_ext_state *dest)
 {
 	asm volatile (
@@ -244,6 +249,11 @@ static inline void __switch_to_vector(struct task_struct *prev,
 	struct pt_regs *regs;
 
 	if (riscv_preempt_v_started(prev)) {
+		if (riscv_v_is_on()) {
+			WARN_ON(prev->thread.riscv_v_flags & RISCV_V_CTX_DEPTH_MASK);
+			riscv_v_disable();
+			prev->thread.riscv_v_flags |= RISCV_PREEMPT_V_IN_SCHEDULE;
+		}
 		if (riscv_preempt_v_dirty(prev)) {
 			__riscv_v_vstate_save(&prev->thread.kernel_vstate,
 					      prev->thread.kernel_vstate.datap);
@@ -254,10 +264,16 @@ static inline void __switch_to_vector(struct task_struct *prev,
 		riscv_v_vstate_save(&prev->thread.vstate, regs);
 	}
 
-	if (riscv_preempt_v_started(next))
-		riscv_preempt_v_set_restore(next);
-	else
+	if (riscv_preempt_v_started(next)) {
+		if (next->thread.riscv_v_flags & RISCV_PREEMPT_V_IN_SCHEDULE) {
+			next->thread.riscv_v_flags &= ~RISCV_PREEMPT_V_IN_SCHEDULE;
+			riscv_v_enable();
+		} else {
+			riscv_preempt_v_set_restore(next);
+		}
+	} else {
 		riscv_v_vstate_set_restore(next, task_pt_regs(next));
+	}
 }
 
 void riscv_v_vstate_ctrl_init(struct task_struct *tsk);
-- 
2.39.3 (Apple Git-145)



From andybnac at gmail.com  Wed Nov 27 09:29:07 2024
From: andybnac at gmail.com (Andy Chiu)
Date: Thu, 28 Nov 2024 01:29:07 +0800
Subject: [PATCH v3 6/7] riscv: add a data fence for CMODX in the kernel mode
In-Reply-To: <20241127172908.17149-1-andybnac@gmail.com>
References: <20241127172908.17149-1-andybnac@gmail.com>
Message-ID: <20241127172908.17149-7-andybnac@gmail.com>

RISC-V spec explicitly calls out that a local fence.i is not enough for
the code modification to be visble from a remote hart. In fact, it
states:

To make a store to instruction memory visible to all RISC-V harts, the
writing hart also has to execute a data FENCE before requesting that all
remote RISC-V harts execute a FENCE.I.

Thus, add a fence here to order data writes before making the IPI.

Signed-off-by: Andy Chiu <andybnac at gmail.com>
---
 arch/riscv/mm/cacheflush.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
index b81672729887..b2e4b81763f8 100644
--- a/arch/riscv/mm/cacheflush.c
+++ b/arch/riscv/mm/cacheflush.c
@@ -24,7 +24,20 @@ void flush_icache_all(void)
 
 	if (num_online_cpus() < 2)
 		return;
-	else if (riscv_use_sbi_for_rfence())
+
+	/*
+	 * Make sure all previous writes to the D$ are ordered before making
+	 * the IPI. The RISC-V spec states that a hart must execute a data fence
+	 * before triggering a remote fence.i in order to make the modification
+	 * visable for remote harts.
+	 *
+	 * IPIs on RISC-V are triggered by MMIO writes to either CLINT or
+	 * S-IMSIC, so the fence ensures previous data writes "happen before"
+	 * the MMIO.
+	 */
+	RISCV_FENCE(w, o);
+
+	if (riscv_use_sbi_for_rfence())
 		sbi_remote_fence_i(NULL);
 	else
 		on_each_cpu(ipi_remote_fence_i, NULL, 1);
-- 
2.39.3 (Apple Git-145)



From andybnac at gmail.com  Wed Nov 27 09:29:08 2024
From: andybnac at gmail.com (Andy Chiu)
Date: Thu, 28 Nov 2024 01:29:08 +0800
Subject: [PATCH v3 7/7] riscv: ftrace: support PREEMPT
In-Reply-To: <20241127172908.17149-1-andybnac@gmail.com>
References: <20241127172908.17149-1-andybnac@gmail.com>
Message-ID: <20241127172908.17149-8-andybnac@gmail.com>

From: Andy Chiu <andy.chiu at sifive.com>

Now, we can safely enable dynamic ftrace with kernel preemption.

Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
---
 arch/riscv/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 75a5ebde4427..554e4e363c54 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -148,7 +148,7 @@ config RISCV
 	select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
-	select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !PREEMPTION
+	select HAVE_FUNCTION_TRACER if !XIP_KERNEL
 	select HAVE_EBPF_JIT if MMU
 	select HAVE_GUP_FAST if MMU
 	select HAVE_FUNCTION_ARG_ACCESS_API
-- 
2.39.3 (Apple Git-145)



From yury.norov at gmail.com  Wed Nov 27 11:06:10 2024
From: yury.norov at gmail.com (Yury Norov)
Date: Wed, 27 Nov 2024 11:06:10 -0800
Subject: [PATCH] riscv: Always inline bitops
In-Reply-To: <20241123-riscv-always-inline-bitops-v1-1-00e8262ab1cf@kernel.org>
References: <20241123-riscv-always-inline-bitops-v1-1-00e8262ab1cf@kernel.org>
Message-ID: <Z0dtohAlZqad841q@yury-ThinkPad>

On Sat, Nov 23, 2024 at 07:30:19PM -0700, Nathan Chancellor wrote:
> When building allmodconfig + ThinLTO with certain versions of clang,
> arch_set_bit() may not be inlined, resulting in a modpost warning:
> 
>   WARNING: modpost: vmlinux: section mismatch in reference: arch_set_bit+0x58 (section: .text.arch_set_bit) -> numa_nodes_parsed (section: .init.data)
> 
> acpi_numa_rintc_affinity_init() calls arch_set_bit() via __node_set()
> with numa_nodes_parsed, which is marked as __initdata. If arch_set_bit()
> is not inlined, modpost will flag that it is being called with data that
> will be freed after init.
> 
> As acpi_numa_rintc_affinity_init() is marked as __init, there is not
> actually a functional issue here. However, the bitop functions should be
> marked as __always_inline, so that they work consistently for init and
> non-init code, which the comment in include/linux/nodemask.h alludes to.
> This matches s390 and x86's implementations.
> 
> Signed-off-by: Nathan Chancellor <nathan at kernel.org>

Applied, thanks!

So we have generic, x86 and riscv bitops inlined, and powerpc and s390
non-inlined. We need to align them all, I think.

Thanks,
Yury

> ---
>  arch/riscv/include/asm/bitops.h | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
> index fae152ea0508d2e1ea490fffd645eab99cf387bf..c6bd3d8354a96b4e7bbef0e98a201da412301b57 100644
> --- a/arch/riscv/include/asm/bitops.h
> +++ b/arch/riscv/include/asm/bitops.h
> @@ -228,7 +228,7 @@ static __always_inline int variable_fls(unsigned int x)
>   *
>   * This operation may be reordered on other architectures than x86.
>   */
> -static inline int arch_test_and_set_bit(int nr, volatile unsigned long *addr)
> +static __always_inline int arch_test_and_set_bit(int nr, volatile unsigned long *addr)
>  {
>  	return __test_and_op_bit(or, __NOP, nr, addr);
>  }
> @@ -240,7 +240,7 @@ static inline int arch_test_and_set_bit(int nr, volatile unsigned long *addr)
>   *
>   * This operation can be reordered on other architectures other than x86.
>   */
> -static inline int arch_test_and_clear_bit(int nr, volatile unsigned long *addr)
> +static __always_inline int arch_test_and_clear_bit(int nr, volatile unsigned long *addr)
>  {
>  	return __test_and_op_bit(and, __NOT, nr, addr);
>  }
> @@ -253,7 +253,7 @@ static inline int arch_test_and_clear_bit(int nr, volatile unsigned long *addr)
>   * This operation is atomic and cannot be reordered.
>   * It also implies a memory barrier.
>   */
> -static inline int arch_test_and_change_bit(int nr, volatile unsigned long *addr)
> +static __always_inline int arch_test_and_change_bit(int nr, volatile unsigned long *addr)
>  {
>  	return __test_and_op_bit(xor, __NOP, nr, addr);
>  }
> @@ -270,7 +270,7 @@ static inline int arch_test_and_change_bit(int nr, volatile unsigned long *addr)
>   * Note that @nr may be almost arbitrarily large; this function is not
>   * restricted to acting on a single-word quantity.
>   */
> -static inline void arch_set_bit(int nr, volatile unsigned long *addr)
> +static __always_inline void arch_set_bit(int nr, volatile unsigned long *addr)
>  {
>  	__op_bit(or, __NOP, nr, addr);
>  }
> @@ -284,7 +284,7 @@ static inline void arch_set_bit(int nr, volatile unsigned long *addr)
>   * on non x86 architectures, so if you are writing portable code,
>   * make sure not to rely on its reordering guarantees.
>   */
> -static inline void arch_clear_bit(int nr, volatile unsigned long *addr)
> +static __always_inline void arch_clear_bit(int nr, volatile unsigned long *addr)
>  {
>  	__op_bit(and, __NOT, nr, addr);
>  }
> @@ -298,7 +298,7 @@ static inline void arch_clear_bit(int nr, volatile unsigned long *addr)
>   * Note that @nr may be almost arbitrarily large; this function is not
>   * restricted to acting on a single-word quantity.
>   */
> -static inline void arch_change_bit(int nr, volatile unsigned long *addr)
> +static __always_inline void arch_change_bit(int nr, volatile unsigned long *addr)
>  {
>  	__op_bit(xor, __NOP, nr, addr);
>  }
> @@ -311,7 +311,7 @@ static inline void arch_change_bit(int nr, volatile unsigned long *addr)
>   * This operation is atomic and provides acquire barrier semantics.
>   * It can be used to implement bit locks.
>   */
> -static inline int arch_test_and_set_bit_lock(
> +static __always_inline int arch_test_and_set_bit_lock(
>  	unsigned long nr, volatile unsigned long *addr)
>  {
>  	return __test_and_op_bit_ord(or, __NOP, nr, addr, .aq);
> @@ -324,7 +324,7 @@ static inline int arch_test_and_set_bit_lock(
>   *
>   * This operation is atomic and provides release barrier semantics.
>   */
> -static inline void arch_clear_bit_unlock(
> +static __always_inline void arch_clear_bit_unlock(
>  	unsigned long nr, volatile unsigned long *addr)
>  {
>  	__op_bit_ord(and, __NOT, nr, addr, .rl);
> @@ -345,13 +345,13 @@ static inline void arch_clear_bit_unlock(
>   * non-atomic property here: it's a lot more instructions and we still have to
>   * provide release semantics anyway.
>   */
> -static inline void arch___clear_bit_unlock(
> +static __always_inline void arch___clear_bit_unlock(
>  	unsigned long nr, volatile unsigned long *addr)
>  {
>  	arch_clear_bit_unlock(nr, addr);
>  }
>  
> -static inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,
> +static __always_inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,
>  		volatile unsigned long *addr)
>  {
>  	unsigned long res;
> 
> ---
> base-commit: 0eb512779d642b21ced83778287a0f7a3ca8f2a1
> change-id: 20241123-riscv-always-inline-bitops-0021c4dae36b
> 
> Best regards,
> -- 
> Nathan Chancellor <nathan at kernel.org>


From charlie at rivosinc.com  Wed Nov 27 11:18:32 2024
From: charlie at rivosinc.com (Charlie Jenkins)
Date: Wed, 27 Nov 2024 11:18:32 -0800
Subject: [PATCH v2] riscv: module: use a plain variable for list_head
 instead of a pointer
In-Reply-To: <20241127142519.3038691-1-cleger@rivosinc.com>
References: <20241127142519.3038691-1-cleger@rivosinc.com>
Message-ID: <Z0dwiIUThatX1H_X@ghost>

On Wed, Nov 27, 2024 at 03:25:17PM +0100, Cl?ment L?ger wrote:
> rel_head's list_head member, rel_entry, doesn't need to be allocated,
> its storage can just be part of the allocated rel_head. Remove the
> pointer which allows to get rid of the allocation as well as an existing
> memory leak found by Kai Zang using kmemleak.
> 
> Reported-by: Kai Zhang <zhangkai at iscas.ac.cn>
> Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>

Thanks for looking into this!

Reviewed-by: Charlie Jenkins <charlie at rivosinc.com>
Tested-by: Charlie Jenkins <charlie at rivosinc.com>

> ---
> 
> V2:
>  - Add Kai Reported-by
>  - Reword the commit description (Andrew)
> 
> ---
>  arch/riscv/kernel/module.c | 18 ++++--------------
>  1 file changed, 4 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
> index 1cd461f3d872..47d0ebeec93c 100644
> --- a/arch/riscv/kernel/module.c
> +++ b/arch/riscv/kernel/module.c
> @@ -23,7 +23,7 @@ struct used_bucket {
>  
>  struct relocation_head {
>  	struct hlist_node node;
> -	struct list_head *rel_entry;
> +	struct list_head rel_entry;
>  	void *location;
>  };
>  
> @@ -634,7 +634,7 @@ process_accumulated_relocations(struct module *me,
>  			location = rel_head_iter->location;
>  			list_for_each_entry_safe(rel_entry_iter,
>  						 rel_entry_iter_tmp,
> -						 rel_head_iter->rel_entry,
> +						 &rel_head_iter->rel_entry,
>  						 head) {
>  				curr_type = rel_entry_iter->type;
>  				reloc_handlers[curr_type].reloc_handler(
> @@ -704,16 +704,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
>  			return -ENOMEM;
>  		}
>  
> -		rel_head->rel_entry =
> -			kmalloc(sizeof(struct list_head), GFP_KERNEL);
> -
> -		if (!rel_head->rel_entry) {
> -			kfree(entry);
> -			kfree(rel_head);
> -			return -ENOMEM;
> -		}
> -
> -		INIT_LIST_HEAD(rel_head->rel_entry);
> +		INIT_LIST_HEAD(&rel_head->rel_entry);
>  		rel_head->location = location;
>  		INIT_HLIST_NODE(&rel_head->node);
>  		if (!current_head->first) {
> @@ -722,7 +713,6 @@ static int add_relocation_to_accumulate(struct module *me, int type,
>  
>  			if (!bucket) {
>  				kfree(entry);
> -				kfree(rel_head->rel_entry);
>  				kfree(rel_head);
>  				return -ENOMEM;
>  			}
> @@ -735,7 +725,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
>  	}
>  
>  	/* Add relocation to head of discovered rel_head */
> -	list_add_tail(&entry->head, rel_head->rel_entry);
> +	list_add_tail(&entry->head, &rel_head->rel_entry);
>  
>  	return 0;
>  }
> -- 
> 2.45.2
> 


From maz at kernel.org  Wed Nov 27 11:32:06 2024
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 27 Nov 2024 19:32:06 +0000
Subject: [PATCH v4 24/26] arch_numa: switch over to numa_memblks
In-Reply-To: <20240807064110.1003856-25-rppt@kernel.org>
References: <20240807064110.1003856-1-rppt@kernel.org>
	<20240807064110.1003856-25-rppt@kernel.org>
Message-ID: <867c8ov5ft.wl-maz@kernel.org>

Hi Mike,

Sorry for reviving a rather old thread.

On Wed, 07 Aug 2024 07:41:08 +0100,
Mike Rapoport <rppt at kernel.org> wrote:
> 
> From: "Mike Rapoport (Microsoft)" <rppt at kernel.org>
> 
> Until now arch_numa was directly translating firmware NUMA information
> to memblock.
> 
> Using numa_memblks as an intermediate step has a few advantages:
> * alignment with more battle tested x86 implementation
> * availability of NUMA emulation
> * maintaining node information for not yet populated memory
> 
> Adjust a few places in numa_memblks to compile with 32-bit phys_addr_t
> and replace current functionality related to numa_add_memblk() and
> __node_distance() in arch_numa with the implementation based on
> numa_memblks and add functions required by numa_emulation.
> 
> Signed-off-by: Mike Rapoport (Microsoft) <rppt at kernel.org>
> Tested-by: Zi Yan <ziy at nvidia.com> # for x86_64 and arm64
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Tested-by: Jonathan Cameron <Jonathan.Cameron at huawei.com> [arm64 + CXL via QEMU]
> Acked-by: Dan Williams <dan.j.williams at intel.com>
> Acked-by: David Hildenbrand <david at redhat.com>
> ---
>  drivers/base/Kconfig       |   1 +
>  drivers/base/arch_numa.c   | 201 +++++++++++--------------------------
>  include/asm-generic/numa.h |   6 +-
>  mm/numa_memblks.c          |  17 ++--
>  4 files changed, 75 insertions(+), 150 deletions(-)
>

[...]

>  static int __init numa_register_nodes(void)
>  {
>  	int nid;
> -	struct memblock_region *mblk;
> -
> -	/* Check that valid nid is set to memblks */
> -	for_each_mem_region(mblk) {
> -		int mblk_nid = memblock_get_region_node(mblk);
> -		phys_addr_t start = mblk->base;
> -		phys_addr_t end = mblk->base + mblk->size - 1;
> -
> -		if (mblk_nid == NUMA_NO_NODE || mblk_nid >= MAX_NUMNODES) {
> -			pr_warn("Warning: invalid memblk node %d [mem %pap-%pap]\n",
> -				mblk_nid, &start, &end);
> -			return -EINVAL;
> -		}
> -	}
>  

This hunk has the unfortunate side effect of killing my ThunderX
extremely early at boot time, as this sorry excuse for a machine
really relies on the kernel recognising that whatever NUMA information
the FW offers is BS.

Reverting this hunk restores happiness (sort of).

FWIW, I've posted a patch with such revert at [1].

Thanks,

	M.

[1] https://lore.kernel.org/r/20241127193000.3702637-1-maz at kernel.org

-- 
Without deviation from the norm, progress is not possible.


From pr-tracker-bot at kernel.org  Wed Nov 27 11:37:12 2024
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Wed, 27 Nov 2024 19:37:12 +0000
Subject: [GIT PULL] RISC-V Paches for the 6.13 Merge Window, Part 1
In-Reply-To: <mhng-5c0ea89d-908b-4009-ba23-e4fac45618b4@palmer-ri-x1c9>
References: <mhng-5c0ea89d-908b-4009-ba23-e4fac45618b4@palmer-ri-x1c9>
Message-ID: <173273623222.1191875.109864199559601828.pr-tracker-bot@kernel.org>

The pull request you sent on Wed, 27 Nov 2024 07:30:53 -0800 (PST):

> git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git tags/riscv-for-linus-6.13-mw1

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/91dbbe6c9ffe5eded9a3e75d773ff92da8d2bc57

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From bjorn at kernel.org  Wed Nov 27 13:25:57 2024
From: bjorn at kernel.org (=?utf-8?B?QmrDtnJuIFTDtnBlbA==?=)
Date: Wed, 27 Nov 2024 22:25:57 +0100
Subject: [PATCH v3 0/7] riscv: ftrace: atmoic patching and preempt
 improvements
In-Reply-To: <20241127172908.17149-1-andybnac@gmail.com>
References: <20241127172908.17149-1-andybnac@gmail.com>
Message-ID: <87frncmkre.fsf@all.your.base.are.belong.to.us>

Adding Steven.

Andy Chiu <andybnac at gmail.com> writes:

> This series makes atmoic code patching possible in riscv ftrace. A
> direct benefit of this is that we can get rid of stop_machine() when
> patching function entries. This also makes it possible to run ftrace
> with full kernel preemption. Before this series, the kernel initializes
> patchable function entries to NOP4 + NOP4. To start tracing, it updates
> entries to AUIPC + JALR while holding other cores in stop_machine.
> stop_machine() is required because it is impossible to update 2
> instructions, and be seen atomically. And preemption must have to be
> prevented, as kernel preemption allows process to be scheduled out while
> executing on one of these instruction pairs.
>
> This series addresses the problem by initializing the first NOP4 to
> AUIPC. So, atmoic patching is possible because the kernel only has to
> update one instruction. As long as the instruction is naturally aligned,
> then it is expected to be updated atomically.
>
> However, the address range of the ftrace trampoline is limited to +-2K
> from ftrace_caller after appplying this series. This issue is expected
> to be solved by Puranjay's CALL_OPS, where it adds 8B naturally align
> data in front of pacthable functions and can  use it to direct execution
> out to any custom trampolines.
>
> The series is composed by three parts. The first part cleans up the
> existing issues when the kernel is compiled with clang.The second part
> modifies the ftrace code patching mechanism (2-4) as mentioned above.
> Then prepare ftrace to be able to run with kernel preemption (5,6)
>
> An ongoing fix:
>
> Since there is no room for marking *kernel_text_address as notrace[1] at
> source code level, there is a significant performance regression when
> using function_graph with TRACE_IRQFLAGS enabled. There can be as much as
> 8 graph handler being called in each function-entry. The current
> workaround requires us echo "*kernel_text_address" into
> set_ftrace_notrace before starting the trace. However, we observed that
> the kernel still enables the patch site in some cases even with
> *kernel_text_address properly added in the file While the root cause is
> still under investagtion, we consider that it should not be the reason
> for holding back the code patching, in order to unblock the call_ops
> part.

Maybe Steven knows this from the top of his head!

As Andy points out, "*kernel_text_address" is used in the stack
unwinding on RISC-V. So, if you do a tracing without filtering *and*
TRACE_IRQFLAGS, one will drown in traces.

E.g. the ftrace selftest:
  | $ ./ftracetest -vvv test.d/ftrace/fgraph-multi.tc

will generate a lot of traces.

Now, if we add:
--8<--
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-multi.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-multi.tc
index ff88f97e41fb..4f30a4d81d99 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-multi.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-multi.tc
@@ -84,6 +84,7 @@ cd $INSTANCE2
 do_test '*rcu*' 'rcu'
 cd $WD
 cd $INSTANCE3
+echo '*kernel_text_address' > set_ftrace_notrace
 echo function_graph > current_tracer
 
 sleep 1
-->8--

The graph tracer will not honor the "set_ftrace_notrace" in $INSTANCE3,
but still enable the *kernel_text_address traces. (Note that there are
no filters in the test, so *all* ftrace recs will be enabled.)

Are we holding the graph tracer wrong?


Happy thanksgiving!
Bj?rn


From seanjc at google.com  Wed Nov 27 16:55:31 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:31 -0800
Subject: [PATCH v4 00/16] KVM: selftests: "tree" wide overhauls
Message-ID: <20241128005547.4077116-1-seanjc@google.com>

Two separate series (mmu_stress_test[1] and $ARCH[2]), posted as one to
avoid unpleasant conflicts, and because I hope to land both in kvm/next
shortly after 6.12-rc1 since they impact all of KVM selftests.

mmu_stress_test
---------------
Convert the max_guest_memory_test into a more generic mmu_stress_test.
The basic gist of the "conversion" is to have the test do mprotect() on
guest memory while vCPUs are accessing said memory, e.g. to verify KVM
and mmu_notifiers are working as intended.

The original plan was that patch 3 would be a single patch, but things
snowballed in order to rework vcpu_get_reg() to return a value instead
of using an out-param.  Having to define a variable just to bump the
program counter on arm64 annoyed me.

$ARCH
-----
Play nice with treewrite builds of unsupported architectures, e.g. arm
(32-bit), as KVM selftests' Makefile doesn't do anything to ensure the
target architecture is actually one KVM selftests supports.

The last two patches are opportunistic changes (since the above Makefile
change will generate conflicts everywhere) to switch to using $(ARCH)
instead of the target triple for arch specific directories, e.g. arm64
instead of aarch64, mainly so as not to be different from the rest of
the kernel.

Compile tested on all architectures, runtime tested on x86 and arm64.

v4:
 - Rebase and squash the series.
 - Exclude Makefile.kvm from .gitignore. [kernel test bot]

v3 (of mmu_stress_test):
 - Rebased onto v6.12-rc2.
 - Disable strict aliasing to fix the PMCR snafu.
 - Collect reviews. [Drew]
 - Minor changelog fixes. [Drew]
 - Include ucall_common.h to prep for RISC-V. [Drew]

v2:
 - Rebase onto kvm/next.
 - Add the aforementioned vcpu_get_reg() changes/disaster.
 - Actually add arm64 support for the fancy mprotect() testcase (I did this
   before v1, but managed to forget to include the changes when posting).
 - Emit "mov %rax, (%rax)" on x86. [James]
 - Add a comment to explain the fancy mprotect() vs. vCPUs logic.
 - Drop the KVM x86 patches (applied and/or will be handled separately).

v1: https://lore.kernel.org/all/20240809194335.1726916-1-seanjc at google.com

[1] https://lore.kernel.org/all/20241009154953.1073471-1-seanjc at google.com
[2] https://lore.kernel.org/all/20240826190116.145945-1-seanjc at google.com

Sean Christopherson (16):
  KVM: Move KVM_REG_SIZE() definition to common uAPI header
  KVM: selftests: Return a value from vcpu_get_reg() instead of using an
    out-param
  KVM: selftests: Assert that vcpu_{g,s}et_reg() won't truncate
  KVM: selftests: Check for a potential unhandled exception iff KVM_RUN
    succeeded
  KVM: selftests: Rename max_guest_memory_test to mmu_stress_test
  KVM: selftests: Only muck with SREGS on x86 in mmu_stress_test
  KVM: selftests: Compute number of extra pages needed in
    mmu_stress_test
  KVM: sefltests: Explicitly include ucall_common.h in mmu_stress_test.c
  KVM: selftests: Enable mmu_stress_test on arm64
  KVM: selftests: Use vcpu_arch_put_guest() in mmu_stress_test
  KVM: selftests: Precisely limit the number of guest loops in
    mmu_stress_test
  KVM: selftests: Add a read-only mprotect() phase to mmu_stress_test
  KVM: selftests: Verify KVM correctly handles mprotect(PROT_READ)
  KVM: selftests: Provide empty 'all' and 'clean' targets for
    unsupported ARCHs
  KVM: selftests: Use canonical $(ARCH) paths for KVM selftests
    directories
  KVM: selftests: Override ARCH for x86_64 instead of using ARCH_DIR

 MAINTAINERS                                   |  12 +-
 arch/arm64/include/uapi/asm/kvm.h             |   3 -
 arch/riscv/include/uapi/asm/kvm.h             |   3 -
 include/uapi/linux/kvm.h                      |   4 +
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          | 345 +-----------------
 tools/testing/selftests/kvm/Makefile.kvm      | 330 +++++++++++++++++
 .../kvm/{aarch64 => arm64}/aarch32_id_regs.c  |  10 +-
 .../kvm/{aarch64 => arm64}/arch_timer.c       |   0
 .../arch_timer_edge_cases.c                   |   0
 .../kvm/{aarch64 => arm64}/debug-exceptions.c |   4 +-
 .../kvm/{aarch64 => arm64}/get-reg-list.c     |   0
 .../kvm/{aarch64 => arm64}/hypercalls.c       |   6 +-
 .../kvm/{aarch64 => arm64}/mmio_abort.c       |   0
 .../kvm/{aarch64 => arm64}/no-vgic-v3.c       |   2 +-
 .../kvm/{aarch64 => arm64}/page_fault_test.c  |   0
 .../kvm/{aarch64 => arm64}/psci_test.c        |   6 +-
 .../kvm/{aarch64 => arm64}/set_id_regs.c      |  18 +-
 .../kvm/{aarch64 => arm64}/smccc_filter.c     |   0
 .../{aarch64 => arm64}/vcpu_width_config.c    |   0
 .../kvm/{aarch64 => arm64}/vgic_init.c        |   0
 .../kvm/{aarch64 => arm64}/vgic_irq.c         |   0
 .../kvm/{aarch64 => arm64}/vgic_lpi_stress.c  |   0
 .../{aarch64 => arm64}/vpmu_counter_access.c  |  19 +-
 .../selftests/kvm/dirty_log_perf_test.c       |   2 +-
 .../include/{aarch64 => arm64}/arch_timer.h   |   0
 .../kvm/include/{aarch64 => arm64}/delay.h    |   0
 .../kvm/include/{aarch64 => arm64}/gic.h      |   0
 .../kvm/include/{aarch64 => arm64}/gic_v3.h   |   0
 .../include/{aarch64 => arm64}/gic_v3_its.h   |   0
 .../{aarch64 => arm64}/kvm_util_arch.h        |   0
 .../include/{aarch64 => arm64}/processor.h    |   0
 .../kvm/include/{aarch64 => arm64}/spinlock.h |   0
 .../kvm/include/{aarch64 => arm64}/ucall.h    |   0
 .../kvm/include/{aarch64 => arm64}/vgic.h     |   0
 .../testing/selftests/kvm/include/kvm_util.h  |  10 +-
 .../kvm/include/{s390x => s390}/debug_print.h |   0
 .../{s390x => s390}/diag318_test_handler.h    |   0
 .../kvm/include/{s390x => s390}/facility.h    |   0
 .../include/{s390x => s390}/kvm_util_arch.h   |   0
 .../kvm/include/{s390x => s390}/processor.h   |   0
 .../kvm/include/{s390x => s390}/sie.h         |   0
 .../kvm/include/{s390x => s390}/ucall.h       |   0
 .../kvm/include/{x86_64 => x86}/apic.h        |   2 -
 .../kvm/include/{x86_64 => x86}/evmcs.h       |   3 -
 .../kvm/include/{x86_64 => x86}/hyperv.h      |   3 -
 .../include/{x86_64 => x86}/kvm_util_arch.h   |   0
 .../kvm/include/{x86_64 => x86}/mce.h         |   2 -
 .../kvm/include/{x86_64 => x86}/pmu.h         |   0
 .../kvm/include/{x86_64 => x86}/processor.h   |   2 -
 .../kvm/include/{x86_64 => x86}/sev.h         |   0
 .../kvm/include/{x86_64 => x86}/svm.h         |   6 -
 .../kvm/include/{x86_64 => x86}/svm_util.h    |   3 -
 .../kvm/include/{x86_64 => x86}/ucall.h       |   0
 .../kvm/include/{x86_64 => x86}/vmx.h         |   2 -
 .../kvm/lib/{aarch64 => arm64}/gic.c          |   0
 .../kvm/lib/{aarch64 => arm64}/gic_private.h  |   0
 .../kvm/lib/{aarch64 => arm64}/gic_v3.c       |   0
 .../kvm/lib/{aarch64 => arm64}/gic_v3_its.c   |   0
 .../kvm/lib/{aarch64 => arm64}/handlers.S     |   0
 .../kvm/lib/{aarch64 => arm64}/processor.c    |   8 +-
 .../kvm/lib/{aarch64 => arm64}/spinlock.c     |   0
 .../kvm/lib/{aarch64 => arm64}/ucall.c        |   0
 .../kvm/lib/{aarch64 => arm64}/vgic.c         |   0
 tools/testing/selftests/kvm/lib/kvm_util.c    |   3 +-
 .../selftests/kvm/lib/riscv/processor.c       |  66 ++--
 .../{s390x => s390}/diag318_test_handler.c    |   0
 .../kvm/lib/{s390x => s390}/facility.c        |   0
 .../kvm/lib/{s390x => s390}/processor.c       |   0
 .../selftests/kvm/lib/{s390x => s390}/ucall.c |   0
 .../selftests/kvm/lib/{x86_64 => x86}/apic.c  |   0
 .../kvm/lib/{x86_64 => x86}/handlers.S        |   0
 .../kvm/lib/{x86_64 => x86}/hyperv.c          |   0
 .../kvm/lib/{x86_64 => x86}/memstress.c       |   2 +-
 .../selftests/kvm/lib/{x86_64 => x86}/pmu.c   |   0
 .../kvm/lib/{x86_64 => x86}/processor.c       |   2 -
 .../selftests/kvm/lib/{x86_64 => x86}/sev.c   |   0
 .../selftests/kvm/lib/{x86_64 => x86}/svm.c   |   1 -
 .../selftests/kvm/lib/{x86_64 => x86}/ucall.c |   0
 .../selftests/kvm/lib/{x86_64 => x86}/vmx.c   |   2 -
 ..._guest_memory_test.c => mmu_stress_test.c} | 162 +++++++-
 .../testing/selftests/kvm/riscv/arch_timer.c  |   2 +-
 .../testing/selftests/kvm/riscv/ebreak_test.c |   2 +-
 .../selftests/kvm/riscv/sbi_pmu_test.c        |   2 +-
 .../selftests/kvm/{s390x => s390}/cmma_test.c |   0
 .../selftests/kvm/{s390x => s390}/config      |   0
 .../{s390x => s390}/cpumodel_subfuncs_test.c  |   0
 .../kvm/{s390x => s390}/debug_test.c          |   0
 .../selftests/kvm/{s390x => s390}/memop.c     |   0
 .../selftests/kvm/{s390x => s390}/resets.c    |   2 +-
 .../{s390x => s390}/shared_zeropage_test.c    |   0
 .../kvm/{s390x => s390}/sync_regs_test.c      |   0
 .../selftests/kvm/{s390x => s390}/tprot.c     |   0
 .../kvm/{s390x => s390}/ucontrol_test.c       |   0
 .../selftests/kvm/set_memory_region_test.c    |   6 +-
 tools/testing/selftests/kvm/steal_time.c      |   3 +-
 .../selftests/kvm/{x86_64 => x86}/amx_test.c  |   0
 .../kvm/{x86_64 => x86}/apic_bus_clock_test.c |   0
 .../kvm/{x86_64 => x86}/cpuid_test.c          |   0
 .../kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c |   0
 .../kvm/{x86_64 => x86}/debug_regs.c          |   0
 .../dirty_log_page_splitting_test.c           |   0
 .../exit_on_emulation_failure_test.c          |   0
 .../kvm/{x86_64 => x86}/feature_msrs_test.c   |   0
 .../kvm/{x86_64 => x86}/fix_hypercall_test.c  |   0
 .../kvm/{x86_64 => x86}/flds_emulation.h      |   0
 .../kvm/{x86_64 => x86}/hwcr_msr_test.c       |   0
 .../kvm/{x86_64 => x86}/hyperv_clock.c        |   0
 .../kvm/{x86_64 => x86}/hyperv_cpuid.c        |   0
 .../kvm/{x86_64 => x86}/hyperv_evmcs.c        |   0
 .../hyperv_extended_hypercalls.c              |   0
 .../kvm/{x86_64 => x86}/hyperv_features.c     |   0
 .../kvm/{x86_64 => x86}/hyperv_ipi.c          |   0
 .../kvm/{x86_64 => x86}/hyperv_svm_test.c     |   0
 .../kvm/{x86_64 => x86}/hyperv_tlb_flush.c    |   0
 .../kvm/{x86_64 => x86}/kvm_clock_test.c      |   0
 .../kvm/{x86_64 => x86}/kvm_pv_test.c         |   0
 .../kvm/{x86_64 => x86}/max_vcpuid_cap_test.c |   0
 .../kvm/{x86_64 => x86}/monitor_mwait_test.c  |   0
 .../{x86_64 => x86}/nested_exceptions_test.c  |   0
 .../kvm/{x86_64 => x86}/nx_huge_pages_test.c  |   0
 .../kvm/{x86_64 => x86}/nx_huge_pages_test.sh |   0
 .../kvm/{x86_64 => x86}/platform_info_test.c  |   0
 .../kvm/{x86_64 => x86}/pmu_counters_test.c   |   0
 .../{x86_64 => x86}/pmu_event_filter_test.c   |   0
 .../private_mem_conversions_test.c            |   0
 .../private_mem_kvm_exits_test.c              |   0
 .../{x86_64 => x86}/recalc_apic_map_test.c    |   0
 .../kvm/{x86_64 => x86}/set_boot_cpu_id.c     |   0
 .../kvm/{x86_64 => x86}/set_sregs_test.c      |   0
 .../kvm/{x86_64 => x86}/sev_init2_tests.c     |   0
 .../kvm/{x86_64 => x86}/sev_migrate_tests.c   |   0
 .../kvm/{x86_64 => x86}/sev_smoke_test.c      |   0
 .../smaller_maxphyaddr_emulation_test.c       |   0
 .../selftests/kvm/{x86_64 => x86}/smm_test.c  |   0
 .../kvm/{x86_64 => x86}/state_test.c          |   0
 .../kvm/{x86_64 => x86}/svm_int_ctl_test.c    |   0
 .../svm_nested_shutdown_test.c                |   0
 .../svm_nested_soft_inject_test.c             |   0
 .../kvm/{x86_64 => x86}/svm_vmcall_test.c     |   0
 .../kvm/{x86_64 => x86}/sync_regs_test.c      |   0
 .../{x86_64 => x86}/triple_fault_event_test.c |   0
 .../kvm/{x86_64 => x86}/tsc_msrs_test.c       |   0
 .../kvm/{x86_64 => x86}/tsc_scaling_sync.c    |   0
 .../kvm/{x86_64 => x86}/ucna_injection_test.c |   0
 .../kvm/{x86_64 => x86}/userspace_io_test.c   |   0
 .../{x86_64 => x86}/userspace_msr_exit_test.c |   0
 .../{x86_64 => x86}/vmx_apic_access_test.c    |   0
 .../vmx_close_while_nested_test.c             |   0
 .../kvm/{x86_64 => x86}/vmx_dirty_log_test.c  |   0
 .../vmx_exception_with_invalid_guest_state.c  |   0
 .../vmx_invalid_nested_guest_state.c          |   0
 .../kvm/{x86_64 => x86}/vmx_msrs_test.c       |   0
 .../vmx_nested_tsc_scaling_test.c             |   0
 .../kvm/{x86_64 => x86}/vmx_pmu_caps_test.c   |   0
 .../vmx_preemption_timer_test.c               |   0
 .../vmx_set_nested_state_test.c               |   0
 .../kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c |   0
 .../kvm/{x86_64 => x86}/xapic_ipi_test.c      |   0
 .../kvm/{x86_64 => x86}/xapic_state_test.c    |   0
 .../kvm/{x86_64 => x86}/xcr0_cpuid_test.c     |   0
 .../kvm/{x86_64 => x86}/xen_shinfo_test.c     |   0
 .../kvm/{x86_64 => x86}/xen_vmcall_test.c     |   0
 .../kvm/{x86_64 => x86}/xss_msr_test.c        |   0
 164 files changed, 584 insertions(+), 477 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/Makefile.kvm
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/aarch32_id_regs.c (95%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer_edge_cases.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/debug-exceptions.c (99%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/get-reg-list.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/hypercalls.c (98%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/mmio_abort.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/no-vgic-v3.c (98%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/page_fault_test.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/psci_test.c (97%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/set_id_regs.c (97%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/smccc_filter.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vcpu_width_config.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_init.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_irq.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_lpi_stress.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vpmu_counter_access.c (97%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/arch_timer.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/delay.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3_its.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/processor.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/spinlock.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/vgic.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/debug_print.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/diag318_test_handler.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/facility.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/processor.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/sie.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/apic.h (98%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/evmcs.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/hyperv.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/mce.h (94%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/pmu.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/processor.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/sev.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm.h (98%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm_util.h (94%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/vmx.h (99%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_private.h (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3_its.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/handlers.S (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/processor.c (98%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/spinlock.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/vgic.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/diag318_test_handler.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/facility.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/processor.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/apic.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/handlers.S (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/hyperv.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/memstress.c (98%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/pmu.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/processor.c (99%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/sev.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/svm.c (99%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/vmx.c (99%)
 rename tools/testing/selftests/kvm/{max_guest_memory_test.c => mmu_stress_test.c} (60%)
 rename tools/testing/selftests/kvm/{s390x => s390}/cmma_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/config (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/cpumodel_subfuncs_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/debug_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/memop.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/resets.c (99%)
 rename tools/testing/selftests/kvm/{s390x => s390}/shared_zeropage_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/sync_regs_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/tprot.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/ucontrol_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/amx_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/apic_bus_clock_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/cpuid_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/debug_regs.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/dirty_log_page_splitting_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/exit_on_emulation_failure_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/feature_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/fix_hypercall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/flds_emulation.h (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hwcr_msr_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_clock.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_cpuid.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_evmcs.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_extended_hypercalls.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_features.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_ipi.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_svm_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_tlb_flush.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_clock_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_pv_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/max_vcpuid_cap_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/monitor_mwait_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nested_exceptions_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.sh (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/platform_info_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_counters_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_event_filter_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_conversions_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_kvm_exits_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/recalc_apic_map_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/set_boot_cpu_id.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/set_sregs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_init2_tests.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_migrate_tests.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_smoke_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/smaller_maxphyaddr_emulation_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/smm_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_int_ctl_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_shutdown_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_soft_inject_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_vmcall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sync_regs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/triple_fault_event_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_scaling_sync.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/ucna_injection_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_io_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_msr_exit_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_apic_access_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_close_while_nested_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_dirty_log_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_exception_with_invalid_guest_state.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_invalid_nested_guest_state.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_nested_tsc_scaling_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_pmu_caps_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_preemption_timer_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_set_nested_state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_ipi_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xcr0_cpuid_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_shinfo_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_vmcall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xss_msr_test.c (100%)


base-commit: 4d911c7abee56771b0219a9fbf0120d06bdc9c14
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:32 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:32 -0800
Subject: [PATCH v4 01/16] KVM: Move KVM_REG_SIZE() definition to common uAPI header
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-2-seanjc@google.com>

Define KVM_REG_SIZE() in the common kvm.h header, and delete the arm64 and
RISC-V versions.  As evidenced by the surrounding definitions, all aspects
of the register size encoding are generic, i.e. RISC-V should have moved
arm64's definition to common code instead of copy+pasting.

Acked-by: Anup Patel <anup at brainfault.org>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/include/uapi/asm/kvm.h | 3 ---
 arch/riscv/include/uapi/asm/kvm.h | 3 ---
 include/uapi/linux/kvm.h          | 4 ++++
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 66736ff04011..568bf858f319 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -43,9 +43,6 @@
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 #define KVM_DIRTY_LOG_PAGE_OFFSET 64
 
-#define KVM_REG_SIZE(id)						\
-	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
-
 struct kvm_regs {
 	struct user_pt_regs regs;	/* sp = sp_el0 */
 
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 3482c9a73d1b..9f60d6185077 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -211,9 +211,6 @@ struct kvm_riscv_sbi_sta {
 #define KVM_RISCV_TIMER_STATE_OFF	0
 #define KVM_RISCV_TIMER_STATE_ON	1
 
-#define KVM_REG_SIZE(id)		\
-	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
-
 /* If you need to interpret the index values, here is the key: */
 #define KVM_REG_RISCV_TYPE_MASK		0x00000000FF000000
 #define KVM_REG_RISCV_TYPE_SHIFT	24
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 502ea63b5d2e..343de0a51797 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1070,6 +1070,10 @@ struct kvm_dirty_tlb {
 
 #define KVM_REG_SIZE_SHIFT	52
 #define KVM_REG_SIZE_MASK	0x00f0000000000000ULL
+
+#define KVM_REG_SIZE(id)		\
+	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+
 #define KVM_REG_SIZE_U8		0x0000000000000000ULL
 #define KVM_REG_SIZE_U16	0x0010000000000000ULL
 #define KVM_REG_SIZE_U32	0x0020000000000000ULL
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:33 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:33 -0800
Subject: [PATCH v4 02/16] KVM: selftests: Return a value from vcpu_get_reg()
 instead of using an out-param
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-3-seanjc@google.com>

Return a uint64_t from vcpu_get_reg() instead of having the caller provide
a pointer to storage, as none of the vcpu_get_reg() usage in KVM selftests
accesses a register larger than 64 bits, and vcpu_set_reg() only accepts a
64-bit value.  If a use case comes along that needs to get a register that
is larger than 64 bits, then a utility can be added to assert success and
take a void pointer, but until then, forcing an out param yields ugly code
and prevents feeding the output of vcpu_get_reg() into vcpu_set_reg().

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 .../selftests/kvm/aarch64/aarch32_id_regs.c   | 10 +--
 .../selftests/kvm/aarch64/debug-exceptions.c  |  4 +-
 .../selftests/kvm/aarch64/hypercalls.c        |  6 +-
 .../selftests/kvm/aarch64/no-vgic-v3.c        |  2 +-
 .../testing/selftests/kvm/aarch64/psci_test.c |  6 +-
 .../selftests/kvm/aarch64/set_id_regs.c       | 18 ++---
 .../kvm/aarch64/vpmu_counter_access.c         | 19 +++---
 .../testing/selftests/kvm/include/kvm_util.h  |  6 +-
 .../selftests/kvm/lib/aarch64/processor.c     |  8 +--
 .../selftests/kvm/lib/riscv/processor.c       | 66 +++++++++----------
 .../testing/selftests/kvm/riscv/arch_timer.c  |  2 +-
 .../testing/selftests/kvm/riscv/ebreak_test.c |  2 +-
 .../selftests/kvm/riscv/sbi_pmu_test.c        |  2 +-
 tools/testing/selftests/kvm/s390x/resets.c    |  2 +-
 tools/testing/selftests/kvm/steal_time.c      |  3 +-
 15 files changed, 78 insertions(+), 78 deletions(-)

diff --git a/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c b/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c
index 8e5bd07a3727..447d61cae4db 100644
--- a/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c
+++ b/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c
@@ -97,7 +97,7 @@ static void test_user_raz_wi(struct kvm_vcpu *vcpu)
 		uint64_t reg_id = raz_wi_reg_ids[i];
 		uint64_t val;
 
-		vcpu_get_reg(vcpu, reg_id, &val);
+		val = vcpu_get_reg(vcpu, reg_id);
 		TEST_ASSERT_EQ(val, 0);
 
 		/*
@@ -106,7 +106,7 @@ static void test_user_raz_wi(struct kvm_vcpu *vcpu)
 		 */
 		vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);
 
-		vcpu_get_reg(vcpu, reg_id, &val);
+		val = vcpu_get_reg(vcpu, reg_id);
 		TEST_ASSERT_EQ(val, 0);
 	}
 }
@@ -126,14 +126,14 @@ static void test_user_raz_invariant(struct kvm_vcpu *vcpu)
 		uint64_t reg_id = raz_invariant_reg_ids[i];
 		uint64_t val;
 
-		vcpu_get_reg(vcpu, reg_id, &val);
+		val = vcpu_get_reg(vcpu, reg_id);
 		TEST_ASSERT_EQ(val, 0);
 
 		r = __vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);
 		TEST_ASSERT(r < 0 && errno == EINVAL,
 			    "unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);
 
-		vcpu_get_reg(vcpu, reg_id, &val);
+		val = vcpu_get_reg(vcpu, reg_id);
 		TEST_ASSERT_EQ(val, 0);
 	}
 }
@@ -144,7 +144,7 @@ static bool vcpu_aarch64_only(struct kvm_vcpu *vcpu)
 {
 	uint64_t val, el0;
 
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &val);
+	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
 
 	el0 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), val);
 	return el0 == ID_AA64PFR0_EL1_ELx_64BIT_ONLY;
diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
index ff7a949fc96a..c7fb55c9135b 100644
--- a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
+++ b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
@@ -501,7 +501,7 @@ void test_single_step_from_userspace(int test_cnt)
 		TEST_ASSERT(ss_enable, "Unexpected KVM_EXIT_DEBUG");
 
 		/* Check if the current pc is expected. */
-		vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &pc);
+		pc = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc));
 		TEST_ASSERT(!test_pc || pc == test_pc,
 			    "Unexpected pc 0x%lx (expected 0x%lx)",
 			    pc, test_pc);
@@ -583,7 +583,7 @@ int main(int argc, char *argv[])
 	uint64_t aa64dfr0;
 
 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &aa64dfr0);
+	aa64dfr0 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1));
 	__TEST_REQUIRE(debug_version(aa64dfr0) >= 6,
 		       "Armv8 debug architecture not supported.");
 	kvm_vm_free(vm);
diff --git a/tools/testing/selftests/kvm/aarch64/hypercalls.c b/tools/testing/selftests/kvm/aarch64/hypercalls.c
index 9d192ce0078d..ec54ec7726e9 100644
--- a/tools/testing/selftests/kvm/aarch64/hypercalls.c
+++ b/tools/testing/selftests/kvm/aarch64/hypercalls.c
@@ -173,7 +173,7 @@ static void test_fw_regs_before_vm_start(struct kvm_vcpu *vcpu)
 		const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
 
 		/* First 'read' should be an upper limit of the features supported */
-		vcpu_get_reg(vcpu, reg_info->reg, &val);
+		val = vcpu_get_reg(vcpu, reg_info->reg);
 		TEST_ASSERT(val == FW_REG_ULIMIT_VAL(reg_info->max_feat_bit),
 			"Expected all the features to be set for reg: 0x%lx; expected: 0x%lx; read: 0x%lx",
 			reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit), val);
@@ -184,7 +184,7 @@ static void test_fw_regs_before_vm_start(struct kvm_vcpu *vcpu)
 			"Failed to clear all the features of reg: 0x%lx; ret: %d",
 			reg_info->reg, errno);
 
-		vcpu_get_reg(vcpu, reg_info->reg, &val);
+		val = vcpu_get_reg(vcpu, reg_info->reg);
 		TEST_ASSERT(val == 0,
 			"Expected all the features to be cleared for reg: 0x%lx", reg_info->reg);
 
@@ -214,7 +214,7 @@ static void test_fw_regs_after_vm_start(struct kvm_vcpu *vcpu)
 		 * Before starting the VM, the test clears all the bits.
 		 * Check if that's still the case.
 		 */
-		vcpu_get_reg(vcpu, reg_info->reg, &val);
+		val = vcpu_get_reg(vcpu, reg_info->reg);
 		TEST_ASSERT(val == 0,
 			"Expected all the features to be cleared for reg: 0x%lx",
 			reg_info->reg);
diff --git a/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c b/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c
index 58304bbc2036..ebd70430c89d 100644
--- a/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c
+++ b/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c
@@ -164,7 +164,7 @@ int main(int argc, char *argv[])
 	uint64_t pfr0;
 
 	vm = vm_create_with_one_vcpu(&vcpu, NULL);
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &pfr0);
+	pfr0 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
 	__TEST_REQUIRE(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_GIC), pfr0),
 		       "GICv3 not supported.");
 	kvm_vm_free(vm);
diff --git a/tools/testing/selftests/kvm/aarch64/psci_test.c b/tools/testing/selftests/kvm/aarch64/psci_test.c
index eaa7655fefc1..0ab7d5a24482 100644
--- a/tools/testing/selftests/kvm/aarch64/psci_test.c
+++ b/tools/testing/selftests/kvm/aarch64/psci_test.c
@@ -111,8 +111,8 @@ static void assert_vcpu_reset(struct kvm_vcpu *vcpu)
 {
 	uint64_t obs_pc, obs_x0;
 
-	vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &obs_pc);
-	vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.regs[0]), &obs_x0);
+	obs_pc = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc));
+	obs_x0 = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.regs[0]));
 
 	TEST_ASSERT(obs_pc == CPU_ON_ENTRY_ADDR,
 		    "unexpected target cpu pc: %lx (expected: %lx)",
@@ -152,7 +152,7 @@ static void host_test_cpu_on(void)
 	 */
 	vcpu_power_off(target);
 
-	vcpu_get_reg(target, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), &target_mpidr);
+	target_mpidr = vcpu_get_reg(target, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1));
 	vcpu_args_set(source, 1, target_mpidr & MPIDR_HWID_BITMASK);
 	enter_guest(source);
 
diff --git a/tools/testing/selftests/kvm/aarch64/set_id_regs.c b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
index a79b7f18452d..25ba7d382196 100644
--- a/tools/testing/selftests/kvm/aarch64/set_id_regs.c
+++ b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
@@ -346,7 +346,7 @@ static uint64_t test_reg_set_success(struct kvm_vcpu *vcpu, uint64_t reg,
 	uint64_t mask = ftr_bits->mask;
 	uint64_t val, new_val, ftr;
 
-	vcpu_get_reg(vcpu, reg, &val);
+	val = vcpu_get_reg(vcpu, reg);
 	ftr = (val & mask) >> shift;
 
 	ftr = get_safe_value(ftr_bits, ftr);
@@ -356,7 +356,7 @@ static uint64_t test_reg_set_success(struct kvm_vcpu *vcpu, uint64_t reg,
 	val |= ftr;
 
 	vcpu_set_reg(vcpu, reg, val);
-	vcpu_get_reg(vcpu, reg, &new_val);
+	new_val = vcpu_get_reg(vcpu, reg);
 	TEST_ASSERT_EQ(new_val, val);
 
 	return new_val;
@@ -370,7 +370,7 @@ static void test_reg_set_fail(struct kvm_vcpu *vcpu, uint64_t reg,
 	uint64_t val, old_val, ftr;
 	int r;
 
-	vcpu_get_reg(vcpu, reg, &val);
+	val = vcpu_get_reg(vcpu, reg);
 	ftr = (val & mask) >> shift;
 
 	ftr = get_invalid_value(ftr_bits, ftr);
@@ -384,7 +384,7 @@ static void test_reg_set_fail(struct kvm_vcpu *vcpu, uint64_t reg,
 	TEST_ASSERT(r < 0 && errno == EINVAL,
 		    "Unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);
 
-	vcpu_get_reg(vcpu, reg, &val);
+	val = vcpu_get_reg(vcpu, reg);
 	TEST_ASSERT_EQ(val, old_val);
 }
 
@@ -576,7 +576,7 @@ static void test_clidr(struct kvm_vcpu *vcpu)
 	uint64_t clidr;
 	int level;
 
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CLIDR_EL1), &clidr);
+	clidr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CLIDR_EL1));
 
 	/* find the first empty level in the cache hierarchy */
 	for (level = 1; level < 7; level++) {
@@ -601,7 +601,7 @@ static void test_ctr(struct kvm_vcpu *vcpu)
 {
 	u64 ctr;
 
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CTR_EL0), &ctr);
+	ctr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CTR_EL0));
 	ctr &= ~CTR_EL0_DIC_MASK;
 	if (ctr & CTR_EL0_IminLine_MASK)
 		ctr--;
@@ -617,7 +617,7 @@ static void test_vcpu_ftr_id_regs(struct kvm_vcpu *vcpu)
 	test_clidr(vcpu);
 	test_ctr(vcpu);
 
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), &val);
+	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1));
 	val++;
 	vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), val);
 
@@ -630,7 +630,7 @@ static void test_assert_id_reg_unchanged(struct kvm_vcpu *vcpu, uint32_t encodin
 	size_t idx = encoding_to_range_idx(encoding);
 	uint64_t observed;
 
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(encoding), &observed);
+	observed = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(encoding));
 	TEST_ASSERT_EQ(test_reg_vals[idx], observed);
 }
 
@@ -665,7 +665,7 @@ int main(void)
 	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
 
 	/* Check for AARCH64 only system */
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &val);
+	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
 	el0 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), val);
 	aarch64_only = (el0 == ID_AA64PFR0_EL1_ELx_64BIT_ONLY);
 
diff --git a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
index f9c0c86d7e85..f16b3b27e32e 100644
--- a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
+++ b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
@@ -440,8 +440,7 @@ static void create_vpmu_vm(void *guest_code)
 		       "Failed to create vgic-v3, skipping");
 
 	/* Make sure that PMUv3 support is indicated in the ID register */
-	vcpu_get_reg(vpmu_vm.vcpu,
-		     KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &dfr0);
+	dfr0 = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1));
 	pmuver = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), dfr0);
 	TEST_ASSERT(pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF &&
 		    pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP,
@@ -484,7 +483,7 @@ static void test_create_vpmu_vm_with_pmcr_n(uint64_t pmcr_n, bool expect_fail)
 	create_vpmu_vm(guest_code);
 	vcpu = vpmu_vm.vcpu;
 
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr_orig);
+	pmcr_orig = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
 	pmcr = pmcr_orig;
 
 	/*
@@ -493,7 +492,7 @@ static void test_create_vpmu_vm_with_pmcr_n(uint64_t pmcr_n, bool expect_fail)
 	 */
 	set_pmcr_n(&pmcr, pmcr_n);
 	vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), pmcr);
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr);
+	pmcr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
 
 	if (expect_fail)
 		TEST_ASSERT(pmcr_orig == pmcr,
@@ -521,7 +520,7 @@ static void run_access_test(uint64_t pmcr_n)
 	vcpu = vpmu_vm.vcpu;
 
 	/* Save the initial sp to restore them later to run the guest again */
-	vcpu_get_reg(vcpu, ARM64_CORE_REG(sp_el1), &sp);
+	sp = vcpu_get_reg(vcpu, ARM64_CORE_REG(sp_el1));
 
 	run_vcpu(vcpu, pmcr_n);
 
@@ -572,12 +571,12 @@ static void run_pmregs_validity_test(uint64_t pmcr_n)
 		 * Test if the 'set' and 'clr' variants of the registers
 		 * are initialized based on the number of valid counters.
 		 */
-		vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), &reg_val);
+		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id));
 		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
 			    "Initial read of set_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
 			    KVM_ARM64_SYS_REG(set_reg_id), reg_val);
 
-		vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id), &reg_val);
+		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id));
 		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
 			    "Initial read of clr_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
 			    KVM_ARM64_SYS_REG(clr_reg_id), reg_val);
@@ -589,12 +588,12 @@ static void run_pmregs_validity_test(uint64_t pmcr_n)
 		 */
 		vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), max_counters_mask);
 
-		vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), &reg_val);
+		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id));
 		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
 			    "Read of set_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
 			    KVM_ARM64_SYS_REG(set_reg_id), reg_val);
 
-		vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id), &reg_val);
+		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id));
 		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
 			    "Read of clr_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
 			    KVM_ARM64_SYS_REG(clr_reg_id), reg_val);
@@ -625,7 +624,7 @@ static uint64_t get_pmcr_n_limit(void)
 	uint64_t pmcr;
 
 	create_vpmu_vm(guest_code);
-	vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr);
+	pmcr = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
 	destroy_vpmu_vm();
 	return get_pmcr_n(pmcr);
 }
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index bc7c242480d6..287a3ec06df4 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -702,11 +702,13 @@ static inline int __vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t va
 
 	return __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, &reg);
 }
-static inline void vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id, void *addr)
+static inline uint64_t vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id)
 {
-	struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)addr };
+	uint64_t val;
+	struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val };
 
 	vcpu_ioctl(vcpu, KVM_GET_ONE_REG, &reg);
+	return val;
 }
 static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val)
 {
diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c
index 698e34f39241..7ba3aa3755f3 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
@@ -281,8 +281,8 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
 	 */
 	vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CPACR_EL1), 3 << 20);
 
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1), &sctlr_el1);
-	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1), &tcr_el1);
+	sctlr_el1 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1));
+	tcr_el1 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1));
 
 	/* Configure base granule size */
 	switch (vm->mode) {
@@ -360,8 +360,8 @@ void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, uint8_t indent)
 {
 	uint64_t pstate, pc;
 
-	vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pstate), &pstate);
-	vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &pc);
+	pstate = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pstate));
+	pc = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc));
 
 	fprintf(stream, "%*spstate: 0x%.16lx pc: 0x%.16lx\n",
 		indent, "", pstate, pc);
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
index 6ae47b3d6b25..dd663bcf0cc0 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -221,39 +221,39 @@ void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, uint8_t indent)
 {
 	struct kvm_riscv_core core;
 
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(mode), &core.mode);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc), &core.regs.pc);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.ra), &core.regs.ra);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.sp), &core.regs.sp);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.gp), &core.regs.gp);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.tp), &core.regs.tp);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t0), &core.regs.t0);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t1), &core.regs.t1);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t2), &core.regs.t2);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s0), &core.regs.s0);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s1), &core.regs.s1);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a0), &core.regs.a0);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a1), &core.regs.a1);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a2), &core.regs.a2);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a3), &core.regs.a3);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a4), &core.regs.a4);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a5), &core.regs.a5);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a6), &core.regs.a6);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a7), &core.regs.a7);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s2), &core.regs.s2);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s3), &core.regs.s3);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s4), &core.regs.s4);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s5), &core.regs.s5);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s6), &core.regs.s6);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s7), &core.regs.s7);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s8), &core.regs.s8);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s9), &core.regs.s9);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s10), &core.regs.s10);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s11), &core.regs.s11);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t3), &core.regs.t3);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t4), &core.regs.t4);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t5), &core.regs.t5);
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t6), &core.regs.t6);
+	core.mode = vcpu_get_reg(vcpu, RISCV_CORE_REG(mode));
+	core.regs.pc = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc));
+	core.regs.ra = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.ra));
+	core.regs.sp = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.sp));
+	core.regs.gp = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.gp));
+	core.regs.tp = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.tp));
+	core.regs.t0 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t0));
+	core.regs.t1 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t1));
+	core.regs.t2 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t2));
+	core.regs.s0 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s0));
+	core.regs.s1 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s1));
+	core.regs.a0 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a0));
+	core.regs.a1 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a1));
+	core.regs.a2 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a2));
+	core.regs.a3 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a3));
+	core.regs.a4 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a4));
+	core.regs.a5 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a5));
+	core.regs.a6 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a6));
+	core.regs.a7 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a7));
+	core.regs.s2 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s2));
+	core.regs.s3 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s3));
+	core.regs.s4 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s4));
+	core.regs.s5 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s5));
+	core.regs.s6 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s6));
+	core.regs.s7 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s7));
+	core.regs.s8 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s8));
+	core.regs.s9 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s9));
+	core.regs.s10 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s10));
+	core.regs.s11 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s11));
+	core.regs.t3 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t3));
+	core.regs.t4 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t4));
+	core.regs.t5 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t5));
+	core.regs.t6 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t6));
 
 	fprintf(stream,
 		" MODE:  0x%lx\n", core.mode);
diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
index 2c792228ac0b..9e370800a6a2 100644
--- a/tools/testing/selftests/kvm/riscv/arch_timer.c
+++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
@@ -93,7 +93,7 @@ struct kvm_vm *test_vm_create(void)
 		vcpu_init_vector_tables(vcpus[i]);
 
 	/* Initialize guest timer frequency. */
-	vcpu_get_reg(vcpus[0], RISCV_TIMER_REG(frequency), &timer_freq);
+	timer_freq = vcpu_get_reg(vcpus[0], RISCV_TIMER_REG(frequency));
 	sync_global_to_guest(vm, timer_freq);
 	pr_debug("timer_freq: %lu\n", timer_freq);
 
diff --git a/tools/testing/selftests/kvm/riscv/ebreak_test.c b/tools/testing/selftests/kvm/riscv/ebreak_test.c
index 0e0712854953..cfed6c727bfc 100644
--- a/tools/testing/selftests/kvm/riscv/ebreak_test.c
+++ b/tools/testing/selftests/kvm/riscv/ebreak_test.c
@@ -60,7 +60,7 @@ int main(void)
 
 	TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_DEBUG);
 
-	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc), &pc);
+	pc = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc));
 	TEST_ASSERT_EQ(pc, LABEL_ADDRESS(sw_bp_1));
 
 	/* skip sw_bp_1 */
diff --git a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
index f299cbfd23ca..f45c0ecc902d 100644
--- a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
+++ b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
@@ -608,7 +608,7 @@ static void test_vm_events_overflow(void *guest_code)
 
 	vcpu_init_vector_tables(vcpu);
 	/* Initialize guest timer frequency. */
-	vcpu_get_reg(vcpu, RISCV_TIMER_REG(frequency), &timer_freq);
+	timer_freq = vcpu_get_reg(vcpu, RISCV_TIMER_REG(frequency));
 	sync_global_to_guest(vm, timer_freq);
 
 	run_vcpu(vcpu);
diff --git a/tools/testing/selftests/kvm/s390x/resets.c b/tools/testing/selftests/kvm/s390x/resets.c
index 357943f2bea8..b58f75b381e5 100644
--- a/tools/testing/selftests/kvm/s390x/resets.c
+++ b/tools/testing/selftests/kvm/s390x/resets.c
@@ -61,7 +61,7 @@ static void test_one_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t value)
 {
 	uint64_t eval_reg;
 
-	vcpu_get_reg(vcpu, id, &eval_reg);
+	eval_reg = vcpu_get_reg(vcpu, id);
 	TEST_ASSERT(eval_reg == value, "value == 0x%lx", value);
 }
 
diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
index a8d3afa0b86b..cce2520af720 100644
--- a/tools/testing/selftests/kvm/steal_time.c
+++ b/tools/testing/selftests/kvm/steal_time.c
@@ -269,9 +269,8 @@ static void guest_code(int cpu)
 static bool is_steal_time_supported(struct kvm_vcpu *vcpu)
 {
 	uint64_t id = RISCV_SBI_EXT_REG(KVM_RISCV_SBI_EXT_STA);
-	unsigned long enabled;
+	unsigned long enabled = vcpu_get_reg(vcpu, id);
 
-	vcpu_get_reg(vcpu, id, &enabled);
 	TEST_ASSERT(enabled == 0 || enabled == 1, "Expected boolean result");
 
 	return enabled;
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:34 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:34 -0800
Subject: [PATCH v4 03/16] KVM: selftests: Assert that vcpu_{g,s}et_reg() won't truncate
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-4-seanjc@google.com>

Assert that the register being read/written by vcpu_{g,s}et_reg() is no
larger than a uint64_t, i.e. that a selftest isn't unintentionally
truncating the value being read/written.

Ideally, the assert would be done at compile-time, but that would limit
the checks to hardcoded accesses and/or require fancier compile-time
assertion infrastructure to filter out dynamic usage.

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/include/kvm_util.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 287a3ec06df4..4c4e5a847f67 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -707,6 +707,8 @@ static inline uint64_t vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id)
 	uint64_t val;
 	struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val };
 
+	TEST_ASSERT(KVM_REG_SIZE(id) <= sizeof(val), "Reg %lx too big", id);
+
 	vcpu_ioctl(vcpu, KVM_GET_ONE_REG, &reg);
 	return val;
 }
@@ -714,6 +716,8 @@ static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val
 {
 	struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val };
 
+	TEST_ASSERT(KVM_REG_SIZE(id) <= sizeof(val), "Reg %lx too big", id);
+
 	vcpu_ioctl(vcpu, KVM_SET_ONE_REG, &reg);
 }
 
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:35 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:35 -0800
Subject: [PATCH v4 04/16] KVM: selftests: Check for a potential unhandled
 exception iff KVM_RUN succeeded
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-5-seanjc@google.com>

Don't check for an unhandled exception if KVM_RUN failed, e.g. if it
returned errno=EFAULT, as reporting unhandled exceptions is done via a
ucall, i.e. requires KVM_RUN to exit cleanly.  Theoretically, checking
for a ucall on a failed KVM_RUN could get a false positive, e.g. if there
were stale data in vcpu->run from a previous exit.

Reviewed-by: James Houghton <jthoughton at google.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/lib/kvm_util.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 480e3a40d197..33fefeb3ca44 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1648,7 +1648,8 @@ int _vcpu_run(struct kvm_vcpu *vcpu)
 		rc = __vcpu_run(vcpu);
 	} while (rc == -1 && errno == EINTR);
 
-	assert_on_unhandled_exception(vcpu);
+	if (!rc)
+		assert_on_unhandled_exception(vcpu);
 
 	return rc;
 }
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:36 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:36 -0800
Subject: [PATCH v4 05/16] KVM: selftests: Rename max_guest_memory_test to mmu_stress_test
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-6-seanjc@google.com>

Rename max_guest_memory_test to mmu_stress_test so that the name isn't
horribly misleading when future changes extend the test to verify things
like mprotect() interactions, and because the test is useful even when its
configured to populate far less than the maximum amount of guest memory.

Reviewed-by: James Houghton <jthoughton at google.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/Makefile                            | 2 +-
 .../kvm/{max_guest_memory_test.c => mmu_stress_test.c}          | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename tools/testing/selftests/kvm/{max_guest_memory_test.c => mmu_stress_test.c} (100%)

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 41593d2e7de9..4384e5f45c36 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -140,7 +140,7 @@ TEST_GEN_PROGS_x86_64 += guest_print_test
 TEST_GEN_PROGS_x86_64 += hardware_disable_test
 TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
 TEST_GEN_PROGS_x86_64 += kvm_page_table_test
-TEST_GEN_PROGS_x86_64 += max_guest_memory_test
+TEST_GEN_PROGS_x86_64 += mmu_stress_test
 TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
 TEST_GEN_PROGS_x86_64 += memslot_perf_test
 TEST_GEN_PROGS_x86_64 += rseq_test
diff --git a/tools/testing/selftests/kvm/max_guest_memory_test.c b/tools/testing/selftests/kvm/mmu_stress_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/max_guest_memory_test.c
rename to tools/testing/selftests/kvm/mmu_stress_test.c
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:37 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:37 -0800
Subject: [PATCH v4 06/16] KVM: selftests: Only muck with SREGS on x86 in mmu_stress_test
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-7-seanjc@google.com>

Try to get/set SREGS in mmu_stress_test only when running on x86, as the
ioctls are supported only by x86 and PPC, and the latter doesn't yet
support KVM selftests.

Reviewed-by: James Houghton <jthoughton at google.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/mmu_stress_test.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/mmu_stress_test.c b/tools/testing/selftests/kvm/mmu_stress_test.c
index 0b9678858b6d..847da23ec1b1 100644
--- a/tools/testing/selftests/kvm/mmu_stress_test.c
+++ b/tools/testing/selftests/kvm/mmu_stress_test.c
@@ -59,10 +59,10 @@ static void run_vcpu(struct kvm_vcpu *vcpu)
 
 static void *vcpu_worker(void *data)
 {
+	struct kvm_sregs __maybe_unused sregs;
 	struct vcpu_info *info = data;
 	struct kvm_vcpu *vcpu = info->vcpu;
 	struct kvm_vm *vm = vcpu->vm;
-	struct kvm_sregs sregs;
 
 	vcpu_args_set(vcpu, 3, info->start_gpa, info->end_gpa, vm->page_size);
 
@@ -70,12 +70,12 @@ static void *vcpu_worker(void *data)
 
 	run_vcpu(vcpu);
 	rendezvous_with_boss();
+#ifdef __x86_64__
 	vcpu_sregs_get(vcpu, &sregs);
-#ifdef __x86_64__
 	/* Toggle CR0.WP to trigger a MMU context reset. */
 	sregs.cr0 ^= X86_CR0_WP;
-#endif
 	vcpu_sregs_set(vcpu, &sregs);
+#endif
 	rendezvous_with_boss();
 
 	run_vcpu(vcpu);
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:38 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:38 -0800
Subject: [PATCH v4 07/16] KVM: selftests: Compute number of extra pages needed
 in mmu_stress_test
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-8-seanjc@google.com>

Create mmu_stress_tests's VM with the correct number of extra pages needed
to map all of memory in the guest.  The bug hasn't been noticed before as
the test currently runs only on x86, which maps guest memory with 1GiB
pages, i.e. doesn't need much memory in the guest for page tables.

Reviewed-by: James Houghton <jthoughton at google.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/mmu_stress_test.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/mmu_stress_test.c b/tools/testing/selftests/kvm/mmu_stress_test.c
index 847da23ec1b1..5467b12f5903 100644
--- a/tools/testing/selftests/kvm/mmu_stress_test.c
+++ b/tools/testing/selftests/kvm/mmu_stress_test.c
@@ -209,7 +209,13 @@ int main(int argc, char *argv[])
 	vcpus = malloc(nr_vcpus * sizeof(*vcpus));
 	TEST_ASSERT(vcpus, "Failed to allocate vCPU array");
 
-	vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
+	vm = __vm_create_with_vcpus(VM_SHAPE_DEFAULT, nr_vcpus,
+#ifdef __x86_64__
+				    max_mem / SZ_1G,
+#else
+				    max_mem / vm_guest_mode_params[VM_MODE_DEFAULT].page_size,
+#endif
+				    guest_code, vcpus);
 
 	max_gpa = vm->max_gfn << vm->page_shift;
 	TEST_ASSERT(max_gpa > (4 * slot_size), "MAXPHYADDR <4gb ");
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:39 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:39 -0800
Subject: [PATCH v4 08/16] KVM: sefltests: Explicitly include ucall_common.h in mmu_stress_test.c
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-9-seanjc@google.com>

Explicitly include ucall_common.h in the MMU stress test, as unlike arm64
and x86-64, RISC-V doesn't include ucall_common.h in its processor.h, i.e.
this will allow enabling the test on RISC-V.

Reported-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/mmu_stress_test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/testing/selftests/kvm/mmu_stress_test.c b/tools/testing/selftests/kvm/mmu_stress_test.c
index 5467b12f5903..fbb693428a82 100644
--- a/tools/testing/selftests/kvm/mmu_stress_test.c
+++ b/tools/testing/selftests/kvm/mmu_stress_test.c
@@ -15,6 +15,7 @@
 #include "test_util.h"
 #include "guest_modes.h"
 #include "processor.h"
+#include "ucall_common.h"
 
 static void guest_code(uint64_t start_gpa, uint64_t end_gpa, uint64_t stride)
 {
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:40 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:40 -0800
Subject: [PATCH v4 09/16] KVM: selftests: Enable mmu_stress_test on arm64
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-10-seanjc@google.com>

Enable the mmu_stress_test on arm64.  The intent was to enable the test
across all architectures when it was first added, but a few goofs made it
unrunnable on !x86.  Now that those goofs are fixed, at least for arm64,
enable the test.

Cc: Oliver Upton <oliver.upton at linux.dev>
Cc: Marc Zyngier <maz at kernel.org>
Reviewed-by: James Houghton <jthoughton at google.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 4384e5f45c36..c59a337cd4da 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -180,6 +180,7 @@ TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
 TEST_GEN_PROGS_aarch64 += kvm_page_table_test
 TEST_GEN_PROGS_aarch64 += memslot_modification_stress_test
 TEST_GEN_PROGS_aarch64 += memslot_perf_test
+TEST_GEN_PROGS_aarch64 += mmu_stress_test
 TEST_GEN_PROGS_aarch64 += rseq_test
 TEST_GEN_PROGS_aarch64 += set_memory_region_test
 TEST_GEN_PROGS_aarch64 += steal_time
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:41 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:41 -0800
Subject: [PATCH v4 10/16] KVM: selftests: Use vcpu_arch_put_guest() in mmu_stress_test
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-11-seanjc@google.com>

Use vcpu_arch_put_guest() to write memory from the guest in
mmu_stress_test as an easy way to provide a bit of extra coverage.

Reviewed-by: James Houghton <jthoughton at google.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/mmu_stress_test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/mmu_stress_test.c b/tools/testing/selftests/kvm/mmu_stress_test.c
index fbb693428a82..656a837c7f49 100644
--- a/tools/testing/selftests/kvm/mmu_stress_test.c
+++ b/tools/testing/selftests/kvm/mmu_stress_test.c
@@ -23,7 +23,7 @@ static void guest_code(uint64_t start_gpa, uint64_t end_gpa, uint64_t stride)
 
 	for (;;) {
 		for (gpa = start_gpa; gpa < end_gpa; gpa += stride)
-			*((volatile uint64_t *)gpa) = gpa;
+			vcpu_arch_put_guest(*((volatile uint64_t *)gpa), gpa);
 		GUEST_SYNC(0);
 	}
 }
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:42 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:42 -0800
Subject: [PATCH v4 11/16] KVM: selftests: Precisely limit the number of guest
 loops in mmu_stress_test
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-12-seanjc@google.com>

Run the exact number of guest loops required in mmu_stress_test instead
of looping indefinitely in anticipation of adding more stages that run
different code (e.g. reads instead of writes).

Reviewed-by: James Houghton <jthoughton at google.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/mmu_stress_test.c | 25 ++++++++++++++-----
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/kvm/mmu_stress_test.c b/tools/testing/selftests/kvm/mmu_stress_test.c
index 656a837c7f49..c6bf18cb7c89 100644
--- a/tools/testing/selftests/kvm/mmu_stress_test.c
+++ b/tools/testing/selftests/kvm/mmu_stress_test.c
@@ -20,12 +20,15 @@
 static void guest_code(uint64_t start_gpa, uint64_t end_gpa, uint64_t stride)
 {
 	uint64_t gpa;
+	int i;
 
-	for (;;) {
+	for (i = 0; i < 2; i++) {
 		for (gpa = start_gpa; gpa < end_gpa; gpa += stride)
 			vcpu_arch_put_guest(*((volatile uint64_t *)gpa), gpa);
-		GUEST_SYNC(0);
+		GUEST_SYNC(i);
 	}
+
+	GUEST_ASSERT(0);
 }
 
 struct vcpu_info {
@@ -52,10 +55,18 @@ static void rendezvous_with_boss(void)
 	}
 }
 
-static void run_vcpu(struct kvm_vcpu *vcpu)
+static void assert_sync_stage(struct kvm_vcpu *vcpu, int stage)
+{
+	struct ucall uc;
+
+	TEST_ASSERT_EQ(get_ucall(vcpu, &uc), UCALL_SYNC);
+	TEST_ASSERT_EQ(uc.args[1], stage);
+}
+
+static void run_vcpu(struct kvm_vcpu *vcpu, int stage)
 {
 	vcpu_run(vcpu);
-	TEST_ASSERT_EQ(get_ucall(vcpu, NULL), UCALL_SYNC);
+	assert_sync_stage(vcpu, stage);
 }
 
 static void *vcpu_worker(void *data)
@@ -69,7 +80,8 @@ static void *vcpu_worker(void *data)
 
 	rendezvous_with_boss();
 
-	run_vcpu(vcpu);
+	/* Stage 0, write all of guest memory. */
+	run_vcpu(vcpu, 0);
 	rendezvous_with_boss();
 #ifdef __x86_64__
 	vcpu_sregs_get(vcpu, &sregs);
@@ -79,7 +91,8 @@ static void *vcpu_worker(void *data)
 #endif
 	rendezvous_with_boss();
 
-	run_vcpu(vcpu);
+	/* Stage 1, re-write all of guest memory. */
+	run_vcpu(vcpu, 1);
 	rendezvous_with_boss();
 
 	return NULL;
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:43 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:43 -0800
Subject: [PATCH v4 12/16] KVM: selftests: Add a read-only mprotect() phase to mmu_stress_test
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-13-seanjc@google.com>

Add a third phase of mmu_stress_test to verify that mprotect()ing guest
memory to make it read-only doesn't cause explosions, e.g. to verify KVM
correctly handles the resulting mmu_notifier invalidations.

Reviewed-by: James Houghton <jthoughton at google.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/mmu_stress_test.c | 22 +++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/kvm/mmu_stress_test.c b/tools/testing/selftests/kvm/mmu_stress_test.c
index c6bf18cb7c89..0918fade9267 100644
--- a/tools/testing/selftests/kvm/mmu_stress_test.c
+++ b/tools/testing/selftests/kvm/mmu_stress_test.c
@@ -28,6 +28,10 @@ static void guest_code(uint64_t start_gpa, uint64_t end_gpa, uint64_t stride)
 		GUEST_SYNC(i);
 	}
 
+	for (gpa = start_gpa; gpa < end_gpa; gpa += stride)
+		*((volatile uint64_t *)gpa);
+	GUEST_SYNC(2);
+
 	GUEST_ASSERT(0);
 }
 
@@ -95,6 +99,10 @@ static void *vcpu_worker(void *data)
 	run_vcpu(vcpu, 1);
 	rendezvous_with_boss();
 
+	/* Stage 2, read all of guest memory, which is now read-only. */
+	run_vcpu(vcpu, 2);
+	rendezvous_with_boss();
+
 	return NULL;
 }
 
@@ -175,7 +183,7 @@ int main(int argc, char *argv[])
 	const uint64_t start_gpa = SZ_4G;
 	const int first_slot = 1;
 
-	struct timespec time_start, time_run1, time_reset, time_run2;
+	struct timespec time_start, time_run1, time_reset, time_run2, time_ro;
 	uint64_t max_gpa, gpa, slot_size, max_mem, i;
 	int max_slots, slot, opt, fd;
 	bool hugepages = false;
@@ -279,14 +287,20 @@ int main(int argc, char *argv[])
 	rendezvous_with_vcpus(&time_reset, "reset");
 	rendezvous_with_vcpus(&time_run2, "run 2");
 
+	mprotect(mem, slot_size, PROT_READ);
+	rendezvous_with_vcpus(&time_ro, "mprotect RO");
+
+	time_ro    = timespec_sub(time_ro,     time_run2);
 	time_run2  = timespec_sub(time_run2,   time_reset);
-	time_reset = timespec_sub(time_reset, time_run1);
+	time_reset = timespec_sub(time_reset,  time_run1);
 	time_run1  = timespec_sub(time_run1,   time_start);
 
-	pr_info("run1 = %ld.%.9lds, reset = %ld.%.9lds, run2 =  %ld.%.9lds\n",
+	pr_info("run1 = %ld.%.9lds, reset = %ld.%.9lds, run2 = %ld.%.9lds, "
+		"ro = %ld.%.9lds\n",
 		time_run1.tv_sec, time_run1.tv_nsec,
 		time_reset.tv_sec, time_reset.tv_nsec,
-		time_run2.tv_sec, time_run2.tv_nsec);
+		time_run2.tv_sec, time_run2.tv_nsec,
+		time_ro.tv_sec, time_ro.tv_nsec);
 
 	/*
 	 * Delete even numbered slots (arbitrary) and unmap the first half of
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:44 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:44 -0800
Subject: [PATCH v4 13/16] KVM: selftests: Verify KVM correctly handles mprotect(PROT_READ)
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-14-seanjc@google.com>

Add two phases to mmu_stress_test to verify that KVM correctly handles
guest memory that was writable, and then made read-only in the primary MMU,
and then made writable again.

Add bonus coverage for x86 and arm64 to verify that all of guest memory was
marked read-only.  Making forward progress (without making memory writable)
requires arch specific code to skip over the faulting instruction, but the
test can at least verify each vCPU's starting page was made read-only for
other architectures.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/mmu_stress_test.c | 104 +++++++++++++++++-
 1 file changed, 101 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/mmu_stress_test.c b/tools/testing/selftests/kvm/mmu_stress_test.c
index 0918fade9267..d9c76b4c0d88 100644
--- a/tools/testing/selftests/kvm/mmu_stress_test.c
+++ b/tools/testing/selftests/kvm/mmu_stress_test.c
@@ -17,6 +17,8 @@
 #include "processor.h"
 #include "ucall_common.h"
 
+static bool mprotect_ro_done;
+
 static void guest_code(uint64_t start_gpa, uint64_t end_gpa, uint64_t stride)
 {
 	uint64_t gpa;
@@ -32,6 +34,42 @@ static void guest_code(uint64_t start_gpa, uint64_t end_gpa, uint64_t stride)
 		*((volatile uint64_t *)gpa);
 	GUEST_SYNC(2);
 
+	/*
+	 * Write to the region while mprotect(PROT_READ) is underway.  Keep
+	 * looping until the memory is guaranteed to be read-only, otherwise
+	 * vCPUs may complete their writes and advance to the next stage
+	 * prematurely.
+	 *
+	 * For architectures that support skipping the faulting instruction,
+	 * generate the store via inline assembly to ensure the exact length
+	 * of the instruction is known and stable (vcpu_arch_put_guest() on
+	 * fixed-length architectures should work, but the cost of paranoia
+	 * is low in this case).  For x86, hand-code the exact opcode so that
+	 * there is no room for variability in the generated instruction.
+	 */
+	do {
+		for (gpa = start_gpa; gpa < end_gpa; gpa += stride)
+#ifdef __x86_64__
+			asm volatile(".byte 0x48,0x89,0x00" :: "a"(gpa) : "memory"); /* mov %rax, (%rax) */
+#elif defined(__aarch64__)
+			asm volatile("str %0, [%0]" :: "r" (gpa) : "memory");
+#else
+			vcpu_arch_put_guest(*((volatile uint64_t *)gpa), gpa);
+#endif
+	} while (!READ_ONCE(mprotect_ro_done));
+
+	/*
+	 * Only architectures that write the entire range can explicitly sync,
+	 * as other architectures will be stuck on the write fault.
+	 */
+#if defined(__x86_64__) || defined(__aarch64__)
+	GUEST_SYNC(3);
+#endif
+
+	for (gpa = start_gpa; gpa < end_gpa; gpa += stride)
+		vcpu_arch_put_guest(*((volatile uint64_t *)gpa), gpa);
+	GUEST_SYNC(4);
+
 	GUEST_ASSERT(0);
 }
 
@@ -79,6 +117,7 @@ static void *vcpu_worker(void *data)
 	struct vcpu_info *info = data;
 	struct kvm_vcpu *vcpu = info->vcpu;
 	struct kvm_vm *vm = vcpu->vm;
+	int r;
 
 	vcpu_args_set(vcpu, 3, info->start_gpa, info->end_gpa, vm->page_size);
 
@@ -101,6 +140,57 @@ static void *vcpu_worker(void *data)
 
 	/* Stage 2, read all of guest memory, which is now read-only. */
 	run_vcpu(vcpu, 2);
+
+	/*
+	 * Stage 3, write guest memory and verify KVM returns -EFAULT for once
+	 * the mprotect(PROT_READ) lands.  Only architectures that support
+	 * validating *all* of guest memory sync for this stage, as vCPUs will
+	 * be stuck on the faulting instruction for other architectures.  Go to
+	 * stage 3 without a rendezvous
+	 */
+	do {
+		r = _vcpu_run(vcpu);
+	} while (!r);
+	TEST_ASSERT(r == -1 && errno == EFAULT,
+		    "Expected EFAULT on write to RO memory, got r = %d, errno = %d", r, errno);
+
+#if defined(__x86_64__) || defined(__aarch64__)
+	/*
+	 * Verify *all* writes from the guest hit EFAULT due to the VMA now
+	 * being read-only.  x86 and arm64 only at this time as skipping the
+	 * instruction that hits the EFAULT requires advancing the program
+	 * counter, which is arch specific and relies on inline assembly.
+	 */
+#ifdef __x86_64__
+	vcpu->run->kvm_valid_regs = KVM_SYNC_X86_REGS;
+#endif
+	for (;;) {
+		r = _vcpu_run(vcpu);
+		if (!r)
+			break;
+		TEST_ASSERT_EQ(errno, EFAULT);
+#if defined(__x86_64__)
+		WRITE_ONCE(vcpu->run->kvm_dirty_regs, KVM_SYNC_X86_REGS);
+		vcpu->run->s.regs.regs.rip += 3;
+#elif defined(__aarch64__)
+		vcpu_set_reg(vcpu, ARM64_CORE_REG(regs.pc),
+			     vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc)) + 4);
+#endif
+
+	}
+	assert_sync_stage(vcpu, 3);
+#endif /* __x86_64__ || __aarch64__ */
+	rendezvous_with_boss();
+
+	/*
+	 * Stage 4.  Run to completion, waiting for mprotect(PROT_WRITE) to
+	 * make the memory writable again.
+	 */
+	do {
+		r = _vcpu_run(vcpu);
+	} while (r && errno == EFAULT);
+	TEST_ASSERT_EQ(r, 0);
+	assert_sync_stage(vcpu, 4);
 	rendezvous_with_boss();
 
 	return NULL;
@@ -183,7 +273,7 @@ int main(int argc, char *argv[])
 	const uint64_t start_gpa = SZ_4G;
 	const int first_slot = 1;
 
-	struct timespec time_start, time_run1, time_reset, time_run2, time_ro;
+	struct timespec time_start, time_run1, time_reset, time_run2, time_ro, time_rw;
 	uint64_t max_gpa, gpa, slot_size, max_mem, i;
 	int max_slots, slot, opt, fd;
 	bool hugepages = false;
@@ -288,19 +378,27 @@ int main(int argc, char *argv[])
 	rendezvous_with_vcpus(&time_run2, "run 2");
 
 	mprotect(mem, slot_size, PROT_READ);
+	usleep(10);
+	mprotect_ro_done = true;
+	sync_global_to_guest(vm, mprotect_ro_done);
+
 	rendezvous_with_vcpus(&time_ro, "mprotect RO");
+	mprotect(mem, slot_size, PROT_READ | PROT_WRITE);
+	rendezvous_with_vcpus(&time_rw, "mprotect RW");
 
+	time_rw    = timespec_sub(time_rw,     time_ro);
 	time_ro    = timespec_sub(time_ro,     time_run2);
 	time_run2  = timespec_sub(time_run2,   time_reset);
 	time_reset = timespec_sub(time_reset,  time_run1);
 	time_run1  = timespec_sub(time_run1,   time_start);
 
 	pr_info("run1 = %ld.%.9lds, reset = %ld.%.9lds, run2 = %ld.%.9lds, "
-		"ro = %ld.%.9lds\n",
+		"ro = %ld.%.9lds, rw = %ld.%.9lds\n",
 		time_run1.tv_sec, time_run1.tv_nsec,
 		time_reset.tv_sec, time_reset.tv_nsec,
 		time_run2.tv_sec, time_run2.tv_nsec,
-		time_ro.tv_sec, time_ro.tv_nsec);
+		time_ro.tv_sec, time_ro.tv_nsec,
+		time_rw.tv_sec, time_rw.tv_nsec);
 
 	/*
 	 * Delete even numbered slots (arbitrary) and unmap the first half of
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:45 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:45 -0800
Subject: [PATCH v4 14/16] KVM: selftests: Provide empty 'all' and 'clean'
 targets for unsupported ARCHs
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-15-seanjc@google.com>

Provide empty targets for KVM selftests if the target architecture is
unsupported to make it obvious which architectures are supported, and so
that various side effects don't fail and/or do weird things, e.g. as is,
"mkdir -p $(sort $(dir $(TEST_GEN_PROGS)))" fails due to a missing operand,
and conversely, "$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) ..." will
create an empty, useless directory for the unsupported architecture.

Move the guts of the Makefile to Makefile.kvm so that it's easier to see
that the if-statement effectively guards all of KVM selftests.

Reported-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/.gitignore   |   1 +
 tools/testing/selftests/kvm/Makefile     | 336 +----------------------
 tools/testing/selftests/kvm/Makefile.kvm | 334 ++++++++++++++++++++++
 3 files changed, 340 insertions(+), 331 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/Makefile.kvm

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 7f57abf936e7..1d41a046a7bf 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -9,3 +9,4 @@
 !config
 !settings
 !Makefile
+!Makefile.kvm
\ No newline at end of file
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index c59a337cd4da..7b33464bf8cc 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -1,12 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
-include ../../../build/Build.include
-
-all:
-
 top_srcdir = ../../../..
 include $(top_srcdir)/scripts/subarch.include
 ARCH            ?= $(SUBARCH)
 
+ifeq ($(ARCH),$(filter $(ARCH),arm64 s390 riscv x86 x86_64))
 ifeq ($(ARCH),x86)
 	ARCH_DIR := x86_64
 else ifeq ($(ARCH),arm64)
@@ -17,332 +14,9 @@ else
 	ARCH_DIR := $(ARCH)
 endif
 
-LIBKVM += lib/assert.c
-LIBKVM += lib/elf.c
-LIBKVM += lib/guest_modes.c
-LIBKVM += lib/io.c
-LIBKVM += lib/kvm_util.c
-LIBKVM += lib/memstress.c
-LIBKVM += lib/guest_sprintf.c
-LIBKVM += lib/rbtree.c
-LIBKVM += lib/sparsebit.c
-LIBKVM += lib/test_util.c
-LIBKVM += lib/ucall_common.c
-LIBKVM += lib/userfaultfd_util.c
-
-LIBKVM_STRING += lib/string_override.c
-
-LIBKVM_x86_64 += lib/x86_64/apic.c
-LIBKVM_x86_64 += lib/x86_64/handlers.S
-LIBKVM_x86_64 += lib/x86_64/hyperv.c
-LIBKVM_x86_64 += lib/x86_64/memstress.c
-LIBKVM_x86_64 += lib/x86_64/pmu.c
-LIBKVM_x86_64 += lib/x86_64/processor.c
-LIBKVM_x86_64 += lib/x86_64/sev.c
-LIBKVM_x86_64 += lib/x86_64/svm.c
-LIBKVM_x86_64 += lib/x86_64/ucall.c
-LIBKVM_x86_64 += lib/x86_64/vmx.c
-
-LIBKVM_aarch64 += lib/aarch64/gic.c
-LIBKVM_aarch64 += lib/aarch64/gic_v3.c
-LIBKVM_aarch64 += lib/aarch64/gic_v3_its.c
-LIBKVM_aarch64 += lib/aarch64/handlers.S
-LIBKVM_aarch64 += lib/aarch64/processor.c
-LIBKVM_aarch64 += lib/aarch64/spinlock.c
-LIBKVM_aarch64 += lib/aarch64/ucall.c
-LIBKVM_aarch64 += lib/aarch64/vgic.c
-
-LIBKVM_s390x += lib/s390x/diag318_test_handler.c
-LIBKVM_s390x += lib/s390x/processor.c
-LIBKVM_s390x += lib/s390x/ucall.c
-LIBKVM_s390x += lib/s390x/facility.c
-
-LIBKVM_riscv += lib/riscv/handlers.S
-LIBKVM_riscv += lib/riscv/processor.c
-LIBKVM_riscv += lib/riscv/ucall.c
-
-# Non-compiled test targets
-TEST_PROGS_x86_64 += x86_64/nx_huge_pages_test.sh
-
-# Compiled test targets
-TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test
-TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test
-TEST_GEN_PROGS_x86_64 += x86_64/dirty_log_page_splitting_test
-TEST_GEN_PROGS_x86_64 += x86_64/feature_msrs_test
-TEST_GEN_PROGS_x86_64 += x86_64/exit_on_emulation_failure_test
-TEST_GEN_PROGS_x86_64 += x86_64/fix_hypercall_test
-TEST_GEN_PROGS_x86_64 += x86_64/hwcr_msr_test
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_evmcs
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_extended_hypercalls
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_ipi
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_svm_test
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush
-TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test
-TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test
-TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test
-TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test
-TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test
-TEST_GEN_PROGS_x86_64 += x86_64/pmu_counters_test
-TEST_GEN_PROGS_x86_64 += x86_64/pmu_event_filter_test
-TEST_GEN_PROGS_x86_64 += x86_64/private_mem_conversions_test
-TEST_GEN_PROGS_x86_64 += x86_64/private_mem_kvm_exits_test
-TEST_GEN_PROGS_x86_64 += x86_64/set_boot_cpu_id
-TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test
-TEST_GEN_PROGS_x86_64 += x86_64/smaller_maxphyaddr_emulation_test
-TEST_GEN_PROGS_x86_64 += x86_64/smm_test
-TEST_GEN_PROGS_x86_64 += x86_64/state_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
-TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
-TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
-TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test
-TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test
-TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync
-TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
-TEST_GEN_PROGS_x86_64 += x86_64/ucna_injection_test
-TEST_GEN_PROGS_x86_64 += x86_64/userspace_io_test
-TEST_GEN_PROGS_x86_64 += x86_64/userspace_msr_exit_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_apic_access_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_exception_with_invalid_guest_state
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_msrs_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_invalid_nested_guest_state
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_nested_tsc_scaling_test
-TEST_GEN_PROGS_x86_64 += x86_64/apic_bus_clock_test
-TEST_GEN_PROGS_x86_64 += x86_64/xapic_ipi_test
-TEST_GEN_PROGS_x86_64 += x86_64/xapic_state_test
-TEST_GEN_PROGS_x86_64 += x86_64/xcr0_cpuid_test
-TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test
-TEST_GEN_PROGS_x86_64 += x86_64/debug_regs
-TEST_GEN_PROGS_x86_64 += x86_64/tsc_msrs_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test
-TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test
-TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test
-TEST_GEN_PROGS_x86_64 += x86_64/sev_init2_tests
-TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
-TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test
-TEST_GEN_PROGS_x86_64 += x86_64/amx_test
-TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
-TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
-TEST_GEN_PROGS_x86_64 += x86_64/recalc_apic_map_test
-TEST_GEN_PROGS_x86_64 += access_tracking_perf_test
-TEST_GEN_PROGS_x86_64 += coalesced_io_test
-TEST_GEN_PROGS_x86_64 += demand_paging_test
-TEST_GEN_PROGS_x86_64 += dirty_log_test
-TEST_GEN_PROGS_x86_64 += dirty_log_perf_test
-TEST_GEN_PROGS_x86_64 += guest_memfd_test
-TEST_GEN_PROGS_x86_64 += guest_print_test
-TEST_GEN_PROGS_x86_64 += hardware_disable_test
-TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
-TEST_GEN_PROGS_x86_64 += kvm_page_table_test
-TEST_GEN_PROGS_x86_64 += mmu_stress_test
-TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
-TEST_GEN_PROGS_x86_64 += memslot_perf_test
-TEST_GEN_PROGS_x86_64 += rseq_test
-TEST_GEN_PROGS_x86_64 += set_memory_region_test
-TEST_GEN_PROGS_x86_64 += steal_time
-TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
-TEST_GEN_PROGS_x86_64 += system_counter_offset_test
-TEST_GEN_PROGS_x86_64 += pre_fault_memory_test
-
-# Compiled outputs used by test targets
-TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
-
-TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
-TEST_GEN_PROGS_aarch64 += aarch64/arch_timer_edge_cases
-TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
-TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
-TEST_GEN_PROGS_aarch64 += aarch64/mmio_abort
-TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
-TEST_GEN_PROGS_aarch64 += aarch64/psci_test
-TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
-TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
-TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
-TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
-TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
-TEST_GEN_PROGS_aarch64 += aarch64/vgic_lpi_stress
-TEST_GEN_PROGS_aarch64 += aarch64/vpmu_counter_access
-TEST_GEN_PROGS_aarch64 += aarch64/no-vgic-v3
-TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
-TEST_GEN_PROGS_aarch64 += arch_timer
-TEST_GEN_PROGS_aarch64 += coalesced_io_test
-TEST_GEN_PROGS_aarch64 += demand_paging_test
-TEST_GEN_PROGS_aarch64 += dirty_log_test
-TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
-TEST_GEN_PROGS_aarch64 += guest_print_test
-TEST_GEN_PROGS_aarch64 += get-reg-list
-TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
-TEST_GEN_PROGS_aarch64 += kvm_page_table_test
-TEST_GEN_PROGS_aarch64 += memslot_modification_stress_test
-TEST_GEN_PROGS_aarch64 += memslot_perf_test
-TEST_GEN_PROGS_aarch64 += mmu_stress_test
-TEST_GEN_PROGS_aarch64 += rseq_test
-TEST_GEN_PROGS_aarch64 += set_memory_region_test
-TEST_GEN_PROGS_aarch64 += steal_time
-TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
-
-TEST_GEN_PROGS_s390x = s390x/memop
-TEST_GEN_PROGS_s390x += s390x/resets
-TEST_GEN_PROGS_s390x += s390x/sync_regs_test
-TEST_GEN_PROGS_s390x += s390x/tprot
-TEST_GEN_PROGS_s390x += s390x/cmma_test
-TEST_GEN_PROGS_s390x += s390x/debug_test
-TEST_GEN_PROGS_s390x += s390x/cpumodel_subfuncs_test
-TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test
-TEST_GEN_PROGS_s390x += s390x/ucontrol_test
-TEST_GEN_PROGS_s390x += demand_paging_test
-TEST_GEN_PROGS_s390x += dirty_log_test
-TEST_GEN_PROGS_s390x += guest_print_test
-TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
-TEST_GEN_PROGS_s390x += kvm_page_table_test
-TEST_GEN_PROGS_s390x += rseq_test
-TEST_GEN_PROGS_s390x += set_memory_region_test
-TEST_GEN_PROGS_s390x += kvm_binary_stats_test
-
-TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
-TEST_GEN_PROGS_riscv += riscv/ebreak_test
-TEST_GEN_PROGS_riscv += arch_timer
-TEST_GEN_PROGS_riscv += coalesced_io_test
-TEST_GEN_PROGS_riscv += demand_paging_test
-TEST_GEN_PROGS_riscv += dirty_log_test
-TEST_GEN_PROGS_riscv += get-reg-list
-TEST_GEN_PROGS_riscv += guest_print_test
-TEST_GEN_PROGS_riscv += kvm_binary_stats_test
-TEST_GEN_PROGS_riscv += kvm_create_max_vcpus
-TEST_GEN_PROGS_riscv += kvm_page_table_test
-TEST_GEN_PROGS_riscv += set_memory_region_test
-TEST_GEN_PROGS_riscv += steal_time
-
-SPLIT_TESTS += arch_timer
-SPLIT_TESTS += get-reg-list
-
-TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
-TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
-TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH_DIR))
-LIBKVM += $(LIBKVM_$(ARCH_DIR))
-
-OVERRIDE_TARGETS = 1
-
-# lib.mak defines $(OUTPUT), prepends $(OUTPUT)/ to $(TEST_GEN_PROGS), and most
-# importantly defines, i.e. overwrites, $(CC) (unless `make -e` or `make CC=`,
-# which causes the environment variable to override the makefile).
-include ../lib.mk
-
-INSTALL_HDR_PATH = $(top_srcdir)/usr
-LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
-LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
-ifeq ($(ARCH),x86_64)
-LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include
+include Makefile.kvm
 else
-LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
+# Empty targets for unsupported architectures
+all:
+clean:
 endif
-CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
-	-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
-	-fno-builtin-memcmp -fno-builtin-memcpy \
-	-fno-builtin-memset -fno-builtin-strnlen \
-	-fno-stack-protector -fno-PIE -fno-strict-aliasing \
-	-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
-	-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH_DIR) \
-	-I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
-ifeq ($(ARCH),s390)
-	CFLAGS += -march=z10
-endif
-ifeq ($(ARCH),x86)
-ifeq ($(shell echo "void foo(void) { }" | $(CC) -march=x86-64-v2 -x c - -c -o /dev/null 2>/dev/null; echo "$$?"),0)
-	CFLAGS += -march=x86-64-v2
-endif
-endif
-ifeq ($(ARCH),arm64)
-tools_dir := $(top_srcdir)/tools
-arm64_tools_dir := $(tools_dir)/arch/arm64/tools/
-
-ifneq ($(abs_objdir),)
-arm64_hdr_outdir := $(abs_objdir)/tools/
-else
-arm64_hdr_outdir := $(tools_dir)/
-endif
-
-GEN_HDRS := $(arm64_hdr_outdir)arch/arm64/include/generated/
-CFLAGS += -I$(GEN_HDRS)
-
-$(GEN_HDRS): $(wildcard $(arm64_tools_dir)/*)
-	$(MAKE) -C $(arm64_tools_dir) OUTPUT=$(arm64_hdr_outdir)
-endif
-
-no-pie-option := $(call try-run, echo 'int main(void) { return 0; }' | \
-        $(CC) -Werror $(CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie)
-
-# On s390, build the testcases KVM-enabled
-pgste-option = $(call try-run, echo 'int main(void) { return 0; }' | \
-	$(CC) -Werror -Wl$(comma)--s390-pgste -x c - -o "$$TMP",-Wl$(comma)--s390-pgste)
-
-LDLIBS += -ldl
-LDFLAGS += -pthread $(no-pie-option) $(pgste-option)
-
-LIBKVM_C := $(filter %.c,$(LIBKVM))
-LIBKVM_S := $(filter %.S,$(LIBKVM))
-LIBKVM_C_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C))
-LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S))
-LIBKVM_STRING_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING))
-LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ)
-SPLIT_TEST_GEN_PROGS := $(patsubst %, $(OUTPUT)/%, $(SPLIT_TESTS))
-SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH_DIR)/%.o, $(SPLIT_TESTS))
-
-TEST_GEN_OBJ = $(patsubst %, %.o, $(TEST_GEN_PROGS))
-TEST_GEN_OBJ += $(patsubst %, %.o, $(TEST_GEN_PROGS_EXTENDED))
-TEST_DEP_FILES = $(patsubst %.o, %.d, $(TEST_GEN_OBJ))
-TEST_DEP_FILES += $(patsubst %.o, %.d, $(LIBKVM_OBJS))
-TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TEST_GEN_OBJ))
--include $(TEST_DEP_FILES)
-
-$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
-
-$(filter-out $(SPLIT_TEST_GEN_PROGS), $(TEST_GEN_PROGS)) \
-$(TEST_GEN_PROGS_EXTENDED): %: %.o
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
-$(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH_DIR)/%.o
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
-$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH_DIR)/%.o: $(ARCH_DIR)/%.c
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-EXTRA_CLEAN += $(GEN_HDRS) \
-	       $(LIBKVM_OBJS) \
-	       $(SPLIT_TEST_GEN_OBJ) \
-	       $(TEST_DEP_FILES) \
-	       $(TEST_GEN_OBJ) \
-	       cscope.*
-
-$(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(GEN_HDRS)
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-$(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(GEN_HDRS)
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-# Compile the string overrides as freestanding to prevent the compiler from
-# generating self-referential code, e.g. without "freestanding" the compiler may
-# "optimize" memcmp() by invoking memcmp(), thus causing infinite recursion.
-$(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@
-
-$(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
-$(SPLIT_TEST_GEN_OBJ): $(GEN_HDRS)
-$(TEST_GEN_PROGS): $(LIBKVM_OBJS)
-$(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
-$(TEST_GEN_OBJ): $(GEN_HDRS)
-
-cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
-cscope:
-	$(RM) cscope.*
-	(find $(include_paths) -name '*.h' \
-		-exec realpath --relative-base=$(PWD) {} \;; \
-	find . -name '*.c' \
-		-exec realpath --relative-base=$(PWD) {} \;) | sort -u > cscope.files
-	cscope -b
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
new file mode 100644
index 000000000000..e988a72f8c20
--- /dev/null
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -0,0 +1,334 @@
+# SPDX-License-Identifier: GPL-2.0-only
+include ../../../build/Build.include
+
+all:
+
+LIBKVM += lib/assert.c
+LIBKVM += lib/elf.c
+LIBKVM += lib/guest_modes.c
+LIBKVM += lib/io.c
+LIBKVM += lib/kvm_util.c
+LIBKVM += lib/memstress.c
+LIBKVM += lib/guest_sprintf.c
+LIBKVM += lib/rbtree.c
+LIBKVM += lib/sparsebit.c
+LIBKVM += lib/test_util.c
+LIBKVM += lib/ucall_common.c
+LIBKVM += lib/userfaultfd_util.c
+
+LIBKVM_STRING += lib/string_override.c
+
+LIBKVM_x86_64 += lib/x86_64/apic.c
+LIBKVM_x86_64 += lib/x86_64/handlers.S
+LIBKVM_x86_64 += lib/x86_64/hyperv.c
+LIBKVM_x86_64 += lib/x86_64/memstress.c
+LIBKVM_x86_64 += lib/x86_64/pmu.c
+LIBKVM_x86_64 += lib/x86_64/processor.c
+LIBKVM_x86_64 += lib/x86_64/sev.c
+LIBKVM_x86_64 += lib/x86_64/svm.c
+LIBKVM_x86_64 += lib/x86_64/ucall.c
+LIBKVM_x86_64 += lib/x86_64/vmx.c
+
+LIBKVM_aarch64 += lib/aarch64/gic.c
+LIBKVM_aarch64 += lib/aarch64/gic_v3.c
+LIBKVM_aarch64 += lib/aarch64/gic_v3_its.c
+LIBKVM_aarch64 += lib/aarch64/handlers.S
+LIBKVM_aarch64 += lib/aarch64/processor.c
+LIBKVM_aarch64 += lib/aarch64/spinlock.c
+LIBKVM_aarch64 += lib/aarch64/ucall.c
+LIBKVM_aarch64 += lib/aarch64/vgic.c
+
+LIBKVM_s390x += lib/s390x/diag318_test_handler.c
+LIBKVM_s390x += lib/s390x/processor.c
+LIBKVM_s390x += lib/s390x/ucall.c
+LIBKVM_s390x += lib/s390x/facility.c
+
+LIBKVM_riscv += lib/riscv/handlers.S
+LIBKVM_riscv += lib/riscv/processor.c
+LIBKVM_riscv += lib/riscv/ucall.c
+
+# Non-compiled test targets
+TEST_PROGS_x86_64 += x86_64/nx_huge_pages_test.sh
+
+# Compiled test targets
+TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test
+TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test
+TEST_GEN_PROGS_x86_64 += x86_64/dirty_log_page_splitting_test
+TEST_GEN_PROGS_x86_64 += x86_64/feature_msrs_test
+TEST_GEN_PROGS_x86_64 += x86_64/exit_on_emulation_failure_test
+TEST_GEN_PROGS_x86_64 += x86_64/fix_hypercall_test
+TEST_GEN_PROGS_x86_64 += x86_64/hwcr_msr_test
+TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
+TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
+TEST_GEN_PROGS_x86_64 += x86_64/hyperv_evmcs
+TEST_GEN_PROGS_x86_64 += x86_64/hyperv_extended_hypercalls
+TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features
+TEST_GEN_PROGS_x86_64 += x86_64/hyperv_ipi
+TEST_GEN_PROGS_x86_64 += x86_64/hyperv_svm_test
+TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush
+TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test
+TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test
+TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test
+TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test
+TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test
+TEST_GEN_PROGS_x86_64 += x86_64/pmu_counters_test
+TEST_GEN_PROGS_x86_64 += x86_64/pmu_event_filter_test
+TEST_GEN_PROGS_x86_64 += x86_64/private_mem_conversions_test
+TEST_GEN_PROGS_x86_64 += x86_64/private_mem_kvm_exits_test
+TEST_GEN_PROGS_x86_64 += x86_64/set_boot_cpu_id
+TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test
+TEST_GEN_PROGS_x86_64 += x86_64/smaller_maxphyaddr_emulation_test
+TEST_GEN_PROGS_x86_64 += x86_64/smm_test
+TEST_GEN_PROGS_x86_64 += x86_64/state_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
+TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
+TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
+TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test
+TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test
+TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync
+TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
+TEST_GEN_PROGS_x86_64 += x86_64/ucna_injection_test
+TEST_GEN_PROGS_x86_64 += x86_64/userspace_io_test
+TEST_GEN_PROGS_x86_64 += x86_64/userspace_msr_exit_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_apic_access_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_exception_with_invalid_guest_state
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_msrs_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_invalid_nested_guest_state
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_nested_tsc_scaling_test
+TEST_GEN_PROGS_x86_64 += x86_64/apic_bus_clock_test
+TEST_GEN_PROGS_x86_64 += x86_64/xapic_ipi_test
+TEST_GEN_PROGS_x86_64 += x86_64/xapic_state_test
+TEST_GEN_PROGS_x86_64 += x86_64/xcr0_cpuid_test
+TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test
+TEST_GEN_PROGS_x86_64 += x86_64/debug_regs
+TEST_GEN_PROGS_x86_64 += x86_64/tsc_msrs_test
+TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test
+TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test
+TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test
+TEST_GEN_PROGS_x86_64 += x86_64/sev_init2_tests
+TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
+TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test
+TEST_GEN_PROGS_x86_64 += x86_64/amx_test
+TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
+TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
+TEST_GEN_PROGS_x86_64 += x86_64/recalc_apic_map_test
+TEST_GEN_PROGS_x86_64 += access_tracking_perf_test
+TEST_GEN_PROGS_x86_64 += coalesced_io_test
+TEST_GEN_PROGS_x86_64 += demand_paging_test
+TEST_GEN_PROGS_x86_64 += dirty_log_test
+TEST_GEN_PROGS_x86_64 += dirty_log_perf_test
+TEST_GEN_PROGS_x86_64 += guest_memfd_test
+TEST_GEN_PROGS_x86_64 += guest_print_test
+TEST_GEN_PROGS_x86_64 += hardware_disable_test
+TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
+TEST_GEN_PROGS_x86_64 += kvm_page_table_test
+TEST_GEN_PROGS_x86_64 += mmu_stress_test
+TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
+TEST_GEN_PROGS_x86_64 += memslot_perf_test
+TEST_GEN_PROGS_x86_64 += rseq_test
+TEST_GEN_PROGS_x86_64 += set_memory_region_test
+TEST_GEN_PROGS_x86_64 += steal_time
+TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
+TEST_GEN_PROGS_x86_64 += system_counter_offset_test
+TEST_GEN_PROGS_x86_64 += pre_fault_memory_test
+
+# Compiled outputs used by test targets
+TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
+
+TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
+TEST_GEN_PROGS_aarch64 += aarch64/arch_timer_edge_cases
+TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
+TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
+TEST_GEN_PROGS_aarch64 += aarch64/mmio_abort
+TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
+TEST_GEN_PROGS_aarch64 += aarch64/psci_test
+TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
+TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
+TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
+TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
+TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
+TEST_GEN_PROGS_aarch64 += aarch64/vgic_lpi_stress
+TEST_GEN_PROGS_aarch64 += aarch64/vpmu_counter_access
+TEST_GEN_PROGS_aarch64 += aarch64/no-vgic-v3
+TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
+TEST_GEN_PROGS_aarch64 += arch_timer
+TEST_GEN_PROGS_aarch64 += coalesced_io_test
+TEST_GEN_PROGS_aarch64 += demand_paging_test
+TEST_GEN_PROGS_aarch64 += dirty_log_test
+TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
+TEST_GEN_PROGS_aarch64 += guest_print_test
+TEST_GEN_PROGS_aarch64 += get-reg-list
+TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
+TEST_GEN_PROGS_aarch64 += kvm_page_table_test
+TEST_GEN_PROGS_aarch64 += memslot_modification_stress_test
+TEST_GEN_PROGS_aarch64 += memslot_perf_test
+TEST_GEN_PROGS_aarch64 += mmu_stress_test
+TEST_GEN_PROGS_aarch64 += rseq_test
+TEST_GEN_PROGS_aarch64 += set_memory_region_test
+TEST_GEN_PROGS_aarch64 += steal_time
+TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
+
+TEST_GEN_PROGS_s390x = s390x/memop
+TEST_GEN_PROGS_s390x += s390x/resets
+TEST_GEN_PROGS_s390x += s390x/sync_regs_test
+TEST_GEN_PROGS_s390x += s390x/tprot
+TEST_GEN_PROGS_s390x += s390x/cmma_test
+TEST_GEN_PROGS_s390x += s390x/debug_test
+TEST_GEN_PROGS_s390x += s390x/cpumodel_subfuncs_test
+TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test
+TEST_GEN_PROGS_s390x += s390x/ucontrol_test
+TEST_GEN_PROGS_s390x += demand_paging_test
+TEST_GEN_PROGS_s390x += dirty_log_test
+TEST_GEN_PROGS_s390x += guest_print_test
+TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
+TEST_GEN_PROGS_s390x += kvm_page_table_test
+TEST_GEN_PROGS_s390x += rseq_test
+TEST_GEN_PROGS_s390x += set_memory_region_test
+TEST_GEN_PROGS_s390x += kvm_binary_stats_test
+
+TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
+TEST_GEN_PROGS_riscv += riscv/ebreak_test
+TEST_GEN_PROGS_riscv += arch_timer
+TEST_GEN_PROGS_riscv += coalesced_io_test
+TEST_GEN_PROGS_riscv += demand_paging_test
+TEST_GEN_PROGS_riscv += dirty_log_test
+TEST_GEN_PROGS_riscv += get-reg-list
+TEST_GEN_PROGS_riscv += guest_print_test
+TEST_GEN_PROGS_riscv += kvm_binary_stats_test
+TEST_GEN_PROGS_riscv += kvm_create_max_vcpus
+TEST_GEN_PROGS_riscv += kvm_page_table_test
+TEST_GEN_PROGS_riscv += set_memory_region_test
+TEST_GEN_PROGS_riscv += steal_time
+
+SPLIT_TESTS += arch_timer
+SPLIT_TESTS += get-reg-list
+
+TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
+TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
+TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH_DIR))
+LIBKVM += $(LIBKVM_$(ARCH_DIR))
+
+OVERRIDE_TARGETS = 1
+
+# lib.mak defines $(OUTPUT), prepends $(OUTPUT)/ to $(TEST_GEN_PROGS), and most
+# importantly defines, i.e. overwrites, $(CC) (unless `make -e` or `make CC=`,
+# which causes the environment variable to override the makefile).
+include ../lib.mk
+
+INSTALL_HDR_PATH = $(top_srcdir)/usr
+LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
+LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
+ifeq ($(ARCH),x86_64)
+LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include
+else
+LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
+endif
+CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
+	-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
+	-fno-builtin-memcmp -fno-builtin-memcpy \
+	-fno-builtin-memset -fno-builtin-strnlen \
+	-fno-stack-protector -fno-PIE -fno-strict-aliasing \
+	-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
+	-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH_DIR) \
+	-I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
+ifeq ($(ARCH),s390)
+	CFLAGS += -march=z10
+endif
+ifeq ($(ARCH),x86)
+ifeq ($(shell echo "void foo(void) { }" | $(CC) -march=x86-64-v2 -x c - -c -o /dev/null 2>/dev/null; echo "$$?"),0)
+	CFLAGS += -march=x86-64-v2
+endif
+endif
+ifeq ($(ARCH),arm64)
+tools_dir := $(top_srcdir)/tools
+arm64_tools_dir := $(tools_dir)/arch/arm64/tools/
+
+ifneq ($(abs_objdir),)
+arm64_hdr_outdir := $(abs_objdir)/tools/
+else
+arm64_hdr_outdir := $(tools_dir)/
+endif
+
+GEN_HDRS := $(arm64_hdr_outdir)arch/arm64/include/generated/
+CFLAGS += -I$(GEN_HDRS)
+
+$(GEN_HDRS): $(wildcard $(arm64_tools_dir)/*)
+	$(MAKE) -C $(arm64_tools_dir) OUTPUT=$(arm64_hdr_outdir)
+endif
+
+no-pie-option := $(call try-run, echo 'int main(void) { return 0; }' | \
+        $(CC) -Werror $(CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie)
+
+# On s390, build the testcases KVM-enabled
+pgste-option = $(call try-run, echo 'int main(void) { return 0; }' | \
+	$(CC) -Werror -Wl$(comma)--s390-pgste -x c - -o "$$TMP",-Wl$(comma)--s390-pgste)
+
+LDLIBS += -ldl
+LDFLAGS += -pthread $(no-pie-option) $(pgste-option)
+
+LIBKVM_C := $(filter %.c,$(LIBKVM))
+LIBKVM_S := $(filter %.S,$(LIBKVM))
+LIBKVM_C_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C))
+LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S))
+LIBKVM_STRING_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING))
+LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ)
+SPLIT_TEST_GEN_PROGS := $(patsubst %, $(OUTPUT)/%, $(SPLIT_TESTS))
+SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH_DIR)/%.o, $(SPLIT_TESTS))
+
+TEST_GEN_OBJ = $(patsubst %, %.o, $(TEST_GEN_PROGS))
+TEST_GEN_OBJ += $(patsubst %, %.o, $(TEST_GEN_PROGS_EXTENDED))
+TEST_DEP_FILES = $(patsubst %.o, %.d, $(TEST_GEN_OBJ))
+TEST_DEP_FILES += $(patsubst %.o, %.d, $(LIBKVM_OBJS))
+TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TEST_GEN_OBJ))
+-include $(TEST_DEP_FILES)
+
+$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
+
+$(filter-out $(SPLIT_TEST_GEN_PROGS), $(TEST_GEN_PROGS)) \
+$(TEST_GEN_PROGS_EXTENDED): %: %.o
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
+$(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH_DIR)/%.o
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
+$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH_DIR)/%.o: $(ARCH_DIR)/%.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+EXTRA_CLEAN += $(GEN_HDRS) \
+	       $(LIBKVM_OBJS) \
+	       $(SPLIT_TEST_GEN_OBJ) \
+	       $(TEST_DEP_FILES) \
+	       $(TEST_GEN_OBJ) \
+	       cscope.*
+
+$(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(GEN_HDRS)
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+$(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(GEN_HDRS)
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+# Compile the string overrides as freestanding to prevent the compiler from
+# generating self-referential code, e.g. without "freestanding" the compiler may
+# "optimize" memcmp() by invoking memcmp(), thus causing infinite recursion.
+$(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@
+
+$(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
+$(SPLIT_TEST_GEN_OBJ): $(GEN_HDRS)
+$(TEST_GEN_PROGS): $(LIBKVM_OBJS)
+$(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
+$(TEST_GEN_OBJ): $(GEN_HDRS)
+
+cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
+cscope:
+	$(RM) cscope.*
+	(find $(include_paths) -name '*.h' \
+		-exec realpath --relative-base=$(PWD) {} \;; \
+	find . -name '*.c' \
+		-exec realpath --relative-base=$(PWD) {} \;) | sort -u > cscope.files
+	cscope -b
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:46 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:46 -0800
Subject: [PATCH v4 15/16] KVM: selftests: Use canonical $(ARCH) paths for KVM
 selftests directories
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-16-seanjc@google.com>

Use the kernel's canonical $(ARCH) paths instead of the raw target triple
for KVM selftests directories.  KVM selftests are quite nearly the only
place in the entire kernel that using the target triple for directories,
tools/testing/selftests/drivers/s390x being the lone holdout.

Using the kernel's preferred nomenclature eliminates the minor, but
annoying, friction of having to translate to KVM's selftests directories,
e.g. for pattern matching, opening files, running selftests, etc.

Opportunsitically delete file comments that reference the full path of the
file, as they are obviously prone to becoming stale, and serve no known
purpose.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 MAINTAINERS                                   |  12 +-
 tools/testing/selftests/kvm/Makefile          |  10 +-
 tools/testing/selftests/kvm/Makefile.kvm      | 320 +++++++++---------
 .../kvm/{aarch64 => arm64}/aarch32_id_regs.c  |   0
 .../kvm/{aarch64 => arm64}/arch_timer.c       |   0
 .../arch_timer_edge_cases.c                   |   0
 .../kvm/{aarch64 => arm64}/debug-exceptions.c |   0
 .../kvm/{aarch64 => arm64}/get-reg-list.c     |   0
 .../kvm/{aarch64 => arm64}/hypercalls.c       |   0
 .../kvm/{aarch64 => arm64}/mmio_abort.c       |   0
 .../kvm/{aarch64 => arm64}/no-vgic-v3.c       |   0
 .../kvm/{aarch64 => arm64}/page_fault_test.c  |   0
 .../kvm/{aarch64 => arm64}/psci_test.c        |   0
 .../kvm/{aarch64 => arm64}/set_id_regs.c      |   0
 .../kvm/{aarch64 => arm64}/smccc_filter.c     |   0
 .../{aarch64 => arm64}/vcpu_width_config.c    |   0
 .../kvm/{aarch64 => arm64}/vgic_init.c        |   0
 .../kvm/{aarch64 => arm64}/vgic_irq.c         |   0
 .../kvm/{aarch64 => arm64}/vgic_lpi_stress.c  |   0
 .../{aarch64 => arm64}/vpmu_counter_access.c  |   0
 .../selftests/kvm/dirty_log_perf_test.c       |   2 +-
 .../include/{aarch64 => arm64}/arch_timer.h   |   0
 .../kvm/include/{aarch64 => arm64}/delay.h    |   0
 .../kvm/include/{aarch64 => arm64}/gic.h      |   0
 .../kvm/include/{aarch64 => arm64}/gic_v3.h   |   0
 .../include/{aarch64 => arm64}/gic_v3_its.h   |   0
 .../{aarch64 => arm64}/kvm_util_arch.h        |   0
 .../include/{aarch64 => arm64}/processor.h    |   0
 .../kvm/include/{aarch64 => arm64}/spinlock.h |   0
 .../kvm/include/{aarch64 => arm64}/ucall.h    |   0
 .../kvm/include/{aarch64 => arm64}/vgic.h     |   0
 .../kvm/include/{s390x => s390}/debug_print.h |   0
 .../{s390x => s390}/diag318_test_handler.h    |   0
 .../kvm/include/{s390x => s390}/facility.h    |   0
 .../include/{s390x => s390}/kvm_util_arch.h   |   0
 .../kvm/include/{s390x => s390}/processor.h   |   0
 .../kvm/include/{s390x => s390}/sie.h         |   0
 .../kvm/include/{s390x => s390}/ucall.h       |   0
 .../kvm/include/{x86_64 => x86}/apic.h        |   2 -
 .../kvm/include/{x86_64 => x86}/evmcs.h       |   3 -
 .../kvm/include/{x86_64 => x86}/hyperv.h      |   3 -
 .../include/{x86_64 => x86}/kvm_util_arch.h   |   0
 .../kvm/include/{x86_64 => x86}/mce.h         |   2 -
 .../kvm/include/{x86_64 => x86}/pmu.h         |   0
 .../kvm/include/{x86_64 => x86}/processor.h   |   2 -
 .../kvm/include/{x86_64 => x86}/sev.h         |   0
 .../kvm/include/{x86_64 => x86}/svm.h         |   6 -
 .../kvm/include/{x86_64 => x86}/svm_util.h    |   3 -
 .../kvm/include/{x86_64 => x86}/ucall.h       |   0
 .../kvm/include/{x86_64 => x86}/vmx.h         |   2 -
 .../kvm/lib/{aarch64 => arm64}/gic.c          |   0
 .../kvm/lib/{aarch64 => arm64}/gic_private.h  |   0
 .../kvm/lib/{aarch64 => arm64}/gic_v3.c       |   0
 .../kvm/lib/{aarch64 => arm64}/gic_v3_its.c   |   0
 .../kvm/lib/{aarch64 => arm64}/handlers.S     |   0
 .../kvm/lib/{aarch64 => arm64}/processor.c    |   0
 .../kvm/lib/{aarch64 => arm64}/spinlock.c     |   0
 .../kvm/lib/{aarch64 => arm64}/ucall.c        |   0
 .../kvm/lib/{aarch64 => arm64}/vgic.c         |   0
 .../{s390x => s390}/diag318_test_handler.c    |   0
 .../kvm/lib/{s390x => s390}/facility.c        |   0
 .../kvm/lib/{s390x => s390}/processor.c       |   0
 .../selftests/kvm/lib/{s390x => s390}/ucall.c |   0
 .../selftests/kvm/lib/{x86_64 => x86}/apic.c  |   0
 .../kvm/lib/{x86_64 => x86}/handlers.S        |   0
 .../kvm/lib/{x86_64 => x86}/hyperv.c          |   0
 .../kvm/lib/{x86_64 => x86}/memstress.c       |   2 +-
 .../selftests/kvm/lib/{x86_64 => x86}/pmu.c   |   0
 .../kvm/lib/{x86_64 => x86}/processor.c       |   2 -
 .../selftests/kvm/lib/{x86_64 => x86}/sev.c   |   0
 .../selftests/kvm/lib/{x86_64 => x86}/svm.c   |   1 -
 .../selftests/kvm/lib/{x86_64 => x86}/ucall.c |   0
 .../selftests/kvm/lib/{x86_64 => x86}/vmx.c   |   2 -
 .../selftests/kvm/{s390x => s390}/cmma_test.c |   0
 .../selftests/kvm/{s390x => s390}/config      |   0
 .../{s390x => s390}/cpumodel_subfuncs_test.c  |   0
 .../kvm/{s390x => s390}/debug_test.c          |   0
 .../selftests/kvm/{s390x => s390}/memop.c     |   0
 .../selftests/kvm/{s390x => s390}/resets.c    |   0
 .../{s390x => s390}/shared_zeropage_test.c    |   0
 .../kvm/{s390x => s390}/sync_regs_test.c      |   0
 .../selftests/kvm/{s390x => s390}/tprot.c     |   0
 .../kvm/{s390x => s390}/ucontrol_test.c       |   0
 .../selftests/kvm/set_memory_region_test.c    |   6 +-
 .../selftests/kvm/{x86_64 => x86}/amx_test.c  |   0
 .../kvm/{x86_64 => x86}/apic_bus_clock_test.c |   0
 .../kvm/{x86_64 => x86}/cpuid_test.c          |   0
 .../kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c |   0
 .../kvm/{x86_64 => x86}/debug_regs.c          |   0
 .../dirty_log_page_splitting_test.c           |   0
 .../exit_on_emulation_failure_test.c          |   0
 .../kvm/{x86_64 => x86}/feature_msrs_test.c   |   0
 .../kvm/{x86_64 => x86}/fix_hypercall_test.c  |   0
 .../kvm/{x86_64 => x86}/flds_emulation.h      |   0
 .../kvm/{x86_64 => x86}/hwcr_msr_test.c       |   0
 .../kvm/{x86_64 => x86}/hyperv_clock.c        |   0
 .../kvm/{x86_64 => x86}/hyperv_cpuid.c        |   0
 .../kvm/{x86_64 => x86}/hyperv_evmcs.c        |   0
 .../hyperv_extended_hypercalls.c              |   0
 .../kvm/{x86_64 => x86}/hyperv_features.c     |   0
 .../kvm/{x86_64 => x86}/hyperv_ipi.c          |   0
 .../kvm/{x86_64 => x86}/hyperv_svm_test.c     |   0
 .../kvm/{x86_64 => x86}/hyperv_tlb_flush.c    |   0
 .../kvm/{x86_64 => x86}/kvm_clock_test.c      |   0
 .../kvm/{x86_64 => x86}/kvm_pv_test.c         |   0
 .../kvm/{x86_64 => x86}/max_vcpuid_cap_test.c |   0
 .../kvm/{x86_64 => x86}/monitor_mwait_test.c  |   0
 .../{x86_64 => x86}/nested_exceptions_test.c  |   0
 .../kvm/{x86_64 => x86}/nx_huge_pages_test.c  |   0
 .../kvm/{x86_64 => x86}/nx_huge_pages_test.sh |   0
 .../kvm/{x86_64 => x86}/platform_info_test.c  |   0
 .../kvm/{x86_64 => x86}/pmu_counters_test.c   |   0
 .../{x86_64 => x86}/pmu_event_filter_test.c   |   0
 .../private_mem_conversions_test.c            |   0
 .../private_mem_kvm_exits_test.c              |   0
 .../{x86_64 => x86}/recalc_apic_map_test.c    |   0
 .../kvm/{x86_64 => x86}/set_boot_cpu_id.c     |   0
 .../kvm/{x86_64 => x86}/set_sregs_test.c      |   0
 .../kvm/{x86_64 => x86}/sev_init2_tests.c     |   0
 .../kvm/{x86_64 => x86}/sev_migrate_tests.c   |   0
 .../kvm/{x86_64 => x86}/sev_smoke_test.c      |   0
 .../smaller_maxphyaddr_emulation_test.c       |   0
 .../selftests/kvm/{x86_64 => x86}/smm_test.c  |   0
 .../kvm/{x86_64 => x86}/state_test.c          |   0
 .../kvm/{x86_64 => x86}/svm_int_ctl_test.c    |   0
 .../svm_nested_shutdown_test.c                |   0
 .../svm_nested_soft_inject_test.c             |   0
 .../kvm/{x86_64 => x86}/svm_vmcall_test.c     |   0
 .../kvm/{x86_64 => x86}/sync_regs_test.c      |   0
 .../{x86_64 => x86}/triple_fault_event_test.c |   0
 .../kvm/{x86_64 => x86}/tsc_msrs_test.c       |   0
 .../kvm/{x86_64 => x86}/tsc_scaling_sync.c    |   0
 .../kvm/{x86_64 => x86}/ucna_injection_test.c |   0
 .../kvm/{x86_64 => x86}/userspace_io_test.c   |   0
 .../{x86_64 => x86}/userspace_msr_exit_test.c |   0
 .../{x86_64 => x86}/vmx_apic_access_test.c    |   0
 .../vmx_close_while_nested_test.c             |   0
 .../kvm/{x86_64 => x86}/vmx_dirty_log_test.c  |   0
 .../vmx_exception_with_invalid_guest_state.c  |   0
 .../vmx_invalid_nested_guest_state.c          |   0
 .../kvm/{x86_64 => x86}/vmx_msrs_test.c       |   0
 .../vmx_nested_tsc_scaling_test.c             |   0
 .../kvm/{x86_64 => x86}/vmx_pmu_caps_test.c   |   0
 .../vmx_preemption_timer_test.c               |   0
 .../vmx_set_nested_state_test.c               |   0
 .../kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c |   0
 .../kvm/{x86_64 => x86}/xapic_ipi_test.c      |   0
 .../kvm/{x86_64 => x86}/xapic_state_test.c    |   0
 .../kvm/{x86_64 => x86}/xcr0_cpuid_test.c     |   0
 .../kvm/{x86_64 => x86}/xen_shinfo_test.c     |   0
 .../kvm/{x86_64 => x86}/xen_vmcall_test.c     |   0
 .../kvm/{x86_64 => x86}/xss_msr_test.c        |   0
 152 files changed, 172 insertions(+), 208 deletions(-)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/aarch32_id_regs.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer_edge_cases.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/debug-exceptions.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/get-reg-list.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/hypercalls.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/mmio_abort.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/no-vgic-v3.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/page_fault_test.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/psci_test.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/set_id_regs.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/smccc_filter.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vcpu_width_config.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_init.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_irq.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_lpi_stress.c (100%)
 rename tools/testing/selftests/kvm/{aarch64 => arm64}/vpmu_counter_access.c (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/arch_timer.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/delay.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3_its.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/processor.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/spinlock.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/vgic.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/debug_print.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/diag318_test_handler.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/facility.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/processor.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/sie.h (100%)
 rename tools/testing/selftests/kvm/include/{s390x => s390}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/apic.h (98%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/evmcs.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/hyperv.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/kvm_util_arch.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/mce.h (94%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/pmu.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/processor.h (99%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/sev.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm.h (98%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm_util.h (94%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/ucall.h (100%)
 rename tools/testing/selftests/kvm/include/{x86_64 => x86}/vmx.h (99%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_private.h (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3_its.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/handlers.S (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/processor.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/spinlock.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/vgic.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/diag318_test_handler.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/facility.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/processor.c (100%)
 rename tools/testing/selftests/kvm/lib/{s390x => s390}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/apic.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/handlers.S (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/hyperv.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/memstress.c (98%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/pmu.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/processor.c (99%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/sev.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/svm.c (99%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/ucall.c (100%)
 rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/vmx.c (99%)
 rename tools/testing/selftests/kvm/{s390x => s390}/cmma_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/config (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/cpumodel_subfuncs_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/debug_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/memop.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/resets.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/shared_zeropage_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/sync_regs_test.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/tprot.c (100%)
 rename tools/testing/selftests/kvm/{s390x => s390}/ucontrol_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/amx_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/apic_bus_clock_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/cpuid_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/debug_regs.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/dirty_log_page_splitting_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/exit_on_emulation_failure_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/feature_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/fix_hypercall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/flds_emulation.h (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hwcr_msr_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_clock.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_cpuid.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_evmcs.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_extended_hypercalls.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_features.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_ipi.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_svm_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_tlb_flush.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_clock_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_pv_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/max_vcpuid_cap_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/monitor_mwait_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nested_exceptions_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.sh (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/platform_info_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_counters_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_event_filter_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_conversions_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_kvm_exits_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/recalc_apic_map_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/set_boot_cpu_id.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/set_sregs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_init2_tests.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_migrate_tests.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_smoke_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/smaller_maxphyaddr_emulation_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/smm_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_int_ctl_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_shutdown_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_soft_inject_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_vmcall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/sync_regs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/triple_fault_event_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_scaling_sync.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/ucna_injection_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_io_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_msr_exit_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_apic_access_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_close_while_nested_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_dirty_log_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_exception_with_invalid_guest_state.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_invalid_nested_guest_state.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_msrs_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_nested_tsc_scaling_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_pmu_caps_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_preemption_timer_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_set_nested_state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_ipi_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_state_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xcr0_cpuid_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_shinfo_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_vmcall_test.c (100%)
 rename tools/testing/selftests/kvm/{x86_64 => x86}/xss_msr_test.c (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 21fdaa19229a..c2939c8f7ce4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12461,8 +12461,8 @@ F:	arch/arm64/include/asm/kvm*
 F:	arch/arm64/include/uapi/asm/kvm*
 F:	arch/arm64/kvm/
 F:	include/kvm/arm_*
-F:	tools/testing/selftests/kvm/*/aarch64/
-F:	tools/testing/selftests/kvm/aarch64/
+F:	tools/testing/selftests/kvm/*/arm64/
+F:	tools/testing/selftests/kvm/arm64/
 
 KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
 M:	Tianrui Zhao <zhaotianrui at loongson.cn>
@@ -12533,8 +12533,8 @@ F:	arch/s390/kvm/
 F:	arch/s390/mm/gmap.c
 F:	drivers/s390/char/uvdevice.c
 F:	tools/testing/selftests/drivers/s390x/uvdevice/
-F:	tools/testing/selftests/kvm/*/s390x/
-F:	tools/testing/selftests/kvm/s390x/
+F:	tools/testing/selftests/kvm/*/s390/
+F:	tools/testing/selftests/kvm/s390/
 
 KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86)
 M:	Sean Christopherson <seanjc at google.com>
@@ -12551,8 +12551,8 @@ F:	arch/x86/include/uapi/asm/svm.h
 F:	arch/x86/include/uapi/asm/vmx.h
 F:	arch/x86/kvm/
 F:	arch/x86/kvm/*/
-F:	tools/testing/selftests/kvm/*/x86_64/
-F:	tools/testing/selftests/kvm/x86_64/
+F:	tools/testing/selftests/kvm/*/x86/
+F:	tools/testing/selftests/kvm/x86/
 
 KERNFS
 M:	Greg Kroah-Hartman <gregkh at linuxfoundation.org>
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 7b33464bf8cc..9bc2eba1af1c 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -4,16 +4,12 @@ include $(top_srcdir)/scripts/subarch.include
 ARCH            ?= $(SUBARCH)
 
 ifeq ($(ARCH),$(filter $(ARCH),arm64 s390 riscv x86 x86_64))
-ifeq ($(ARCH),x86)
-	ARCH_DIR := x86_64
-else ifeq ($(ARCH),arm64)
-	ARCH_DIR := aarch64
-else ifeq ($(ARCH),s390)
-	ARCH_DIR := s390x
+# Top-level selftests allows ARCH=x86_64 :-(
+ifeq ($(ARCH),x86_64)
+	ARCH_DIR := x86
 else
 	ARCH_DIR := $(ARCH)
 endif
-
 include Makefile.kvm
 else
 # Empty targets for unsupported architectures
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index e988a72f8c20..9888dd6bb483 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -18,177 +18,177 @@ LIBKVM += lib/userfaultfd_util.c
 
 LIBKVM_STRING += lib/string_override.c
 
-LIBKVM_x86_64 += lib/x86_64/apic.c
-LIBKVM_x86_64 += lib/x86_64/handlers.S
-LIBKVM_x86_64 += lib/x86_64/hyperv.c
-LIBKVM_x86_64 += lib/x86_64/memstress.c
-LIBKVM_x86_64 += lib/x86_64/pmu.c
-LIBKVM_x86_64 += lib/x86_64/processor.c
-LIBKVM_x86_64 += lib/x86_64/sev.c
-LIBKVM_x86_64 += lib/x86_64/svm.c
-LIBKVM_x86_64 += lib/x86_64/ucall.c
-LIBKVM_x86_64 += lib/x86_64/vmx.c
+LIBKVM_x86 += lib/x86/apic.c
+LIBKVM_x86 += lib/x86/handlers.S
+LIBKVM_x86 += lib/x86/hyperv.c
+LIBKVM_x86 += lib/x86/memstress.c
+LIBKVM_x86 += lib/x86/pmu.c
+LIBKVM_x86 += lib/x86/processor.c
+LIBKVM_x86 += lib/x86/sev.c
+LIBKVM_x86 += lib/x86/svm.c
+LIBKVM_x86 += lib/x86/ucall.c
+LIBKVM_x86 += lib/x86/vmx.c
 
-LIBKVM_aarch64 += lib/aarch64/gic.c
-LIBKVM_aarch64 += lib/aarch64/gic_v3.c
-LIBKVM_aarch64 += lib/aarch64/gic_v3_its.c
-LIBKVM_aarch64 += lib/aarch64/handlers.S
-LIBKVM_aarch64 += lib/aarch64/processor.c
-LIBKVM_aarch64 += lib/aarch64/spinlock.c
-LIBKVM_aarch64 += lib/aarch64/ucall.c
-LIBKVM_aarch64 += lib/aarch64/vgic.c
+LIBKVM_arm64 += lib/arm64/gic.c
+LIBKVM_arm64 += lib/arm64/gic_v3.c
+LIBKVM_arm64 += lib/arm64/gic_v3_its.c
+LIBKVM_arm64 += lib/arm64/handlers.S
+LIBKVM_arm64 += lib/arm64/processor.c
+LIBKVM_arm64 += lib/arm64/spinlock.c
+LIBKVM_arm64 += lib/arm64/ucall.c
+LIBKVM_arm64 += lib/arm64/vgic.c
 
-LIBKVM_s390x += lib/s390x/diag318_test_handler.c
-LIBKVM_s390x += lib/s390x/processor.c
-LIBKVM_s390x += lib/s390x/ucall.c
-LIBKVM_s390x += lib/s390x/facility.c
+LIBKVM_s390 += lib/s390/diag318_test_handler.c
+LIBKVM_s390 += lib/s390/processor.c
+LIBKVM_s390 += lib/s390/ucall.c
+LIBKVM_s390 += lib/s390/facility.c
 
 LIBKVM_riscv += lib/riscv/handlers.S
 LIBKVM_riscv += lib/riscv/processor.c
 LIBKVM_riscv += lib/riscv/ucall.c
 
 # Non-compiled test targets
-TEST_PROGS_x86_64 += x86_64/nx_huge_pages_test.sh
+TEST_PROGS_x86 += x86/nx_huge_pages_test.sh
 
 # Compiled test targets
-TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test
-TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test
-TEST_GEN_PROGS_x86_64 += x86_64/dirty_log_page_splitting_test
-TEST_GEN_PROGS_x86_64 += x86_64/feature_msrs_test
-TEST_GEN_PROGS_x86_64 += x86_64/exit_on_emulation_failure_test
-TEST_GEN_PROGS_x86_64 += x86_64/fix_hypercall_test
-TEST_GEN_PROGS_x86_64 += x86_64/hwcr_msr_test
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_evmcs
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_extended_hypercalls
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_ipi
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_svm_test
-TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush
-TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test
-TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test
-TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test
-TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test
-TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test
-TEST_GEN_PROGS_x86_64 += x86_64/pmu_counters_test
-TEST_GEN_PROGS_x86_64 += x86_64/pmu_event_filter_test
-TEST_GEN_PROGS_x86_64 += x86_64/private_mem_conversions_test
-TEST_GEN_PROGS_x86_64 += x86_64/private_mem_kvm_exits_test
-TEST_GEN_PROGS_x86_64 += x86_64/set_boot_cpu_id
-TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test
-TEST_GEN_PROGS_x86_64 += x86_64/smaller_maxphyaddr_emulation_test
-TEST_GEN_PROGS_x86_64 += x86_64/smm_test
-TEST_GEN_PROGS_x86_64 += x86_64/state_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
-TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
-TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
-TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test
-TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test
-TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync
-TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
-TEST_GEN_PROGS_x86_64 += x86_64/ucna_injection_test
-TEST_GEN_PROGS_x86_64 += x86_64/userspace_io_test
-TEST_GEN_PROGS_x86_64 += x86_64/userspace_msr_exit_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_apic_access_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_exception_with_invalid_guest_state
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_msrs_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_invalid_nested_guest_state
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_nested_tsc_scaling_test
-TEST_GEN_PROGS_x86_64 += x86_64/apic_bus_clock_test
-TEST_GEN_PROGS_x86_64 += x86_64/xapic_ipi_test
-TEST_GEN_PROGS_x86_64 += x86_64/xapic_state_test
-TEST_GEN_PROGS_x86_64 += x86_64/xcr0_cpuid_test
-TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test
-TEST_GEN_PROGS_x86_64 += x86_64/debug_regs
-TEST_GEN_PROGS_x86_64 += x86_64/tsc_msrs_test
-TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test
-TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test
-TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test
-TEST_GEN_PROGS_x86_64 += x86_64/sev_init2_tests
-TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
-TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test
-TEST_GEN_PROGS_x86_64 += x86_64/amx_test
-TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
-TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
-TEST_GEN_PROGS_x86_64 += x86_64/recalc_apic_map_test
-TEST_GEN_PROGS_x86_64 += access_tracking_perf_test
-TEST_GEN_PROGS_x86_64 += coalesced_io_test
-TEST_GEN_PROGS_x86_64 += demand_paging_test
-TEST_GEN_PROGS_x86_64 += dirty_log_test
-TEST_GEN_PROGS_x86_64 += dirty_log_perf_test
-TEST_GEN_PROGS_x86_64 += guest_memfd_test
-TEST_GEN_PROGS_x86_64 += guest_print_test
-TEST_GEN_PROGS_x86_64 += hardware_disable_test
-TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
-TEST_GEN_PROGS_x86_64 += kvm_page_table_test
-TEST_GEN_PROGS_x86_64 += mmu_stress_test
-TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
-TEST_GEN_PROGS_x86_64 += memslot_perf_test
-TEST_GEN_PROGS_x86_64 += rseq_test
-TEST_GEN_PROGS_x86_64 += set_memory_region_test
-TEST_GEN_PROGS_x86_64 += steal_time
-TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
-TEST_GEN_PROGS_x86_64 += system_counter_offset_test
-TEST_GEN_PROGS_x86_64 += pre_fault_memory_test
+TEST_GEN_PROGS_x86 = x86/cpuid_test
+TEST_GEN_PROGS_x86 += x86/cr4_cpuid_sync_test
+TEST_GEN_PROGS_x86 += x86/dirty_log_page_splitting_test
+TEST_GEN_PROGS_x86 += x86/feature_msrs_test
+TEST_GEN_PROGS_x86 += x86/exit_on_emulation_failure_test
+TEST_GEN_PROGS_x86 += x86/fix_hypercall_test
+TEST_GEN_PROGS_x86 += x86/hwcr_msr_test
+TEST_GEN_PROGS_x86 += x86/hyperv_clock
+TEST_GEN_PROGS_x86 += x86/hyperv_cpuid
+TEST_GEN_PROGS_x86 += x86/hyperv_evmcs
+TEST_GEN_PROGS_x86 += x86/hyperv_extended_hypercalls
+TEST_GEN_PROGS_x86 += x86/hyperv_features
+TEST_GEN_PROGS_x86 += x86/hyperv_ipi
+TEST_GEN_PROGS_x86 += x86/hyperv_svm_test
+TEST_GEN_PROGS_x86 += x86/hyperv_tlb_flush
+TEST_GEN_PROGS_x86 += x86/kvm_clock_test
+TEST_GEN_PROGS_x86 += x86/kvm_pv_test
+TEST_GEN_PROGS_x86 += x86/monitor_mwait_test
+TEST_GEN_PROGS_x86 += x86/nested_exceptions_test
+TEST_GEN_PROGS_x86 += x86/platform_info_test
+TEST_GEN_PROGS_x86 += x86/pmu_counters_test
+TEST_GEN_PROGS_x86 += x86/pmu_event_filter_test
+TEST_GEN_PROGS_x86 += x86/private_mem_conversions_test
+TEST_GEN_PROGS_x86 += x86/private_mem_kvm_exits_test
+TEST_GEN_PROGS_x86 += x86/set_boot_cpu_id
+TEST_GEN_PROGS_x86 += x86/set_sregs_test
+TEST_GEN_PROGS_x86 += x86/smaller_maxphyaddr_emulation_test
+TEST_GEN_PROGS_x86 += x86/smm_test
+TEST_GEN_PROGS_x86 += x86/state_test
+TEST_GEN_PROGS_x86 += x86/vmx_preemption_timer_test
+TEST_GEN_PROGS_x86 += x86/svm_vmcall_test
+TEST_GEN_PROGS_x86 += x86/svm_int_ctl_test
+TEST_GEN_PROGS_x86 += x86/svm_nested_shutdown_test
+TEST_GEN_PROGS_x86 += x86/svm_nested_soft_inject_test
+TEST_GEN_PROGS_x86 += x86/tsc_scaling_sync
+TEST_GEN_PROGS_x86 += x86/sync_regs_test
+TEST_GEN_PROGS_x86 += x86/ucna_injection_test
+TEST_GEN_PROGS_x86 += x86/userspace_io_test
+TEST_GEN_PROGS_x86 += x86/userspace_msr_exit_test
+TEST_GEN_PROGS_x86 += x86/vmx_apic_access_test
+TEST_GEN_PROGS_x86 += x86/vmx_close_while_nested_test
+TEST_GEN_PROGS_x86 += x86/vmx_dirty_log_test
+TEST_GEN_PROGS_x86 += x86/vmx_exception_with_invalid_guest_state
+TEST_GEN_PROGS_x86 += x86/vmx_msrs_test
+TEST_GEN_PROGS_x86 += x86/vmx_invalid_nested_guest_state
+TEST_GEN_PROGS_x86 += x86/vmx_set_nested_state_test
+TEST_GEN_PROGS_x86 += x86/vmx_tsc_adjust_test
+TEST_GEN_PROGS_x86 += x86/vmx_nested_tsc_scaling_test
+TEST_GEN_PROGS_x86 += x86/apic_bus_clock_test
+TEST_GEN_PROGS_x86 += x86/xapic_ipi_test
+TEST_GEN_PROGS_x86 += x86/xapic_state_test
+TEST_GEN_PROGS_x86 += x86/xcr0_cpuid_test
+TEST_GEN_PROGS_x86 += x86/xss_msr_test
+TEST_GEN_PROGS_x86 += x86/debug_regs
+TEST_GEN_PROGS_x86 += x86/tsc_msrs_test
+TEST_GEN_PROGS_x86 += x86/vmx_pmu_caps_test
+TEST_GEN_PROGS_x86 += x86/xen_shinfo_test
+TEST_GEN_PROGS_x86 += x86/xen_vmcall_test
+TEST_GEN_PROGS_x86 += x86/sev_init2_tests
+TEST_GEN_PROGS_x86 += x86/sev_migrate_tests
+TEST_GEN_PROGS_x86 += x86/sev_smoke_test
+TEST_GEN_PROGS_x86 += x86/amx_test
+TEST_GEN_PROGS_x86 += x86/max_vcpuid_cap_test
+TEST_GEN_PROGS_x86 += x86/triple_fault_event_test
+TEST_GEN_PROGS_x86 += x86/recalc_apic_map_test
+TEST_GEN_PROGS_x86 += access_tracking_perf_test
+TEST_GEN_PROGS_x86 += coalesced_io_test
+TEST_GEN_PROGS_x86 += demand_paging_test
+TEST_GEN_PROGS_x86 += dirty_log_test
+TEST_GEN_PROGS_x86 += dirty_log_perf_test
+TEST_GEN_PROGS_x86 += guest_memfd_test
+TEST_GEN_PROGS_x86 += guest_print_test
+TEST_GEN_PROGS_x86 += hardware_disable_test
+TEST_GEN_PROGS_x86 += kvm_create_max_vcpus
+TEST_GEN_PROGS_x86 += kvm_page_table_test
+TEST_GEN_PROGS_x86 += memslot_modification_stress_test
+TEST_GEN_PROGS_x86 += memslot_perf_test
+TEST_GEN_PROGS_x86 += mmu_stress_test
+TEST_GEN_PROGS_x86 += rseq_test
+TEST_GEN_PROGS_x86 += set_memory_region_test
+TEST_GEN_PROGS_x86 += steal_time
+TEST_GEN_PROGS_x86 += kvm_binary_stats_test
+TEST_GEN_PROGS_x86 += system_counter_offset_test
+TEST_GEN_PROGS_x86 += pre_fault_memory_test
 
 # Compiled outputs used by test targets
-TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
+TEST_GEN_PROGS_EXTENDED_x86 += x86/nx_huge_pages_test
 
-TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
-TEST_GEN_PROGS_aarch64 += aarch64/arch_timer_edge_cases
-TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
-TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
-TEST_GEN_PROGS_aarch64 += aarch64/mmio_abort
-TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
-TEST_GEN_PROGS_aarch64 += aarch64/psci_test
-TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
-TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
-TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
-TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
-TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
-TEST_GEN_PROGS_aarch64 += aarch64/vgic_lpi_stress
-TEST_GEN_PROGS_aarch64 += aarch64/vpmu_counter_access
-TEST_GEN_PROGS_aarch64 += aarch64/no-vgic-v3
-TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
-TEST_GEN_PROGS_aarch64 += arch_timer
-TEST_GEN_PROGS_aarch64 += coalesced_io_test
-TEST_GEN_PROGS_aarch64 += demand_paging_test
-TEST_GEN_PROGS_aarch64 += dirty_log_test
-TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
-TEST_GEN_PROGS_aarch64 += guest_print_test
-TEST_GEN_PROGS_aarch64 += get-reg-list
-TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
-TEST_GEN_PROGS_aarch64 += kvm_page_table_test
-TEST_GEN_PROGS_aarch64 += memslot_modification_stress_test
-TEST_GEN_PROGS_aarch64 += memslot_perf_test
-TEST_GEN_PROGS_aarch64 += mmu_stress_test
-TEST_GEN_PROGS_aarch64 += rseq_test
-TEST_GEN_PROGS_aarch64 += set_memory_region_test
-TEST_GEN_PROGS_aarch64 += steal_time
-TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
+TEST_GEN_PROGS_arm64 += arm64/aarch32_id_regs
+TEST_GEN_PROGS_arm64 += arm64/arch_timer_edge_cases
+TEST_GEN_PROGS_arm64 += arm64/debug-exceptions
+TEST_GEN_PROGS_arm64 += arm64/hypercalls
+TEST_GEN_PROGS_arm64 += arm64/mmio_abort
+TEST_GEN_PROGS_arm64 += arm64/page_fault_test
+TEST_GEN_PROGS_arm64 += arm64/psci_test
+TEST_GEN_PROGS_arm64 += arm64/set_id_regs
+TEST_GEN_PROGS_arm64 += arm64/smccc_filter
+TEST_GEN_PROGS_arm64 += arm64/vcpu_width_config
+TEST_GEN_PROGS_arm64 += arm64/vgic_init
+TEST_GEN_PROGS_arm64 += arm64/vgic_irq
+TEST_GEN_PROGS_arm64 += arm64/vgic_lpi_stress
+TEST_GEN_PROGS_arm64 += arm64/vpmu_counter_access
+TEST_GEN_PROGS_arm64 += arm64/no-vgic-v3
+TEST_GEN_PROGS_arm64 += access_tracking_perf_test
+TEST_GEN_PROGS_arm64 += arch_timer
+TEST_GEN_PROGS_arm64 += coalesced_io_test
+TEST_GEN_PROGS_arm64 += demand_paging_test
+TEST_GEN_PROGS_arm64 += dirty_log_test
+TEST_GEN_PROGS_arm64 += dirty_log_perf_test
+TEST_GEN_PROGS_arm64 += guest_print_test
+TEST_GEN_PROGS_arm64 += get-reg-list
+TEST_GEN_PROGS_arm64 += kvm_create_max_vcpus
+TEST_GEN_PROGS_arm64 += kvm_page_table_test
+TEST_GEN_PROGS_arm64 += memslot_modification_stress_test
+TEST_GEN_PROGS_arm64 += memslot_perf_test
+TEST_GEN_PROGS_arm64 += mmu_stress_test
+TEST_GEN_PROGS_arm64 += rseq_test
+TEST_GEN_PROGS_arm64 += set_memory_region_test
+TEST_GEN_PROGS_arm64 += steal_time
+TEST_GEN_PROGS_arm64 += kvm_binary_stats_test
 
-TEST_GEN_PROGS_s390x = s390x/memop
-TEST_GEN_PROGS_s390x += s390x/resets
-TEST_GEN_PROGS_s390x += s390x/sync_regs_test
-TEST_GEN_PROGS_s390x += s390x/tprot
-TEST_GEN_PROGS_s390x += s390x/cmma_test
-TEST_GEN_PROGS_s390x += s390x/debug_test
-TEST_GEN_PROGS_s390x += s390x/cpumodel_subfuncs_test
-TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test
-TEST_GEN_PROGS_s390x += s390x/ucontrol_test
-TEST_GEN_PROGS_s390x += demand_paging_test
-TEST_GEN_PROGS_s390x += dirty_log_test
-TEST_GEN_PROGS_s390x += guest_print_test
-TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
-TEST_GEN_PROGS_s390x += kvm_page_table_test
-TEST_GEN_PROGS_s390x += rseq_test
-TEST_GEN_PROGS_s390x += set_memory_region_test
-TEST_GEN_PROGS_s390x += kvm_binary_stats_test
+TEST_GEN_PROGS_s390 = s390/memop
+TEST_GEN_PROGS_s390 += s390/resets
+TEST_GEN_PROGS_s390 += s390/sync_regs_test
+TEST_GEN_PROGS_s390 += s390/tprot
+TEST_GEN_PROGS_s390 += s390/cmma_test
+TEST_GEN_PROGS_s390 += s390/debug_test
+TEST_GEN_PROGS_s390 += s390/cpumodel_subfuncs_test
+TEST_GEN_PROGS_s390 += s390/shared_zeropage_test
+TEST_GEN_PROGS_s390 += s390/ucontrol_test
+TEST_GEN_PROGS_s390 += demand_paging_test
+TEST_GEN_PROGS_s390 += dirty_log_test
+TEST_GEN_PROGS_s390 += guest_print_test
+TEST_GEN_PROGS_s390 += kvm_create_max_vcpus
+TEST_GEN_PROGS_s390 += kvm_page_table_test
+TEST_GEN_PROGS_s390 += rseq_test
+TEST_GEN_PROGS_s390 += set_memory_region_test
+TEST_GEN_PROGS_s390 += kvm_binary_stats_test
 
 TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
 TEST_GEN_PROGS_riscv += riscv/ebreak_test
@@ -222,11 +222,7 @@ include ../lib.mk
 INSTALL_HDR_PATH = $(top_srcdir)/usr
 LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
 LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
-ifeq ($(ARCH),x86_64)
-LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include
-else
-LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
-endif
+LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH_DIR)/include
 CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
 	-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
 	-fno-builtin-memcmp -fno-builtin-memcpy \
diff --git a/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c b/tools/testing/selftests/kvm/arm64/aarch32_id_regs.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c
rename to tools/testing/selftests/kvm/arm64/aarch32_id_regs.c
diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/arm64/arch_timer.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/arch_timer.c
rename to tools/testing/selftests/kvm/arm64/arch_timer.c
diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer_edge_cases.c b/tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/arch_timer_edge_cases.c
rename to tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c
diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools/testing/selftests/kvm/arm64/debug-exceptions.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/debug-exceptions.c
rename to tools/testing/selftests/kvm/arm64/debug-exceptions.c
diff --git a/tools/testing/selftests/kvm/aarch64/get-reg-list.c b/tools/testing/selftests/kvm/arm64/get-reg-list.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/get-reg-list.c
rename to tools/testing/selftests/kvm/arm64/get-reg-list.c
diff --git a/tools/testing/selftests/kvm/aarch64/hypercalls.c b/tools/testing/selftests/kvm/arm64/hypercalls.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/hypercalls.c
rename to tools/testing/selftests/kvm/arm64/hypercalls.c
diff --git a/tools/testing/selftests/kvm/aarch64/mmio_abort.c b/tools/testing/selftests/kvm/arm64/mmio_abort.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/mmio_abort.c
rename to tools/testing/selftests/kvm/arm64/mmio_abort.c
diff --git a/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c b/tools/testing/selftests/kvm/arm64/no-vgic-v3.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/no-vgic-v3.c
rename to tools/testing/selftests/kvm/arm64/no-vgic-v3.c
diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c b/tools/testing/selftests/kvm/arm64/page_fault_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/page_fault_test.c
rename to tools/testing/selftests/kvm/arm64/page_fault_test.c
diff --git a/tools/testing/selftests/kvm/aarch64/psci_test.c b/tools/testing/selftests/kvm/arm64/psci_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/psci_test.c
rename to tools/testing/selftests/kvm/arm64/psci_test.c
diff --git a/tools/testing/selftests/kvm/aarch64/set_id_regs.c b/tools/testing/selftests/kvm/arm64/set_id_regs.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/set_id_regs.c
rename to tools/testing/selftests/kvm/arm64/set_id_regs.c
diff --git a/tools/testing/selftests/kvm/aarch64/smccc_filter.c b/tools/testing/selftests/kvm/arm64/smccc_filter.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/smccc_filter.c
rename to tools/testing/selftests/kvm/arm64/smccc_filter.c
diff --git a/tools/testing/selftests/kvm/aarch64/vcpu_width_config.c b/tools/testing/selftests/kvm/arm64/vcpu_width_config.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/vcpu_width_config.c
rename to tools/testing/selftests/kvm/arm64/vcpu_width_config.c
diff --git a/tools/testing/selftests/kvm/aarch64/vgic_init.c b/tools/testing/selftests/kvm/arm64/vgic_init.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/vgic_init.c
rename to tools/testing/selftests/kvm/arm64/vgic_init.c
diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/arm64/vgic_irq.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/vgic_irq.c
rename to tools/testing/selftests/kvm/arm64/vgic_irq.c
diff --git a/tools/testing/selftests/kvm/aarch64/vgic_lpi_stress.c b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/vgic_lpi_stress.c
rename to tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
diff --git a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
similarity index 100%
rename from tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
rename to tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/testing/selftests/kvm/dirty_log_perf_test.c
index 9f24303acb8c..e79817bd0e29 100644
--- a/tools/testing/selftests/kvm/dirty_log_perf_test.c
+++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c
@@ -21,7 +21,7 @@
 #include "ucall_common.h"
 
 #ifdef __aarch64__
-#include "aarch64/vgic.h"
+#include "arm64/vgic.h"
 
 static int gic_fd;
 
diff --git a/tools/testing/selftests/kvm/include/aarch64/arch_timer.h b/tools/testing/selftests/kvm/include/arm64/arch_timer.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/arch_timer.h
rename to tools/testing/selftests/kvm/include/arm64/arch_timer.h
diff --git a/tools/testing/selftests/kvm/include/aarch64/delay.h b/tools/testing/selftests/kvm/include/arm64/delay.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/delay.h
rename to tools/testing/selftests/kvm/include/arm64/delay.h
diff --git a/tools/testing/selftests/kvm/include/aarch64/gic.h b/tools/testing/selftests/kvm/include/arm64/gic.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/gic.h
rename to tools/testing/selftests/kvm/include/arm64/gic.h
diff --git a/tools/testing/selftests/kvm/include/aarch64/gic_v3.h b/tools/testing/selftests/kvm/include/arm64/gic_v3.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/gic_v3.h
rename to tools/testing/selftests/kvm/include/arm64/gic_v3.h
diff --git a/tools/testing/selftests/kvm/include/aarch64/gic_v3_its.h b/tools/testing/selftests/kvm/include/arm64/gic_v3_its.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/gic_v3_its.h
rename to tools/testing/selftests/kvm/include/arm64/gic_v3_its.h
diff --git a/tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/arm64/kvm_util_arch.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
rename to tools/testing/selftests/kvm/include/arm64/kvm_util_arch.h
diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/arm64/processor.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/processor.h
rename to tools/testing/selftests/kvm/include/arm64/processor.h
diff --git a/tools/testing/selftests/kvm/include/aarch64/spinlock.h b/tools/testing/selftests/kvm/include/arm64/spinlock.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/spinlock.h
rename to tools/testing/selftests/kvm/include/arm64/spinlock.h
diff --git a/tools/testing/selftests/kvm/include/aarch64/ucall.h b/tools/testing/selftests/kvm/include/arm64/ucall.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/ucall.h
rename to tools/testing/selftests/kvm/include/arm64/ucall.h
diff --git a/tools/testing/selftests/kvm/include/aarch64/vgic.h b/tools/testing/selftests/kvm/include/arm64/vgic.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/aarch64/vgic.h
rename to tools/testing/selftests/kvm/include/arm64/vgic.h
diff --git a/tools/testing/selftests/kvm/include/s390x/debug_print.h b/tools/testing/selftests/kvm/include/s390/debug_print.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/s390x/debug_print.h
rename to tools/testing/selftests/kvm/include/s390/debug_print.h
diff --git a/tools/testing/selftests/kvm/include/s390x/diag318_test_handler.h b/tools/testing/selftests/kvm/include/s390/diag318_test_handler.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/s390x/diag318_test_handler.h
rename to tools/testing/selftests/kvm/include/s390/diag318_test_handler.h
diff --git a/tools/testing/selftests/kvm/include/s390x/facility.h b/tools/testing/selftests/kvm/include/s390/facility.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/s390x/facility.h
rename to tools/testing/selftests/kvm/include/s390/facility.h
diff --git a/tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h b/tools/testing/selftests/kvm/include/s390/kvm_util_arch.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
rename to tools/testing/selftests/kvm/include/s390/kvm_util_arch.h
diff --git a/tools/testing/selftests/kvm/include/s390x/processor.h b/tools/testing/selftests/kvm/include/s390/processor.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/s390x/processor.h
rename to tools/testing/selftests/kvm/include/s390/processor.h
diff --git a/tools/testing/selftests/kvm/include/s390x/sie.h b/tools/testing/selftests/kvm/include/s390/sie.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/s390x/sie.h
rename to tools/testing/selftests/kvm/include/s390/sie.h
diff --git a/tools/testing/selftests/kvm/include/s390x/ucall.h b/tools/testing/selftests/kvm/include/s390/ucall.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/s390x/ucall.h
rename to tools/testing/selftests/kvm/include/s390/ucall.h
diff --git a/tools/testing/selftests/kvm/include/x86_64/apic.h b/tools/testing/selftests/kvm/include/x86/apic.h
similarity index 98%
rename from tools/testing/selftests/kvm/include/x86_64/apic.h
rename to tools/testing/selftests/kvm/include/x86/apic.h
index 51990094effd..80fe9f69b38d 100644
--- a/tools/testing/selftests/kvm/include/x86_64/apic.h
+++ b/tools/testing/selftests/kvm/include/x86/apic.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * tools/testing/selftests/kvm/include/x86_64/apic.h
- *
  * Copyright (C) 2021, Google LLC.
  */
 
diff --git a/tools/testing/selftests/kvm/include/x86_64/evmcs.h b/tools/testing/selftests/kvm/include/x86/evmcs.h
similarity index 99%
rename from tools/testing/selftests/kvm/include/x86_64/evmcs.h
rename to tools/testing/selftests/kvm/include/x86/evmcs.h
index 901caf0e0939..5a74bb30e2f8 100644
--- a/tools/testing/selftests/kvm/include/x86_64/evmcs.h
+++ b/tools/testing/selftests/kvm/include/x86/evmcs.h
@@ -1,9 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * tools/testing/selftests/kvm/include/x86_64/evmcs.h
- *
  * Copyright (C) 2018, Red Hat, Inc.
- *
  */
 
 #ifndef SELFTEST_KVM_EVMCS_H
diff --git a/tools/testing/selftests/kvm/include/x86_64/hyperv.h b/tools/testing/selftests/kvm/include/x86/hyperv.h
similarity index 99%
rename from tools/testing/selftests/kvm/include/x86_64/hyperv.h
rename to tools/testing/selftests/kvm/include/x86/hyperv.h
index 6849e2552f1b..f13e532be240 100644
--- a/tools/testing/selftests/kvm/include/x86_64/hyperv.h
+++ b/tools/testing/selftests/kvm/include/x86/hyperv.h
@@ -1,9 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * tools/testing/selftests/kvm/include/x86_64/hyperv.h
- *
  * Copyright (C) 2021, Red Hat, Inc.
- *
  */
 
 #ifndef SELFTEST_KVM_HYPERV_H
diff --git a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/x86/kvm_util_arch.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
rename to tools/testing/selftests/kvm/include/x86/kvm_util_arch.h
diff --git a/tools/testing/selftests/kvm/include/x86_64/mce.h b/tools/testing/selftests/kvm/include/x86/mce.h
similarity index 94%
rename from tools/testing/selftests/kvm/include/x86_64/mce.h
rename to tools/testing/selftests/kvm/include/x86/mce.h
index 6119321f3f5d..295f2d554754 100644
--- a/tools/testing/selftests/kvm/include/x86_64/mce.h
+++ b/tools/testing/selftests/kvm/include/x86/mce.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * tools/testing/selftests/kvm/include/x86_64/mce.h
- *
  * Copyright (C) 2022, Google LLC.
  */
 
diff --git a/tools/testing/selftests/kvm/include/x86_64/pmu.h b/tools/testing/selftests/kvm/include/x86/pmu.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/x86_64/pmu.h
rename to tools/testing/selftests/kvm/include/x86/pmu.h
diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h
similarity index 99%
rename from tools/testing/selftests/kvm/include/x86_64/processor.h
rename to tools/testing/selftests/kvm/include/x86/processor.h
index 645200e95f89..9ec984cf8674 100644
--- a/tools/testing/selftests/kvm/include/x86_64/processor.h
+++ b/tools/testing/selftests/kvm/include/x86/processor.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * tools/testing/selftests/kvm/include/x86_64/processor.h
- *
  * Copyright (C) 2018, Google LLC.
  */
 
diff --git a/tools/testing/selftests/kvm/include/x86_64/sev.h b/tools/testing/selftests/kvm/include/x86/sev.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/x86_64/sev.h
rename to tools/testing/selftests/kvm/include/x86/sev.h
diff --git a/tools/testing/selftests/kvm/include/x86_64/svm.h b/tools/testing/selftests/kvm/include/x86/svm.h
similarity index 98%
rename from tools/testing/selftests/kvm/include/x86_64/svm.h
rename to tools/testing/selftests/kvm/include/x86/svm.h
index 4803e1056055..29cffd0a9181 100644
--- a/tools/testing/selftests/kvm/include/x86_64/svm.h
+++ b/tools/testing/selftests/kvm/include/x86/svm.h
@@ -1,10 +1,4 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/*
- * tools/testing/selftests/kvm/include/x86_64/svm.h
- * This is a copy of arch/x86/include/asm/svm.h
- *
- */
-
 #ifndef SELFTEST_KVM_SVM_H
 #define SELFTEST_KVM_SVM_H
 
diff --git a/tools/testing/selftests/kvm/include/x86_64/svm_util.h b/tools/testing/selftests/kvm/include/x86/svm_util.h
similarity index 94%
rename from tools/testing/selftests/kvm/include/x86_64/svm_util.h
rename to tools/testing/selftests/kvm/include/x86/svm_util.h
index 044f0f872ba9..b74c6dcddcbd 100644
--- a/tools/testing/selftests/kvm/include/x86_64/svm_util.h
+++ b/tools/testing/selftests/kvm/include/x86/svm_util.h
@@ -1,8 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * tools/testing/selftests/kvm/include/x86_64/svm_utils.h
- * Header for nested SVM testing
- *
  * Copyright (C) 2020, Red Hat, Inc.
  */
 
diff --git a/tools/testing/selftests/kvm/include/x86_64/ucall.h b/tools/testing/selftests/kvm/include/x86/ucall.h
similarity index 100%
rename from tools/testing/selftests/kvm/include/x86_64/ucall.h
rename to tools/testing/selftests/kvm/include/x86/ucall.h
diff --git a/tools/testing/selftests/kvm/include/x86_64/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
similarity index 99%
rename from tools/testing/selftests/kvm/include/x86_64/vmx.h
rename to tools/testing/selftests/kvm/include/x86/vmx.h
index 5f0c0a29c556..edb3c391b982 100644
--- a/tools/testing/selftests/kvm/include/x86_64/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * tools/testing/selftests/kvm/include/x86_64/vmx.h
- *
  * Copyright (C) 2018, Google LLC.
  */
 
diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic.c b/tools/testing/selftests/kvm/lib/arm64/gic.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/aarch64/gic.c
rename to tools/testing/selftests/kvm/lib/arm64/gic.c
diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_private.h b/tools/testing/selftests/kvm/lib/arm64/gic_private.h
similarity index 100%
rename from tools/testing/selftests/kvm/lib/aarch64/gic_private.h
rename to tools/testing/selftests/kvm/lib/arm64/gic_private.h
diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c b/tools/testing/selftests/kvm/lib/arm64/gic_v3.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/aarch64/gic_v3.c
rename to tools/testing/selftests/kvm/lib/arm64/gic_v3.c
diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3_its.c b/tools/testing/selftests/kvm/lib/arm64/gic_v3_its.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/aarch64/gic_v3_its.c
rename to tools/testing/selftests/kvm/lib/arm64/gic_v3_its.c
diff --git a/tools/testing/selftests/kvm/lib/aarch64/handlers.S b/tools/testing/selftests/kvm/lib/arm64/handlers.S
similarity index 100%
rename from tools/testing/selftests/kvm/lib/aarch64/handlers.S
rename to tools/testing/selftests/kvm/lib/arm64/handlers.S
diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/aarch64/processor.c
rename to tools/testing/selftests/kvm/lib/arm64/processor.c
diff --git a/tools/testing/selftests/kvm/lib/aarch64/spinlock.c b/tools/testing/selftests/kvm/lib/arm64/spinlock.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/aarch64/spinlock.c
rename to tools/testing/selftests/kvm/lib/arm64/spinlock.c
diff --git a/tools/testing/selftests/kvm/lib/aarch64/ucall.c b/tools/testing/selftests/kvm/lib/arm64/ucall.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/aarch64/ucall.c
rename to tools/testing/selftests/kvm/lib/arm64/ucall.c
diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/arm64/vgic.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/aarch64/vgic.c
rename to tools/testing/selftests/kvm/lib/arm64/vgic.c
diff --git a/tools/testing/selftests/kvm/lib/s390x/diag318_test_handler.c b/tools/testing/selftests/kvm/lib/s390/diag318_test_handler.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/s390x/diag318_test_handler.c
rename to tools/testing/selftests/kvm/lib/s390/diag318_test_handler.c
diff --git a/tools/testing/selftests/kvm/lib/s390x/facility.c b/tools/testing/selftests/kvm/lib/s390/facility.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/s390x/facility.c
rename to tools/testing/selftests/kvm/lib/s390/facility.c
diff --git a/tools/testing/selftests/kvm/lib/s390x/processor.c b/tools/testing/selftests/kvm/lib/s390/processor.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/s390x/processor.c
rename to tools/testing/selftests/kvm/lib/s390/processor.c
diff --git a/tools/testing/selftests/kvm/lib/s390x/ucall.c b/tools/testing/selftests/kvm/lib/s390/ucall.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/s390x/ucall.c
rename to tools/testing/selftests/kvm/lib/s390/ucall.c
diff --git a/tools/testing/selftests/kvm/lib/x86_64/apic.c b/tools/testing/selftests/kvm/lib/x86/apic.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/x86_64/apic.c
rename to tools/testing/selftests/kvm/lib/x86/apic.c
diff --git a/tools/testing/selftests/kvm/lib/x86_64/handlers.S b/tools/testing/selftests/kvm/lib/x86/handlers.S
similarity index 100%
rename from tools/testing/selftests/kvm/lib/x86_64/handlers.S
rename to tools/testing/selftests/kvm/lib/x86/handlers.S
diff --git a/tools/testing/selftests/kvm/lib/x86_64/hyperv.c b/tools/testing/selftests/kvm/lib/x86/hyperv.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/x86_64/hyperv.c
rename to tools/testing/selftests/kvm/lib/x86/hyperv.c
diff --git a/tools/testing/selftests/kvm/lib/x86_64/memstress.c b/tools/testing/selftests/kvm/lib/x86/memstress.c
similarity index 98%
rename from tools/testing/selftests/kvm/lib/x86_64/memstress.c
rename to tools/testing/selftests/kvm/lib/x86/memstress.c
index d61e623afc8c..7f5d62a65c68 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/memstress.c
+++ b/tools/testing/selftests/kvm/lib/x86/memstress.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * x86_64-specific extensions to memstress.c.
+ * x86-specific extensions to memstress.c.
  *
  * Copyright (C) 2022, Google, Inc.
  */
diff --git a/tools/testing/selftests/kvm/lib/x86_64/pmu.c b/tools/testing/selftests/kvm/lib/x86/pmu.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/x86_64/pmu.c
rename to tools/testing/selftests/kvm/lib/x86/pmu.c
diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
similarity index 99%
rename from tools/testing/selftests/kvm/lib/x86_64/processor.c
rename to tools/testing/selftests/kvm/lib/x86/processor.c
index 636b29ba8985..bd5a802fa7a5 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -1,7 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * tools/testing/selftests/kvm/lib/x86_64/processor.c
- *
  * Copyright (C) 2018, Google LLC.
  */
 
diff --git a/tools/testing/selftests/kvm/lib/x86_64/sev.c b/tools/testing/selftests/kvm/lib/x86/sev.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/x86_64/sev.c
rename to tools/testing/selftests/kvm/lib/x86/sev.c
diff --git a/tools/testing/selftests/kvm/lib/x86_64/svm.c b/tools/testing/selftests/kvm/lib/x86/svm.c
similarity index 99%
rename from tools/testing/selftests/kvm/lib/x86_64/svm.c
rename to tools/testing/selftests/kvm/lib/x86/svm.c
index 5495a92dfd5a..d239c2097391 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/svm.c
+++ b/tools/testing/selftests/kvm/lib/x86/svm.c
@@ -1,6 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * tools/testing/selftests/kvm/lib/x86_64/svm.c
  * Helpers used for nested SVM testing
  * Largely inspired from KVM unit test svm.c
  *
diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86/ucall.c
similarity index 100%
rename from tools/testing/selftests/kvm/lib/x86_64/ucall.c
rename to tools/testing/selftests/kvm/lib/x86/ucall.c
diff --git a/tools/testing/selftests/kvm/lib/x86_64/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
similarity index 99%
rename from tools/testing/selftests/kvm/lib/x86_64/vmx.c
rename to tools/testing/selftests/kvm/lib/x86/vmx.c
index d7ac122820bf..d4d1208dd023 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -1,7 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * tools/testing/selftests/kvm/lib/x86_64/vmx.c
- *
  * Copyright (C) 2018, Google LLC.
  */
 
diff --git a/tools/testing/selftests/kvm/s390x/cmma_test.c b/tools/testing/selftests/kvm/s390/cmma_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/cmma_test.c
rename to tools/testing/selftests/kvm/s390/cmma_test.c
diff --git a/tools/testing/selftests/kvm/s390x/config b/tools/testing/selftests/kvm/s390/config
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/config
rename to tools/testing/selftests/kvm/s390/config
diff --git a/tools/testing/selftests/kvm/s390x/cpumodel_subfuncs_test.c b/tools/testing/selftests/kvm/s390/cpumodel_subfuncs_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/cpumodel_subfuncs_test.c
rename to tools/testing/selftests/kvm/s390/cpumodel_subfuncs_test.c
diff --git a/tools/testing/selftests/kvm/s390x/debug_test.c b/tools/testing/selftests/kvm/s390/debug_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/debug_test.c
rename to tools/testing/selftests/kvm/s390/debug_test.c
diff --git a/tools/testing/selftests/kvm/s390x/memop.c b/tools/testing/selftests/kvm/s390/memop.c
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/memop.c
rename to tools/testing/selftests/kvm/s390/memop.c
diff --git a/tools/testing/selftests/kvm/s390x/resets.c b/tools/testing/selftests/kvm/s390/resets.c
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/resets.c
rename to tools/testing/selftests/kvm/s390/resets.c
diff --git a/tools/testing/selftests/kvm/s390x/shared_zeropage_test.c b/tools/testing/selftests/kvm/s390/shared_zeropage_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/shared_zeropage_test.c
rename to tools/testing/selftests/kvm/s390/shared_zeropage_test.c
diff --git a/tools/testing/selftests/kvm/s390x/sync_regs_test.c b/tools/testing/selftests/kvm/s390/sync_regs_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/sync_regs_test.c
rename to tools/testing/selftests/kvm/s390/sync_regs_test.c
diff --git a/tools/testing/selftests/kvm/s390x/tprot.c b/tools/testing/selftests/kvm/s390/tprot.c
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/tprot.c
rename to tools/testing/selftests/kvm/s390/tprot.c
diff --git a/tools/testing/selftests/kvm/s390x/ucontrol_test.c b/tools/testing/selftests/kvm/s390/ucontrol_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/s390x/ucontrol_test.c
rename to tools/testing/selftests/kvm/s390/ucontrol_test.c
diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c
index a8267628e9ed..86ee3385e860 100644
--- a/tools/testing/selftests/kvm/set_memory_region_test.c
+++ b/tools/testing/selftests/kvm/set_memory_region_test.c
@@ -17,9 +17,9 @@
 #include <processor.h>
 
 /*
- * s390x needs at least 1MB alignment, and the x86_64 MOVE/DELETE tests need a
- * 2MB sized and aligned region so that the initial region corresponds to
- * exactly one large page.
+ * s390 needs at least 1MB alignment, and the x86 MOVE/DELETE tests need a 2MB
+ * sized and aligned region so that the initial region corresponds to exactly
+ * one large page.
  */
 #define MEM_REGION_SIZE		0x200000
 
diff --git a/tools/testing/selftests/kvm/x86_64/amx_test.c b/tools/testing/selftests/kvm/x86/amx_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/amx_test.c
rename to tools/testing/selftests/kvm/x86/amx_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/apic_bus_clock_test.c b/tools/testing/selftests/kvm/x86/apic_bus_clock_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/apic_bus_clock_test.c
rename to tools/testing/selftests/kvm/x86/apic_bus_clock_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/cpuid_test.c b/tools/testing/selftests/kvm/x86/cpuid_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/cpuid_test.c
rename to tools/testing/selftests/kvm/x86/cpuid_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c b/tools/testing/selftests/kvm/x86/cr4_cpuid_sync_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c
rename to tools/testing/selftests/kvm/x86/cr4_cpuid_sync_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/debug_regs.c b/tools/testing/selftests/kvm/x86/debug_regs.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/debug_regs.c
rename to tools/testing/selftests/kvm/x86/debug_regs.c
diff --git a/tools/testing/selftests/kvm/x86_64/dirty_log_page_splitting_test.c b/tools/testing/selftests/kvm/x86/dirty_log_page_splitting_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/dirty_log_page_splitting_test.c
rename to tools/testing/selftests/kvm/x86/dirty_log_page_splitting_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/exit_on_emulation_failure_test.c b/tools/testing/selftests/kvm/x86/exit_on_emulation_failure_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/exit_on_emulation_failure_test.c
rename to tools/testing/selftests/kvm/x86/exit_on_emulation_failure_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/feature_msrs_test.c b/tools/testing/selftests/kvm/x86/feature_msrs_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/feature_msrs_test.c
rename to tools/testing/selftests/kvm/x86/feature_msrs_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c b/tools/testing/selftests/kvm/x86/fix_hypercall_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c
rename to tools/testing/selftests/kvm/x86/fix_hypercall_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/flds_emulation.h b/tools/testing/selftests/kvm/x86/flds_emulation.h
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/flds_emulation.h
rename to tools/testing/selftests/kvm/x86/flds_emulation.h
diff --git a/tools/testing/selftests/kvm/x86_64/hwcr_msr_test.c b/tools/testing/selftests/kvm/x86/hwcr_msr_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/hwcr_msr_test.c
rename to tools/testing/selftests/kvm/x86/hwcr_msr_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_clock.c b/tools/testing/selftests/kvm/x86/hyperv_clock.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/hyperv_clock.c
rename to tools/testing/selftests/kvm/x86/hyperv_clock.c
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c b/tools/testing/selftests/kvm/x86/hyperv_cpuid.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c
rename to tools/testing/selftests/kvm/x86/hyperv_cpuid.c
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c
rename to tools/testing/selftests/kvm/x86/hyperv_evmcs.c
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_extended_hypercalls.c b/tools/testing/selftests/kvm/x86/hyperv_extended_hypercalls.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/hyperv_extended_hypercalls.c
rename to tools/testing/selftests/kvm/x86/hyperv_extended_hypercalls.c
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_features.c b/tools/testing/selftests/kvm/x86/hyperv_features.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/hyperv_features.c
rename to tools/testing/selftests/kvm/x86/hyperv_features.c
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_ipi.c b/tools/testing/selftests/kvm/x86/hyperv_ipi.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/hyperv_ipi.c
rename to tools/testing/selftests/kvm/x86/hyperv_ipi.c
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c b/tools/testing/selftests/kvm/x86/hyperv_svm_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
rename to tools/testing/selftests/kvm/x86/hyperv_svm_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_tlb_flush.c b/tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/hyperv_tlb_flush.c
rename to tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c
diff --git a/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c b/tools/testing/selftests/kvm/x86/kvm_clock_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
rename to tools/testing/selftests/kvm/x86/kvm_clock_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c b/tools/testing/selftests/kvm/x86/kvm_pv_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/kvm_pv_test.c
rename to tools/testing/selftests/kvm/x86/kvm_pv_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/max_vcpuid_cap_test.c b/tools/testing/selftests/kvm/x86/max_vcpuid_cap_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/max_vcpuid_cap_test.c
rename to tools/testing/selftests/kvm/x86/max_vcpuid_cap_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c b/tools/testing/selftests/kvm/x86/monitor_mwait_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c
rename to tools/testing/selftests/kvm/x86/monitor_mwait_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/nested_exceptions_test.c b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/nested_exceptions_test.c
rename to tools/testing/selftests/kvm/x86/nested_exceptions_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c
rename to tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.sh
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh
rename to tools/testing/selftests/kvm/x86/nx_huge_pages_test.sh
diff --git a/tools/testing/selftests/kvm/x86_64/platform_info_test.c b/tools/testing/selftests/kvm/x86/platform_info_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/platform_info_test.c
rename to tools/testing/selftests/kvm/x86/platform_info_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/pmu_counters_test.c b/tools/testing/selftests/kvm/x86/pmu_counters_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/pmu_counters_test.c
rename to tools/testing/selftests/kvm/x86/pmu_counters_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86/pmu_event_filter_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
rename to tools/testing/selftests/kvm/x86/pmu_event_filter_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/private_mem_conversions_test.c b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/private_mem_conversions_test.c
rename to tools/testing/selftests/kvm/x86/private_mem_conversions_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/private_mem_kvm_exits_test.c b/tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/private_mem_kvm_exits_test.c
rename to tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/recalc_apic_map_test.c b/tools/testing/selftests/kvm/x86/recalc_apic_map_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/recalc_apic_map_test.c
rename to tools/testing/selftests/kvm/x86/recalc_apic_map_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/set_boot_cpu_id.c b/tools/testing/selftests/kvm/x86/set_boot_cpu_id.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/set_boot_cpu_id.c
rename to tools/testing/selftests/kvm/x86/set_boot_cpu_id.c
diff --git a/tools/testing/selftests/kvm/x86_64/set_sregs_test.c b/tools/testing/selftests/kvm/x86/set_sregs_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/set_sregs_test.c
rename to tools/testing/selftests/kvm/x86/set_sregs_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/sev_init2_tests.c b/tools/testing/selftests/kvm/x86/sev_init2_tests.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/sev_init2_tests.c
rename to tools/testing/selftests/kvm/x86/sev_init2_tests.c
diff --git a/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c b/tools/testing/selftests/kvm/x86/sev_migrate_tests.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c
rename to tools/testing/selftests/kvm/x86/sev_migrate_tests.c
diff --git a/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
rename to tools/testing/selftests/kvm/x86/sev_smoke_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c b/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c
rename to tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/smm_test.c b/tools/testing/selftests/kvm/x86/smm_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/smm_test.c
rename to tools/testing/selftests/kvm/x86/smm_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/state_test.c
rename to tools/testing/selftests/kvm/x86/state_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c b/tools/testing/selftests/kvm/x86/svm_int_ctl_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c
rename to tools/testing/selftests/kvm/x86/svm_int_ctl_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c b/tools/testing/selftests/kvm/x86/svm_nested_shutdown_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c
rename to tools/testing/selftests/kvm/x86/svm_nested_shutdown_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c b/tools/testing/selftests/kvm/x86/svm_nested_soft_inject_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c
rename to tools/testing/selftests/kvm/x86/svm_nested_soft_inject_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/svm_vmcall_test.c b/tools/testing/selftests/kvm/x86/svm_vmcall_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/svm_vmcall_test.c
rename to tools/testing/selftests/kvm/x86/svm_vmcall_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/sync_regs_test.c b/tools/testing/selftests/kvm/x86/sync_regs_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/sync_regs_test.c
rename to tools/testing/selftests/kvm/x86/sync_regs_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/triple_fault_event_test.c b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/triple_fault_event_test.c
rename to tools/testing/selftests/kvm/x86/triple_fault_event_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/tsc_msrs_test.c b/tools/testing/selftests/kvm/x86/tsc_msrs_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/tsc_msrs_test.c
rename to tools/testing/selftests/kvm/x86/tsc_msrs_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/tsc_scaling_sync.c b/tools/testing/selftests/kvm/x86/tsc_scaling_sync.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/tsc_scaling_sync.c
rename to tools/testing/selftests/kvm/x86/tsc_scaling_sync.c
diff --git a/tools/testing/selftests/kvm/x86_64/ucna_injection_test.c b/tools/testing/selftests/kvm/x86/ucna_injection_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/ucna_injection_test.c
rename to tools/testing/selftests/kvm/x86/ucna_injection_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/userspace_io_test.c b/tools/testing/selftests/kvm/x86/userspace_io_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/userspace_io_test.c
rename to tools/testing/selftests/kvm/x86/userspace_io_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c b/tools/testing/selftests/kvm/x86/userspace_msr_exit_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c
rename to tools/testing/selftests/kvm/x86/userspace_msr_exit_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_apic_access_test.c b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_apic_access_test.c
rename to tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c b/tools/testing/selftests/kvm/x86/vmx_close_while_nested_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c
rename to tools/testing/selftests/kvm/x86/vmx_close_while_nested_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c b/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c
rename to tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c b/tools/testing/selftests/kvm/x86/vmx_exception_with_invalid_guest_state.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c
rename to tools/testing/selftests/kvm/x86/vmx_exception_with_invalid_guest_state.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_invalid_nested_guest_state.c b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_invalid_nested_guest_state.c
rename to tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_msrs_test.c b/tools/testing/selftests/kvm/x86/vmx_msrs_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_msrs_test.c
rename to tools/testing/selftests/kvm/x86/vmx_msrs_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_nested_tsc_scaling_test.c b/tools/testing/selftests/kvm/x86/vmx_nested_tsc_scaling_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_nested_tsc_scaling_test.c
rename to tools/testing/selftests/kvm/x86/vmx_nested_tsc_scaling_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c b/tools/testing/selftests/kvm/x86/vmx_pmu_caps_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c
rename to tools/testing/selftests/kvm/x86/vmx_pmu_caps_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_preemption_timer_test.c b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_preemption_timer_test.c
rename to tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c
rename to tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c
rename to tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c
rename to tools/testing/selftests/kvm/x86/xapic_ipi_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/xapic_state_test.c b/tools/testing/selftests/kvm/x86/xapic_state_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/xapic_state_test.c
rename to tools/testing/selftests/kvm/x86/xapic_state_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c b/tools/testing/selftests/kvm/x86/xcr0_cpuid_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c
rename to tools/testing/selftests/kvm/x86/xcr0_cpuid_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c b/tools/testing/selftests/kvm/x86/xen_shinfo_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c
rename to tools/testing/selftests/kvm/x86/xen_shinfo_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/xen_vmcall_test.c b/tools/testing/selftests/kvm/x86/xen_vmcall_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/xen_vmcall_test.c
rename to tools/testing/selftests/kvm/x86/xen_vmcall_test.c
diff --git a/tools/testing/selftests/kvm/x86_64/xss_msr_test.c b/tools/testing/selftests/kvm/x86/xss_msr_test.c
similarity index 100%
rename from tools/testing/selftests/kvm/x86_64/xss_msr_test.c
rename to tools/testing/selftests/kvm/x86/xss_msr_test.c
-- 
2.47.0.338.g60cca15819-goog



From seanjc at google.com  Wed Nov 27 16:55:47 2024
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 27 Nov 2024 16:55:47 -0800
Subject: [PATCH v4 16/16] KVM: selftests: Override ARCH for x86_64 instead of
 using ARCH_DIR
In-Reply-To: <20241128005547.4077116-1-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
Message-ID: <20241128005547.4077116-17-seanjc@google.com>

Now that KVM selftests uses the kernel's canonical arch paths, directly
override ARCH to 'x86' when targeting x86_64 instead of defining ARCH_DIR
to redirect to appropriate paths.  ARCH_DIR was originally added to deal
with KVM selftests using the target triple ARCH for directories, e.g.
s390x and aarch64; keeping it around just to deal with the one-off alias
from x86_64=>x86 is unnecessary and confusing.

Note, even when selftests are built from the top-level Makefile, ARCH is
scoped to KVM's makefiles, i.e. overriding ARCH won't trip up some other
selftests that (somehow) expects x86_64 and can't work with x86.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/Makefile     |  4 +---
 tools/testing/selftests/kvm/Makefile.kvm | 20 ++++++++++----------
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 9bc2eba1af1c..20af35a91d6f 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -6,9 +6,7 @@ ARCH            ?= $(SUBARCH)
 ifeq ($(ARCH),$(filter $(ARCH),arm64 s390 riscv x86 x86_64))
 # Top-level selftests allows ARCH=x86_64 :-(
 ifeq ($(ARCH),x86_64)
-	ARCH_DIR := x86
-else
-	ARCH_DIR := $(ARCH)
+	ARCH := x86
 endif
 include Makefile.kvm
 else
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 9888dd6bb483..4277b983cace 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -207,10 +207,10 @@ TEST_GEN_PROGS_riscv += steal_time
 SPLIT_TESTS += arch_timer
 SPLIT_TESTS += get-reg-list
 
-TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
-TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
-TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH_DIR))
-LIBKVM += $(LIBKVM_$(ARCH_DIR))
+TEST_PROGS += $(TEST_PROGS_$(ARCH))
+TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH))
+TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH))
+LIBKVM += $(LIBKVM_$(ARCH))
 
 OVERRIDE_TARGETS = 1
 
@@ -222,14 +222,14 @@ include ../lib.mk
 INSTALL_HDR_PATH = $(top_srcdir)/usr
 LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
 LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
-LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH_DIR)/include
+LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
 CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
 	-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
 	-fno-builtin-memcmp -fno-builtin-memcpy \
 	-fno-builtin-memset -fno-builtin-strnlen \
 	-fno-stack-protector -fno-PIE -fno-strict-aliasing \
 	-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
-	-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH_DIR) \
+	-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH) \
 	-I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
 ifeq ($(ARCH),s390)
 	CFLAGS += -march=z10
@@ -273,7 +273,7 @@ LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S))
 LIBKVM_STRING_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING))
 LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ)
 SPLIT_TEST_GEN_PROGS := $(patsubst %, $(OUTPUT)/%, $(SPLIT_TESTS))
-SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH_DIR)/%.o, $(SPLIT_TESTS))
+SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH)/%.o, $(SPLIT_TESTS))
 
 TEST_GEN_OBJ = $(patsubst %, %.o, $(TEST_GEN_PROGS))
 TEST_GEN_OBJ += $(patsubst %, %.o, $(TEST_GEN_PROGS_EXTENDED))
@@ -282,7 +282,7 @@ TEST_DEP_FILES += $(patsubst %.o, %.d, $(LIBKVM_OBJS))
 TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TEST_GEN_OBJ))
 -include $(TEST_DEP_FILES)
 
-$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
+$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
 
 $(filter-out $(SPLIT_TEST_GEN_PROGS), $(TEST_GEN_PROGS)) \
 $(TEST_GEN_PROGS_EXTENDED): %: %.o
@@ -290,9 +290,9 @@ $(TEST_GEN_PROGS_EXTENDED): %: %.o
 $(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
 
-$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH_DIR)/%.o
+$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH)/%.o
 	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
-$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH_DIR)/%.o: $(ARCH_DIR)/%.c
+$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH)/%.o: $(ARCH)/%.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
 
 EXTRA_CLEAN += $(GEN_HDRS) \
-- 
2.47.0.338.g60cca15819-goog



From zhangkai at iscas.ac.cn  Wed Nov 27 17:01:52 2024
From: zhangkai at iscas.ac.cn (laokz)
Date: Thu, 28 Nov 2024 09:01:52 +0800
Subject: [PATCH v2] riscv: module: use a plain variable for list_head
 instead of a pointer
In-Reply-To: <20241127142519.3038691-1-cleger@rivosinc.com>
References: <20241127142519.3038691-1-cleger@rivosinc.com>
Message-ID: <980b98978ab4ee912b37cb101ad43bce20b56dcb.camel@iscas.ac.cn>

On Wed, 2024-11-27 at 15:25 +0100, Cl?ment L?ger wrote:
> rel_head's list_head member, rel_entry, doesn't need to be allocated,
> its storage can just be part of the allocated rel_head. Remove the

Oh my poor English. OK, it's more better than just add the lost kfree.

> pointer which allows to get rid of the allocation as well as an
> existing
> memory leak found by Kai Zang using kmemleak.
                            ^
                           Zhang

BTW. Doesn't it need a fixes tag like what you suggested? (The bug
might come from 6.7)

> 
> Reported-by: Kai Zhang <zhangkai at iscas.ac.cn>
> Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> ---
> 
> V2:
> ?- Add Kai Reported-by
> ?- Reword the commit description (Andrew)
> 
> ---
> ?arch/riscv/kernel/module.c | 18 ++++--------------
> ?1 file changed, 4 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
> index 1cd461f3d872..47d0ebeec93c 100644
> --- a/arch/riscv/kernel/module.c
> +++ b/arch/riscv/kernel/module.c
> @@ -23,7 +23,7 @@ struct used_bucket {
> ?
> ?struct relocation_head {
> ????????struct hlist_node node;
> -???????struct list_head *rel_entry;
> +???????struct list_head rel_entry;
> ????????void *location;
> ?};
> ?
> @@ -634,7 +634,7 @@ process_accumulated_relocations(struct module
> *me,
> ????????????????????????location = rel_head_iter->location;
> ????????????????????????list_for_each_entry_safe(rel_entry_iter,
> ???????????????????????????????????????????????? rel_entry_iter_tmp,
> -??????????????????????????????????????????????? rel_head_iter-
> >rel_entry,
> +??????????????????????????????????????????????? &rel_head_iter-
> >rel_entry,
> ???????????????????????????????????????????????? head) {
> ????????????????????????????????curr_type = rel_entry_iter->type;
> ????????????????????????????????reloc_handlers[curr_type].reloc_handl
> er(
> @@ -704,16 +704,7 @@ static int add_relocation_to_accumulate(struct
> module *me, int type,
> ????????????????????????return -ENOMEM;
> ????????????????}
> ?
> -???????????????rel_head->rel_entry =
> -???????????????????????kmalloc(sizeof(struct list_head),
> GFP_KERNEL);
> -
> -???????????????if (!rel_head->rel_entry) {
> -???????????????????????kfree(entry);
> -???????????????????????kfree(rel_head);
> -???????????????????????return -ENOMEM;
> -???????????????}
> -
> -???????????????INIT_LIST_HEAD(rel_head->rel_entry);
> +???????????????INIT_LIST_HEAD(&rel_head->rel_entry);
> ????????????????rel_head->location = location;
> ????????????????INIT_HLIST_NODE(&rel_head->node);
> ????????????????if (!current_head->first) {
> @@ -722,7 +713,6 @@ static int add_relocation_to_accumulate(struct
> module *me, int type,
> ?
> ????????????????????????if (!bucket) {
> ????????????????????????????????kfree(entry);
> -???????????????????????????????kfree(rel_head->rel_entry);
> ????????????????????????????????kfree(rel_head);
> ????????????????????????????????return -ENOMEM;
> ????????????????????????}
> @@ -735,7 +725,7 @@ static int add_relocation_to_accumulate(struct
> module *me, int type,
> ????????}
> ?
> ????????/* Add relocation to head of discovered rel_head */
> -???????list_add_tail(&entry->head, rel_head->rel_entry);
> +???????list_add_tail(&entry->head, &rel_head->rel_entry);
> ?
> ????????return 0;
> ?}


From minda.chen at starfivetech.com  Wed Nov 27 17:31:04 2024
From: minda.chen at starfivetech.com (Minda Chen)
Date: Thu, 28 Nov 2024 01:31:04 +0000
Subject: [PATCH v5 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable
 usb0 host function
In-Reply-To: <CAJM55Z_Cy2aAfWY-6csKBuv3AJ44h4fCCvJ0ZSbLOYcKw6g=bA@mail.gmail.com>
References: <20241126075740.17419-1-e@freeshell.de>
 <CAJM55Z9wWCaS+FxZ=Gg_RfXXafNEJZC1zHZoPWQ2Y9QYDf9OyA@mail.gmail.com>
 <eb06c8e0-ebda-47b9-94f6-6e6eca21097d@freeshell.de>
 <CAJM55Z_Cy2aAfWY-6csKBuv3AJ44h4fCCvJ0ZSbLOYcKw6g=bA@mail.gmail.com>
Message-ID: <SHXPR01MB086308813C0B311845FDA2C7E629A@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>



> 
> E Shattow wrote:
> > Hi Emil, thanks for taking time to review!
> >
> > Added CC: Minda Chen, Hal Feng
> >
> > Please Minda and Hal can you follow-up on Emil's comments as well?
> >
> > On 11/27/24 03:00, Emil Renner Berthing wrote:
> > > E Shattow wrote:
> > >> Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host
> > >> mode and connect vbus pinctrl.
> > >>
> > >> This functionality depends on setting the USB over-current register
> > >> to disable at bootloader phase, for example U-Boot:
> > >> https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.426
> > >> 8-6-minda.chen at starfivetech.com/
> > > Hi E,
> > >
> > > Ideally the JH7110 pinctrl driver would be updated, so Linux can do
> > > this itself and doesn't need to rely on u-boot doing it. I already asked for this
> here:
> > >
> > >
> https://lore.kernel.org/all/CAJM55Z-+Cxdebcn4MLXfQdOVhx4c2SQ+zMH8cjn
> > > -Yq35xO8g0A at mail.gmail.com/
> >
> > Yes, I agree, and Linux is not the only consumer of devicetree. I
> > would like USB function to work for users of Linux and U-Boot on these
> > boards by copying what the vendor Board Support Package does what is
> > shipped with the products. If it is more in-depth than this I will
> > defer to Hal or Minda.
> >
> >
> > For some wider context, upstream U-Boot is about to adopt the
> > dt-rebasing via Hal's OF_UPSTREAM for JH7110 boards series and then
> > also there is a patch set from Minda Chen to add the on-chip JH7110
> > USB support to U-Boot, and so then and there it will depend on these
> > dts changes. If you have Milk-V Mars then already there are three of
> > four USB-A receptacle ports which are functional on PCIe-connected
> > VL805 USB chipset.
> >
> > >
> > >> If the over-current register is not prepared for us then the result
> > >> is no change in functional outcome with this patch applied; there
> > >> is an error visible to the user and this additional usb
> > >> configuration fails (same as it is now). On Milk-V Mars with four
> > >> USB-A ports this applies to one of the ports and the remaining three
> VL805-connected ports via PCIe are not changed.
> > > Thanks for the patches. I don't quite understand when you write "no
> > > change in functional outcome with this patch applied". The USB-C
> > > port is already configured as a peripheral, and I just tried setting
> > > up an ethernet gadget on my VF2 running 6.12 and that works quite
> > > well. Does it not work on the Milk-V Mars board? If it does then these
> patches would break that functionality.
> > >
> > > Here is the script I used for that:
> > > https://paste.c-net.org/BravoLonely
> > >
> > > At the very least you'll need to explain in the commit message
> > > itself why changing the USB-C port from peripheral mode to host mode
> > > is OK. But ideally maybe you could make it work in OTG mode, so
> > > userspace can choose how they want to use the port. The same goes for the
> PINE64 board too.
> > >
> > > /Emil
> >
> > USB-C port on Mars is not wired for data here, that is only true for
> > VisionFive2. If the user wants to use their USB-A receptacle as OTG
> > port I will not object to a future improvement, but here we want the
> > basic expectations of users covered that they should have four working
> > USB-A receptacle ports in U-Boot (and possibly in Linux, depending on
> > the overcurrent register wherever it is set). This is what I am
> > meaning, there may be somebody using a male-male USB-A USB-A cable for
> > OTG but more likely is that people just want to plug in USB
> > peripherals to host ports and use their mouse / keyboard / flash memory, I
> think.
> 
> You're right, sorry. I'm so used to the JH7110 boards being similar, but this is
> actually one of the few differences between the Mars and VF2 that was not
> caught when the Mars dts was first upstreamed.
> 
> Yes, with 4 similar USB-A ports you'd definitely expect all of them to work in host
> mode. With an explanation like the above in the commit message I (now) think
> your changes makes sense.
> 
> Thanks!
> /Emil
> 
Thanks. E Shadow

The USB and PCIe0 setting in some JH7110 boards.
                 PCIe0                                      cadence USB controller
VF2:       connect with VL805 USB3.0 ( 4 USB 3.0 type A ports)       (USB 2.0)Type C port(role: peripheral)
Milkv mars  connect with VL805 USB3.0 ( 3 USB 3.0 type A ports)       (USB 2.0)1 Type A port (role:host)
Milkv cm    PCIe slot											(USB 2.0)micro B port (role:host)
Star64       disabled?pcie PHY0 connect to cadence USB?         1 usb 3.0 port + USB 2.0 hub (role:host)

H E Shadow
I see you also add star64 USB configuration. I hope also add this to star64 board dts base on
V6.13-rc1. Thanks.

&pcie0 {
	status = "disabled";
};

&pciephy0 {
	starfive,sys-syscon = <&sys_syscon 0x18>;
	starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>;
	status = "okay";
};

&usb0 {
	pinctrl-names = "default";
	pinctrl-0 = <&usb_pins>;
	dr_mode = "host";
	status = "okay";
};

&usb_cdns3 {
	phys = <&usbphy0>, <&pciephy0>;
	phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy";
};

> >
> >
> > There is no USB-C port on Star64.
> >
> > >
> > >> Changes since v4:
> > >>   - Rebase on latest master
> > >>
> > >> Changes since v3:
> > >>   - Rebase on linux-next/master
> > >>   - use tabs for code indent
> > >>
> > >> Changes since v2:
> > >>   - Rebase on 6.12
> > >>
> > >> E Shattow (1):
> > >>    riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host
> > >> function
> > >>
> > >>   .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18
> +++++++++++++++++-
> > >>   1 file changed, 17 insertions(+), 1 deletion(-)
> > >>
> > >> --
> > >> 2.45.2
> > >>
> > Thanks again Emil.? -E
> >

From zhouquan at iscas.ac.cn  Wed Nov 27 19:20:53 2024
From: zhouquan at iscas.ac.cn (zhouquan at iscas.ac.cn)
Date: Thu, 28 Nov 2024 11:20:53 +0800
Subject: [PATCH 0/4] RISC-V: KVM: Allow Svvptc/Zabha/Ziccrse exts for guests
Message-ID: <cover.1732762121.git.zhouquan@iscas.ac.cn>

From: Quan Zhou <zhouquan at iscas.ac.cn>

Advertise Svvptc/Zabha/Ziccrse extensions to KVM guest
when underlying host supports it.

Quan Zhou (4):
  RISC-V: KVM: Allow Svvptc extension for Guest/VM
  RISC-V: KVM: Allow Zabha extension for Guest/VM
  RISC-V: KVM: Allow Ziccrse extension for Guest/VM
  KVM: riscv: selftests: Add Svvptc/Zabha/Ziccrse exts to get-reg-list
    test

 arch/riscv/include/uapi/asm/kvm.h                |  3 +++
 arch/riscv/kvm/vcpu_onereg.c                     |  6 ++++++
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 12 ++++++++++++
 3 files changed, 21 insertions(+)

-- 
2.34.1



From zhouquan at iscas.ac.cn  Wed Nov 27 19:21:15 2024
From: zhouquan at iscas.ac.cn (zhouquan at iscas.ac.cn)
Date: Thu, 28 Nov 2024 11:21:15 +0800
Subject: [PATCH 1/4] RISC-V: KVM: Allow Svvptc extension for Guest/VM
In-Reply-To: <cover.1732762121.git.zhouquan@iscas.ac.cn>
References: <cover.1732762121.git.zhouquan@iscas.ac.cn>
Message-ID: <35d9c91a69ebcb81b40dc4f7f51e290c3d94b2d9.1732762121.git.zhouquan@iscas.ac.cn>

From: Quan Zhou <zhouquan at iscas.ac.cn>

Extend the KVM ISA extension ONE_REG interface to allow KVM user space
to detect and enable Svvptc extension for Guest/VM.

Signed-off-by: Quan Zhou <zhouquan at iscas.ac.cn>
---
 arch/riscv/include/uapi/asm/kvm.h | 1 +
 arch/riscv/kvm/vcpu_onereg.c      | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 4f24201376b1..9db33f52f56e 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -177,6 +177,7 @@ enum KVM_RISCV_ISA_EXT_ID {
 	KVM_RISCV_ISA_EXT_ZAWRS,
 	KVM_RISCV_ISA_EXT_SMNPM,
 	KVM_RISCV_ISA_EXT_SSNPM,
+	KVM_RISCV_ISA_EXT_SVVPTC,
 	KVM_RISCV_ISA_EXT_MAX,
 };
 
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 5b68490ad9b7..67965feb5b74 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -41,6 +41,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
 	KVM_ISA_EXT_ARR(SSNPM),
 	KVM_ISA_EXT_ARR(SSTC),
 	KVM_ISA_EXT_ARR(SVINVAL),
+	KVM_ISA_EXT_ARR(SVVPTC),
 	KVM_ISA_EXT_ARR(SVNAPOT),
 	KVM_ISA_EXT_ARR(SVPBMT),
 	KVM_ISA_EXT_ARR(ZACAS),
@@ -135,6 +136,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
 	case KVM_RISCV_ISA_EXT_SSNPM:
 	case KVM_RISCV_ISA_EXT_SSTC:
 	case KVM_RISCV_ISA_EXT_SVINVAL:
+	case KVM_RISCV_ISA_EXT_SVVPTC:
 	case KVM_RISCV_ISA_EXT_SVNAPOT:
 	case KVM_RISCV_ISA_EXT_ZACAS:
 	case KVM_RISCV_ISA_EXT_ZAWRS:
-- 
2.34.1



From zhouquan at iscas.ac.cn  Wed Nov 27 19:21:26 2024
From: zhouquan at iscas.ac.cn (zhouquan at iscas.ac.cn)
Date: Thu, 28 Nov 2024 11:21:26 +0800
Subject: [PATCH 2/4] RISC-V: KVM: Allow Zabha extension for Guest/VM
In-Reply-To: <cover.1732762121.git.zhouquan@iscas.ac.cn>
References: <cover.1732762121.git.zhouquan@iscas.ac.cn>
Message-ID: <ea2918b299348aca0f5a45630b7b7c9889f47fa6.1732762121.git.zhouquan@iscas.ac.cn>

From: Quan Zhou <zhouquan at iscas.ac.cn>

Extend the KVM ISA extension ONE_REG interface to allow KVM user space
to detect and enable Zabha extension for Guest/VM.

Signed-off-by: Quan Zhou <zhouquan at iscas.ac.cn>
---
 arch/riscv/include/uapi/asm/kvm.h | 1 +
 arch/riscv/kvm/vcpu_onereg.c      | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 9db33f52f56e..340618131249 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -178,6 +178,7 @@ enum KVM_RISCV_ISA_EXT_ID {
 	KVM_RISCV_ISA_EXT_SMNPM,
 	KVM_RISCV_ISA_EXT_SSNPM,
 	KVM_RISCV_ISA_EXT_SVVPTC,
+	KVM_RISCV_ISA_EXT_ZABHA,
 	KVM_RISCV_ISA_EXT_MAX,
 };
 
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 67965feb5b74..9a30a98f30bc 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -44,6 +44,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
 	KVM_ISA_EXT_ARR(SVVPTC),
 	KVM_ISA_EXT_ARR(SVNAPOT),
 	KVM_ISA_EXT_ARR(SVPBMT),
+	KVM_ISA_EXT_ARR(ZABHA),
 	KVM_ISA_EXT_ARR(ZACAS),
 	KVM_ISA_EXT_ARR(ZAWRS),
 	KVM_ISA_EXT_ARR(ZBA),
@@ -138,6 +139,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
 	case KVM_RISCV_ISA_EXT_SVINVAL:
 	case KVM_RISCV_ISA_EXT_SVVPTC:
 	case KVM_RISCV_ISA_EXT_SVNAPOT:
+	case KVM_RISCV_ISA_EXT_ZABHA:
 	case KVM_RISCV_ISA_EXT_ZACAS:
 	case KVM_RISCV_ISA_EXT_ZAWRS:
 	case KVM_RISCV_ISA_EXT_ZBA:
-- 
2.34.1



From zhouquan at iscas.ac.cn  Wed Nov 27 19:22:07 2024
From: zhouquan at iscas.ac.cn (zhouquan at iscas.ac.cn)
Date: Thu, 28 Nov 2024 11:22:07 +0800
Subject: [PATCH 3/4] RISC-V: KVM: Allow Ziccrse extension for Guest/VM
In-Reply-To: <cover.1732762121.git.zhouquan@iscas.ac.cn>
References: <cover.1732762121.git.zhouquan@iscas.ac.cn>
Message-ID: <77198ab759eb01ca490f4c2199910e778b57d372.1732762121.git.zhouquan@iscas.ac.cn>

From: Quan Zhou <zhouquan at iscas.ac.cn>

Extend the KVM ISA extension ONE_REG interface to allow KVM user space
to detect and enable Ziccrse extension for Guest/VM.

Signed-off-by: Quan Zhou <zhouquan at iscas.ac.cn>
---
 arch/riscv/include/uapi/asm/kvm.h | 1 +
 arch/riscv/kvm/vcpu_onereg.c      | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 340618131249..f7afb4267148 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -179,6 +179,7 @@ enum KVM_RISCV_ISA_EXT_ID {
 	KVM_RISCV_ISA_EXT_SSNPM,
 	KVM_RISCV_ISA_EXT_SVVPTC,
 	KVM_RISCV_ISA_EXT_ZABHA,
+	KVM_RISCV_ISA_EXT_ZICCRSE,
 	KVM_RISCV_ISA_EXT_MAX,
 };
 
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 9a30a98f30bc..ed8e17da1536 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -64,6 +64,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
 	KVM_ISA_EXT_ARR(ZFHMIN),
 	KVM_ISA_EXT_ARR(ZICBOM),
 	KVM_ISA_EXT_ARR(ZICBOZ),
+	KVM_ISA_EXT_ARR(ZICCRSE),
 	KVM_ISA_EXT_ARR(ZICNTR),
 	KVM_ISA_EXT_ARR(ZICOND),
 	KVM_ISA_EXT_ARR(ZICSR),
@@ -157,6 +158,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
 	case KVM_RISCV_ISA_EXT_ZFA:
 	case KVM_RISCV_ISA_EXT_ZFH:
 	case KVM_RISCV_ISA_EXT_ZFHMIN:
+	case KVM_RISCV_ISA_EXT_ZICCRSE:
 	case KVM_RISCV_ISA_EXT_ZICNTR:
 	case KVM_RISCV_ISA_EXT_ZICOND:
 	case KVM_RISCV_ISA_EXT_ZICSR:
-- 
2.34.1



From zhouquan at iscas.ac.cn  Wed Nov 27 19:22:14 2024
From: zhouquan at iscas.ac.cn (zhouquan at iscas.ac.cn)
Date: Thu, 28 Nov 2024 11:22:14 +0800
Subject: [PATCH 4/4] KVM: riscv: selftests: Add Svvptc/Zabha/Ziccrse exts to get-reg-list test
In-Reply-To: <cover.1732762121.git.zhouquan@iscas.ac.cn>
References: <cover.1732762121.git.zhouquan@iscas.ac.cn>
Message-ID: <21d3a5314a9cd6ac5b3aa445060ae2679a44c792.1732762121.git.zhouquan@iscas.ac.cn>

From: Quan Zhou <zhouquan at iscas.ac.cn>

The KVM RISC-V allows Svvptc/Zabha/Ziccrse extensions for Guest/VM
so add them to get-reg-list test.

Signed-off-by: Quan Zhou <zhouquan at iscas.ac.cn>
---
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index 54ab484d0000..a697db1ff411 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -48,8 +48,10 @@ bool filter_reg(__u64 reg)
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SSNPM:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SSTC:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVINVAL:
+	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVVPTC:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVNAPOT:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVPBMT:
+	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZABHA:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZACAS:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZAWRS:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZBA:
@@ -69,6 +71,7 @@ bool filter_reg(__u64 reg)
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZFHMIN:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICBOM:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICBOZ:
+	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICCRSE:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICNTR:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICOND:
 	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICSR:
@@ -423,8 +426,10 @@ static const char *isa_ext_single_id_to_str(__u64 reg_off)
 		KVM_ISA_EXT_ARR(SSNPM),
 		KVM_ISA_EXT_ARR(SSTC),
 		KVM_ISA_EXT_ARR(SVINVAL),
+		KVM_ISA_EXT_ARR(SVVPTC),
 		KVM_ISA_EXT_ARR(SVNAPOT),
 		KVM_ISA_EXT_ARR(SVPBMT),
+		KVM_ISA_EXT_ARR(ZABHA),
 		KVM_ISA_EXT_ARR(ZACAS),
 		KVM_ISA_EXT_ARR(ZAWRS),
 		KVM_ISA_EXT_ARR(ZBA),
@@ -444,6 +449,7 @@ static const char *isa_ext_single_id_to_str(__u64 reg_off)
 		KVM_ISA_EXT_ARR(ZFHMIN),
 		KVM_ISA_EXT_ARR(ZICBOM),
 		KVM_ISA_EXT_ARR(ZICBOZ),
+		KVM_ISA_EXT_ARR(ZICCRSE),
 		KVM_ISA_EXT_ARR(ZICNTR),
 		KVM_ISA_EXT_ARR(ZICOND),
 		KVM_ISA_EXT_ARR(ZICSR),
@@ -956,8 +962,10 @@ KVM_ISA_EXT_SIMPLE_CONFIG(sscofpmf, SSCOFPMF);
 KVM_ISA_EXT_SIMPLE_CONFIG(ssnpm, SSNPM);
 KVM_ISA_EXT_SIMPLE_CONFIG(sstc, SSTC);
 KVM_ISA_EXT_SIMPLE_CONFIG(svinval, SVINVAL);
+KVM_ISA_EXT_SIMPLE_CONFIG(svvptc, SVVPTC);
 KVM_ISA_EXT_SIMPLE_CONFIG(svnapot, SVNAPOT);
 KVM_ISA_EXT_SIMPLE_CONFIG(svpbmt, SVPBMT);
+KVM_ISA_EXT_SIMPLE_CONFIG(zabha, ZABHA);
 KVM_ISA_EXT_SIMPLE_CONFIG(zacas, ZACAS);
 KVM_ISA_EXT_SIMPLE_CONFIG(zawrs, ZAWRS);
 KVM_ISA_EXT_SIMPLE_CONFIG(zba, ZBA);
@@ -977,6 +985,7 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zfh, ZFH);
 KVM_ISA_EXT_SIMPLE_CONFIG(zfhmin, ZFHMIN);
 KVM_ISA_EXT_SUBLIST_CONFIG(zicbom, ZICBOM);
 KVM_ISA_EXT_SUBLIST_CONFIG(zicboz, ZICBOZ);
+KVM_ISA_EXT_SIMPLE_CONFIG(ziccrse, ZICCRSE);
 KVM_ISA_EXT_SIMPLE_CONFIG(zicntr, ZICNTR);
 KVM_ISA_EXT_SIMPLE_CONFIG(zicond, ZICOND);
 KVM_ISA_EXT_SIMPLE_CONFIG(zicsr, ZICSR);
@@ -1021,8 +1030,10 @@ struct vcpu_reg_list *vcpu_configs[] = {
 	&config_ssnpm,
 	&config_sstc,
 	&config_svinval,
+	&config_svvptc,
 	&config_svnapot,
 	&config_svpbmt,
+	&config_zabha,
 	&config_zacas,
 	&config_zawrs,
 	&config_zba,
@@ -1042,6 +1053,7 @@ struct vcpu_reg_list *vcpu_configs[] = {
 	&config_zfhmin,
 	&config_zicbom,
 	&config_zicboz,
+	&config_ziccrse,
 	&config_zicntr,
 	&config_zicond,
 	&config_zicsr,
-- 
2.34.1



From lkp at intel.com  Wed Nov 27 22:50:05 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 28 Nov 2024 14:50:05 +0800
Subject: [PATCH v3 3/3] clk: spacemit: Add clock support for Spacemit K1
 SoC
In-Reply-To: <20241126143125.9980-7-heylenay@4d2.org>
References: <20241126143125.9980-7-heylenay@4d2.org>
Message-ID: <202411281451.lC2FKL6C-lkp@intel.com>

Hi Haylen,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 2d5404caa8c7bb5c4e0435f94b28834ae5456623]

url:    https://github.com/intel-lab-lkp/linux/commits/Haylen-Chu/dt-bindings-clock-spacemit-Add-clock-controllers-of-Spacemit-K1-SoC/20241128-101248
base:   2d5404caa8c7bb5c4e0435f94b28834ae5456623
patch link:    https://lore.kernel.org/r/20241126143125.9980-7-heylenay%404d2.org
patch subject: [PATCH v3 3/3] clk: spacemit: Add clock support for Spacemit K1 SoC
config: arm-randconfig-001-20241128 (https://download.01.org/0day-ci/archive/20241128/202411281451.lC2FKL6C-lkp at intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 592c0fe55f6d9a811028b5f3507be91458ab2713)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241128/202411281451.lC2FKL6C-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411281451.lC2FKL6C-lkp at intel.com/

All warnings (new ones prefixed by >>):

   drivers/clk/spacemit/ccu_pll.c:128:16: warning: variable 'old_rate' set but not used [-Wunused-but-set-variable]
     128 |         unsigned long old_rate;
         |                       ^
>> drivers/clk/spacemit/ccu_pll.c:152:2: warning: variable 'val' is uninitialized when used here [-Wuninitialized]
     152 |         val |= entry->reg5 << PLL_SWCR1_REG5_OFF;
         |         ^~~
   drivers/clk/spacemit/ccu_pll.c:130:15: note: initialize the variable 'val' to silence this warning
     130 |         u32 mask, val;
         |                      ^
         |                       = 0
>> drivers/clk/spacemit/ccu_pll.c:141:14: warning: variable 'entry' is used uninitialized whenever 'for' loop exits because its condition is false [-Wsometimes-uninitialized]
     141 |         for (i = 0; i < params->tbl_size; i++) {
         |                     ^~~~~~~~~~~~~~~~~~~~
   drivers/clk/spacemit/ccu_pll.c:152:9: note: uninitialized use occurs here
     152 |         val |= entry->reg5 << PLL_SWCR1_REG5_OFF;
         |                ^~~~~
   drivers/clk/spacemit/ccu_pll.c:141:14: note: remove the condition if it is always true
     141 |         for (i = 0; i < params->tbl_size; i++) {
         |                     ^~~~~~~~~~~~~~~~~~~~
   drivers/clk/spacemit/ccu_pll.c:127:32: note: initialize the variable 'entry' to silence this warning
     127 |         struct ccu_pll_rate_tbl *entry;
         |                                       ^
         |                                        = NULL
   3 warnings generated.


vim +/val +152 drivers/clk/spacemit/ccu_pll.c

   115	
   116	/*
   117	 * pll rate change requires sequence:
   118	 * clock off -> change rate setting -> clock on
   119	 * This function doesn't really change rate, but cache the config
   120	 */
   121	static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
   122				       unsigned long parent_rate)
   123	{
   124		struct ccu_pll *p = hw_to_ccu_pll(hw);
   125		struct ccu_common *common = &p->common;
   126		struct ccu_pll_config *params = &p->pll;
   127		struct ccu_pll_rate_tbl *entry;
 > 128		unsigned long old_rate;
   129		bool found = false;
   130		u32 mask, val;
   131		int i;
   132	
   133		if (ccu_pll_is_enabled(hw)) {
   134			pr_err("%s %s is enabled, ignore the setrate!\n",
   135			       __func__, __clk_get_name(hw->clk));
   136			return 0;
   137		}
   138	
   139		old_rate = __get_vco_freq(hw);
   140	
 > 141		for (i = 0; i < params->tbl_size; i++) {
   142			if (rate == params->rate_tbl[i].rate) {
   143				found = true;
   144				entry = &params->rate_tbl[i];
   145				break;
   146			}
   147		}
   148		WARN_ON_ONCE(!found);
   149	
   150		mask = PLL_SWCR1_REG5_MASK | PLL_SWCR1_REG6_MASK;
   151		mask |= PLL_SWCR1_REG7_MASK | PLL_SWCR1_REG8_MASK;
 > 152		val |= entry->reg5 << PLL_SWCR1_REG5_OFF;
   153		val |= entry->reg6 << PLL_SWCR1_REG6_OFF;
   154		val |= entry->reg7 << PLL_SWCR1_REG7_OFF;
   155		val |= entry->reg8 << PLL_SWCR1_REG8_OFF;
   156		ccu_update(swcr1, common, mask, val);
   157	
   158		mask = PLL_SWCR3_DIV_INT_MASK | PLL_SWCR3_DIV_FRC_MASK;
   159		val = entry->div_int << PLL_SWCR3_DIV_INT_OFF;
   160		val |= entry->div_frac << PLL_SWCR3_DIV_FRC_OFF;
   161		ccu_update(swcr3, common, mask, val);
   162	
   163		return 0;
   164	}
   165	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From cleger at rivosinc.com  Wed Nov 27 23:36:04 2024
From: cleger at rivosinc.com (=?UTF-8?B?Q2zDqW1lbnQgTMOpZ2Vy?=)
Date: Thu, 28 Nov 2024 08:36:04 +0100
Subject: [PATCH v2] riscv: module: use a plain variable for list_head
 instead of a pointer
In-Reply-To: <980b98978ab4ee912b37cb101ad43bce20b56dcb.camel@iscas.ac.cn>
References: <20241127142519.3038691-1-cleger@rivosinc.com>
 <980b98978ab4ee912b37cb101ad43bce20b56dcb.camel@iscas.ac.cn>
Message-ID: <ba0f252c-345e-4988-8d4f-36116708f19e@rivosinc.com>



On 28/11/2024 02:01, laokz wrote:
> On Wed, 2024-11-27 at 15:25 +0100, Cl?ment L?ger wrote:
>> rel_head's list_head member, rel_entry, doesn't need to be allocated,
>> its storage can just be part of the allocated rel_head. Remove the
> 
> Oh my poor English. OK, it's more better than just add the lost kfree.
> 
>> pointer which allows to get rid of the allocation as well as an
>> existing
>> memory leak found by Kai Zang using kmemleak.
>                             ^
>                            Zhang
> 
> BTW. Doesn't it need a fixes tag like what you suggested? (The bug
> might come from 6.7)

Hey Kai,

Apologies for misspelling your name, I'll fix that !

That's a good question, I guess I could have added it indeed but since
it was rather a rework, I left it out. But it's probably better to add
it anyway. I'll send a V3 with the Fixes tag as well as fixing your name
spelling.

Thanks,

Cl?ment

> 
>>
>> Reported-by: Kai Zhang <zhangkai at iscas.ac.cn>
>> Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
>> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
>> ---
>>
>> V2:
>> ?- Add Kai Reported-by
>> ?- Reword the commit description (Andrew)
>>
>> ---
>> ?arch/riscv/kernel/module.c | 18 ++++--------------
>> ?1 file changed, 4 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
>> index 1cd461f3d872..47d0ebeec93c 100644
>> --- a/arch/riscv/kernel/module.c
>> +++ b/arch/riscv/kernel/module.c
>> @@ -23,7 +23,7 @@ struct used_bucket {
>> ?
>> ?struct relocation_head {
>> ????????struct hlist_node node;
>> -???????struct list_head *rel_entry;
>> +???????struct list_head rel_entry;
>> ????????void *location;
>> ?};
>> ?
>> @@ -634,7 +634,7 @@ process_accumulated_relocations(struct module
>> *me,
>> ????????????????????????location = rel_head_iter->location;
>> ????????????????????????list_for_each_entry_safe(rel_entry_iter,
>> ???????????????????????????????????????????????? rel_entry_iter_tmp,
>> -??????????????????????????????????????????????? rel_head_iter-
>>> rel_entry,
>> +??????????????????????????????????????????????? &rel_head_iter-
>>> rel_entry,
>> ???????????????????????????????????????????????? head) {
>> ????????????????????????????????curr_type = rel_entry_iter->type;
>> ????????????????????????????????reloc_handlers[curr_type].reloc_handl
>> er(
>> @@ -704,16 +704,7 @@ static int add_relocation_to_accumulate(struct
>> module *me, int type,
>> ????????????????????????return -ENOMEM;
>> ????????????????}
>> ?
>> -???????????????rel_head->rel_entry =
>> -???????????????????????kmalloc(sizeof(struct list_head),
>> GFP_KERNEL);
>> -
>> -???????????????if (!rel_head->rel_entry) {
>> -???????????????????????kfree(entry);
>> -???????????????????????kfree(rel_head);
>> -???????????????????????return -ENOMEM;
>> -???????????????}
>> -
>> -???????????????INIT_LIST_HEAD(rel_head->rel_entry);
>> +???????????????INIT_LIST_HEAD(&rel_head->rel_entry);
>> ????????????????rel_head->location = location;
>> ????????????????INIT_HLIST_NODE(&rel_head->node);
>> ????????????????if (!current_head->first) {
>> @@ -722,7 +713,6 @@ static int add_relocation_to_accumulate(struct
>> module *me, int type,
>> ?
>> ????????????????????????if (!bucket) {
>> ????????????????????????????????kfree(entry);
>> -???????????????????????????????kfree(rel_head->rel_entry);
>> ????????????????????????????????kfree(rel_head);
>> ????????????????????????????????return -ENOMEM;
>> ????????????????????????}
>> @@ -735,7 +725,7 @@ static int add_relocation_to_accumulate(struct
>> module *me, int type,
>> ????????}
>> ?
>> ????????/* Add relocation to head of discovered rel_head */
>> -???????list_add_tail(&entry->head, rel_head->rel_entry);
>> +???????list_add_tail(&entry->head, &rel_head->rel_entry);
>> ?
>> ????????return 0;
>> ?}
> 



From e at freeshell.de  Thu Nov 28 00:01:04 2024
From: e at freeshell.de (E Shattow)
Date: Thu, 28 Nov 2024 00:01:04 -0800
Subject: [PATCH v5 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable
 usb0 host function
In-Reply-To: <SHXPR01MB086308813C0B311845FDA2C7E629A@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>
References: <20241126075740.17419-1-e@freeshell.de>
 <CAJM55Z9wWCaS+FxZ=Gg_RfXXafNEJZC1zHZoPWQ2Y9QYDf9OyA@mail.gmail.com>
 <eb06c8e0-ebda-47b9-94f6-6e6eca21097d@freeshell.de>
 <CAJM55Z_Cy2aAfWY-6csKBuv3AJ44h4fCCvJ0ZSbLOYcKw6g=bA@mail.gmail.com>
 <SHXPR01MB086308813C0B311845FDA2C7E629A@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>
Message-ID: <971ae8a4-1add-45ed-8daf-951aef013e64@freeshell.de>

Re-sending my reply plain text not HTML format. -E

On 11/27/24 17:31, Minda Chen wrote:
>> E Shattow wrote:
>>> Hi Emil, thanks for taking time to review!
>>>
>>> Added CC: Minda Chen, Hal Feng
>>>
>>> Please Minda and Hal can you follow-up on Emil's comments as well?
>>>
>>> On 11/27/24 03:00, Emil Renner Berthing wrote:
>>>> E Shattow wrote:
>>>>> Enable host mode JH7110 on-chip USB for Milk-V Mars by setting host
>>>>> mode and connect vbus pinctrl.
>>>>>
>>>>> This functionality depends on setting the USB over-current register
>>>>> to disable at bootloader phase, for example U-Boot:
>>>>> https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.426
>>>>> 8-6-minda.chen at starfivetech.com/
>>>> Hi E,
>>>>
>>>> Ideally the JH7110 pinctrl driver would be updated, so Linux can do
>>>> this itself and doesn't need to rely on u-boot doing it. I already asked for this
>> here:
>> https://lore.kernel.org/all/CAJM55Z-+Cxdebcn4MLXfQdOVhx4c2SQ+zMH8cjn
>>>> -Yq35xO8g0A at mail.gmail.com/
>>> Yes, I agree, and Linux is not the only consumer of devicetree. I
>>> would like USB function to work for users of Linux and U-Boot on these
>>> boards by copying what the vendor Board Support Package does what is
>>> shipped with the products. If it is more in-depth than this I will
>>> defer to Hal or Minda.
>>>
>>>
>>> For some wider context, upstream U-Boot is about to adopt the
>>> dt-rebasing via Hal's OF_UPSTREAM for JH7110 boards series and then
>>> also there is a patch set from Minda Chen to add the on-chip JH7110
>>> USB support to U-Boot, and so then and there it will depend on these
>>> dts changes. If you have Milk-V Mars then already there are three of
>>> four USB-A receptacle ports which are functional on PCIe-connected
>>> VL805 USB chipset.
>>>
>>>>> If the over-current register is not prepared for us then the result
>>>>> is no change in functional outcome with this patch applied; there
>>>>> is an error visible to the user and this additional usb
>>>>> configuration fails (same as it is now). On Milk-V Mars with four
>>>>> USB-A ports this applies to one of the ports and the remaining three
>> VL805-connected ports via PCIe are not changed.
>>>> Thanks for the patches. I don't quite understand when you write "no
>>>> change in functional outcome with this patch applied". The USB-C
>>>> port is already configured as a peripheral, and I just tried setting
>>>> up an ethernet gadget on my VF2 running 6.12 and that works quite
>>>> well. Does it not work on the Milk-V Mars board? If it does then these
>> patches would break that functionality.
>>>> Here is the script I used for that:
>>>> https://paste.c-net.org/BravoLonely
>>>>
>>>> At the very least you'll need to explain in the commit message
>>>> itself why changing the USB-C port from peripheral mode to host mode
>>>> is OK. But ideally maybe you could make it work in OTG mode, so
>>>> userspace can choose how they want to use the port. The same goes for the
>> PINE64 board too.
>>>> /Emil
>>> USB-C port on Mars is not wired for data here, that is only true for
>>> VisionFive2. If the user wants to use their USB-A receptacle as OTG
>>> port I will not object to a future improvement, but here we want the
>>> basic expectations of users covered that they should have four working
>>> USB-A receptacle ports in U-Boot (and possibly in Linux, depending on
>>> the overcurrent register wherever it is set). This is what I am
>>> meaning, there may be somebody using a male-male USB-A USB-A cable for
>>> OTG but more likely is that people just want to plug in USB
>>> peripherals to host ports and use their mouse / keyboard / flash memory, I
>> think.
>>
>> You're right, sorry. I'm so used to the JH7110 boards being similar, but this is
>> actually one of the few differences between the Mars and VF2 that was not
>> caught when the Mars dts was first upstreamed.
>>
>> Yes, with 4 similar USB-A ports you'd definitely expect all of them to work in host
>> mode. With an explanation like the above in the commit message I (now) think
>> your changes makes sense.
>>
>> Thanks!
>> /Emil
>>
Hi Minda, thanks for taking time to review and explain the multiple USB 
configurations.

> Thanks. E Shadow
>
> The USB and PCIe0 setting in some JH7110 boards.
>                   PCIe0                                      cadence USB controller
> VF2:       connect with VL805 USB3.0 ( 4 USB 3.0 type A ports)       (USB 2.0)Type C port(role: peripheral)
> Milkv mars  connect with VL805 USB3.0 ( 3 USB 3.0 type A ports)       (USB 2.0)1 Type A port (role:host)
> Milkv cm    PCIe slot											(USB 2.0)micro B port (role:host)
> Star64       disabled?pcie PHY0 connect to cadence USB?         1 usb 3.0 port + USB 2.0 hub (role:host)
>
> H E Shadow
> I see you also add star64 USB configuration. I hope also add this to star64 board dts base on
> V6.13-rc1. Thanks.

Yes, on Star64 board I see there is one "blue colour" USB-A port and 
three "black colour" USB-A port. The product webpage 
https://wiki.pine64.org/wiki/STAR64 does say "1? USB3.0 Dedicated Host 
port / 3? USB2.0 Host port".

> &pcie0 {
> 	status = "disabled";
> };

For JH7110 is it allowed to have PCIe0 "okay" PCIe1 "okay" and also have 
USB 2.0?? We disable this PCIe0 here because of JH7110 USB3.0 design on 
Mars and on Star64?? Can JH7110 have USB 3.0 and USB 2.0 together (does 
Star64 do this, or is it USB 2.0 hub attach to JH7110 USB 3.0?)

> &pciephy0 {
> 	starfive,sys-syscon = <&sys_syscon 0x18>;
> 	starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>;
> 	status = "okay";
> };

Minda, I need your help to make a good description of these numbers 0x18 
0x148 0x1f4, for the patch to Linux.


First is 'starfive,sys-sycon':

JH7110 Technical Reference Manual, Table 7. "SYS SYSCONSAIF SYSCFG 24 
Register Description"

https://doc-en.rvspace.org/JH7110/TRM/JH7110_TRM/sys_syscon.html#sys_syscon__table_c3l_fqs_wsb

Register SYS SYSCONSAIF SYSCFG 24 at offset 0x18 why is this needed?? 
Your patch series for Linux 6.12 "Fix configuration for on-chip USB 2.0 
support"

https://lore.kernel.org/lkml/20241015070444.20972-1-minda.chen at starfivetech.com/

changes u0_pdrstn_split_sw_usbpipe_plugen in the driver and why do we 
need this now in the Star64 USB 3.0 dts for Linux 6.13?? Is this needed 
for USB function only u0_pdrstn_split_sw_usbpipe_plugen or is more from 
this register important here ?? And, can you make an explanation so I 
can learn what is the purpose of "u0_pdrstn_split_sw_usbpipe_plugen" or 
any other part of this register we need here (for USB)?


Next is 'stg-syscon':

JH7110 Technical Reference Manual, Table 82. "STG SYSCONSAIF SYSCFG 328 
Register Description"

https://doc-en.rvspace.org/JH7110/TRM/JH7110_TRM/stg_syscon.html#stg_syscon__table_mc4_n5s_wsb

Register STG SYSCONSAIF SYSCFG 328 at offset 0x148 what is this? 
Something PCIe?? Does this have to do with wires on the board going from 
USB-A port to PCIe? What is the explanation why we need this for USB?


JH7110 Technical Reference Manual, Table 125. "STG SYSCONSAIF SYSCFG 500 
Register Description"

https://doc-en.rvspace.org/JH7110/TRM/JH7110_TRM/stg_syscon.html#stg_syscon__table_njd_45s_wsb

Register STG SYSCONSAIF SYSCFG 500 at offset 0x1f4 is more usb3 bitfield 
names, what is a general description why this is needed? Is this "all 
the Cadence IP USB3 things" ?

The documentation devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml 
is not enough information to make a good description. "Total 2 registers 
offset" is a description of the place where the numbers exist for the 
schema but does not say if there is an ordering first,last and the 
expected register names in JH7110 TRM.? Is there more than one 
possibility? or else, will it 100% be exactly STG SYSCONSAIF SYSCFG 
registers 328 and 500 at offsets 0x148 and 0x1f4?


> &usb0 {
> 	pinctrl-names = "default";
> 	pinctrl-0 = <&usb_pins>;
> 	dr_mode = "host";
> 	status = "okay";
> };
>
> &usb_cdns3 {
> 	phys = <&usbphy0>, <&pciephy0>;
> 	phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy";
> };
>
>>> There is no USB-C port on Star64.
>>>
>>>>> Changes since v4:
>>>>>    - Rebase on latest master
>>>>>
>>>>> Changes since v3:
>>>>>    - Rebase on linux-next/master
>>>>>    - use tabs for code indent
>>>>>
>>>>> Changes since v2:
>>>>>    - Rebase on 6.12
>>>>>
>>>>> E Shattow (1):
>>>>>     riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host
>>>>> function
>>>>>
>>>>>    .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18
>> +++++++++++++++++-
>>>>>    1 file changed, 17 insertions(+), 1 deletion(-)
>>>>>
>>>>> --
>>>>> 2.45.2
>>>>>
>>> Thanks again Emil.? -E
>>>

For Emil, my patches of Star64 and Mars are limited in scope to do the 
work of turning up host mode and adding the necessary vbus GPIO 
assignment;? so it's not wrong, and given the advice from Minda it's 
also not the complete support for all USB-A ports that I would like. I 
can extend this series to also include this adjacent USB 3.0 
configuration, or follow up in another series that is specific in topic 
for USB 3.0? Where I'm at on this is the host mode and GPIO 
configuration clearly belongs in dts but I have questions about this 
additional (USB 3.0 specific) configuration. And if we do, what do you 
think about the addition of syscon register offset values in devicetree, 
should they be #define'd somewhere? When it is the vbus GPIO there's 
literal sequential number of GPIO's so I did not find it was any problem 
to use the value. But, when I read "0x1f4" I think, what is that?


Best regards,

-E Shattow "Shadow"



From Usama.Anjum at collabora.com  Thu Nov 28 00:14:50 2024
From: Usama.Anjum at collabora.com (Muhammad Usama Anjum)
Date: Thu, 28 Nov 2024 13:14:50 +0500
Subject: [PATCH v4 01/16] KVM: Move KVM_REG_SIZE() definition to common
 uAPI header
In-Reply-To: <20241128005547.4077116-2-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
 <20241128005547.4077116-2-seanjc@google.com>
Message-ID: <4431aa18-c518-4396-87e8-04176eabdd49@collabora.com>

On 11/28/24 5:55 AM, Sean Christopherson wrote:
> Define KVM_REG_SIZE() in the common kvm.h header, and delete the arm64 and
> RISC-V versions.  As evidenced by the surrounding definitions, all aspects
> of the register size encoding are generic, i.e. RISC-V should have moved
> arm64's definition to common code instead of copy+pasting.
> 
> Acked-by: Anup Patel <anup at brainfault.org>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> Signed-off-by: Sean Christopherson <seanjc at google.com>
Reviewed-by: Muhammad Usama Anjum <usama.anjum at collabora.com>

> ---
>  arch/arm64/include/uapi/asm/kvm.h | 3 ---
>  arch/riscv/include/uapi/asm/kvm.h | 3 ---
>  include/uapi/linux/kvm.h          | 4 ++++
>  3 files changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index 66736ff04011..568bf858f319 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -43,9 +43,6 @@
>  #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
>  #define KVM_DIRTY_LOG_PAGE_OFFSET 64
>  
> -#define KVM_REG_SIZE(id)						\
> -	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
> -
>  struct kvm_regs {
>  	struct user_pt_regs regs;	/* sp = sp_el0 */
>  
> diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
> index 3482c9a73d1b..9f60d6185077 100644
> --- a/arch/riscv/include/uapi/asm/kvm.h
> +++ b/arch/riscv/include/uapi/asm/kvm.h
> @@ -211,9 +211,6 @@ struct kvm_riscv_sbi_sta {
>  #define KVM_RISCV_TIMER_STATE_OFF	0
>  #define KVM_RISCV_TIMER_STATE_ON	1
>  
> -#define KVM_REG_SIZE(id)		\
> -	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
> -
>  /* If you need to interpret the index values, here is the key: */
>  #define KVM_REG_RISCV_TYPE_MASK		0x00000000FF000000
>  #define KVM_REG_RISCV_TYPE_SHIFT	24
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 502ea63b5d2e..343de0a51797 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -1070,6 +1070,10 @@ struct kvm_dirty_tlb {
>  
>  #define KVM_REG_SIZE_SHIFT	52
>  #define KVM_REG_SIZE_MASK	0x00f0000000000000ULL
> +
> +#define KVM_REG_SIZE(id)		\
> +	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
> +
>  #define KVM_REG_SIZE_U8		0x0000000000000000ULL
>  #define KVM_REG_SIZE_U16	0x0010000000000000ULL
>  #define KVM_REG_SIZE_U32	0x0020000000000000ULL


-- 
BR,
Muhammad Usama Anjum


From cleger at rivosinc.com  Thu Nov 28 00:16:34 2024
From: cleger at rivosinc.com (=?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?=)
Date: Thu, 28 Nov 2024 09:16:34 +0100
Subject: [PATCH v3] riscv: module: remove relocation_head rel_entry member allocation
Message-ID: <20241128081636.3620468-1-cleger@rivosinc.com>

relocation_head's list_head member, rel_entry, doesn't need to be
allocated, its storage can just be part of the allocated relocation_head.
Remove the pointer which allows to get rid of the allocation as well as
an existing memory leak found by Kai Zhang using kmemleak.

Fixes: 8fd6c5142395 ("riscv: Add remaining module relocations")
Reported-by: Kai Zhang <zhangkai at iscas.ac.cn>
Signed-off-by: Cl?ment L?ger <cleger at rivosinc.com>
Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
Reviewed-by: Charlie Jenkins <charlie at rivosinc.com>
Tested-by: Charlie Jenkins <charlie at rivosinc.com>
---
V3:
 - Fix Zhang name spelling.
 - Reword commit title.
 - Add a 'Fixes:' tag

V2:
 - Add Kai Zhang 'Reported-by:' tag
 - Reword the commit description (Andrew)

 arch/riscv/kernel/module.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index 1cd461f3d872..47d0ebeec93c 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -23,7 +23,7 @@ struct used_bucket {
 
 struct relocation_head {
 	struct hlist_node node;
-	struct list_head *rel_entry;
+	struct list_head rel_entry;
 	void *location;
 };
 
@@ -634,7 +634,7 @@ process_accumulated_relocations(struct module *me,
 			location = rel_head_iter->location;
 			list_for_each_entry_safe(rel_entry_iter,
 						 rel_entry_iter_tmp,
-						 rel_head_iter->rel_entry,
+						 &rel_head_iter->rel_entry,
 						 head) {
 				curr_type = rel_entry_iter->type;
 				reloc_handlers[curr_type].reloc_handler(
@@ -704,16 +704,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 			return -ENOMEM;
 		}
 
-		rel_head->rel_entry =
-			kmalloc(sizeof(struct list_head), GFP_KERNEL);
-
-		if (!rel_head->rel_entry) {
-			kfree(entry);
-			kfree(rel_head);
-			return -ENOMEM;
-		}
-
-		INIT_LIST_HEAD(rel_head->rel_entry);
+		INIT_LIST_HEAD(&rel_head->rel_entry);
 		rel_head->location = location;
 		INIT_HLIST_NODE(&rel_head->node);
 		if (!current_head->first) {
@@ -722,7 +713,6 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 
 			if (!bucket) {
 				kfree(entry);
-				kfree(rel_head->rel_entry);
 				kfree(rel_head);
 				return -ENOMEM;
 			}
@@ -735,7 +725,7 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 	}
 
 	/* Add relocation to head of discovered rel_head */
-	list_add_tail(&entry->head, rel_head->rel_entry);
+	list_add_tail(&entry->head, &rel_head->rel_entry);
 
 	return 0;
 }
-- 
2.45.2



From Usama.Anjum at collabora.com  Thu Nov 28 00:19:46 2024
From: Usama.Anjum at collabora.com (Muhammad Usama Anjum)
Date: Thu, 28 Nov 2024 13:19:46 +0500
Subject: [PATCH v4 14/16] KVM: selftests: Provide empty 'all' and 'clean'
 targets for unsupported ARCHs
In-Reply-To: <20241128005547.4077116-15-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
 <20241128005547.4077116-15-seanjc@google.com>
Message-ID: <29c1434a-bf33-4ab4-9df5-71fc12b4eceb@collabora.com>

On 11/28/24 5:55 AM, Sean Christopherson wrote:
> Provide empty targets for KVM selftests if the target architecture is
> unsupported to make it obvious which architectures are supported, and so
> that various side effects don't fail and/or do weird things, e.g. as is,
> "mkdir -p $(sort $(dir $(TEST_GEN_PROGS)))" fails due to a missing operand,
> and conversely, "$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) ..." will
> create an empty, useless directory for the unsupported architecture.
> 
> Move the guts of the Makefile to Makefile.kvm so that it's easier to see
> that the if-statement effectively guards all of KVM selftests.
> 
> Reported-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
> Signed-off-by: Sean Christopherson <seanjc at google.com>
Acked-by: Muhammad Usama Anjum <usama.anjum at collabora.com>

> ---
>  tools/testing/selftests/kvm/.gitignore   |   1 +
>  tools/testing/selftests/kvm/Makefile     | 336 +----------------------
>  tools/testing/selftests/kvm/Makefile.kvm | 334 ++++++++++++++++++++++
>  3 files changed, 340 insertions(+), 331 deletions(-)
>  create mode 100644 tools/testing/selftests/kvm/Makefile.kvm
> 
> diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
> index 7f57abf936e7..1d41a046a7bf 100644
> --- a/tools/testing/selftests/kvm/.gitignore
> +++ b/tools/testing/selftests/kvm/.gitignore
> @@ -9,3 +9,4 @@
>  !config
>  !settings
>  !Makefile
> +!Makefile.kvm
> \ No newline at end of file
> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> index c59a337cd4da..7b33464bf8cc 100644
> --- a/tools/testing/selftests/kvm/Makefile
> +++ b/tools/testing/selftests/kvm/Makefile
> @@ -1,12 +1,9 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> -include ../../../build/Build.include
> -
> -all:
> -
>  top_srcdir = ../../../..
>  include $(top_srcdir)/scripts/subarch.include
>  ARCH            ?= $(SUBARCH)
>  
> +ifeq ($(ARCH),$(filter $(ARCH),arm64 s390 riscv x86 x86_64))
>  ifeq ($(ARCH),x86)
>  	ARCH_DIR := x86_64
>  else ifeq ($(ARCH),arm64)
> @@ -17,332 +14,9 @@ else
>  	ARCH_DIR := $(ARCH)
>  endif
>  
> -LIBKVM += lib/assert.c
> -LIBKVM += lib/elf.c
> -LIBKVM += lib/guest_modes.c
> -LIBKVM += lib/io.c
> -LIBKVM += lib/kvm_util.c
> -LIBKVM += lib/memstress.c
> -LIBKVM += lib/guest_sprintf.c
> -LIBKVM += lib/rbtree.c
> -LIBKVM += lib/sparsebit.c
> -LIBKVM += lib/test_util.c
> -LIBKVM += lib/ucall_common.c
> -LIBKVM += lib/userfaultfd_util.c
> -
> -LIBKVM_STRING += lib/string_override.c
> -
> -LIBKVM_x86_64 += lib/x86_64/apic.c
> -LIBKVM_x86_64 += lib/x86_64/handlers.S
> -LIBKVM_x86_64 += lib/x86_64/hyperv.c
> -LIBKVM_x86_64 += lib/x86_64/memstress.c
> -LIBKVM_x86_64 += lib/x86_64/pmu.c
> -LIBKVM_x86_64 += lib/x86_64/processor.c
> -LIBKVM_x86_64 += lib/x86_64/sev.c
> -LIBKVM_x86_64 += lib/x86_64/svm.c
> -LIBKVM_x86_64 += lib/x86_64/ucall.c
> -LIBKVM_x86_64 += lib/x86_64/vmx.c
> -
> -LIBKVM_aarch64 += lib/aarch64/gic.c
> -LIBKVM_aarch64 += lib/aarch64/gic_v3.c
> -LIBKVM_aarch64 += lib/aarch64/gic_v3_its.c
> -LIBKVM_aarch64 += lib/aarch64/handlers.S
> -LIBKVM_aarch64 += lib/aarch64/processor.c
> -LIBKVM_aarch64 += lib/aarch64/spinlock.c
> -LIBKVM_aarch64 += lib/aarch64/ucall.c
> -LIBKVM_aarch64 += lib/aarch64/vgic.c
> -
> -LIBKVM_s390x += lib/s390x/diag318_test_handler.c
> -LIBKVM_s390x += lib/s390x/processor.c
> -LIBKVM_s390x += lib/s390x/ucall.c
> -LIBKVM_s390x += lib/s390x/facility.c
> -
> -LIBKVM_riscv += lib/riscv/handlers.S
> -LIBKVM_riscv += lib/riscv/processor.c
> -LIBKVM_riscv += lib/riscv/ucall.c
> -
> -# Non-compiled test targets
> -TEST_PROGS_x86_64 += x86_64/nx_huge_pages_test.sh
> -
> -# Compiled test targets
> -TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test
> -TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test
> -TEST_GEN_PROGS_x86_64 += x86_64/dirty_log_page_splitting_test
> -TEST_GEN_PROGS_x86_64 += x86_64/feature_msrs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/exit_on_emulation_failure_test
> -TEST_GEN_PROGS_x86_64 += x86_64/fix_hypercall_test
> -TEST_GEN_PROGS_x86_64 += x86_64/hwcr_msr_test
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_evmcs
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_extended_hypercalls
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_ipi
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_svm_test
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush
> -TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test
> -TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test
> -TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test
> -TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test
> -TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test
> -TEST_GEN_PROGS_x86_64 += x86_64/pmu_counters_test
> -TEST_GEN_PROGS_x86_64 += x86_64/pmu_event_filter_test
> -TEST_GEN_PROGS_x86_64 += x86_64/private_mem_conversions_test
> -TEST_GEN_PROGS_x86_64 += x86_64/private_mem_kvm_exits_test
> -TEST_GEN_PROGS_x86_64 += x86_64/set_boot_cpu_id
> -TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/smaller_maxphyaddr_emulation_test
> -TEST_GEN_PROGS_x86_64 += x86_64/smm_test
> -TEST_GEN_PROGS_x86_64 += x86_64/state_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
> -TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
> -TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
> -TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test
> -TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test
> -TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync
> -TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/ucna_injection_test
> -TEST_GEN_PROGS_x86_64 += x86_64/userspace_io_test
> -TEST_GEN_PROGS_x86_64 += x86_64/userspace_msr_exit_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_apic_access_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_exception_with_invalid_guest_state
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_msrs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_invalid_nested_guest_state
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_nested_tsc_scaling_test
> -TEST_GEN_PROGS_x86_64 += x86_64/apic_bus_clock_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xapic_ipi_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xapic_state_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xcr0_cpuid_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test
> -TEST_GEN_PROGS_x86_64 += x86_64/debug_regs
> -TEST_GEN_PROGS_x86_64 += x86_64/tsc_msrs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test
> -TEST_GEN_PROGS_x86_64 += x86_64/sev_init2_tests
> -TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
> -TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test
> -TEST_GEN_PROGS_x86_64 += x86_64/amx_test
> -TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
> -TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
> -TEST_GEN_PROGS_x86_64 += x86_64/recalc_apic_map_test
> -TEST_GEN_PROGS_x86_64 += access_tracking_perf_test
> -TEST_GEN_PROGS_x86_64 += coalesced_io_test
> -TEST_GEN_PROGS_x86_64 += demand_paging_test
> -TEST_GEN_PROGS_x86_64 += dirty_log_test
> -TEST_GEN_PROGS_x86_64 += dirty_log_perf_test
> -TEST_GEN_PROGS_x86_64 += guest_memfd_test
> -TEST_GEN_PROGS_x86_64 += guest_print_test
> -TEST_GEN_PROGS_x86_64 += hardware_disable_test
> -TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
> -TEST_GEN_PROGS_x86_64 += kvm_page_table_test
> -TEST_GEN_PROGS_x86_64 += mmu_stress_test
> -TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
> -TEST_GEN_PROGS_x86_64 += memslot_perf_test
> -TEST_GEN_PROGS_x86_64 += rseq_test
> -TEST_GEN_PROGS_x86_64 += set_memory_region_test
> -TEST_GEN_PROGS_x86_64 += steal_time
> -TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
> -TEST_GEN_PROGS_x86_64 += system_counter_offset_test
> -TEST_GEN_PROGS_x86_64 += pre_fault_memory_test
> -
> -# Compiled outputs used by test targets
> -TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
> -
> -TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
> -TEST_GEN_PROGS_aarch64 += aarch64/arch_timer_edge_cases
> -TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
> -TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
> -TEST_GEN_PROGS_aarch64 += aarch64/mmio_abort
> -TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
> -TEST_GEN_PROGS_aarch64 += aarch64/psci_test
> -TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
> -TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
> -TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
> -TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
> -TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
> -TEST_GEN_PROGS_aarch64 += aarch64/vgic_lpi_stress
> -TEST_GEN_PROGS_aarch64 += aarch64/vpmu_counter_access
> -TEST_GEN_PROGS_aarch64 += aarch64/no-vgic-v3
> -TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
> -TEST_GEN_PROGS_aarch64 += arch_timer
> -TEST_GEN_PROGS_aarch64 += coalesced_io_test
> -TEST_GEN_PROGS_aarch64 += demand_paging_test
> -TEST_GEN_PROGS_aarch64 += dirty_log_test
> -TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
> -TEST_GEN_PROGS_aarch64 += guest_print_test
> -TEST_GEN_PROGS_aarch64 += get-reg-list
> -TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
> -TEST_GEN_PROGS_aarch64 += kvm_page_table_test
> -TEST_GEN_PROGS_aarch64 += memslot_modification_stress_test
> -TEST_GEN_PROGS_aarch64 += memslot_perf_test
> -TEST_GEN_PROGS_aarch64 += mmu_stress_test
> -TEST_GEN_PROGS_aarch64 += rseq_test
> -TEST_GEN_PROGS_aarch64 += set_memory_region_test
> -TEST_GEN_PROGS_aarch64 += steal_time
> -TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
> -
> -TEST_GEN_PROGS_s390x = s390x/memop
> -TEST_GEN_PROGS_s390x += s390x/resets
> -TEST_GEN_PROGS_s390x += s390x/sync_regs_test
> -TEST_GEN_PROGS_s390x += s390x/tprot
> -TEST_GEN_PROGS_s390x += s390x/cmma_test
> -TEST_GEN_PROGS_s390x += s390x/debug_test
> -TEST_GEN_PROGS_s390x += s390x/cpumodel_subfuncs_test
> -TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test
> -TEST_GEN_PROGS_s390x += s390x/ucontrol_test
> -TEST_GEN_PROGS_s390x += demand_paging_test
> -TEST_GEN_PROGS_s390x += dirty_log_test
> -TEST_GEN_PROGS_s390x += guest_print_test
> -TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
> -TEST_GEN_PROGS_s390x += kvm_page_table_test
> -TEST_GEN_PROGS_s390x += rseq_test
> -TEST_GEN_PROGS_s390x += set_memory_region_test
> -TEST_GEN_PROGS_s390x += kvm_binary_stats_test
> -
> -TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
> -TEST_GEN_PROGS_riscv += riscv/ebreak_test
> -TEST_GEN_PROGS_riscv += arch_timer
> -TEST_GEN_PROGS_riscv += coalesced_io_test
> -TEST_GEN_PROGS_riscv += demand_paging_test
> -TEST_GEN_PROGS_riscv += dirty_log_test
> -TEST_GEN_PROGS_riscv += get-reg-list
> -TEST_GEN_PROGS_riscv += guest_print_test
> -TEST_GEN_PROGS_riscv += kvm_binary_stats_test
> -TEST_GEN_PROGS_riscv += kvm_create_max_vcpus
> -TEST_GEN_PROGS_riscv += kvm_page_table_test
> -TEST_GEN_PROGS_riscv += set_memory_region_test
> -TEST_GEN_PROGS_riscv += steal_time
> -
> -SPLIT_TESTS += arch_timer
> -SPLIT_TESTS += get-reg-list
> -
> -TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
> -TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
> -TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH_DIR))
> -LIBKVM += $(LIBKVM_$(ARCH_DIR))
> -
> -OVERRIDE_TARGETS = 1
> -
> -# lib.mak defines $(OUTPUT), prepends $(OUTPUT)/ to $(TEST_GEN_PROGS), and most
> -# importantly defines, i.e. overwrites, $(CC) (unless `make -e` or `make CC=`,
> -# which causes the environment variable to override the makefile).
> -include ../lib.mk
> -
> -INSTALL_HDR_PATH = $(top_srcdir)/usr
> -LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
> -LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
> -ifeq ($(ARCH),x86_64)
> -LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include
> +include Makefile.kvm
>  else
> -LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
> +# Empty targets for unsupported architectures
> +all:
> +clean:
>  endif
> -CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
> -	-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
> -	-fno-builtin-memcmp -fno-builtin-memcpy \
> -	-fno-builtin-memset -fno-builtin-strnlen \
> -	-fno-stack-protector -fno-PIE -fno-strict-aliasing \
> -	-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
> -	-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH_DIR) \
> -	-I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
> -ifeq ($(ARCH),s390)
> -	CFLAGS += -march=z10
> -endif
> -ifeq ($(ARCH),x86)
> -ifeq ($(shell echo "void foo(void) { }" | $(CC) -march=x86-64-v2 -x c - -c -o /dev/null 2>/dev/null; echo "$$?"),0)
> -	CFLAGS += -march=x86-64-v2
> -endif
> -endif
> -ifeq ($(ARCH),arm64)
> -tools_dir := $(top_srcdir)/tools
> -arm64_tools_dir := $(tools_dir)/arch/arm64/tools/
> -
> -ifneq ($(abs_objdir),)
> -arm64_hdr_outdir := $(abs_objdir)/tools/
> -else
> -arm64_hdr_outdir := $(tools_dir)/
> -endif
> -
> -GEN_HDRS := $(arm64_hdr_outdir)arch/arm64/include/generated/
> -CFLAGS += -I$(GEN_HDRS)
> -
> -$(GEN_HDRS): $(wildcard $(arm64_tools_dir)/*)
> -	$(MAKE) -C $(arm64_tools_dir) OUTPUT=$(arm64_hdr_outdir)
> -endif
> -
> -no-pie-option := $(call try-run, echo 'int main(void) { return 0; }' | \
> -        $(CC) -Werror $(CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie)
> -
> -# On s390, build the testcases KVM-enabled
> -pgste-option = $(call try-run, echo 'int main(void) { return 0; }' | \
> -	$(CC) -Werror -Wl$(comma)--s390-pgste -x c - -o "$$TMP",-Wl$(comma)--s390-pgste)
> -
> -LDLIBS += -ldl
> -LDFLAGS += -pthread $(no-pie-option) $(pgste-option)
> -
> -LIBKVM_C := $(filter %.c,$(LIBKVM))
> -LIBKVM_S := $(filter %.S,$(LIBKVM))
> -LIBKVM_C_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C))
> -LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S))
> -LIBKVM_STRING_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING))
> -LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ)
> -SPLIT_TEST_GEN_PROGS := $(patsubst %, $(OUTPUT)/%, $(SPLIT_TESTS))
> -SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH_DIR)/%.o, $(SPLIT_TESTS))
> -
> -TEST_GEN_OBJ = $(patsubst %, %.o, $(TEST_GEN_PROGS))
> -TEST_GEN_OBJ += $(patsubst %, %.o, $(TEST_GEN_PROGS_EXTENDED))
> -TEST_DEP_FILES = $(patsubst %.o, %.d, $(TEST_GEN_OBJ))
> -TEST_DEP_FILES += $(patsubst %.o, %.d, $(LIBKVM_OBJS))
> -TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TEST_GEN_OBJ))
> --include $(TEST_DEP_FILES)
> -
> -$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
> -
> -$(filter-out $(SPLIT_TEST_GEN_PROGS), $(TEST_GEN_PROGS)) \
> -$(TEST_GEN_PROGS_EXTENDED): %: %.o
> -	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
> -$(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
> -	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> -
> -$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH_DIR)/%.o
> -	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
> -$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH_DIR)/%.o: $(ARCH_DIR)/%.c
> -	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> -
> -EXTRA_CLEAN += $(GEN_HDRS) \
> -	       $(LIBKVM_OBJS) \
> -	       $(SPLIT_TEST_GEN_OBJ) \
> -	       $(TEST_DEP_FILES) \
> -	       $(TEST_GEN_OBJ) \
> -	       cscope.*
> -
> -$(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(GEN_HDRS)
> -	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> -
> -$(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(GEN_HDRS)
> -	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> -
> -# Compile the string overrides as freestanding to prevent the compiler from
> -# generating self-referential code, e.g. without "freestanding" the compiler may
> -# "optimize" memcmp() by invoking memcmp(), thus causing infinite recursion.
> -$(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
> -	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@
> -
> -$(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
> -$(SPLIT_TEST_GEN_OBJ): $(GEN_HDRS)
> -$(TEST_GEN_PROGS): $(LIBKVM_OBJS)
> -$(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
> -$(TEST_GEN_OBJ): $(GEN_HDRS)
> -
> -cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
> -cscope:
> -	$(RM) cscope.*
> -	(find $(include_paths) -name '*.h' \
> -		-exec realpath --relative-base=$(PWD) {} \;; \
> -	find . -name '*.c' \
> -		-exec realpath --relative-base=$(PWD) {} \;) | sort -u > cscope.files
> -	cscope -b
> diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
> new file mode 100644
> index 000000000000..e988a72f8c20
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/Makefile.kvm
> @@ -0,0 +1,334 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +include ../../../build/Build.include
> +
> +all:
> +
> +LIBKVM += lib/assert.c
> +LIBKVM += lib/elf.c
> +LIBKVM += lib/guest_modes.c
> +LIBKVM += lib/io.c
> +LIBKVM += lib/kvm_util.c
> +LIBKVM += lib/memstress.c
> +LIBKVM += lib/guest_sprintf.c
> +LIBKVM += lib/rbtree.c
> +LIBKVM += lib/sparsebit.c
> +LIBKVM += lib/test_util.c
> +LIBKVM += lib/ucall_common.c
> +LIBKVM += lib/userfaultfd_util.c
> +
> +LIBKVM_STRING += lib/string_override.c
> +
> +LIBKVM_x86_64 += lib/x86_64/apic.c
> +LIBKVM_x86_64 += lib/x86_64/handlers.S
> +LIBKVM_x86_64 += lib/x86_64/hyperv.c
> +LIBKVM_x86_64 += lib/x86_64/memstress.c
> +LIBKVM_x86_64 += lib/x86_64/pmu.c
> +LIBKVM_x86_64 += lib/x86_64/processor.c
> +LIBKVM_x86_64 += lib/x86_64/sev.c
> +LIBKVM_x86_64 += lib/x86_64/svm.c
> +LIBKVM_x86_64 += lib/x86_64/ucall.c
> +LIBKVM_x86_64 += lib/x86_64/vmx.c
> +
> +LIBKVM_aarch64 += lib/aarch64/gic.c
> +LIBKVM_aarch64 += lib/aarch64/gic_v3.c
> +LIBKVM_aarch64 += lib/aarch64/gic_v3_its.c
> +LIBKVM_aarch64 += lib/aarch64/handlers.S
> +LIBKVM_aarch64 += lib/aarch64/processor.c
> +LIBKVM_aarch64 += lib/aarch64/spinlock.c
> +LIBKVM_aarch64 += lib/aarch64/ucall.c
> +LIBKVM_aarch64 += lib/aarch64/vgic.c
> +
> +LIBKVM_s390x += lib/s390x/diag318_test_handler.c
> +LIBKVM_s390x += lib/s390x/processor.c
> +LIBKVM_s390x += lib/s390x/ucall.c
> +LIBKVM_s390x += lib/s390x/facility.c
> +
> +LIBKVM_riscv += lib/riscv/handlers.S
> +LIBKVM_riscv += lib/riscv/processor.c
> +LIBKVM_riscv += lib/riscv/ucall.c
> +
> +# Non-compiled test targets
> +TEST_PROGS_x86_64 += x86_64/nx_huge_pages_test.sh
> +
> +# Compiled test targets
> +TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test
> +TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test
> +TEST_GEN_PROGS_x86_64 += x86_64/dirty_log_page_splitting_test
> +TEST_GEN_PROGS_x86_64 += x86_64/feature_msrs_test
> +TEST_GEN_PROGS_x86_64 += x86_64/exit_on_emulation_failure_test
> +TEST_GEN_PROGS_x86_64 += x86_64/fix_hypercall_test
> +TEST_GEN_PROGS_x86_64 += x86_64/hwcr_msr_test
> +TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
> +TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
> +TEST_GEN_PROGS_x86_64 += x86_64/hyperv_evmcs
> +TEST_GEN_PROGS_x86_64 += x86_64/hyperv_extended_hypercalls
> +TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features
> +TEST_GEN_PROGS_x86_64 += x86_64/hyperv_ipi
> +TEST_GEN_PROGS_x86_64 += x86_64/hyperv_svm_test
> +TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush
> +TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test
> +TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test
> +TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test
> +TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test
> +TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test
> +TEST_GEN_PROGS_x86_64 += x86_64/pmu_counters_test
> +TEST_GEN_PROGS_x86_64 += x86_64/pmu_event_filter_test
> +TEST_GEN_PROGS_x86_64 += x86_64/private_mem_conversions_test
> +TEST_GEN_PROGS_x86_64 += x86_64/private_mem_kvm_exits_test
> +TEST_GEN_PROGS_x86_64 += x86_64/set_boot_cpu_id
> +TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test
> +TEST_GEN_PROGS_x86_64 += x86_64/smaller_maxphyaddr_emulation_test
> +TEST_GEN_PROGS_x86_64 += x86_64/smm_test
> +TEST_GEN_PROGS_x86_64 += x86_64/state_test
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
> +TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
> +TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
> +TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test
> +TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test
> +TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync
> +TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
> +TEST_GEN_PROGS_x86_64 += x86_64/ucna_injection_test
> +TEST_GEN_PROGS_x86_64 += x86_64/userspace_io_test
> +TEST_GEN_PROGS_x86_64 += x86_64/userspace_msr_exit_test
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_apic_access_test
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_exception_with_invalid_guest_state
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_msrs_test
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_invalid_nested_guest_state
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_nested_tsc_scaling_test
> +TEST_GEN_PROGS_x86_64 += x86_64/apic_bus_clock_test
> +TEST_GEN_PROGS_x86_64 += x86_64/xapic_ipi_test
> +TEST_GEN_PROGS_x86_64 += x86_64/xapic_state_test
> +TEST_GEN_PROGS_x86_64 += x86_64/xcr0_cpuid_test
> +TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test
> +TEST_GEN_PROGS_x86_64 += x86_64/debug_regs
> +TEST_GEN_PROGS_x86_64 += x86_64/tsc_msrs_test
> +TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test
> +TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test
> +TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test
> +TEST_GEN_PROGS_x86_64 += x86_64/sev_init2_tests
> +TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
> +TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test
> +TEST_GEN_PROGS_x86_64 += x86_64/amx_test
> +TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
> +TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
> +TEST_GEN_PROGS_x86_64 += x86_64/recalc_apic_map_test
> +TEST_GEN_PROGS_x86_64 += access_tracking_perf_test
> +TEST_GEN_PROGS_x86_64 += coalesced_io_test
> +TEST_GEN_PROGS_x86_64 += demand_paging_test
> +TEST_GEN_PROGS_x86_64 += dirty_log_test
> +TEST_GEN_PROGS_x86_64 += dirty_log_perf_test
> +TEST_GEN_PROGS_x86_64 += guest_memfd_test
> +TEST_GEN_PROGS_x86_64 += guest_print_test
> +TEST_GEN_PROGS_x86_64 += hardware_disable_test
> +TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
> +TEST_GEN_PROGS_x86_64 += kvm_page_table_test
> +TEST_GEN_PROGS_x86_64 += mmu_stress_test
> +TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
> +TEST_GEN_PROGS_x86_64 += memslot_perf_test
> +TEST_GEN_PROGS_x86_64 += rseq_test
> +TEST_GEN_PROGS_x86_64 += set_memory_region_test
> +TEST_GEN_PROGS_x86_64 += steal_time
> +TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
> +TEST_GEN_PROGS_x86_64 += system_counter_offset_test
> +TEST_GEN_PROGS_x86_64 += pre_fault_memory_test
> +
> +# Compiled outputs used by test targets
> +TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
> +
> +TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
> +TEST_GEN_PROGS_aarch64 += aarch64/arch_timer_edge_cases
> +TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
> +TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
> +TEST_GEN_PROGS_aarch64 += aarch64/mmio_abort
> +TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
> +TEST_GEN_PROGS_aarch64 += aarch64/psci_test
> +TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
> +TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
> +TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
> +TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
> +TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
> +TEST_GEN_PROGS_aarch64 += aarch64/vgic_lpi_stress
> +TEST_GEN_PROGS_aarch64 += aarch64/vpmu_counter_access
> +TEST_GEN_PROGS_aarch64 += aarch64/no-vgic-v3
> +TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
> +TEST_GEN_PROGS_aarch64 += arch_timer
> +TEST_GEN_PROGS_aarch64 += coalesced_io_test
> +TEST_GEN_PROGS_aarch64 += demand_paging_test
> +TEST_GEN_PROGS_aarch64 += dirty_log_test
> +TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
> +TEST_GEN_PROGS_aarch64 += guest_print_test
> +TEST_GEN_PROGS_aarch64 += get-reg-list
> +TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
> +TEST_GEN_PROGS_aarch64 += kvm_page_table_test
> +TEST_GEN_PROGS_aarch64 += memslot_modification_stress_test
> +TEST_GEN_PROGS_aarch64 += memslot_perf_test
> +TEST_GEN_PROGS_aarch64 += mmu_stress_test
> +TEST_GEN_PROGS_aarch64 += rseq_test
> +TEST_GEN_PROGS_aarch64 += set_memory_region_test
> +TEST_GEN_PROGS_aarch64 += steal_time
> +TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
> +
> +TEST_GEN_PROGS_s390x = s390x/memop
> +TEST_GEN_PROGS_s390x += s390x/resets
> +TEST_GEN_PROGS_s390x += s390x/sync_regs_test
> +TEST_GEN_PROGS_s390x += s390x/tprot
> +TEST_GEN_PROGS_s390x += s390x/cmma_test
> +TEST_GEN_PROGS_s390x += s390x/debug_test
> +TEST_GEN_PROGS_s390x += s390x/cpumodel_subfuncs_test
> +TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test
> +TEST_GEN_PROGS_s390x += s390x/ucontrol_test
> +TEST_GEN_PROGS_s390x += demand_paging_test
> +TEST_GEN_PROGS_s390x += dirty_log_test
> +TEST_GEN_PROGS_s390x += guest_print_test
> +TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
> +TEST_GEN_PROGS_s390x += kvm_page_table_test
> +TEST_GEN_PROGS_s390x += rseq_test
> +TEST_GEN_PROGS_s390x += set_memory_region_test
> +TEST_GEN_PROGS_s390x += kvm_binary_stats_test
> +
> +TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
> +TEST_GEN_PROGS_riscv += riscv/ebreak_test
> +TEST_GEN_PROGS_riscv += arch_timer
> +TEST_GEN_PROGS_riscv += coalesced_io_test
> +TEST_GEN_PROGS_riscv += demand_paging_test
> +TEST_GEN_PROGS_riscv += dirty_log_test
> +TEST_GEN_PROGS_riscv += get-reg-list
> +TEST_GEN_PROGS_riscv += guest_print_test
> +TEST_GEN_PROGS_riscv += kvm_binary_stats_test
> +TEST_GEN_PROGS_riscv += kvm_create_max_vcpus
> +TEST_GEN_PROGS_riscv += kvm_page_table_test
> +TEST_GEN_PROGS_riscv += set_memory_region_test
> +TEST_GEN_PROGS_riscv += steal_time
> +
> +SPLIT_TESTS += arch_timer
> +SPLIT_TESTS += get-reg-list
> +
> +TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
> +TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
> +TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH_DIR))
> +LIBKVM += $(LIBKVM_$(ARCH_DIR))
> +
> +OVERRIDE_TARGETS = 1
> +
> +# lib.mak defines $(OUTPUT), prepends $(OUTPUT)/ to $(TEST_GEN_PROGS), and most
> +# importantly defines, i.e. overwrites, $(CC) (unless `make -e` or `make CC=`,
> +# which causes the environment variable to override the makefile).
> +include ../lib.mk
> +
> +INSTALL_HDR_PATH = $(top_srcdir)/usr
> +LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
> +LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
> +ifeq ($(ARCH),x86_64)
> +LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include
> +else
> +LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
> +endif
> +CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
> +	-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
> +	-fno-builtin-memcmp -fno-builtin-memcpy \
> +	-fno-builtin-memset -fno-builtin-strnlen \
> +	-fno-stack-protector -fno-PIE -fno-strict-aliasing \
> +	-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
> +	-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH_DIR) \
> +	-I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
> +ifeq ($(ARCH),s390)
> +	CFLAGS += -march=z10
> +endif
> +ifeq ($(ARCH),x86)
> +ifeq ($(shell echo "void foo(void) { }" | $(CC) -march=x86-64-v2 -x c - -c -o /dev/null 2>/dev/null; echo "$$?"),0)
> +	CFLAGS += -march=x86-64-v2
> +endif
> +endif
> +ifeq ($(ARCH),arm64)
> +tools_dir := $(top_srcdir)/tools
> +arm64_tools_dir := $(tools_dir)/arch/arm64/tools/
> +
> +ifneq ($(abs_objdir),)
> +arm64_hdr_outdir := $(abs_objdir)/tools/
> +else
> +arm64_hdr_outdir := $(tools_dir)/
> +endif
> +
> +GEN_HDRS := $(arm64_hdr_outdir)arch/arm64/include/generated/
> +CFLAGS += -I$(GEN_HDRS)
> +
> +$(GEN_HDRS): $(wildcard $(arm64_tools_dir)/*)
> +	$(MAKE) -C $(arm64_tools_dir) OUTPUT=$(arm64_hdr_outdir)
> +endif
> +
> +no-pie-option := $(call try-run, echo 'int main(void) { return 0; }' | \
> +        $(CC) -Werror $(CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie)
> +
> +# On s390, build the testcases KVM-enabled
> +pgste-option = $(call try-run, echo 'int main(void) { return 0; }' | \
> +	$(CC) -Werror -Wl$(comma)--s390-pgste -x c - -o "$$TMP",-Wl$(comma)--s390-pgste)
> +
> +LDLIBS += -ldl
> +LDFLAGS += -pthread $(no-pie-option) $(pgste-option)
> +
> +LIBKVM_C := $(filter %.c,$(LIBKVM))
> +LIBKVM_S := $(filter %.S,$(LIBKVM))
> +LIBKVM_C_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C))
> +LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S))
> +LIBKVM_STRING_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING))
> +LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ)
> +SPLIT_TEST_GEN_PROGS := $(patsubst %, $(OUTPUT)/%, $(SPLIT_TESTS))
> +SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH_DIR)/%.o, $(SPLIT_TESTS))
> +
> +TEST_GEN_OBJ = $(patsubst %, %.o, $(TEST_GEN_PROGS))
> +TEST_GEN_OBJ += $(patsubst %, %.o, $(TEST_GEN_PROGS_EXTENDED))
> +TEST_DEP_FILES = $(patsubst %.o, %.d, $(TEST_GEN_OBJ))
> +TEST_DEP_FILES += $(patsubst %.o, %.d, $(LIBKVM_OBJS))
> +TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TEST_GEN_OBJ))
> +-include $(TEST_DEP_FILES)
> +
> +$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
> +
> +$(filter-out $(SPLIT_TEST_GEN_PROGS), $(TEST_GEN_PROGS)) \
> +$(TEST_GEN_PROGS_EXTENDED): %: %.o
> +	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $< $(LIBKVM_OBJS) $(LDLIBS) -o $@
> +$(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
> +	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> +
> +$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH_DIR)/%.o
> +	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
> +$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH_DIR)/%.o: $(ARCH_DIR)/%.c
> +	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> +
> +EXTRA_CLEAN += $(GEN_HDRS) \
> +	       $(LIBKVM_OBJS) \
> +	       $(SPLIT_TEST_GEN_OBJ) \
> +	       $(TEST_DEP_FILES) \
> +	       $(TEST_GEN_OBJ) \
> +	       cscope.*
> +
> +$(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(GEN_HDRS)
> +	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> +
> +$(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(GEN_HDRS)
> +	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
> +
> +# Compile the string overrides as freestanding to prevent the compiler from
> +# generating self-referential code, e.g. without "freestanding" the compiler may
> +# "optimize" memcmp() by invoking memcmp(), thus causing infinite recursion.
> +$(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c
> +	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@
> +
> +$(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS))))
> +$(SPLIT_TEST_GEN_OBJ): $(GEN_HDRS)
> +$(TEST_GEN_PROGS): $(LIBKVM_OBJS)
> +$(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS)
> +$(TEST_GEN_OBJ): $(GEN_HDRS)
> +
> +cscope: include_paths = $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include lib ..
> +cscope:
> +	$(RM) cscope.*
> +	(find $(include_paths) -name '*.h' \
> +		-exec realpath --relative-base=$(PWD) {} \;; \
> +	find . -name '*.c' \
> +		-exec realpath --relative-base=$(PWD) {} \;) | sort -u > cscope.files
> +	cscope -b


-- 
BR,
Muhammad Usama Anjum


From Usama.Anjum at collabora.com  Thu Nov 28 00:20:26 2024
From: Usama.Anjum at collabora.com (Muhammad Usama Anjum)
Date: Thu, 28 Nov 2024 13:20:26 +0500
Subject: [PATCH v4 15/16] KVM: selftests: Use canonical $(ARCH) paths for
 KVM selftests directories
In-Reply-To: <20241128005547.4077116-16-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
 <20241128005547.4077116-16-seanjc@google.com>
Message-ID: <5ee15da3-fb65-49be-9b96-9839aa0975ff@collabora.com>

On 11/28/24 5:55 AM, Sean Christopherson wrote:
> Use the kernel's canonical $(ARCH) paths instead of the raw target triple
> for KVM selftests directories.  KVM selftests are quite nearly the only
> place in the entire kernel that using the target triple for directories,
> tools/testing/selftests/drivers/s390x being the lone holdout.
> 
> Using the kernel's preferred nomenclature eliminates the minor, but
> annoying, friction of having to translate to KVM's selftests directories,
> e.g. for pattern matching, opening files, running selftests, etc.
> 
> Opportunsitically delete file comments that reference the full path of the
> file, as they are obviously prone to becoming stale, and serve no known
> purpose.
> 
> Signed-off-by: Sean Christopherson <seanjc at google.com>
Reviewed-by: Muhammad Usama Anjum <usama.anjum at collabora.com>

> ---
>  MAINTAINERS                                   |  12 +-
>  tools/testing/selftests/kvm/Makefile          |  10 +-
>  tools/testing/selftests/kvm/Makefile.kvm      | 320 +++++++++---------
>  .../kvm/{aarch64 => arm64}/aarch32_id_regs.c  |   0
>  .../kvm/{aarch64 => arm64}/arch_timer.c       |   0
>  .../arch_timer_edge_cases.c                   |   0
>  .../kvm/{aarch64 => arm64}/debug-exceptions.c |   0
>  .../kvm/{aarch64 => arm64}/get-reg-list.c     |   0
>  .../kvm/{aarch64 => arm64}/hypercalls.c       |   0
>  .../kvm/{aarch64 => arm64}/mmio_abort.c       |   0
>  .../kvm/{aarch64 => arm64}/no-vgic-v3.c       |   0
>  .../kvm/{aarch64 => arm64}/page_fault_test.c  |   0
>  .../kvm/{aarch64 => arm64}/psci_test.c        |   0
>  .../kvm/{aarch64 => arm64}/set_id_regs.c      |   0
>  .../kvm/{aarch64 => arm64}/smccc_filter.c     |   0
>  .../{aarch64 => arm64}/vcpu_width_config.c    |   0
>  .../kvm/{aarch64 => arm64}/vgic_init.c        |   0
>  .../kvm/{aarch64 => arm64}/vgic_irq.c         |   0
>  .../kvm/{aarch64 => arm64}/vgic_lpi_stress.c  |   0
>  .../{aarch64 => arm64}/vpmu_counter_access.c  |   0
>  .../selftests/kvm/dirty_log_perf_test.c       |   2 +-
>  .../include/{aarch64 => arm64}/arch_timer.h   |   0
>  .../kvm/include/{aarch64 => arm64}/delay.h    |   0
>  .../kvm/include/{aarch64 => arm64}/gic.h      |   0
>  .../kvm/include/{aarch64 => arm64}/gic_v3.h   |   0
>  .../include/{aarch64 => arm64}/gic_v3_its.h   |   0
>  .../{aarch64 => arm64}/kvm_util_arch.h        |   0
>  .../include/{aarch64 => arm64}/processor.h    |   0
>  .../kvm/include/{aarch64 => arm64}/spinlock.h |   0
>  .../kvm/include/{aarch64 => arm64}/ucall.h    |   0
>  .../kvm/include/{aarch64 => arm64}/vgic.h     |   0
>  .../kvm/include/{s390x => s390}/debug_print.h |   0
>  .../{s390x => s390}/diag318_test_handler.h    |   0
>  .../kvm/include/{s390x => s390}/facility.h    |   0
>  .../include/{s390x => s390}/kvm_util_arch.h   |   0
>  .../kvm/include/{s390x => s390}/processor.h   |   0
>  .../kvm/include/{s390x => s390}/sie.h         |   0
>  .../kvm/include/{s390x => s390}/ucall.h       |   0
>  .../kvm/include/{x86_64 => x86}/apic.h        |   2 -
>  .../kvm/include/{x86_64 => x86}/evmcs.h       |   3 -
>  .../kvm/include/{x86_64 => x86}/hyperv.h      |   3 -
>  .../include/{x86_64 => x86}/kvm_util_arch.h   |   0
>  .../kvm/include/{x86_64 => x86}/mce.h         |   2 -
>  .../kvm/include/{x86_64 => x86}/pmu.h         |   0
>  .../kvm/include/{x86_64 => x86}/processor.h   |   2 -
>  .../kvm/include/{x86_64 => x86}/sev.h         |   0
>  .../kvm/include/{x86_64 => x86}/svm.h         |   6 -
>  .../kvm/include/{x86_64 => x86}/svm_util.h    |   3 -
>  .../kvm/include/{x86_64 => x86}/ucall.h       |   0
>  .../kvm/include/{x86_64 => x86}/vmx.h         |   2 -
>  .../kvm/lib/{aarch64 => arm64}/gic.c          |   0
>  .../kvm/lib/{aarch64 => arm64}/gic_private.h  |   0
>  .../kvm/lib/{aarch64 => arm64}/gic_v3.c       |   0
>  .../kvm/lib/{aarch64 => arm64}/gic_v3_its.c   |   0
>  .../kvm/lib/{aarch64 => arm64}/handlers.S     |   0
>  .../kvm/lib/{aarch64 => arm64}/processor.c    |   0
>  .../kvm/lib/{aarch64 => arm64}/spinlock.c     |   0
>  .../kvm/lib/{aarch64 => arm64}/ucall.c        |   0
>  .../kvm/lib/{aarch64 => arm64}/vgic.c         |   0
>  .../{s390x => s390}/diag318_test_handler.c    |   0
>  .../kvm/lib/{s390x => s390}/facility.c        |   0
>  .../kvm/lib/{s390x => s390}/processor.c       |   0
>  .../selftests/kvm/lib/{s390x => s390}/ucall.c |   0
>  .../selftests/kvm/lib/{x86_64 => x86}/apic.c  |   0
>  .../kvm/lib/{x86_64 => x86}/handlers.S        |   0
>  .../kvm/lib/{x86_64 => x86}/hyperv.c          |   0
>  .../kvm/lib/{x86_64 => x86}/memstress.c       |   2 +-
>  .../selftests/kvm/lib/{x86_64 => x86}/pmu.c   |   0
>  .../kvm/lib/{x86_64 => x86}/processor.c       |   2 -
>  .../selftests/kvm/lib/{x86_64 => x86}/sev.c   |   0
>  .../selftests/kvm/lib/{x86_64 => x86}/svm.c   |   1 -
>  .../selftests/kvm/lib/{x86_64 => x86}/ucall.c |   0
>  .../selftests/kvm/lib/{x86_64 => x86}/vmx.c   |   2 -
>  .../selftests/kvm/{s390x => s390}/cmma_test.c |   0
>  .../selftests/kvm/{s390x => s390}/config      |   0
>  .../{s390x => s390}/cpumodel_subfuncs_test.c  |   0
>  .../kvm/{s390x => s390}/debug_test.c          |   0
>  .../selftests/kvm/{s390x => s390}/memop.c     |   0
>  .../selftests/kvm/{s390x => s390}/resets.c    |   0
>  .../{s390x => s390}/shared_zeropage_test.c    |   0
>  .../kvm/{s390x => s390}/sync_regs_test.c      |   0
>  .../selftests/kvm/{s390x => s390}/tprot.c     |   0
>  .../kvm/{s390x => s390}/ucontrol_test.c       |   0
>  .../selftests/kvm/set_memory_region_test.c    |   6 +-
>  .../selftests/kvm/{x86_64 => x86}/amx_test.c  |   0
>  .../kvm/{x86_64 => x86}/apic_bus_clock_test.c |   0
>  .../kvm/{x86_64 => x86}/cpuid_test.c          |   0
>  .../kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c |   0
>  .../kvm/{x86_64 => x86}/debug_regs.c          |   0
>  .../dirty_log_page_splitting_test.c           |   0
>  .../exit_on_emulation_failure_test.c          |   0
>  .../kvm/{x86_64 => x86}/feature_msrs_test.c   |   0
>  .../kvm/{x86_64 => x86}/fix_hypercall_test.c  |   0
>  .../kvm/{x86_64 => x86}/flds_emulation.h      |   0
>  .../kvm/{x86_64 => x86}/hwcr_msr_test.c       |   0
>  .../kvm/{x86_64 => x86}/hyperv_clock.c        |   0
>  .../kvm/{x86_64 => x86}/hyperv_cpuid.c        |   0
>  .../kvm/{x86_64 => x86}/hyperv_evmcs.c        |   0
>  .../hyperv_extended_hypercalls.c              |   0
>  .../kvm/{x86_64 => x86}/hyperv_features.c     |   0
>  .../kvm/{x86_64 => x86}/hyperv_ipi.c          |   0
>  .../kvm/{x86_64 => x86}/hyperv_svm_test.c     |   0
>  .../kvm/{x86_64 => x86}/hyperv_tlb_flush.c    |   0
>  .../kvm/{x86_64 => x86}/kvm_clock_test.c      |   0
>  .../kvm/{x86_64 => x86}/kvm_pv_test.c         |   0
>  .../kvm/{x86_64 => x86}/max_vcpuid_cap_test.c |   0
>  .../kvm/{x86_64 => x86}/monitor_mwait_test.c  |   0
>  .../{x86_64 => x86}/nested_exceptions_test.c  |   0
>  .../kvm/{x86_64 => x86}/nx_huge_pages_test.c  |   0
>  .../kvm/{x86_64 => x86}/nx_huge_pages_test.sh |   0
>  .../kvm/{x86_64 => x86}/platform_info_test.c  |   0
>  .../kvm/{x86_64 => x86}/pmu_counters_test.c   |   0
>  .../{x86_64 => x86}/pmu_event_filter_test.c   |   0
>  .../private_mem_conversions_test.c            |   0
>  .../private_mem_kvm_exits_test.c              |   0
>  .../{x86_64 => x86}/recalc_apic_map_test.c    |   0
>  .../kvm/{x86_64 => x86}/set_boot_cpu_id.c     |   0
>  .../kvm/{x86_64 => x86}/set_sregs_test.c      |   0
>  .../kvm/{x86_64 => x86}/sev_init2_tests.c     |   0
>  .../kvm/{x86_64 => x86}/sev_migrate_tests.c   |   0
>  .../kvm/{x86_64 => x86}/sev_smoke_test.c      |   0
>  .../smaller_maxphyaddr_emulation_test.c       |   0
>  .../selftests/kvm/{x86_64 => x86}/smm_test.c  |   0
>  .../kvm/{x86_64 => x86}/state_test.c          |   0
>  .../kvm/{x86_64 => x86}/svm_int_ctl_test.c    |   0
>  .../svm_nested_shutdown_test.c                |   0
>  .../svm_nested_soft_inject_test.c             |   0
>  .../kvm/{x86_64 => x86}/svm_vmcall_test.c     |   0
>  .../kvm/{x86_64 => x86}/sync_regs_test.c      |   0
>  .../{x86_64 => x86}/triple_fault_event_test.c |   0
>  .../kvm/{x86_64 => x86}/tsc_msrs_test.c       |   0
>  .../kvm/{x86_64 => x86}/tsc_scaling_sync.c    |   0
>  .../kvm/{x86_64 => x86}/ucna_injection_test.c |   0
>  .../kvm/{x86_64 => x86}/userspace_io_test.c   |   0
>  .../{x86_64 => x86}/userspace_msr_exit_test.c |   0
>  .../{x86_64 => x86}/vmx_apic_access_test.c    |   0
>  .../vmx_close_while_nested_test.c             |   0
>  .../kvm/{x86_64 => x86}/vmx_dirty_log_test.c  |   0
>  .../vmx_exception_with_invalid_guest_state.c  |   0
>  .../vmx_invalid_nested_guest_state.c          |   0
>  .../kvm/{x86_64 => x86}/vmx_msrs_test.c       |   0
>  .../vmx_nested_tsc_scaling_test.c             |   0
>  .../kvm/{x86_64 => x86}/vmx_pmu_caps_test.c   |   0
>  .../vmx_preemption_timer_test.c               |   0
>  .../vmx_set_nested_state_test.c               |   0
>  .../kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c |   0
>  .../kvm/{x86_64 => x86}/xapic_ipi_test.c      |   0
>  .../kvm/{x86_64 => x86}/xapic_state_test.c    |   0
>  .../kvm/{x86_64 => x86}/xcr0_cpuid_test.c     |   0
>  .../kvm/{x86_64 => x86}/xen_shinfo_test.c     |   0
>  .../kvm/{x86_64 => x86}/xen_vmcall_test.c     |   0
>  .../kvm/{x86_64 => x86}/xss_msr_test.c        |   0
>  152 files changed, 172 insertions(+), 208 deletions(-)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/aarch32_id_regs.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/arch_timer_edge_cases.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/debug-exceptions.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/get-reg-list.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/hypercalls.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/mmio_abort.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/no-vgic-v3.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/page_fault_test.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/psci_test.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/set_id_regs.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/smccc_filter.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vcpu_width_config.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_init.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_irq.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vgic_lpi_stress.c (100%)
>  rename tools/testing/selftests/kvm/{aarch64 => arm64}/vpmu_counter_access.c (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/arch_timer.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/delay.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/gic_v3_its.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/kvm_util_arch.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/processor.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/spinlock.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/ucall.h (100%)
>  rename tools/testing/selftests/kvm/include/{aarch64 => arm64}/vgic.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/debug_print.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/diag318_test_handler.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/facility.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/kvm_util_arch.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/processor.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/sie.h (100%)
>  rename tools/testing/selftests/kvm/include/{s390x => s390}/ucall.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/apic.h (98%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/evmcs.h (99%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/hyperv.h (99%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/kvm_util_arch.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/mce.h (94%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/pmu.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/processor.h (99%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/sev.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm.h (98%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/svm_util.h (94%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/ucall.h (100%)
>  rename tools/testing/selftests/kvm/include/{x86_64 => x86}/vmx.h (99%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_private.h (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/gic_v3_its.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/handlers.S (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/processor.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/spinlock.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/ucall.c (100%)
>  rename tools/testing/selftests/kvm/lib/{aarch64 => arm64}/vgic.c (100%)
>  rename tools/testing/selftests/kvm/lib/{s390x => s390}/diag318_test_handler.c (100%)
>  rename tools/testing/selftests/kvm/lib/{s390x => s390}/facility.c (100%)
>  rename tools/testing/selftests/kvm/lib/{s390x => s390}/processor.c (100%)
>  rename tools/testing/selftests/kvm/lib/{s390x => s390}/ucall.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/apic.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/handlers.S (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/hyperv.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/memstress.c (98%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/pmu.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/processor.c (99%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/sev.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/svm.c (99%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/ucall.c (100%)
>  rename tools/testing/selftests/kvm/lib/{x86_64 => x86}/vmx.c (99%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/cmma_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/config (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/cpumodel_subfuncs_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/debug_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/memop.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/resets.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/shared_zeropage_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/sync_regs_test.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/tprot.c (100%)
>  rename tools/testing/selftests/kvm/{s390x => s390}/ucontrol_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/amx_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/apic_bus_clock_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/cpuid_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/cr4_cpuid_sync_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/debug_regs.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/dirty_log_page_splitting_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/exit_on_emulation_failure_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/feature_msrs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/fix_hypercall_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/flds_emulation.h (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hwcr_msr_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_clock.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_cpuid.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_evmcs.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_extended_hypercalls.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_features.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_ipi.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_svm_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/hyperv_tlb_flush.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_clock_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/kvm_pv_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/max_vcpuid_cap_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/monitor_mwait_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/nested_exceptions_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/nx_huge_pages_test.sh (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/platform_info_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_counters_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/pmu_event_filter_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_conversions_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/private_mem_kvm_exits_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/recalc_apic_map_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/set_boot_cpu_id.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/set_sregs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_init2_tests.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_migrate_tests.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/sev_smoke_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/smaller_maxphyaddr_emulation_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/smm_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/state_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_int_ctl_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_shutdown_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_nested_soft_inject_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/svm_vmcall_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/sync_regs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/triple_fault_event_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_msrs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/tsc_scaling_sync.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/ucna_injection_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_io_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/userspace_msr_exit_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_apic_access_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_close_while_nested_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_dirty_log_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_exception_with_invalid_guest_state.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_invalid_nested_guest_state.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_msrs_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_nested_tsc_scaling_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_pmu_caps_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_preemption_timer_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_set_nested_state_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/vmx_tsc_adjust_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_ipi_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xapic_state_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xcr0_cpuid_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_shinfo_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xen_vmcall_test.c (100%)
>  rename tools/testing/selftests/kvm/{x86_64 => x86}/xss_msr_test.c (100%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 21fdaa19229a..c2939c8f7ce4 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -12461,8 +12461,8 @@ F:	arch/arm64/include/asm/kvm*
>  F:	arch/arm64/include/uapi/asm/kvm*
>  F:	arch/arm64/kvm/
>  F:	include/kvm/arm_*
> -F:	tools/testing/selftests/kvm/*/aarch64/
> -F:	tools/testing/selftests/kvm/aarch64/
> +F:	tools/testing/selftests/kvm/*/arm64/
> +F:	tools/testing/selftests/kvm/arm64/
>  
>  KERNEL VIRTUAL MACHINE FOR LOONGARCH (KVM/LoongArch)
>  M:	Tianrui Zhao <zhaotianrui at loongson.cn>
> @@ -12533,8 +12533,8 @@ F:	arch/s390/kvm/
>  F:	arch/s390/mm/gmap.c
>  F:	drivers/s390/char/uvdevice.c
>  F:	tools/testing/selftests/drivers/s390x/uvdevice/
> -F:	tools/testing/selftests/kvm/*/s390x/
> -F:	tools/testing/selftests/kvm/s390x/
> +F:	tools/testing/selftests/kvm/*/s390/
> +F:	tools/testing/selftests/kvm/s390/
>  
>  KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86)
>  M:	Sean Christopherson <seanjc at google.com>
> @@ -12551,8 +12551,8 @@ F:	arch/x86/include/uapi/asm/svm.h
>  F:	arch/x86/include/uapi/asm/vmx.h
>  F:	arch/x86/kvm/
>  F:	arch/x86/kvm/*/
> -F:	tools/testing/selftests/kvm/*/x86_64/
> -F:	tools/testing/selftests/kvm/x86_64/
> +F:	tools/testing/selftests/kvm/*/x86/
> +F:	tools/testing/selftests/kvm/x86/
>  
>  KERNFS
>  M:	Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> index 7b33464bf8cc..9bc2eba1af1c 100644
> --- a/tools/testing/selftests/kvm/Makefile
> +++ b/tools/testing/selftests/kvm/Makefile
> @@ -4,16 +4,12 @@ include $(top_srcdir)/scripts/subarch.include
>  ARCH            ?= $(SUBARCH)
>  
>  ifeq ($(ARCH),$(filter $(ARCH),arm64 s390 riscv x86 x86_64))
> -ifeq ($(ARCH),x86)
> -	ARCH_DIR := x86_64
> -else ifeq ($(ARCH),arm64)
> -	ARCH_DIR := aarch64
> -else ifeq ($(ARCH),s390)
> -	ARCH_DIR := s390x
> +# Top-level selftests allows ARCH=x86_64 :-(
> +ifeq ($(ARCH),x86_64)
> +	ARCH_DIR := x86
>  else
>  	ARCH_DIR := $(ARCH)
>  endif
> -
>  include Makefile.kvm
>  else
>  # Empty targets for unsupported architectures
> diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
> index e988a72f8c20..9888dd6bb483 100644
> --- a/tools/testing/selftests/kvm/Makefile.kvm
> +++ b/tools/testing/selftests/kvm/Makefile.kvm
> @@ -18,177 +18,177 @@ LIBKVM += lib/userfaultfd_util.c
>  
>  LIBKVM_STRING += lib/string_override.c
>  
> -LIBKVM_x86_64 += lib/x86_64/apic.c
> -LIBKVM_x86_64 += lib/x86_64/handlers.S
> -LIBKVM_x86_64 += lib/x86_64/hyperv.c
> -LIBKVM_x86_64 += lib/x86_64/memstress.c
> -LIBKVM_x86_64 += lib/x86_64/pmu.c
> -LIBKVM_x86_64 += lib/x86_64/processor.c
> -LIBKVM_x86_64 += lib/x86_64/sev.c
> -LIBKVM_x86_64 += lib/x86_64/svm.c
> -LIBKVM_x86_64 += lib/x86_64/ucall.c
> -LIBKVM_x86_64 += lib/x86_64/vmx.c
> +LIBKVM_x86 += lib/x86/apic.c
> +LIBKVM_x86 += lib/x86/handlers.S
> +LIBKVM_x86 += lib/x86/hyperv.c
> +LIBKVM_x86 += lib/x86/memstress.c
> +LIBKVM_x86 += lib/x86/pmu.c
> +LIBKVM_x86 += lib/x86/processor.c
> +LIBKVM_x86 += lib/x86/sev.c
> +LIBKVM_x86 += lib/x86/svm.c
> +LIBKVM_x86 += lib/x86/ucall.c
> +LIBKVM_x86 += lib/x86/vmx.c
>  
> -LIBKVM_aarch64 += lib/aarch64/gic.c
> -LIBKVM_aarch64 += lib/aarch64/gic_v3.c
> -LIBKVM_aarch64 += lib/aarch64/gic_v3_its.c
> -LIBKVM_aarch64 += lib/aarch64/handlers.S
> -LIBKVM_aarch64 += lib/aarch64/processor.c
> -LIBKVM_aarch64 += lib/aarch64/spinlock.c
> -LIBKVM_aarch64 += lib/aarch64/ucall.c
> -LIBKVM_aarch64 += lib/aarch64/vgic.c
> +LIBKVM_arm64 += lib/arm64/gic.c
> +LIBKVM_arm64 += lib/arm64/gic_v3.c
> +LIBKVM_arm64 += lib/arm64/gic_v3_its.c
> +LIBKVM_arm64 += lib/arm64/handlers.S
> +LIBKVM_arm64 += lib/arm64/processor.c
> +LIBKVM_arm64 += lib/arm64/spinlock.c
> +LIBKVM_arm64 += lib/arm64/ucall.c
> +LIBKVM_arm64 += lib/arm64/vgic.c
>  
> -LIBKVM_s390x += lib/s390x/diag318_test_handler.c
> -LIBKVM_s390x += lib/s390x/processor.c
> -LIBKVM_s390x += lib/s390x/ucall.c
> -LIBKVM_s390x += lib/s390x/facility.c
> +LIBKVM_s390 += lib/s390/diag318_test_handler.c
> +LIBKVM_s390 += lib/s390/processor.c
> +LIBKVM_s390 += lib/s390/ucall.c
> +LIBKVM_s390 += lib/s390/facility.c
>  
>  LIBKVM_riscv += lib/riscv/handlers.S
>  LIBKVM_riscv += lib/riscv/processor.c
>  LIBKVM_riscv += lib/riscv/ucall.c
>  
>  # Non-compiled test targets
> -TEST_PROGS_x86_64 += x86_64/nx_huge_pages_test.sh
> +TEST_PROGS_x86 += x86/nx_huge_pages_test.sh
>  
>  # Compiled test targets
> -TEST_GEN_PROGS_x86_64 = x86_64/cpuid_test
> -TEST_GEN_PROGS_x86_64 += x86_64/cr4_cpuid_sync_test
> -TEST_GEN_PROGS_x86_64 += x86_64/dirty_log_page_splitting_test
> -TEST_GEN_PROGS_x86_64 += x86_64/feature_msrs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/exit_on_emulation_failure_test
> -TEST_GEN_PROGS_x86_64 += x86_64/fix_hypercall_test
> -TEST_GEN_PROGS_x86_64 += x86_64/hwcr_msr_test
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_evmcs
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_extended_hypercalls
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_ipi
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_svm_test
> -TEST_GEN_PROGS_x86_64 += x86_64/hyperv_tlb_flush
> -TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test
> -TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test
> -TEST_GEN_PROGS_x86_64 += x86_64/monitor_mwait_test
> -TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test
> -TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test
> -TEST_GEN_PROGS_x86_64 += x86_64/pmu_counters_test
> -TEST_GEN_PROGS_x86_64 += x86_64/pmu_event_filter_test
> -TEST_GEN_PROGS_x86_64 += x86_64/private_mem_conversions_test
> -TEST_GEN_PROGS_x86_64 += x86_64/private_mem_kvm_exits_test
> -TEST_GEN_PROGS_x86_64 += x86_64/set_boot_cpu_id
> -TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/smaller_maxphyaddr_emulation_test
> -TEST_GEN_PROGS_x86_64 += x86_64/smm_test
> -TEST_GEN_PROGS_x86_64 += x86_64/state_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_preemption_timer_test
> -TEST_GEN_PROGS_x86_64 += x86_64/svm_vmcall_test
> -TEST_GEN_PROGS_x86_64 += x86_64/svm_int_ctl_test
> -TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_shutdown_test
> -TEST_GEN_PROGS_x86_64 += x86_64/svm_nested_soft_inject_test
> -TEST_GEN_PROGS_x86_64 += x86_64/tsc_scaling_sync
> -TEST_GEN_PROGS_x86_64 += x86_64/sync_regs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/ucna_injection_test
> -TEST_GEN_PROGS_x86_64 += x86_64/userspace_io_test
> -TEST_GEN_PROGS_x86_64 += x86_64/userspace_msr_exit_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_apic_access_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_close_while_nested_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_dirty_log_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_exception_with_invalid_guest_state
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_msrs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_invalid_nested_guest_state
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_nested_tsc_scaling_test
> -TEST_GEN_PROGS_x86_64 += x86_64/apic_bus_clock_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xapic_ipi_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xapic_state_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xcr0_cpuid_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xss_msr_test
> -TEST_GEN_PROGS_x86_64 += x86_64/debug_regs
> -TEST_GEN_PROGS_x86_64 += x86_64/tsc_msrs_test
> -TEST_GEN_PROGS_x86_64 += x86_64/vmx_pmu_caps_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xen_shinfo_test
> -TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test
> -TEST_GEN_PROGS_x86_64 += x86_64/sev_init2_tests
> -TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests
> -TEST_GEN_PROGS_x86_64 += x86_64/sev_smoke_test
> -TEST_GEN_PROGS_x86_64 += x86_64/amx_test
> -TEST_GEN_PROGS_x86_64 += x86_64/max_vcpuid_cap_test
> -TEST_GEN_PROGS_x86_64 += x86_64/triple_fault_event_test
> -TEST_GEN_PROGS_x86_64 += x86_64/recalc_apic_map_test
> -TEST_GEN_PROGS_x86_64 += access_tracking_perf_test
> -TEST_GEN_PROGS_x86_64 += coalesced_io_test
> -TEST_GEN_PROGS_x86_64 += demand_paging_test
> -TEST_GEN_PROGS_x86_64 += dirty_log_test
> -TEST_GEN_PROGS_x86_64 += dirty_log_perf_test
> -TEST_GEN_PROGS_x86_64 += guest_memfd_test
> -TEST_GEN_PROGS_x86_64 += guest_print_test
> -TEST_GEN_PROGS_x86_64 += hardware_disable_test
> -TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
> -TEST_GEN_PROGS_x86_64 += kvm_page_table_test
> -TEST_GEN_PROGS_x86_64 += mmu_stress_test
> -TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
> -TEST_GEN_PROGS_x86_64 += memslot_perf_test
> -TEST_GEN_PROGS_x86_64 += rseq_test
> -TEST_GEN_PROGS_x86_64 += set_memory_region_test
> -TEST_GEN_PROGS_x86_64 += steal_time
> -TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
> -TEST_GEN_PROGS_x86_64 += system_counter_offset_test
> -TEST_GEN_PROGS_x86_64 += pre_fault_memory_test
> +TEST_GEN_PROGS_x86 = x86/cpuid_test
> +TEST_GEN_PROGS_x86 += x86/cr4_cpuid_sync_test
> +TEST_GEN_PROGS_x86 += x86/dirty_log_page_splitting_test
> +TEST_GEN_PROGS_x86 += x86/feature_msrs_test
> +TEST_GEN_PROGS_x86 += x86/exit_on_emulation_failure_test
> +TEST_GEN_PROGS_x86 += x86/fix_hypercall_test
> +TEST_GEN_PROGS_x86 += x86/hwcr_msr_test
> +TEST_GEN_PROGS_x86 += x86/hyperv_clock
> +TEST_GEN_PROGS_x86 += x86/hyperv_cpuid
> +TEST_GEN_PROGS_x86 += x86/hyperv_evmcs
> +TEST_GEN_PROGS_x86 += x86/hyperv_extended_hypercalls
> +TEST_GEN_PROGS_x86 += x86/hyperv_features
> +TEST_GEN_PROGS_x86 += x86/hyperv_ipi
> +TEST_GEN_PROGS_x86 += x86/hyperv_svm_test
> +TEST_GEN_PROGS_x86 += x86/hyperv_tlb_flush
> +TEST_GEN_PROGS_x86 += x86/kvm_clock_test
> +TEST_GEN_PROGS_x86 += x86/kvm_pv_test
> +TEST_GEN_PROGS_x86 += x86/monitor_mwait_test
> +TEST_GEN_PROGS_x86 += x86/nested_exceptions_test
> +TEST_GEN_PROGS_x86 += x86/platform_info_test
> +TEST_GEN_PROGS_x86 += x86/pmu_counters_test
> +TEST_GEN_PROGS_x86 += x86/pmu_event_filter_test
> +TEST_GEN_PROGS_x86 += x86/private_mem_conversions_test
> +TEST_GEN_PROGS_x86 += x86/private_mem_kvm_exits_test
> +TEST_GEN_PROGS_x86 += x86/set_boot_cpu_id
> +TEST_GEN_PROGS_x86 += x86/set_sregs_test
> +TEST_GEN_PROGS_x86 += x86/smaller_maxphyaddr_emulation_test
> +TEST_GEN_PROGS_x86 += x86/smm_test
> +TEST_GEN_PROGS_x86 += x86/state_test
> +TEST_GEN_PROGS_x86 += x86/vmx_preemption_timer_test
> +TEST_GEN_PROGS_x86 += x86/svm_vmcall_test
> +TEST_GEN_PROGS_x86 += x86/svm_int_ctl_test
> +TEST_GEN_PROGS_x86 += x86/svm_nested_shutdown_test
> +TEST_GEN_PROGS_x86 += x86/svm_nested_soft_inject_test
> +TEST_GEN_PROGS_x86 += x86/tsc_scaling_sync
> +TEST_GEN_PROGS_x86 += x86/sync_regs_test
> +TEST_GEN_PROGS_x86 += x86/ucna_injection_test
> +TEST_GEN_PROGS_x86 += x86/userspace_io_test
> +TEST_GEN_PROGS_x86 += x86/userspace_msr_exit_test
> +TEST_GEN_PROGS_x86 += x86/vmx_apic_access_test
> +TEST_GEN_PROGS_x86 += x86/vmx_close_while_nested_test
> +TEST_GEN_PROGS_x86 += x86/vmx_dirty_log_test
> +TEST_GEN_PROGS_x86 += x86/vmx_exception_with_invalid_guest_state
> +TEST_GEN_PROGS_x86 += x86/vmx_msrs_test
> +TEST_GEN_PROGS_x86 += x86/vmx_invalid_nested_guest_state
> +TEST_GEN_PROGS_x86 += x86/vmx_set_nested_state_test
> +TEST_GEN_PROGS_x86 += x86/vmx_tsc_adjust_test
> +TEST_GEN_PROGS_x86 += x86/vmx_nested_tsc_scaling_test
> +TEST_GEN_PROGS_x86 += x86/apic_bus_clock_test
> +TEST_GEN_PROGS_x86 += x86/xapic_ipi_test
> +TEST_GEN_PROGS_x86 += x86/xapic_state_test
> +TEST_GEN_PROGS_x86 += x86/xcr0_cpuid_test
> +TEST_GEN_PROGS_x86 += x86/xss_msr_test
> +TEST_GEN_PROGS_x86 += x86/debug_regs
> +TEST_GEN_PROGS_x86 += x86/tsc_msrs_test
> +TEST_GEN_PROGS_x86 += x86/vmx_pmu_caps_test
> +TEST_GEN_PROGS_x86 += x86/xen_shinfo_test
> +TEST_GEN_PROGS_x86 += x86/xen_vmcall_test
> +TEST_GEN_PROGS_x86 += x86/sev_init2_tests
> +TEST_GEN_PROGS_x86 += x86/sev_migrate_tests
> +TEST_GEN_PROGS_x86 += x86/sev_smoke_test
> +TEST_GEN_PROGS_x86 += x86/amx_test
> +TEST_GEN_PROGS_x86 += x86/max_vcpuid_cap_test
> +TEST_GEN_PROGS_x86 += x86/triple_fault_event_test
> +TEST_GEN_PROGS_x86 += x86/recalc_apic_map_test
> +TEST_GEN_PROGS_x86 += access_tracking_perf_test
> +TEST_GEN_PROGS_x86 += coalesced_io_test
> +TEST_GEN_PROGS_x86 += demand_paging_test
> +TEST_GEN_PROGS_x86 += dirty_log_test
> +TEST_GEN_PROGS_x86 += dirty_log_perf_test
> +TEST_GEN_PROGS_x86 += guest_memfd_test
> +TEST_GEN_PROGS_x86 += guest_print_test
> +TEST_GEN_PROGS_x86 += hardware_disable_test
> +TEST_GEN_PROGS_x86 += kvm_create_max_vcpus
> +TEST_GEN_PROGS_x86 += kvm_page_table_test
> +TEST_GEN_PROGS_x86 += memslot_modification_stress_test
> +TEST_GEN_PROGS_x86 += memslot_perf_test
> +TEST_GEN_PROGS_x86 += mmu_stress_test
> +TEST_GEN_PROGS_x86 += rseq_test
> +TEST_GEN_PROGS_x86 += set_memory_region_test
> +TEST_GEN_PROGS_x86 += steal_time
> +TEST_GEN_PROGS_x86 += kvm_binary_stats_test
> +TEST_GEN_PROGS_x86 += system_counter_offset_test
> +TEST_GEN_PROGS_x86 += pre_fault_memory_test
>  
>  # Compiled outputs used by test targets
> -TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
> +TEST_GEN_PROGS_EXTENDED_x86 += x86/nx_huge_pages_test
>  
> -TEST_GEN_PROGS_aarch64 += aarch64/aarch32_id_regs
> -TEST_GEN_PROGS_aarch64 += aarch64/arch_timer_edge_cases
> -TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
> -TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
> -TEST_GEN_PROGS_aarch64 += aarch64/mmio_abort
> -TEST_GEN_PROGS_aarch64 += aarch64/page_fault_test
> -TEST_GEN_PROGS_aarch64 += aarch64/psci_test
> -TEST_GEN_PROGS_aarch64 += aarch64/set_id_regs
> -TEST_GEN_PROGS_aarch64 += aarch64/smccc_filter
> -TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
> -TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
> -TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq
> -TEST_GEN_PROGS_aarch64 += aarch64/vgic_lpi_stress
> -TEST_GEN_PROGS_aarch64 += aarch64/vpmu_counter_access
> -TEST_GEN_PROGS_aarch64 += aarch64/no-vgic-v3
> -TEST_GEN_PROGS_aarch64 += access_tracking_perf_test
> -TEST_GEN_PROGS_aarch64 += arch_timer
> -TEST_GEN_PROGS_aarch64 += coalesced_io_test
> -TEST_GEN_PROGS_aarch64 += demand_paging_test
> -TEST_GEN_PROGS_aarch64 += dirty_log_test
> -TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
> -TEST_GEN_PROGS_aarch64 += guest_print_test
> -TEST_GEN_PROGS_aarch64 += get-reg-list
> -TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
> -TEST_GEN_PROGS_aarch64 += kvm_page_table_test
> -TEST_GEN_PROGS_aarch64 += memslot_modification_stress_test
> -TEST_GEN_PROGS_aarch64 += memslot_perf_test
> -TEST_GEN_PROGS_aarch64 += mmu_stress_test
> -TEST_GEN_PROGS_aarch64 += rseq_test
> -TEST_GEN_PROGS_aarch64 += set_memory_region_test
> -TEST_GEN_PROGS_aarch64 += steal_time
> -TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
> +TEST_GEN_PROGS_arm64 += arm64/aarch32_id_regs
> +TEST_GEN_PROGS_arm64 += arm64/arch_timer_edge_cases
> +TEST_GEN_PROGS_arm64 += arm64/debug-exceptions
> +TEST_GEN_PROGS_arm64 += arm64/hypercalls
> +TEST_GEN_PROGS_arm64 += arm64/mmio_abort
> +TEST_GEN_PROGS_arm64 += arm64/page_fault_test
> +TEST_GEN_PROGS_arm64 += arm64/psci_test
> +TEST_GEN_PROGS_arm64 += arm64/set_id_regs
> +TEST_GEN_PROGS_arm64 += arm64/smccc_filter
> +TEST_GEN_PROGS_arm64 += arm64/vcpu_width_config
> +TEST_GEN_PROGS_arm64 += arm64/vgic_init
> +TEST_GEN_PROGS_arm64 += arm64/vgic_irq
> +TEST_GEN_PROGS_arm64 += arm64/vgic_lpi_stress
> +TEST_GEN_PROGS_arm64 += arm64/vpmu_counter_access
> +TEST_GEN_PROGS_arm64 += arm64/no-vgic-v3
> +TEST_GEN_PROGS_arm64 += access_tracking_perf_test
> +TEST_GEN_PROGS_arm64 += arch_timer
> +TEST_GEN_PROGS_arm64 += coalesced_io_test
> +TEST_GEN_PROGS_arm64 += demand_paging_test
> +TEST_GEN_PROGS_arm64 += dirty_log_test
> +TEST_GEN_PROGS_arm64 += dirty_log_perf_test
> +TEST_GEN_PROGS_arm64 += guest_print_test
> +TEST_GEN_PROGS_arm64 += get-reg-list
> +TEST_GEN_PROGS_arm64 += kvm_create_max_vcpus
> +TEST_GEN_PROGS_arm64 += kvm_page_table_test
> +TEST_GEN_PROGS_arm64 += memslot_modification_stress_test
> +TEST_GEN_PROGS_arm64 += memslot_perf_test
> +TEST_GEN_PROGS_arm64 += mmu_stress_test
> +TEST_GEN_PROGS_arm64 += rseq_test
> +TEST_GEN_PROGS_arm64 += set_memory_region_test
> +TEST_GEN_PROGS_arm64 += steal_time
> +TEST_GEN_PROGS_arm64 += kvm_binary_stats_test
>  
> -TEST_GEN_PROGS_s390x = s390x/memop
> -TEST_GEN_PROGS_s390x += s390x/resets
> -TEST_GEN_PROGS_s390x += s390x/sync_regs_test
> -TEST_GEN_PROGS_s390x += s390x/tprot
> -TEST_GEN_PROGS_s390x += s390x/cmma_test
> -TEST_GEN_PROGS_s390x += s390x/debug_test
> -TEST_GEN_PROGS_s390x += s390x/cpumodel_subfuncs_test
> -TEST_GEN_PROGS_s390x += s390x/shared_zeropage_test
> -TEST_GEN_PROGS_s390x += s390x/ucontrol_test
> -TEST_GEN_PROGS_s390x += demand_paging_test
> -TEST_GEN_PROGS_s390x += dirty_log_test
> -TEST_GEN_PROGS_s390x += guest_print_test
> -TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
> -TEST_GEN_PROGS_s390x += kvm_page_table_test
> -TEST_GEN_PROGS_s390x += rseq_test
> -TEST_GEN_PROGS_s390x += set_memory_region_test
> -TEST_GEN_PROGS_s390x += kvm_binary_stats_test
> +TEST_GEN_PROGS_s390 = s390/memop
> +TEST_GEN_PROGS_s390 += s390/resets
> +TEST_GEN_PROGS_s390 += s390/sync_regs_test
> +TEST_GEN_PROGS_s390 += s390/tprot
> +TEST_GEN_PROGS_s390 += s390/cmma_test
> +TEST_GEN_PROGS_s390 += s390/debug_test
> +TEST_GEN_PROGS_s390 += s390/cpumodel_subfuncs_test
> +TEST_GEN_PROGS_s390 += s390/shared_zeropage_test
> +TEST_GEN_PROGS_s390 += s390/ucontrol_test
> +TEST_GEN_PROGS_s390 += demand_paging_test
> +TEST_GEN_PROGS_s390 += dirty_log_test
> +TEST_GEN_PROGS_s390 += guest_print_test
> +TEST_GEN_PROGS_s390 += kvm_create_max_vcpus
> +TEST_GEN_PROGS_s390 += kvm_page_table_test
> +TEST_GEN_PROGS_s390 += rseq_test
> +TEST_GEN_PROGS_s390 += set_memory_region_test
> +TEST_GEN_PROGS_s390 += kvm_binary_stats_test
>  
>  TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
>  TEST_GEN_PROGS_riscv += riscv/ebreak_test
> @@ -222,11 +222,7 @@ include ../lib.mk
>  INSTALL_HDR_PATH = $(top_srcdir)/usr
>  LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
>  LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
> -ifeq ($(ARCH),x86_64)
> -LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include
> -else
> -LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
> -endif
> +LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH_DIR)/include
>  CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
>  	-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
>  	-fno-builtin-memcmp -fno-builtin-memcpy \
> diff --git a/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c b/tools/testing/selftests/kvm/arm64/aarch32_id_regs.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c
> rename to tools/testing/selftests/kvm/arm64/aarch32_id_regs.c
> diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/arm64/arch_timer.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/arch_timer.c
> rename to tools/testing/selftests/kvm/arm64/arch_timer.c
> diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer_edge_cases.c b/tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/arch_timer_edge_cases.c
> rename to tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c
> diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools/testing/selftests/kvm/arm64/debug-exceptions.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/debug-exceptions.c
> rename to tools/testing/selftests/kvm/arm64/debug-exceptions.c
> diff --git a/tools/testing/selftests/kvm/aarch64/get-reg-list.c b/tools/testing/selftests/kvm/arm64/get-reg-list.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/get-reg-list.c
> rename to tools/testing/selftests/kvm/arm64/get-reg-list.c
> diff --git a/tools/testing/selftests/kvm/aarch64/hypercalls.c b/tools/testing/selftests/kvm/arm64/hypercalls.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/hypercalls.c
> rename to tools/testing/selftests/kvm/arm64/hypercalls.c
> diff --git a/tools/testing/selftests/kvm/aarch64/mmio_abort.c b/tools/testing/selftests/kvm/arm64/mmio_abort.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/mmio_abort.c
> rename to tools/testing/selftests/kvm/arm64/mmio_abort.c
> diff --git a/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c b/tools/testing/selftests/kvm/arm64/no-vgic-v3.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/no-vgic-v3.c
> rename to tools/testing/selftests/kvm/arm64/no-vgic-v3.c
> diff --git a/tools/testing/selftests/kvm/aarch64/page_fault_test.c b/tools/testing/selftests/kvm/arm64/page_fault_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/page_fault_test.c
> rename to tools/testing/selftests/kvm/arm64/page_fault_test.c
> diff --git a/tools/testing/selftests/kvm/aarch64/psci_test.c b/tools/testing/selftests/kvm/arm64/psci_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/psci_test.c
> rename to tools/testing/selftests/kvm/arm64/psci_test.c
> diff --git a/tools/testing/selftests/kvm/aarch64/set_id_regs.c b/tools/testing/selftests/kvm/arm64/set_id_regs.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/set_id_regs.c
> rename to tools/testing/selftests/kvm/arm64/set_id_regs.c
> diff --git a/tools/testing/selftests/kvm/aarch64/smccc_filter.c b/tools/testing/selftests/kvm/arm64/smccc_filter.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/smccc_filter.c
> rename to tools/testing/selftests/kvm/arm64/smccc_filter.c
> diff --git a/tools/testing/selftests/kvm/aarch64/vcpu_width_config.c b/tools/testing/selftests/kvm/arm64/vcpu_width_config.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/vcpu_width_config.c
> rename to tools/testing/selftests/kvm/arm64/vcpu_width_config.c
> diff --git a/tools/testing/selftests/kvm/aarch64/vgic_init.c b/tools/testing/selftests/kvm/arm64/vgic_init.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/vgic_init.c
> rename to tools/testing/selftests/kvm/arm64/vgic_init.c
> diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/arm64/vgic_irq.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/vgic_irq.c
> rename to tools/testing/selftests/kvm/arm64/vgic_irq.c
> diff --git a/tools/testing/selftests/kvm/aarch64/vgic_lpi_stress.c b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/vgic_lpi_stress.c
> rename to tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c
> diff --git a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
> rename to tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
> diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/testing/selftests/kvm/dirty_log_perf_test.c
> index 9f24303acb8c..e79817bd0e29 100644
> --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c
> +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c
> @@ -21,7 +21,7 @@
>  #include "ucall_common.h"
>  
>  #ifdef __aarch64__
> -#include "aarch64/vgic.h"
> +#include "arm64/vgic.h"
>  
>  static int gic_fd;
>  
> diff --git a/tools/testing/selftests/kvm/include/aarch64/arch_timer.h b/tools/testing/selftests/kvm/include/arm64/arch_timer.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/arch_timer.h
> rename to tools/testing/selftests/kvm/include/arm64/arch_timer.h
> diff --git a/tools/testing/selftests/kvm/include/aarch64/delay.h b/tools/testing/selftests/kvm/include/arm64/delay.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/delay.h
> rename to tools/testing/selftests/kvm/include/arm64/delay.h
> diff --git a/tools/testing/selftests/kvm/include/aarch64/gic.h b/tools/testing/selftests/kvm/include/arm64/gic.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/gic.h
> rename to tools/testing/selftests/kvm/include/arm64/gic.h
> diff --git a/tools/testing/selftests/kvm/include/aarch64/gic_v3.h b/tools/testing/selftests/kvm/include/arm64/gic_v3.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/gic_v3.h
> rename to tools/testing/selftests/kvm/include/arm64/gic_v3.h
> diff --git a/tools/testing/selftests/kvm/include/aarch64/gic_v3_its.h b/tools/testing/selftests/kvm/include/arm64/gic_v3_its.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/gic_v3_its.h
> rename to tools/testing/selftests/kvm/include/arm64/gic_v3_its.h
> diff --git a/tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/arm64/kvm_util_arch.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/kvm_util_arch.h
> rename to tools/testing/selftests/kvm/include/arm64/kvm_util_arch.h
> diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/arm64/processor.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/processor.h
> rename to tools/testing/selftests/kvm/include/arm64/processor.h
> diff --git a/tools/testing/selftests/kvm/include/aarch64/spinlock.h b/tools/testing/selftests/kvm/include/arm64/spinlock.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/spinlock.h
> rename to tools/testing/selftests/kvm/include/arm64/spinlock.h
> diff --git a/tools/testing/selftests/kvm/include/aarch64/ucall.h b/tools/testing/selftests/kvm/include/arm64/ucall.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/ucall.h
> rename to tools/testing/selftests/kvm/include/arm64/ucall.h
> diff --git a/tools/testing/selftests/kvm/include/aarch64/vgic.h b/tools/testing/selftests/kvm/include/arm64/vgic.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/aarch64/vgic.h
> rename to tools/testing/selftests/kvm/include/arm64/vgic.h
> diff --git a/tools/testing/selftests/kvm/include/s390x/debug_print.h b/tools/testing/selftests/kvm/include/s390/debug_print.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/s390x/debug_print.h
> rename to tools/testing/selftests/kvm/include/s390/debug_print.h
> diff --git a/tools/testing/selftests/kvm/include/s390x/diag318_test_handler.h b/tools/testing/selftests/kvm/include/s390/diag318_test_handler.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/s390x/diag318_test_handler.h
> rename to tools/testing/selftests/kvm/include/s390/diag318_test_handler.h
> diff --git a/tools/testing/selftests/kvm/include/s390x/facility.h b/tools/testing/selftests/kvm/include/s390/facility.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/s390x/facility.h
> rename to tools/testing/selftests/kvm/include/s390/facility.h
> diff --git a/tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h b/tools/testing/selftests/kvm/include/s390/kvm_util_arch.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/s390x/kvm_util_arch.h
> rename to tools/testing/selftests/kvm/include/s390/kvm_util_arch.h
> diff --git a/tools/testing/selftests/kvm/include/s390x/processor.h b/tools/testing/selftests/kvm/include/s390/processor.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/s390x/processor.h
> rename to tools/testing/selftests/kvm/include/s390/processor.h
> diff --git a/tools/testing/selftests/kvm/include/s390x/sie.h b/tools/testing/selftests/kvm/include/s390/sie.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/s390x/sie.h
> rename to tools/testing/selftests/kvm/include/s390/sie.h
> diff --git a/tools/testing/selftests/kvm/include/s390x/ucall.h b/tools/testing/selftests/kvm/include/s390/ucall.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/s390x/ucall.h
> rename to tools/testing/selftests/kvm/include/s390/ucall.h
> diff --git a/tools/testing/selftests/kvm/include/x86_64/apic.h b/tools/testing/selftests/kvm/include/x86/apic.h
> similarity index 98%
> rename from tools/testing/selftests/kvm/include/x86_64/apic.h
> rename to tools/testing/selftests/kvm/include/x86/apic.h
> index 51990094effd..80fe9f69b38d 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/apic.h
> +++ b/tools/testing/selftests/kvm/include/x86/apic.h
> @@ -1,7 +1,5 @@
>  /* SPDX-License-Identifier: GPL-2.0-only */
>  /*
> - * tools/testing/selftests/kvm/include/x86_64/apic.h
> - *
>   * Copyright (C) 2021, Google LLC.
>   */
>  
> diff --git a/tools/testing/selftests/kvm/include/x86_64/evmcs.h b/tools/testing/selftests/kvm/include/x86/evmcs.h
> similarity index 99%
> rename from tools/testing/selftests/kvm/include/x86_64/evmcs.h
> rename to tools/testing/selftests/kvm/include/x86/evmcs.h
> index 901caf0e0939..5a74bb30e2f8 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/evmcs.h
> +++ b/tools/testing/selftests/kvm/include/x86/evmcs.h
> @@ -1,9 +1,6 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
>  /*
> - * tools/testing/selftests/kvm/include/x86_64/evmcs.h
> - *
>   * Copyright (C) 2018, Red Hat, Inc.
> - *
>   */
>  
>  #ifndef SELFTEST_KVM_EVMCS_H
> diff --git a/tools/testing/selftests/kvm/include/x86_64/hyperv.h b/tools/testing/selftests/kvm/include/x86/hyperv.h
> similarity index 99%
> rename from tools/testing/selftests/kvm/include/x86_64/hyperv.h
> rename to tools/testing/selftests/kvm/include/x86/hyperv.h
> index 6849e2552f1b..f13e532be240 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/hyperv.h
> +++ b/tools/testing/selftests/kvm/include/x86/hyperv.h
> @@ -1,9 +1,6 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
>  /*
> - * tools/testing/selftests/kvm/include/x86_64/hyperv.h
> - *
>   * Copyright (C) 2021, Red Hat, Inc.
> - *
>   */
>  
>  #ifndef SELFTEST_KVM_HYPERV_H
> diff --git a/tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h b/tools/testing/selftests/kvm/include/x86/kvm_util_arch.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/x86_64/kvm_util_arch.h
> rename to tools/testing/selftests/kvm/include/x86/kvm_util_arch.h
> diff --git a/tools/testing/selftests/kvm/include/x86_64/mce.h b/tools/testing/selftests/kvm/include/x86/mce.h
> similarity index 94%
> rename from tools/testing/selftests/kvm/include/x86_64/mce.h
> rename to tools/testing/selftests/kvm/include/x86/mce.h
> index 6119321f3f5d..295f2d554754 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/mce.h
> +++ b/tools/testing/selftests/kvm/include/x86/mce.h
> @@ -1,7 +1,5 @@
>  /* SPDX-License-Identifier: GPL-2.0-only */
>  /*
> - * tools/testing/selftests/kvm/include/x86_64/mce.h
> - *
>   * Copyright (C) 2022, Google LLC.
>   */
>  
> diff --git a/tools/testing/selftests/kvm/include/x86_64/pmu.h b/tools/testing/selftests/kvm/include/x86/pmu.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/x86_64/pmu.h
> rename to tools/testing/selftests/kvm/include/x86/pmu.h
> diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h
> similarity index 99%
> rename from tools/testing/selftests/kvm/include/x86_64/processor.h
> rename to tools/testing/selftests/kvm/include/x86/processor.h
> index 645200e95f89..9ec984cf8674 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/processor.h
> +++ b/tools/testing/selftests/kvm/include/x86/processor.h
> @@ -1,7 +1,5 @@
>  /* SPDX-License-Identifier: GPL-2.0-only */
>  /*
> - * tools/testing/selftests/kvm/include/x86_64/processor.h
> - *
>   * Copyright (C) 2018, Google LLC.
>   */
>  
> diff --git a/tools/testing/selftests/kvm/include/x86_64/sev.h b/tools/testing/selftests/kvm/include/x86/sev.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/x86_64/sev.h
> rename to tools/testing/selftests/kvm/include/x86/sev.h
> diff --git a/tools/testing/selftests/kvm/include/x86_64/svm.h b/tools/testing/selftests/kvm/include/x86/svm.h
> similarity index 98%
> rename from tools/testing/selftests/kvm/include/x86_64/svm.h
> rename to tools/testing/selftests/kvm/include/x86/svm.h
> index 4803e1056055..29cffd0a9181 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/svm.h
> +++ b/tools/testing/selftests/kvm/include/x86/svm.h
> @@ -1,10 +1,4 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * tools/testing/selftests/kvm/include/x86_64/svm.h
> - * This is a copy of arch/x86/include/asm/svm.h
> - *
> - */
> -
>  #ifndef SELFTEST_KVM_SVM_H
>  #define SELFTEST_KVM_SVM_H
>  
> diff --git a/tools/testing/selftests/kvm/include/x86_64/svm_util.h b/tools/testing/selftests/kvm/include/x86/svm_util.h
> similarity index 94%
> rename from tools/testing/selftests/kvm/include/x86_64/svm_util.h
> rename to tools/testing/selftests/kvm/include/x86/svm_util.h
> index 044f0f872ba9..b74c6dcddcbd 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/svm_util.h
> +++ b/tools/testing/selftests/kvm/include/x86/svm_util.h
> @@ -1,8 +1,5 @@
>  /* SPDX-License-Identifier: GPL-2.0-only */
>  /*
> - * tools/testing/selftests/kvm/include/x86_64/svm_utils.h
> - * Header for nested SVM testing
> - *
>   * Copyright (C) 2020, Red Hat, Inc.
>   */
>  
> diff --git a/tools/testing/selftests/kvm/include/x86_64/ucall.h b/tools/testing/selftests/kvm/include/x86/ucall.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/include/x86_64/ucall.h
> rename to tools/testing/selftests/kvm/include/x86/ucall.h
> diff --git a/tools/testing/selftests/kvm/include/x86_64/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
> similarity index 99%
> rename from tools/testing/selftests/kvm/include/x86_64/vmx.h
> rename to tools/testing/selftests/kvm/include/x86/vmx.h
> index 5f0c0a29c556..edb3c391b982 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/vmx.h
> +++ b/tools/testing/selftests/kvm/include/x86/vmx.h
> @@ -1,7 +1,5 @@
>  /* SPDX-License-Identifier: GPL-2.0-only */
>  /*
> - * tools/testing/selftests/kvm/include/x86_64/vmx.h
> - *
>   * Copyright (C) 2018, Google LLC.
>   */
>  
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic.c b/tools/testing/selftests/kvm/lib/arm64/gic.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/aarch64/gic.c
> rename to tools/testing/selftests/kvm/lib/arm64/gic.c
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_private.h b/tools/testing/selftests/kvm/lib/arm64/gic_private.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/aarch64/gic_private.h
> rename to tools/testing/selftests/kvm/lib/arm64/gic_private.h
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c b/tools/testing/selftests/kvm/lib/arm64/gic_v3.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/aarch64/gic_v3.c
> rename to tools/testing/selftests/kvm/lib/arm64/gic_v3.c
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3_its.c b/tools/testing/selftests/kvm/lib/arm64/gic_v3_its.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/aarch64/gic_v3_its.c
> rename to tools/testing/selftests/kvm/lib/arm64/gic_v3_its.c
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/handlers.S b/tools/testing/selftests/kvm/lib/arm64/handlers.S
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/aarch64/handlers.S
> rename to tools/testing/selftests/kvm/lib/arm64/handlers.S
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/aarch64/processor.c
> rename to tools/testing/selftests/kvm/lib/arm64/processor.c
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/spinlock.c b/tools/testing/selftests/kvm/lib/arm64/spinlock.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/aarch64/spinlock.c
> rename to tools/testing/selftests/kvm/lib/arm64/spinlock.c
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/ucall.c b/tools/testing/selftests/kvm/lib/arm64/ucall.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/aarch64/ucall.c
> rename to tools/testing/selftests/kvm/lib/arm64/ucall.c
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/arm64/vgic.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/aarch64/vgic.c
> rename to tools/testing/selftests/kvm/lib/arm64/vgic.c
> diff --git a/tools/testing/selftests/kvm/lib/s390x/diag318_test_handler.c b/tools/testing/selftests/kvm/lib/s390/diag318_test_handler.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/s390x/diag318_test_handler.c
> rename to tools/testing/selftests/kvm/lib/s390/diag318_test_handler.c
> diff --git a/tools/testing/selftests/kvm/lib/s390x/facility.c b/tools/testing/selftests/kvm/lib/s390/facility.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/s390x/facility.c
> rename to tools/testing/selftests/kvm/lib/s390/facility.c
> diff --git a/tools/testing/selftests/kvm/lib/s390x/processor.c b/tools/testing/selftests/kvm/lib/s390/processor.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/s390x/processor.c
> rename to tools/testing/selftests/kvm/lib/s390/processor.c
> diff --git a/tools/testing/selftests/kvm/lib/s390x/ucall.c b/tools/testing/selftests/kvm/lib/s390/ucall.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/s390x/ucall.c
> rename to tools/testing/selftests/kvm/lib/s390/ucall.c
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/apic.c b/tools/testing/selftests/kvm/lib/x86/apic.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/x86_64/apic.c
> rename to tools/testing/selftests/kvm/lib/x86/apic.c
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/handlers.S b/tools/testing/selftests/kvm/lib/x86/handlers.S
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/x86_64/handlers.S
> rename to tools/testing/selftests/kvm/lib/x86/handlers.S
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/hyperv.c b/tools/testing/selftests/kvm/lib/x86/hyperv.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/x86_64/hyperv.c
> rename to tools/testing/selftests/kvm/lib/x86/hyperv.c
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/memstress.c b/tools/testing/selftests/kvm/lib/x86/memstress.c
> similarity index 98%
> rename from tools/testing/selftests/kvm/lib/x86_64/memstress.c
> rename to tools/testing/selftests/kvm/lib/x86/memstress.c
> index d61e623afc8c..7f5d62a65c68 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/memstress.c
> +++ b/tools/testing/selftests/kvm/lib/x86/memstress.c
> @@ -1,6 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /*
> - * x86_64-specific extensions to memstress.c.
> + * x86-specific extensions to memstress.c.
>   *
>   * Copyright (C) 2022, Google, Inc.
>   */
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/pmu.c b/tools/testing/selftests/kvm/lib/x86/pmu.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/x86_64/pmu.c
> rename to tools/testing/selftests/kvm/lib/x86/pmu.c
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
> similarity index 99%
> rename from tools/testing/selftests/kvm/lib/x86_64/processor.c
> rename to tools/testing/selftests/kvm/lib/x86/processor.c
> index 636b29ba8985..bd5a802fa7a5 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
> +++ b/tools/testing/selftests/kvm/lib/x86/processor.c
> @@ -1,7 +1,5 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * tools/testing/selftests/kvm/lib/x86_64/processor.c
> - *
>   * Copyright (C) 2018, Google LLC.
>   */
>  
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/sev.c b/tools/testing/selftests/kvm/lib/x86/sev.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/x86_64/sev.c
> rename to tools/testing/selftests/kvm/lib/x86/sev.c
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/svm.c b/tools/testing/selftests/kvm/lib/x86/svm.c
> similarity index 99%
> rename from tools/testing/selftests/kvm/lib/x86_64/svm.c
> rename to tools/testing/selftests/kvm/lib/x86/svm.c
> index 5495a92dfd5a..d239c2097391 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/svm.c
> +++ b/tools/testing/selftests/kvm/lib/x86/svm.c
> @@ -1,6 +1,5 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * tools/testing/selftests/kvm/lib/x86_64/svm.c
>   * Helpers used for nested SVM testing
>   * Largely inspired from KVM unit test svm.c
>   *
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/ucall.c b/tools/testing/selftests/kvm/lib/x86/ucall.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/lib/x86_64/ucall.c
> rename to tools/testing/selftests/kvm/lib/x86/ucall.c
> diff --git a/tools/testing/selftests/kvm/lib/x86_64/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
> similarity index 99%
> rename from tools/testing/selftests/kvm/lib/x86_64/vmx.c
> rename to tools/testing/selftests/kvm/lib/x86/vmx.c
> index d7ac122820bf..d4d1208dd023 100644
> --- a/tools/testing/selftests/kvm/lib/x86_64/vmx.c
> +++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
> @@ -1,7 +1,5 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * tools/testing/selftests/kvm/lib/x86_64/vmx.c
> - *
>   * Copyright (C) 2018, Google LLC.
>   */
>  
> diff --git a/tools/testing/selftests/kvm/s390x/cmma_test.c b/tools/testing/selftests/kvm/s390/cmma_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/cmma_test.c
> rename to tools/testing/selftests/kvm/s390/cmma_test.c
> diff --git a/tools/testing/selftests/kvm/s390x/config b/tools/testing/selftests/kvm/s390/config
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/config
> rename to tools/testing/selftests/kvm/s390/config
> diff --git a/tools/testing/selftests/kvm/s390x/cpumodel_subfuncs_test.c b/tools/testing/selftests/kvm/s390/cpumodel_subfuncs_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/cpumodel_subfuncs_test.c
> rename to tools/testing/selftests/kvm/s390/cpumodel_subfuncs_test.c
> diff --git a/tools/testing/selftests/kvm/s390x/debug_test.c b/tools/testing/selftests/kvm/s390/debug_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/debug_test.c
> rename to tools/testing/selftests/kvm/s390/debug_test.c
> diff --git a/tools/testing/selftests/kvm/s390x/memop.c b/tools/testing/selftests/kvm/s390/memop.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/memop.c
> rename to tools/testing/selftests/kvm/s390/memop.c
> diff --git a/tools/testing/selftests/kvm/s390x/resets.c b/tools/testing/selftests/kvm/s390/resets.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/resets.c
> rename to tools/testing/selftests/kvm/s390/resets.c
> diff --git a/tools/testing/selftests/kvm/s390x/shared_zeropage_test.c b/tools/testing/selftests/kvm/s390/shared_zeropage_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/shared_zeropage_test.c
> rename to tools/testing/selftests/kvm/s390/shared_zeropage_test.c
> diff --git a/tools/testing/selftests/kvm/s390x/sync_regs_test.c b/tools/testing/selftests/kvm/s390/sync_regs_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/sync_regs_test.c
> rename to tools/testing/selftests/kvm/s390/sync_regs_test.c
> diff --git a/tools/testing/selftests/kvm/s390x/tprot.c b/tools/testing/selftests/kvm/s390/tprot.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/tprot.c
> rename to tools/testing/selftests/kvm/s390/tprot.c
> diff --git a/tools/testing/selftests/kvm/s390x/ucontrol_test.c b/tools/testing/selftests/kvm/s390/ucontrol_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/s390x/ucontrol_test.c
> rename to tools/testing/selftests/kvm/s390/ucontrol_test.c
> diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c
> index a8267628e9ed..86ee3385e860 100644
> --- a/tools/testing/selftests/kvm/set_memory_region_test.c
> +++ b/tools/testing/selftests/kvm/set_memory_region_test.c
> @@ -17,9 +17,9 @@
>  #include <processor.h>
>  
>  /*
> - * s390x needs at least 1MB alignment, and the x86_64 MOVE/DELETE tests need a
> - * 2MB sized and aligned region so that the initial region corresponds to
> - * exactly one large page.
> + * s390 needs at least 1MB alignment, and the x86 MOVE/DELETE tests need a 2MB
> + * sized and aligned region so that the initial region corresponds to exactly
> + * one large page.
>   */
>  #define MEM_REGION_SIZE		0x200000
>  
> diff --git a/tools/testing/selftests/kvm/x86_64/amx_test.c b/tools/testing/selftests/kvm/x86/amx_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/amx_test.c
> rename to tools/testing/selftests/kvm/x86/amx_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/apic_bus_clock_test.c b/tools/testing/selftests/kvm/x86/apic_bus_clock_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/apic_bus_clock_test.c
> rename to tools/testing/selftests/kvm/x86/apic_bus_clock_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/cpuid_test.c b/tools/testing/selftests/kvm/x86/cpuid_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/cpuid_test.c
> rename to tools/testing/selftests/kvm/x86/cpuid_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c b/tools/testing/selftests/kvm/x86/cr4_cpuid_sync_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/cr4_cpuid_sync_test.c
> rename to tools/testing/selftests/kvm/x86/cr4_cpuid_sync_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/debug_regs.c b/tools/testing/selftests/kvm/x86/debug_regs.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/debug_regs.c
> rename to tools/testing/selftests/kvm/x86/debug_regs.c
> diff --git a/tools/testing/selftests/kvm/x86_64/dirty_log_page_splitting_test.c b/tools/testing/selftests/kvm/x86/dirty_log_page_splitting_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/dirty_log_page_splitting_test.c
> rename to tools/testing/selftests/kvm/x86/dirty_log_page_splitting_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/exit_on_emulation_failure_test.c b/tools/testing/selftests/kvm/x86/exit_on_emulation_failure_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/exit_on_emulation_failure_test.c
> rename to tools/testing/selftests/kvm/x86/exit_on_emulation_failure_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/feature_msrs_test.c b/tools/testing/selftests/kvm/x86/feature_msrs_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/feature_msrs_test.c
> rename to tools/testing/selftests/kvm/x86/feature_msrs_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c b/tools/testing/selftests/kvm/x86/fix_hypercall_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/fix_hypercall_test.c
> rename to tools/testing/selftests/kvm/x86/fix_hypercall_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/flds_emulation.h b/tools/testing/selftests/kvm/x86/flds_emulation.h
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/flds_emulation.h
> rename to tools/testing/selftests/kvm/x86/flds_emulation.h
> diff --git a/tools/testing/selftests/kvm/x86_64/hwcr_msr_test.c b/tools/testing/selftests/kvm/x86/hwcr_msr_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/hwcr_msr_test.c
> rename to tools/testing/selftests/kvm/x86/hwcr_msr_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_clock.c b/tools/testing/selftests/kvm/x86/hyperv_clock.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/hyperv_clock.c
> rename to tools/testing/selftests/kvm/x86/hyperv_clock.c
> diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c b/tools/testing/selftests/kvm/x86/hyperv_cpuid.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/hyperv_cpuid.c
> rename to tools/testing/selftests/kvm/x86/hyperv_cpuid.c
> diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c b/tools/testing/selftests/kvm/x86/hyperv_evmcs.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/hyperv_evmcs.c
> rename to tools/testing/selftests/kvm/x86/hyperv_evmcs.c
> diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_extended_hypercalls.c b/tools/testing/selftests/kvm/x86/hyperv_extended_hypercalls.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/hyperv_extended_hypercalls.c
> rename to tools/testing/selftests/kvm/x86/hyperv_extended_hypercalls.c
> diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_features.c b/tools/testing/selftests/kvm/x86/hyperv_features.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/hyperv_features.c
> rename to tools/testing/selftests/kvm/x86/hyperv_features.c
> diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_ipi.c b/tools/testing/selftests/kvm/x86/hyperv_ipi.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/hyperv_ipi.c
> rename to tools/testing/selftests/kvm/x86/hyperv_ipi.c
> diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c b/tools/testing/selftests/kvm/x86/hyperv_svm_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
> rename to tools/testing/selftests/kvm/x86/hyperv_svm_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_tlb_flush.c b/tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/hyperv_tlb_flush.c
> rename to tools/testing/selftests/kvm/x86/hyperv_tlb_flush.c
> diff --git a/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c b/tools/testing/selftests/kvm/x86/kvm_clock_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
> rename to tools/testing/selftests/kvm/x86/kvm_clock_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c b/tools/testing/selftests/kvm/x86/kvm_pv_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/kvm_pv_test.c
> rename to tools/testing/selftests/kvm/x86/kvm_pv_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/max_vcpuid_cap_test.c b/tools/testing/selftests/kvm/x86/max_vcpuid_cap_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/max_vcpuid_cap_test.c
> rename to tools/testing/selftests/kvm/x86/max_vcpuid_cap_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c b/tools/testing/selftests/kvm/x86/monitor_mwait_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/monitor_mwait_test.c
> rename to tools/testing/selftests/kvm/x86/monitor_mwait_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/nested_exceptions_test.c b/tools/testing/selftests/kvm/x86/nested_exceptions_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/nested_exceptions_test.c
> rename to tools/testing/selftests/kvm/x86/nested_exceptions_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c
> rename to tools/testing/selftests/kvm/x86/nx_huge_pages_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh b/tools/testing/selftests/kvm/x86/nx_huge_pages_test.sh
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh
> rename to tools/testing/selftests/kvm/x86/nx_huge_pages_test.sh
> diff --git a/tools/testing/selftests/kvm/x86_64/platform_info_test.c b/tools/testing/selftests/kvm/x86/platform_info_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/platform_info_test.c
> rename to tools/testing/selftests/kvm/x86/platform_info_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/pmu_counters_test.c b/tools/testing/selftests/kvm/x86/pmu_counters_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/pmu_counters_test.c
> rename to tools/testing/selftests/kvm/x86/pmu_counters_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86/pmu_event_filter_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
> rename to tools/testing/selftests/kvm/x86/pmu_event_filter_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/private_mem_conversions_test.c b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/private_mem_conversions_test.c
> rename to tools/testing/selftests/kvm/x86/private_mem_conversions_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/private_mem_kvm_exits_test.c b/tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/private_mem_kvm_exits_test.c
> rename to tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/recalc_apic_map_test.c b/tools/testing/selftests/kvm/x86/recalc_apic_map_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/recalc_apic_map_test.c
> rename to tools/testing/selftests/kvm/x86/recalc_apic_map_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/set_boot_cpu_id.c b/tools/testing/selftests/kvm/x86/set_boot_cpu_id.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/set_boot_cpu_id.c
> rename to tools/testing/selftests/kvm/x86/set_boot_cpu_id.c
> diff --git a/tools/testing/selftests/kvm/x86_64/set_sregs_test.c b/tools/testing/selftests/kvm/x86/set_sregs_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/set_sregs_test.c
> rename to tools/testing/selftests/kvm/x86/set_sregs_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/sev_init2_tests.c b/tools/testing/selftests/kvm/x86/sev_init2_tests.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/sev_init2_tests.c
> rename to tools/testing/selftests/kvm/x86/sev_init2_tests.c
> diff --git a/tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c b/tools/testing/selftests/kvm/x86/sev_migrate_tests.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/sev_migrate_tests.c
> rename to tools/testing/selftests/kvm/x86/sev_migrate_tests.c
> diff --git a/tools/testing/selftests/kvm/x86_64/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/sev_smoke_test.c
> rename to tools/testing/selftests/kvm/x86/sev_smoke_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c b/tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/smaller_maxphyaddr_emulation_test.c
> rename to tools/testing/selftests/kvm/x86/smaller_maxphyaddr_emulation_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/smm_test.c b/tools/testing/selftests/kvm/x86/smm_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/smm_test.c
> rename to tools/testing/selftests/kvm/x86/smm_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/state_test.c b/tools/testing/selftests/kvm/x86/state_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/state_test.c
> rename to tools/testing/selftests/kvm/x86/state_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c b/tools/testing/selftests/kvm/x86/svm_int_ctl_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/svm_int_ctl_test.c
> rename to tools/testing/selftests/kvm/x86/svm_int_ctl_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c b/tools/testing/selftests/kvm/x86/svm_nested_shutdown_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/svm_nested_shutdown_test.c
> rename to tools/testing/selftests/kvm/x86/svm_nested_shutdown_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c b/tools/testing/selftests/kvm/x86/svm_nested_soft_inject_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/svm_nested_soft_inject_test.c
> rename to tools/testing/selftests/kvm/x86/svm_nested_soft_inject_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/svm_vmcall_test.c b/tools/testing/selftests/kvm/x86/svm_vmcall_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/svm_vmcall_test.c
> rename to tools/testing/selftests/kvm/x86/svm_vmcall_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/sync_regs_test.c b/tools/testing/selftests/kvm/x86/sync_regs_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/sync_regs_test.c
> rename to tools/testing/selftests/kvm/x86/sync_regs_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/triple_fault_event_test.c b/tools/testing/selftests/kvm/x86/triple_fault_event_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/triple_fault_event_test.c
> rename to tools/testing/selftests/kvm/x86/triple_fault_event_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/tsc_msrs_test.c b/tools/testing/selftests/kvm/x86/tsc_msrs_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/tsc_msrs_test.c
> rename to tools/testing/selftests/kvm/x86/tsc_msrs_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/tsc_scaling_sync.c b/tools/testing/selftests/kvm/x86/tsc_scaling_sync.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/tsc_scaling_sync.c
> rename to tools/testing/selftests/kvm/x86/tsc_scaling_sync.c
> diff --git a/tools/testing/selftests/kvm/x86_64/ucna_injection_test.c b/tools/testing/selftests/kvm/x86/ucna_injection_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/ucna_injection_test.c
> rename to tools/testing/selftests/kvm/x86/ucna_injection_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/userspace_io_test.c b/tools/testing/selftests/kvm/x86/userspace_io_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/userspace_io_test.c
> rename to tools/testing/selftests/kvm/x86/userspace_io_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c b/tools/testing/selftests/kvm/x86/userspace_msr_exit_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c
> rename to tools/testing/selftests/kvm/x86/userspace_msr_exit_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_apic_access_test.c b/tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_apic_access_test.c
> rename to tools/testing/selftests/kvm/x86/vmx_apic_access_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c b/tools/testing/selftests/kvm/x86/vmx_close_while_nested_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c
> rename to tools/testing/selftests/kvm/x86/vmx_close_while_nested_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c b/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c
> rename to tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c b/tools/testing/selftests/kvm/x86/vmx_exception_with_invalid_guest_state.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_exception_with_invalid_guest_state.c
> rename to tools/testing/selftests/kvm/x86/vmx_exception_with_invalid_guest_state.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_invalid_nested_guest_state.c b/tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_invalid_nested_guest_state.c
> rename to tools/testing/selftests/kvm/x86/vmx_invalid_nested_guest_state.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_msrs_test.c b/tools/testing/selftests/kvm/x86/vmx_msrs_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_msrs_test.c
> rename to tools/testing/selftests/kvm/x86/vmx_msrs_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_nested_tsc_scaling_test.c b/tools/testing/selftests/kvm/x86/vmx_nested_tsc_scaling_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_nested_tsc_scaling_test.c
> rename to tools/testing/selftests/kvm/x86/vmx_nested_tsc_scaling_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c b/tools/testing/selftests/kvm/x86/vmx_pmu_caps_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_pmu_caps_test.c
> rename to tools/testing/selftests/kvm/x86/vmx_pmu_caps_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_preemption_timer_test.c b/tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_preemption_timer_test.c
> rename to tools/testing/selftests/kvm/x86/vmx_preemption_timer_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c
> rename to tools/testing/selftests/kvm/x86/vmx_set_nested_state_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c
> rename to tools/testing/selftests/kvm/x86/vmx_tsc_adjust_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c
> rename to tools/testing/selftests/kvm/x86/xapic_ipi_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/xapic_state_test.c b/tools/testing/selftests/kvm/x86/xapic_state_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/xapic_state_test.c
> rename to tools/testing/selftests/kvm/x86/xapic_state_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c b/tools/testing/selftests/kvm/x86/xcr0_cpuid_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/xcr0_cpuid_test.c
> rename to tools/testing/selftests/kvm/x86/xcr0_cpuid_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c b/tools/testing/selftests/kvm/x86/xen_shinfo_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c
> rename to tools/testing/selftests/kvm/x86/xen_shinfo_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/xen_vmcall_test.c b/tools/testing/selftests/kvm/x86/xen_vmcall_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/xen_vmcall_test.c
> rename to tools/testing/selftests/kvm/x86/xen_vmcall_test.c
> diff --git a/tools/testing/selftests/kvm/x86_64/xss_msr_test.c b/tools/testing/selftests/kvm/x86/xss_msr_test.c
> similarity index 100%
> rename from tools/testing/selftests/kvm/x86_64/xss_msr_test.c
> rename to tools/testing/selftests/kvm/x86/xss_msr_test.c


-- 
BR,
Muhammad Usama Anjum


From Usama.Anjum at collabora.com  Thu Nov 28 00:20:41 2024
From: Usama.Anjum at collabora.com (Muhammad Usama Anjum)
Date: Thu, 28 Nov 2024 13:20:41 +0500
Subject: [PATCH v4 16/16] KVM: selftests: Override ARCH for x86_64 instead
 of using ARCH_DIR
In-Reply-To: <20241128005547.4077116-17-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
 <20241128005547.4077116-17-seanjc@google.com>
Message-ID: <1d5a0d11-273b-4b0c-9ac4-597ad675defb@collabora.com>

On 11/28/24 5:55 AM, Sean Christopherson wrote:
> Now that KVM selftests uses the kernel's canonical arch paths, directly
> override ARCH to 'x86' when targeting x86_64 instead of defining ARCH_DIR
> to redirect to appropriate paths.  ARCH_DIR was originally added to deal
> with KVM selftests using the target triple ARCH for directories, e.g.
> s390x and aarch64; keeping it around just to deal with the one-off alias
> from x86_64=>x86 is unnecessary and confusing.
> 
> Note, even when selftests are built from the top-level Makefile, ARCH is
> scoped to KVM's makefiles, i.e. overriding ARCH won't trip up some other
> selftests that (somehow) expects x86_64 and can't work with x86.
> 
> Signed-off-by: Sean Christopherson <seanjc at google.com>
Reviewed-by: Muhammad Usama Anjum <usama.anjum at collabora.com>

> ---
>  tools/testing/selftests/kvm/Makefile     |  4 +---
>  tools/testing/selftests/kvm/Makefile.kvm | 20 ++++++++++----------
>  2 files changed, 11 insertions(+), 13 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> index 9bc2eba1af1c..20af35a91d6f 100644
> --- a/tools/testing/selftests/kvm/Makefile
> +++ b/tools/testing/selftests/kvm/Makefile
> @@ -6,9 +6,7 @@ ARCH            ?= $(SUBARCH)
>  ifeq ($(ARCH),$(filter $(ARCH),arm64 s390 riscv x86 x86_64))
>  # Top-level selftests allows ARCH=x86_64 :-(
>  ifeq ($(ARCH),x86_64)
> -	ARCH_DIR := x86
> -else
> -	ARCH_DIR := $(ARCH)
> +	ARCH := x86
>  endif
>  include Makefile.kvm
>  else
> diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
> index 9888dd6bb483..4277b983cace 100644
> --- a/tools/testing/selftests/kvm/Makefile.kvm
> +++ b/tools/testing/selftests/kvm/Makefile.kvm
> @@ -207,10 +207,10 @@ TEST_GEN_PROGS_riscv += steal_time
>  SPLIT_TESTS += arch_timer
>  SPLIT_TESTS += get-reg-list
>  
> -TEST_PROGS += $(TEST_PROGS_$(ARCH_DIR))
> -TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH_DIR))
> -TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH_DIR))
> -LIBKVM += $(LIBKVM_$(ARCH_DIR))
> +TEST_PROGS += $(TEST_PROGS_$(ARCH))
> +TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(ARCH))
> +TEST_GEN_PROGS_EXTENDED += $(TEST_GEN_PROGS_EXTENDED_$(ARCH))
> +LIBKVM += $(LIBKVM_$(ARCH))
>  
>  OVERRIDE_TARGETS = 1
>  
> @@ -222,14 +222,14 @@ include ../lib.mk
>  INSTALL_HDR_PATH = $(top_srcdir)/usr
>  LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
>  LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include
> -LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH_DIR)/include
> +LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include
>  CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
>  	-Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \
>  	-fno-builtin-memcmp -fno-builtin-memcpy \
>  	-fno-builtin-memset -fno-builtin-strnlen \
>  	-fno-stack-protector -fno-PIE -fno-strict-aliasing \
>  	-I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \
> -	-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH_DIR) \
> +	-I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH) \
>  	-I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
>  ifeq ($(ARCH),s390)
>  	CFLAGS += -march=z10
> @@ -273,7 +273,7 @@ LIBKVM_S_OBJ := $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S))
>  LIBKVM_STRING_OBJ := $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING))
>  LIBKVM_OBJS = $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ)
>  SPLIT_TEST_GEN_PROGS := $(patsubst %, $(OUTPUT)/%, $(SPLIT_TESTS))
> -SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH_DIR)/%.o, $(SPLIT_TESTS))
> +SPLIT_TEST_GEN_OBJ := $(patsubst %, $(OUTPUT)/$(ARCH)/%.o, $(SPLIT_TESTS))
>  
>  TEST_GEN_OBJ = $(patsubst %, %.o, $(TEST_GEN_PROGS))
>  TEST_GEN_OBJ += $(patsubst %, %.o, $(TEST_GEN_PROGS_EXTENDED))
> @@ -282,7 +282,7 @@ TEST_DEP_FILES += $(patsubst %.o, %.d, $(LIBKVM_OBJS))
>  TEST_DEP_FILES += $(patsubst %.o, %.d, $(SPLIT_TEST_GEN_OBJ))
>  -include $(TEST_DEP_FILES)
>  
> -$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
> +$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH) $(dir $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ))))
>  
>  $(filter-out $(SPLIT_TEST_GEN_PROGS), $(TEST_GEN_PROGS)) \
>  $(TEST_GEN_PROGS_EXTENDED): %: %.o
> @@ -290,9 +290,9 @@ $(TEST_GEN_PROGS_EXTENDED): %: %.o
>  $(TEST_GEN_OBJ): $(OUTPUT)/%.o: %.c
>  	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
>  
> -$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH_DIR)/%.o
> +$(SPLIT_TEST_GEN_PROGS): $(OUTPUT)/%: $(OUTPUT)/%.o $(OUTPUT)/$(ARCH)/%.o
>  	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
> -$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH_DIR)/%.o: $(ARCH_DIR)/%.c
> +$(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH)/%.o: $(ARCH)/%.c
>  	$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
>  
>  EXTRA_CLEAN += $(GEN_HDRS) \


-- 
BR,
Muhammad Usama Anjum


From imbrenda at linux.ibm.com  Thu Nov 28 00:25:36 2024
From: imbrenda at linux.ibm.com (Claudio Imbrenda)
Date: Thu, 28 Nov 2024 09:25:36 +0100
Subject: [PATCH v4 02/16] KVM: selftests: Return a value from
 vcpu_get_reg() instead of using an out-param
In-Reply-To: <20241128005547.4077116-3-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
	<20241128005547.4077116-3-seanjc@google.com>
Message-ID: <20241128092536.16e08a27@p-imbrenda>

On Wed, 27 Nov 2024 16:55:33 -0800
Sean Christopherson <seanjc at google.com> wrote:

> Return a uint64_t from vcpu_get_reg() instead of having the caller provide
> a pointer to storage, as none of the vcpu_get_reg() usage in KVM selftests
> accesses a register larger than 64 bits, and vcpu_set_reg() only accepts a
> 64-bit value.  If a use case comes along that needs to get a register that
> is larger than 64 bits, then a utility can be added to assert success and
> take a void pointer, but until then, forcing an out param yields ugly code
> and prevents feeding the output of vcpu_get_reg() into vcpu_set_reg().
> 
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> Signed-off-by: Sean Christopherson <seanjc at google.com>

for the s390 part:

Acked-by: Claudio Imbrenda <imbrenda at linux.ibm.com>

> ---
>  .../selftests/kvm/aarch64/aarch32_id_regs.c   | 10 +--
>  .../selftests/kvm/aarch64/debug-exceptions.c  |  4 +-
>  .../selftests/kvm/aarch64/hypercalls.c        |  6 +-
>  .../selftests/kvm/aarch64/no-vgic-v3.c        |  2 +-
>  .../testing/selftests/kvm/aarch64/psci_test.c |  6 +-
>  .../selftests/kvm/aarch64/set_id_regs.c       | 18 ++---
>  .../kvm/aarch64/vpmu_counter_access.c         | 19 +++---
>  .../testing/selftests/kvm/include/kvm_util.h  |  6 +-
>  .../selftests/kvm/lib/aarch64/processor.c     |  8 +--
>  .../selftests/kvm/lib/riscv/processor.c       | 66 +++++++++----------
>  .../testing/selftests/kvm/riscv/arch_timer.c  |  2 +-
>  .../testing/selftests/kvm/riscv/ebreak_test.c |  2 +-
>  .../selftests/kvm/riscv/sbi_pmu_test.c        |  2 +-
>  tools/testing/selftests/kvm/s390x/resets.c    |  2 +-
>  tools/testing/selftests/kvm/steal_time.c      |  3 +-
>  15 files changed, 78 insertions(+), 78 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c b/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c
> index 8e5bd07a3727..447d61cae4db 100644
> --- a/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c
> +++ b/tools/testing/selftests/kvm/aarch64/aarch32_id_regs.c
> @@ -97,7 +97,7 @@ static void test_user_raz_wi(struct kvm_vcpu *vcpu)
>  		uint64_t reg_id = raz_wi_reg_ids[i];
>  		uint64_t val;
>  
> -		vcpu_get_reg(vcpu, reg_id, &val);
> +		val = vcpu_get_reg(vcpu, reg_id);
>  		TEST_ASSERT_EQ(val, 0);
>  
>  		/*
> @@ -106,7 +106,7 @@ static void test_user_raz_wi(struct kvm_vcpu *vcpu)
>  		 */
>  		vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);
>  
> -		vcpu_get_reg(vcpu, reg_id, &val);
> +		val = vcpu_get_reg(vcpu, reg_id);
>  		TEST_ASSERT_EQ(val, 0);
>  	}
>  }
> @@ -126,14 +126,14 @@ static void test_user_raz_invariant(struct kvm_vcpu *vcpu)
>  		uint64_t reg_id = raz_invariant_reg_ids[i];
>  		uint64_t val;
>  
> -		vcpu_get_reg(vcpu, reg_id, &val);
> +		val = vcpu_get_reg(vcpu, reg_id);
>  		TEST_ASSERT_EQ(val, 0);
>  
>  		r = __vcpu_set_reg(vcpu, reg_id, BAD_ID_REG_VAL);
>  		TEST_ASSERT(r < 0 && errno == EINVAL,
>  			    "unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);
>  
> -		vcpu_get_reg(vcpu, reg_id, &val);
> +		val = vcpu_get_reg(vcpu, reg_id);
>  		TEST_ASSERT_EQ(val, 0);
>  	}
>  }
> @@ -144,7 +144,7 @@ static bool vcpu_aarch64_only(struct kvm_vcpu *vcpu)
>  {
>  	uint64_t val, el0;
>  
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &val);
> +	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
>  
>  	el0 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), val);
>  	return el0 == ID_AA64PFR0_EL1_ELx_64BIT_ONLY;
> diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
> index ff7a949fc96a..c7fb55c9135b 100644
> --- a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
> +++ b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c
> @@ -501,7 +501,7 @@ void test_single_step_from_userspace(int test_cnt)
>  		TEST_ASSERT(ss_enable, "Unexpected KVM_EXIT_DEBUG");
>  
>  		/* Check if the current pc is expected. */
> -		vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &pc);
> +		pc = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc));
>  		TEST_ASSERT(!test_pc || pc == test_pc,
>  			    "Unexpected pc 0x%lx (expected 0x%lx)",
>  			    pc, test_pc);
> @@ -583,7 +583,7 @@ int main(int argc, char *argv[])
>  	uint64_t aa64dfr0;
>  
>  	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &aa64dfr0);
> +	aa64dfr0 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1));
>  	__TEST_REQUIRE(debug_version(aa64dfr0) >= 6,
>  		       "Armv8 debug architecture not supported.");
>  	kvm_vm_free(vm);
> diff --git a/tools/testing/selftests/kvm/aarch64/hypercalls.c b/tools/testing/selftests/kvm/aarch64/hypercalls.c
> index 9d192ce0078d..ec54ec7726e9 100644
> --- a/tools/testing/selftests/kvm/aarch64/hypercalls.c
> +++ b/tools/testing/selftests/kvm/aarch64/hypercalls.c
> @@ -173,7 +173,7 @@ static void test_fw_regs_before_vm_start(struct kvm_vcpu *vcpu)
>  		const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
>  
>  		/* First 'read' should be an upper limit of the features supported */
> -		vcpu_get_reg(vcpu, reg_info->reg, &val);
> +		val = vcpu_get_reg(vcpu, reg_info->reg);
>  		TEST_ASSERT(val == FW_REG_ULIMIT_VAL(reg_info->max_feat_bit),
>  			"Expected all the features to be set for reg: 0x%lx; expected: 0x%lx; read: 0x%lx",
>  			reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit), val);
> @@ -184,7 +184,7 @@ static void test_fw_regs_before_vm_start(struct kvm_vcpu *vcpu)
>  			"Failed to clear all the features of reg: 0x%lx; ret: %d",
>  			reg_info->reg, errno);
>  
> -		vcpu_get_reg(vcpu, reg_info->reg, &val);
> +		val = vcpu_get_reg(vcpu, reg_info->reg);
>  		TEST_ASSERT(val == 0,
>  			"Expected all the features to be cleared for reg: 0x%lx", reg_info->reg);
>  
> @@ -214,7 +214,7 @@ static void test_fw_regs_after_vm_start(struct kvm_vcpu *vcpu)
>  		 * Before starting the VM, the test clears all the bits.
>  		 * Check if that's still the case.
>  		 */
> -		vcpu_get_reg(vcpu, reg_info->reg, &val);
> +		val = vcpu_get_reg(vcpu, reg_info->reg);
>  		TEST_ASSERT(val == 0,
>  			"Expected all the features to be cleared for reg: 0x%lx",
>  			reg_info->reg);
> diff --git a/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c b/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c
> index 58304bbc2036..ebd70430c89d 100644
> --- a/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c
> +++ b/tools/testing/selftests/kvm/aarch64/no-vgic-v3.c
> @@ -164,7 +164,7 @@ int main(int argc, char *argv[])
>  	uint64_t pfr0;
>  
>  	vm = vm_create_with_one_vcpu(&vcpu, NULL);
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &pfr0);
> +	pfr0 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
>  	__TEST_REQUIRE(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_GIC), pfr0),
>  		       "GICv3 not supported.");
>  	kvm_vm_free(vm);
> diff --git a/tools/testing/selftests/kvm/aarch64/psci_test.c b/tools/testing/selftests/kvm/aarch64/psci_test.c
> index eaa7655fefc1..0ab7d5a24482 100644
> --- a/tools/testing/selftests/kvm/aarch64/psci_test.c
> +++ b/tools/testing/selftests/kvm/aarch64/psci_test.c
> @@ -111,8 +111,8 @@ static void assert_vcpu_reset(struct kvm_vcpu *vcpu)
>  {
>  	uint64_t obs_pc, obs_x0;
>  
> -	vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &obs_pc);
> -	vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.regs[0]), &obs_x0);
> +	obs_pc = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc));
> +	obs_x0 = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.regs[0]));
>  
>  	TEST_ASSERT(obs_pc == CPU_ON_ENTRY_ADDR,
>  		    "unexpected target cpu pc: %lx (expected: %lx)",
> @@ -152,7 +152,7 @@ static void host_test_cpu_on(void)
>  	 */
>  	vcpu_power_off(target);
>  
> -	vcpu_get_reg(target, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), &target_mpidr);
> +	target_mpidr = vcpu_get_reg(target, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1));
>  	vcpu_args_set(source, 1, target_mpidr & MPIDR_HWID_BITMASK);
>  	enter_guest(source);
>  
> diff --git a/tools/testing/selftests/kvm/aarch64/set_id_regs.c b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
> index a79b7f18452d..25ba7d382196 100644
> --- a/tools/testing/selftests/kvm/aarch64/set_id_regs.c
> +++ b/tools/testing/selftests/kvm/aarch64/set_id_regs.c
> @@ -346,7 +346,7 @@ static uint64_t test_reg_set_success(struct kvm_vcpu *vcpu, uint64_t reg,
>  	uint64_t mask = ftr_bits->mask;
>  	uint64_t val, new_val, ftr;
>  
> -	vcpu_get_reg(vcpu, reg, &val);
> +	val = vcpu_get_reg(vcpu, reg);
>  	ftr = (val & mask) >> shift;
>  
>  	ftr = get_safe_value(ftr_bits, ftr);
> @@ -356,7 +356,7 @@ static uint64_t test_reg_set_success(struct kvm_vcpu *vcpu, uint64_t reg,
>  	val |= ftr;
>  
>  	vcpu_set_reg(vcpu, reg, val);
> -	vcpu_get_reg(vcpu, reg, &new_val);
> +	new_val = vcpu_get_reg(vcpu, reg);
>  	TEST_ASSERT_EQ(new_val, val);
>  
>  	return new_val;
> @@ -370,7 +370,7 @@ static void test_reg_set_fail(struct kvm_vcpu *vcpu, uint64_t reg,
>  	uint64_t val, old_val, ftr;
>  	int r;
>  
> -	vcpu_get_reg(vcpu, reg, &val);
> +	val = vcpu_get_reg(vcpu, reg);
>  	ftr = (val & mask) >> shift;
>  
>  	ftr = get_invalid_value(ftr_bits, ftr);
> @@ -384,7 +384,7 @@ static void test_reg_set_fail(struct kvm_vcpu *vcpu, uint64_t reg,
>  	TEST_ASSERT(r < 0 && errno == EINVAL,
>  		    "Unexpected KVM_SET_ONE_REG error: r=%d, errno=%d", r, errno);
>  
> -	vcpu_get_reg(vcpu, reg, &val);
> +	val = vcpu_get_reg(vcpu, reg);
>  	TEST_ASSERT_EQ(val, old_val);
>  }
>  
> @@ -576,7 +576,7 @@ static void test_clidr(struct kvm_vcpu *vcpu)
>  	uint64_t clidr;
>  	int level;
>  
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CLIDR_EL1), &clidr);
> +	clidr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CLIDR_EL1));
>  
>  	/* find the first empty level in the cache hierarchy */
>  	for (level = 1; level < 7; level++) {
> @@ -601,7 +601,7 @@ static void test_ctr(struct kvm_vcpu *vcpu)
>  {
>  	u64 ctr;
>  
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CTR_EL0), &ctr);
> +	ctr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CTR_EL0));
>  	ctr &= ~CTR_EL0_DIC_MASK;
>  	if (ctr & CTR_EL0_IminLine_MASK)
>  		ctr--;
> @@ -617,7 +617,7 @@ static void test_vcpu_ftr_id_regs(struct kvm_vcpu *vcpu)
>  	test_clidr(vcpu);
>  	test_ctr(vcpu);
>  
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), &val);
> +	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1));
>  	val++;
>  	vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MPIDR_EL1), val);
>  
> @@ -630,7 +630,7 @@ static void test_assert_id_reg_unchanged(struct kvm_vcpu *vcpu, uint32_t encodin
>  	size_t idx = encoding_to_range_idx(encoding);
>  	uint64_t observed;
>  
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(encoding), &observed);
> +	observed = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(encoding));
>  	TEST_ASSERT_EQ(test_reg_vals[idx], observed);
>  }
>  
> @@ -665,7 +665,7 @@ int main(void)
>  	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
>  
>  	/* Check for AARCH64 only system */
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1), &val);
> +	val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1));
>  	el0 = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_EL0), val);
>  	aarch64_only = (el0 == ID_AA64PFR0_EL1_ELx_64BIT_ONLY);
>  
> diff --git a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
> index f9c0c86d7e85..f16b3b27e32e 100644
> --- a/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
> +++ b/tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c
> @@ -440,8 +440,7 @@ static void create_vpmu_vm(void *guest_code)
>  		       "Failed to create vgic-v3, skipping");
>  
>  	/* Make sure that PMUv3 support is indicated in the ID register */
> -	vcpu_get_reg(vpmu_vm.vcpu,
> -		     KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &dfr0);
> +	dfr0 = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1));
>  	pmuver = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_EL1_PMUVer), dfr0);
>  	TEST_ASSERT(pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF &&
>  		    pmuver >= ID_AA64DFR0_EL1_PMUVer_IMP,
> @@ -484,7 +483,7 @@ static void test_create_vpmu_vm_with_pmcr_n(uint64_t pmcr_n, bool expect_fail)
>  	create_vpmu_vm(guest_code);
>  	vcpu = vpmu_vm.vcpu;
>  
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr_orig);
> +	pmcr_orig = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
>  	pmcr = pmcr_orig;
>  
>  	/*
> @@ -493,7 +492,7 @@ static void test_create_vpmu_vm_with_pmcr_n(uint64_t pmcr_n, bool expect_fail)
>  	 */
>  	set_pmcr_n(&pmcr, pmcr_n);
>  	vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), pmcr);
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr);
> +	pmcr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
>  
>  	if (expect_fail)
>  		TEST_ASSERT(pmcr_orig == pmcr,
> @@ -521,7 +520,7 @@ static void run_access_test(uint64_t pmcr_n)
>  	vcpu = vpmu_vm.vcpu;
>  
>  	/* Save the initial sp to restore them later to run the guest again */
> -	vcpu_get_reg(vcpu, ARM64_CORE_REG(sp_el1), &sp);
> +	sp = vcpu_get_reg(vcpu, ARM64_CORE_REG(sp_el1));
>  
>  	run_vcpu(vcpu, pmcr_n);
>  
> @@ -572,12 +571,12 @@ static void run_pmregs_validity_test(uint64_t pmcr_n)
>  		 * Test if the 'set' and 'clr' variants of the registers
>  		 * are initialized based on the number of valid counters.
>  		 */
> -		vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), &reg_val);
> +		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id));
>  		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
>  			    "Initial read of set_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
>  			    KVM_ARM64_SYS_REG(set_reg_id), reg_val);
>  
> -		vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id), &reg_val);
> +		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id));
>  		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
>  			    "Initial read of clr_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
>  			    KVM_ARM64_SYS_REG(clr_reg_id), reg_val);
> @@ -589,12 +588,12 @@ static void run_pmregs_validity_test(uint64_t pmcr_n)
>  		 */
>  		vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), max_counters_mask);
>  
> -		vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id), &reg_val);
> +		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(set_reg_id));
>  		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
>  			    "Read of set_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
>  			    KVM_ARM64_SYS_REG(set_reg_id), reg_val);
>  
> -		vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id), &reg_val);
> +		reg_val = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(clr_reg_id));
>  		TEST_ASSERT((reg_val & (~valid_counters_mask)) == 0,
>  			    "Read of clr_reg: 0x%llx has unimplemented counters enabled: 0x%lx",
>  			    KVM_ARM64_SYS_REG(clr_reg_id), reg_val);
> @@ -625,7 +624,7 @@ static uint64_t get_pmcr_n_limit(void)
>  	uint64_t pmcr;
>  
>  	create_vpmu_vm(guest_code);
> -	vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0), &pmcr);
> +	pmcr = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0));
>  	destroy_vpmu_vm();
>  	return get_pmcr_n(pmcr);
>  }
> diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
> index bc7c242480d6..287a3ec06df4 100644
> --- a/tools/testing/selftests/kvm/include/kvm_util.h
> +++ b/tools/testing/selftests/kvm/include/kvm_util.h
> @@ -702,11 +702,13 @@ static inline int __vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t va
>  
>  	return __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, &reg);
>  }
> -static inline void vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id, void *addr)
> +static inline uint64_t vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id)
>  {
> -	struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)addr };
> +	uint64_t val;
> +	struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)&val };
>  
>  	vcpu_ioctl(vcpu, KVM_GET_ONE_REG, &reg);
> +	return val;
>  }
>  static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t val)
>  {
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c
> index 698e34f39241..7ba3aa3755f3 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/processor.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c
> @@ -281,8 +281,8 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
>  	 */
>  	vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CPACR_EL1), 3 << 20);
>  
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1), &sctlr_el1);
> -	vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1), &tcr_el1);
> +	sctlr_el1 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1));
> +	tcr_el1 = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1));
>  
>  	/* Configure base granule size */
>  	switch (vm->mode) {
> @@ -360,8 +360,8 @@ void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, uint8_t indent)
>  {
>  	uint64_t pstate, pc;
>  
> -	vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pstate), &pstate);
> -	vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &pc);
> +	pstate = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pstate));
> +	pc = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc));
>  
>  	fprintf(stream, "%*spstate: 0x%.16lx pc: 0x%.16lx\n",
>  		indent, "", pstate, pc);
> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> index 6ae47b3d6b25..dd663bcf0cc0 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> @@ -221,39 +221,39 @@ void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, uint8_t indent)
>  {
>  	struct kvm_riscv_core core;
>  
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(mode), &core.mode);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc), &core.regs.pc);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.ra), &core.regs.ra);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.sp), &core.regs.sp);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.gp), &core.regs.gp);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.tp), &core.regs.tp);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t0), &core.regs.t0);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t1), &core.regs.t1);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t2), &core.regs.t2);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s0), &core.regs.s0);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s1), &core.regs.s1);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a0), &core.regs.a0);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a1), &core.regs.a1);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a2), &core.regs.a2);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a3), &core.regs.a3);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a4), &core.regs.a4);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a5), &core.regs.a5);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a6), &core.regs.a6);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a7), &core.regs.a7);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s2), &core.regs.s2);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s3), &core.regs.s3);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s4), &core.regs.s4);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s5), &core.regs.s5);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s6), &core.regs.s6);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s7), &core.regs.s7);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s8), &core.regs.s8);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s9), &core.regs.s9);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s10), &core.regs.s10);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s11), &core.regs.s11);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t3), &core.regs.t3);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t4), &core.regs.t4);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t5), &core.regs.t5);
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t6), &core.regs.t6);
> +	core.mode = vcpu_get_reg(vcpu, RISCV_CORE_REG(mode));
> +	core.regs.pc = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc));
> +	core.regs.ra = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.ra));
> +	core.regs.sp = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.sp));
> +	core.regs.gp = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.gp));
> +	core.regs.tp = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.tp));
> +	core.regs.t0 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t0));
> +	core.regs.t1 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t1));
> +	core.regs.t2 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t2));
> +	core.regs.s0 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s0));
> +	core.regs.s1 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s1));
> +	core.regs.a0 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a0));
> +	core.regs.a1 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a1));
> +	core.regs.a2 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a2));
> +	core.regs.a3 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a3));
> +	core.regs.a4 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a4));
> +	core.regs.a5 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a5));
> +	core.regs.a6 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a6));
> +	core.regs.a7 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a7));
> +	core.regs.s2 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s2));
> +	core.regs.s3 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s3));
> +	core.regs.s4 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s4));
> +	core.regs.s5 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s5));
> +	core.regs.s6 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s6));
> +	core.regs.s7 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s7));
> +	core.regs.s8 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s8));
> +	core.regs.s9 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s9));
> +	core.regs.s10 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s10));
> +	core.regs.s11 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s11));
> +	core.regs.t3 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t3));
> +	core.regs.t4 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t4));
> +	core.regs.t5 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t5));
> +	core.regs.t6 = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t6));
>  
>  	fprintf(stream,
>  		" MODE:  0x%lx\n", core.mode);
> diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
> index 2c792228ac0b..9e370800a6a2 100644
> --- a/tools/testing/selftests/kvm/riscv/arch_timer.c
> +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> @@ -93,7 +93,7 @@ struct kvm_vm *test_vm_create(void)
>  		vcpu_init_vector_tables(vcpus[i]);
>  
>  	/* Initialize guest timer frequency. */
> -	vcpu_get_reg(vcpus[0], RISCV_TIMER_REG(frequency), &timer_freq);
> +	timer_freq = vcpu_get_reg(vcpus[0], RISCV_TIMER_REG(frequency));
>  	sync_global_to_guest(vm, timer_freq);
>  	pr_debug("timer_freq: %lu\n", timer_freq);
>  
> diff --git a/tools/testing/selftests/kvm/riscv/ebreak_test.c b/tools/testing/selftests/kvm/riscv/ebreak_test.c
> index 0e0712854953..cfed6c727bfc 100644
> --- a/tools/testing/selftests/kvm/riscv/ebreak_test.c
> +++ b/tools/testing/selftests/kvm/riscv/ebreak_test.c
> @@ -60,7 +60,7 @@ int main(void)
>  
>  	TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_DEBUG);
>  
> -	vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc), &pc);
> +	pc = vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc));
>  	TEST_ASSERT_EQ(pc, LABEL_ADDRESS(sw_bp_1));
>  
>  	/* skip sw_bp_1 */
> diff --git a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
> index f299cbfd23ca..f45c0ecc902d 100644
> --- a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
> +++ b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
> @@ -608,7 +608,7 @@ static void test_vm_events_overflow(void *guest_code)
>  
>  	vcpu_init_vector_tables(vcpu);
>  	/* Initialize guest timer frequency. */
> -	vcpu_get_reg(vcpu, RISCV_TIMER_REG(frequency), &timer_freq);
> +	timer_freq = vcpu_get_reg(vcpu, RISCV_TIMER_REG(frequency));
>  	sync_global_to_guest(vm, timer_freq);
>  
>  	run_vcpu(vcpu);
> diff --git a/tools/testing/selftests/kvm/s390x/resets.c b/tools/testing/selftests/kvm/s390x/resets.c
> index 357943f2bea8..b58f75b381e5 100644
> --- a/tools/testing/selftests/kvm/s390x/resets.c
> +++ b/tools/testing/selftests/kvm/s390x/resets.c
> @@ -61,7 +61,7 @@ static void test_one_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t value)
>  {
>  	uint64_t eval_reg;
>  
> -	vcpu_get_reg(vcpu, id, &eval_reg);
> +	eval_reg = vcpu_get_reg(vcpu, id);
>  	TEST_ASSERT(eval_reg == value, "value == 0x%lx", value);
>  }
>  
> diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c
> index a8d3afa0b86b..cce2520af720 100644
> --- a/tools/testing/selftests/kvm/steal_time.c
> +++ b/tools/testing/selftests/kvm/steal_time.c
> @@ -269,9 +269,8 @@ static void guest_code(int cpu)
>  static bool is_steal_time_supported(struct kvm_vcpu *vcpu)
>  {
>  	uint64_t id = RISCV_SBI_EXT_REG(KVM_RISCV_SBI_EXT_STA);
> -	unsigned long enabled;
> +	unsigned long enabled = vcpu_get_reg(vcpu, id);
>  
> -	vcpu_get_reg(vcpu, id, &enabled);
>  	TEST_ASSERT(enabled == 0 || enabled == 1, "Expected boolean result");
>  
>  	return enabled;



From imbrenda at linux.ibm.com  Thu Nov 28 00:25:46 2024
From: imbrenda at linux.ibm.com (Claudio Imbrenda)
Date: Thu, 28 Nov 2024 09:25:46 +0100
Subject: [PATCH v4 15/16] KVM: selftests: Use canonical $(ARCH) paths
 for KVM selftests directories
In-Reply-To: <20241128005547.4077116-16-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
	<20241128005547.4077116-16-seanjc@google.com>
Message-ID: <20241128092546.7a5b3f30@p-imbrenda>

On Wed, 27 Nov 2024 16:55:46 -0800
Sean Christopherson <seanjc at google.com> wrote:

> Use the kernel's canonical $(ARCH) paths instead of the raw target triple
> for KVM selftests directories.  KVM selftests are quite nearly the only
> place in the entire kernel that using the target triple for directories,
> tools/testing/selftests/drivers/s390x being the lone holdout.
> 
> Using the kernel's preferred nomenclature eliminates the minor, but
> annoying, friction of having to translate to KVM's selftests directories,
> e.g. for pattern matching, opening files, running selftests, etc.
> 
> Opportunsitically delete file comments that reference the full path of the
> file, as they are obviously prone to becoming stale, and serve no known
> purpose.
> 
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> ---

just one minor nit

[...]

> diff --git a/tools/testing/selftests/kvm/include/x86_64/svm_util.h b/tools/testing/selftests/kvm/include/x86/svm_util.h
> similarity index 94%
> rename from tools/testing/selftests/kvm/include/x86_64/svm_util.h
> rename to tools/testing/selftests/kvm/include/x86/svm_util.h
> index 044f0f872ba9..b74c6dcddcbd 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/svm_util.h
> +++ b/tools/testing/selftests/kvm/include/x86/svm_util.h
> @@ -1,8 +1,5 @@
>  /* SPDX-License-Identifier: GPL-2.0-only */
>  /*
> - * tools/testing/selftests/kvm/include/x86_64/svm_utils.h

this line clearly has to go ^

> - * Header for nested SVM testing

but I think this one can stay? ^


regardless, for the s390 part:

Acked-by: Claudio Imbrenda <imbrenda at linux.ibm.com>

> - *
>   * Copyright (C) 2020, Red Hat, Inc.
>   */
>  

[...]


From ajones at ventanamicro.com  Thu Nov 28 00:32:19 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 28 Nov 2024 09:32:19 +0100
Subject: [PATCH v2] riscv: module: use a plain variable for list_head
 instead of a pointer
In-Reply-To: <980b98978ab4ee912b37cb101ad43bce20b56dcb.camel@iscas.ac.cn>
References: <20241127142519.3038691-1-cleger@rivosinc.com>
 <980b98978ab4ee912b37cb101ad43bce20b56dcb.camel@iscas.ac.cn>
Message-ID: <20241128-0e953467c518d79d12dbf202@orel>

On Thu, Nov 28, 2024 at 09:01:52AM +0800, laokz wrote:
> On Wed, 2024-11-27 at 15:25 +0100, Cl?ment L?ger wrote:
> > rel_head's list_head member, rel_entry, doesn't need to be allocated,
> > its storage can just be part of the allocated rel_head. Remove the
> 
> Oh my poor English. OK, it's more better than just add the lost kfree.
>

It wasn't the English I was correcting. That was fine, but just saying
the object could be "a plain variable" wasn't giving any justification
for the change and, to me, even implied that rel_entry was locally
scoped. So, when I first skimmed the patch and saw that it was getting
appended to a list, I almost stated the patch was wrong. It was clear
after looking closer, but it could have been clear the first time
through if the commit message had better guided me.

Thanks,
drew


From ajones at ventanamicro.com  Thu Nov 28 00:42:41 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 28 Nov 2024 09:42:41 +0100
Subject: [PATCH v4 14/16] KVM: selftests: Provide empty 'all' and 'clean'
 targets for unsupported ARCHs
In-Reply-To: <20241128005547.4077116-15-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
 <20241128005547.4077116-15-seanjc@google.com>
Message-ID: <20241128-24a975e227dd4b86393f21ed@orel>

On Wed, Nov 27, 2024 at 04:55:45PM -0800, Sean Christopherson wrote:
> Provide empty targets for KVM selftests if the target architecture is
> unsupported to make it obvious which architectures are supported, and so
> that various side effects don't fail and/or do weird things, e.g. as is,
> "mkdir -p $(sort $(dir $(TEST_GEN_PROGS)))" fails due to a missing operand,
> and conversely, "$(shell mkdir -p $(sort $(OUTPUT)/$(ARCH_DIR) ..." will
> create an empty, useless directory for the unsupported architecture.
> 
> Move the guts of the Makefile to Makefile.kvm so that it's easier to see
> that the if-statement effectively guards all of KVM selftests.
> 
> Reported-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> ---
>  tools/testing/selftests/kvm/.gitignore   |   1 +
>  tools/testing/selftests/kvm/Makefile     | 336 +----------------------
>  tools/testing/selftests/kvm/Makefile.kvm | 334 ++++++++++++++++++++++
>  3 files changed, 340 insertions(+), 331 deletions(-)
>  create mode 100644 tools/testing/selftests/kvm/Makefile.kvm
>

Acked-by: Andrew Jones <ajones at ventanamicro.com>


From ajones at ventanamicro.com  Thu Nov 28 00:43:06 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 28 Nov 2024 09:43:06 +0100
Subject: [PATCH v4 15/16] KVM: selftests: Use canonical $(ARCH) paths for
 KVM selftests directories
In-Reply-To: <20241128005547.4077116-16-seanjc@google.com>
References: <20241128005547.4077116-1-seanjc@google.com>
 <20241128005547.4077116-16-seanjc@google.com>
Message-ID: <20241128-d7a5061ce8160000cd5260bd@orel>

On Wed, Nov 27, 2024 at 04:55:46PM -0800, Sean Christopherson wrote:
> Use the kernel's canonical $(ARCH) paths instead of the raw target triple
> for KVM selftests directories.  KVM selftests are quite nearly the only
> place in the entire kernel that using the target triple for directories,
> tools/testing/selftests/drivers/s390x being the lone holdout.
> 
> Using the kernel's preferred nomenclature eliminates the minor, but
> annoying, friction of having to translate to KVM's selftests directories,
> e.g. for pattern matching, opening files, running selftests, etc.
> 
> Opportunsitically delete file comments that reference the full path of the
> file, as they are obviously prone to becoming stale, and serve no known
> purpose.
> 
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> ---

Acked-by: Andrew Jones <ajones at ventanamicro.com>


From ajones at ventanamicro.com  Thu Nov 28 00:50:29 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 28 Nov 2024 09:50:29 +0100
Subject: [PATCH 1/4] RISC-V: KVM: Allow Svvptc extension for Guest/VM
In-Reply-To: <35d9c91a69ebcb81b40dc4f7f51e290c3d94b2d9.1732762121.git.zhouquan@iscas.ac.cn>
References: <cover.1732762121.git.zhouquan@iscas.ac.cn>
 <35d9c91a69ebcb81b40dc4f7f51e290c3d94b2d9.1732762121.git.zhouquan@iscas.ac.cn>
Message-ID: <20241128-1e20d2226e4be72c121df6fc@orel>

On Thu, Nov 28, 2024 at 11:21:15AM +0800, zhouquan at iscas.ac.cn wrote:
> From: Quan Zhou <zhouquan at iscas.ac.cn>
> 
> Extend the KVM ISA extension ONE_REG interface to allow KVM user space
> to detect and enable Svvptc extension for Guest/VM.
> 
> Signed-off-by: Quan Zhou <zhouquan at iscas.ac.cn>
> ---
>  arch/riscv/include/uapi/asm/kvm.h | 1 +
>  arch/riscv/kvm/vcpu_onereg.c      | 2 ++
>  2 files changed, 3 insertions(+)
> 
> diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
> index 4f24201376b1..9db33f52f56e 100644
> --- a/arch/riscv/include/uapi/asm/kvm.h
> +++ b/arch/riscv/include/uapi/asm/kvm.h
> @@ -177,6 +177,7 @@ enum KVM_RISCV_ISA_EXT_ID {
>  	KVM_RISCV_ISA_EXT_ZAWRS,
>  	KVM_RISCV_ISA_EXT_SMNPM,
>  	KVM_RISCV_ISA_EXT_SSNPM,
> +	KVM_RISCV_ISA_EXT_SVVPTC,
>  	KVM_RISCV_ISA_EXT_MAX,
>  };
>  
> diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
> index 5b68490ad9b7..67965feb5b74 100644
> --- a/arch/riscv/kvm/vcpu_onereg.c
> +++ b/arch/riscv/kvm/vcpu_onereg.c
> @@ -41,6 +41,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
>  	KVM_ISA_EXT_ARR(SSNPM),
>  	KVM_ISA_EXT_ARR(SSTC),
>  	KVM_ISA_EXT_ARR(SVINVAL),
> +	KVM_ISA_EXT_ARR(SVVPTC),

Alphabetic order, please.

>  	KVM_ISA_EXT_ARR(SVNAPOT),
>  	KVM_ISA_EXT_ARR(SVPBMT),
>  	KVM_ISA_EXT_ARR(ZACAS),
> @@ -135,6 +136,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
>  	case KVM_RISCV_ISA_EXT_SSNPM:
>  	case KVM_RISCV_ISA_EXT_SSTC:
>  	case KVM_RISCV_ISA_EXT_SVINVAL:
> +	case KVM_RISCV_ISA_EXT_SVVPTC:

Same comment as above.

>  	case KVM_RISCV_ISA_EXT_SVNAPOT:
>  	case KVM_RISCV_ISA_EXT_ZACAS:
>  	case KVM_RISCV_ISA_EXT_ZAWRS:
> -- 
> 2.34.1
> 

Otherwise,

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>

Thanks,
drew


From ajones at ventanamicro.com  Thu Nov 28 00:52:06 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 28 Nov 2024 09:52:06 +0100
Subject: [PATCH 2/4] RISC-V: KVM: Allow Zabha extension for Guest/VM
In-Reply-To: <ea2918b299348aca0f5a45630b7b7c9889f47fa6.1732762121.git.zhouquan@iscas.ac.cn>
References: <cover.1732762121.git.zhouquan@iscas.ac.cn>
 <ea2918b299348aca0f5a45630b7b7c9889f47fa6.1732762121.git.zhouquan@iscas.ac.cn>
Message-ID: <20241128-4d652d29ba99a3e8ffa8121a@orel>

On Thu, Nov 28, 2024 at 11:21:26AM +0800, zhouquan at iscas.ac.cn wrote:
> From: Quan Zhou <zhouquan at iscas.ac.cn>
> 
> Extend the KVM ISA extension ONE_REG interface to allow KVM user space
> to detect and enable Zabha extension for Guest/VM.
> 
> Signed-off-by: Quan Zhou <zhouquan at iscas.ac.cn>
> ---
>  arch/riscv/include/uapi/asm/kvm.h | 1 +
>  arch/riscv/kvm/vcpu_onereg.c      | 2 ++
>  2 files changed, 3 insertions(+)
> 
> diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
> index 9db33f52f56e..340618131249 100644
> --- a/arch/riscv/include/uapi/asm/kvm.h
> +++ b/arch/riscv/include/uapi/asm/kvm.h
> @@ -178,6 +178,7 @@ enum KVM_RISCV_ISA_EXT_ID {
>  	KVM_RISCV_ISA_EXT_SMNPM,
>  	KVM_RISCV_ISA_EXT_SSNPM,
>  	KVM_RISCV_ISA_EXT_SVVPTC,
> +	KVM_RISCV_ISA_EXT_ZABHA,
>  	KVM_RISCV_ISA_EXT_MAX,
>  };
>  
> diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
> index 67965feb5b74..9a30a98f30bc 100644
> --- a/arch/riscv/kvm/vcpu_onereg.c
> +++ b/arch/riscv/kvm/vcpu_onereg.c
> @@ -44,6 +44,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
>  	KVM_ISA_EXT_ARR(SVVPTC),
>  	KVM_ISA_EXT_ARR(SVNAPOT),
>  	KVM_ISA_EXT_ARR(SVPBMT),
> +	KVM_ISA_EXT_ARR(ZABHA),
>  	KVM_ISA_EXT_ARR(ZACAS),
>  	KVM_ISA_EXT_ARR(ZAWRS),
>  	KVM_ISA_EXT_ARR(ZBA),
> @@ -138,6 +139,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
>  	case KVM_RISCV_ISA_EXT_SVINVAL:
>  	case KVM_RISCV_ISA_EXT_SVVPTC:
>  	case KVM_RISCV_ISA_EXT_SVNAPOT:
> +	case KVM_RISCV_ISA_EXT_ZABHA:
>  	case KVM_RISCV_ISA_EXT_ZACAS:
>  	case KVM_RISCV_ISA_EXT_ZAWRS:
>  	case KVM_RISCV_ISA_EXT_ZBA:
> -- 
> 2.34.1
>

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>


From ajones at ventanamicro.com  Thu Nov 28 00:54:44 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 28 Nov 2024 09:54:44 +0100
Subject: [PATCH 3/4] RISC-V: KVM: Allow Ziccrse extension for Guest/VM
In-Reply-To: <77198ab759eb01ca490f4c2199910e778b57d372.1732762121.git.zhouquan@iscas.ac.cn>
References: <cover.1732762121.git.zhouquan@iscas.ac.cn>
 <77198ab759eb01ca490f4c2199910e778b57d372.1732762121.git.zhouquan@iscas.ac.cn>
Message-ID: <20241128-9f7234d55cedf2afd881f82a@orel>

On Thu, Nov 28, 2024 at 11:22:07AM +0800, zhouquan at iscas.ac.cn wrote:
> From: Quan Zhou <zhouquan at iscas.ac.cn>
> 
> Extend the KVM ISA extension ONE_REG interface to allow KVM user space
> to detect and enable Ziccrse extension for Guest/VM.
> 
> Signed-off-by: Quan Zhou <zhouquan at iscas.ac.cn>
> ---
>  arch/riscv/include/uapi/asm/kvm.h | 1 +
>  arch/riscv/kvm/vcpu_onereg.c      | 2 ++
>  2 files changed, 3 insertions(+)
> 
> diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
> index 340618131249..f7afb4267148 100644
> --- a/arch/riscv/include/uapi/asm/kvm.h
> +++ b/arch/riscv/include/uapi/asm/kvm.h
> @@ -179,6 +179,7 @@ enum KVM_RISCV_ISA_EXT_ID {
>  	KVM_RISCV_ISA_EXT_SSNPM,
>  	KVM_RISCV_ISA_EXT_SVVPTC,
>  	KVM_RISCV_ISA_EXT_ZABHA,
> +	KVM_RISCV_ISA_EXT_ZICCRSE,
>  	KVM_RISCV_ISA_EXT_MAX,
>  };
>  
> diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
> index 9a30a98f30bc..ed8e17da1536 100644
> --- a/arch/riscv/kvm/vcpu_onereg.c
> +++ b/arch/riscv/kvm/vcpu_onereg.c
> @@ -64,6 +64,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
>  	KVM_ISA_EXT_ARR(ZFHMIN),
>  	KVM_ISA_EXT_ARR(ZICBOM),
>  	KVM_ISA_EXT_ARR(ZICBOZ),
> +	KVM_ISA_EXT_ARR(ZICCRSE),
>  	KVM_ISA_EXT_ARR(ZICNTR),
>  	KVM_ISA_EXT_ARR(ZICOND),
>  	KVM_ISA_EXT_ARR(ZICSR),
> @@ -157,6 +158,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
>  	case KVM_RISCV_ISA_EXT_ZFA:
>  	case KVM_RISCV_ISA_EXT_ZFH:
>  	case KVM_RISCV_ISA_EXT_ZFHMIN:
> +	case KVM_RISCV_ISA_EXT_ZICCRSE:
>  	case KVM_RISCV_ISA_EXT_ZICNTR:
>  	case KVM_RISCV_ISA_EXT_ZICOND:
>  	case KVM_RISCV_ISA_EXT_ZICSR:
> -- 
> 2.34.1
>

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>


From ajones at ventanamicro.com  Thu Nov 28 01:00:02 2024
From: ajones at ventanamicro.com (Andrew Jones)
Date: Thu, 28 Nov 2024 10:00:02 +0100
Subject: [PATCH 4/4] KVM: riscv: selftests: Add Svvptc/Zabha/Ziccrse exts
 to get-reg-list test
In-Reply-To: <21d3a5314a9cd6ac5b3aa445060ae2679a44c792.1732762121.git.zhouquan@iscas.ac.cn>
References: <cover.1732762121.git.zhouquan@iscas.ac.cn>
 <21d3a5314a9cd6ac5b3aa445060ae2679a44c792.1732762121.git.zhouquan@iscas.ac.cn>
Message-ID: <20241128-846f2b5fdfda9e1aa9e373ee@orel>

On Thu, Nov 28, 2024 at 11:22:14AM +0800, zhouquan at iscas.ac.cn wrote:
> From: Quan Zhou <zhouquan at iscas.ac.cn>
> 
> The KVM RISC-V allows Svvptc/Zabha/Ziccrse extensions for Guest/VM
> so add them to get-reg-list test.
> 
> Signed-off-by: Quan Zhou <zhouquan at iscas.ac.cn>
> ---
>  tools/testing/selftests/kvm/riscv/get-reg-list.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 54ab484d0000..a697db1ff411 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -48,8 +48,10 @@ bool filter_reg(__u64 reg)
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SSNPM:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SSTC:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVINVAL:
> +	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVVPTC:

Alphabetic order, please.

>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVNAPOT:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVPBMT:
> +	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZABHA:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZACAS:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZAWRS:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZBA:
> @@ -69,6 +71,7 @@ bool filter_reg(__u64 reg)
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZFHMIN:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICBOM:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICBOZ:
> +	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICCRSE:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICNTR:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICOND:
>  	case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICSR:
> @@ -423,8 +426,10 @@ static const char *isa_ext_single_id_to_str(__u64 reg_off)
>  		KVM_ISA_EXT_ARR(SSNPM),
>  		KVM_ISA_EXT_ARR(SSTC),
>  		KVM_ISA_EXT_ARR(SVINVAL),
> +		KVM_ISA_EXT_ARR(SVVPTC),

Same comment as above.

>  		KVM_ISA_EXT_ARR(SVNAPOT),
>  		KVM_ISA_EXT_ARR(SVPBMT),
> +		KVM_ISA_EXT_ARR(ZABHA),
>  		KVM_ISA_EXT_ARR(ZACAS),
>  		KVM_ISA_EXT_ARR(ZAWRS),
>  		KVM_ISA_EXT_ARR(ZBA),
> @@ -444,6 +449,7 @@ static const char *isa_ext_single_id_to_str(__u64 reg_off)
>  		KVM_ISA_EXT_ARR(ZFHMIN),
>  		KVM_ISA_EXT_ARR(ZICBOM),
>  		KVM_ISA_EXT_ARR(ZICBOZ),
> +		KVM_ISA_EXT_ARR(ZICCRSE),
>  		KVM_ISA_EXT_ARR(ZICNTR),
>  		KVM_ISA_EXT_ARR(ZICOND),
>  		KVM_ISA_EXT_ARR(ZICSR),
> @@ -956,8 +962,10 @@ KVM_ISA_EXT_SIMPLE_CONFIG(sscofpmf, SSCOFPMF);
>  KVM_ISA_EXT_SIMPLE_CONFIG(ssnpm, SSNPM);
>  KVM_ISA_EXT_SIMPLE_CONFIG(sstc, SSTC);
>  KVM_ISA_EXT_SIMPLE_CONFIG(svinval, SVINVAL);
> +KVM_ISA_EXT_SIMPLE_CONFIG(svvptc, SVVPTC);

Same comment as above.

>  KVM_ISA_EXT_SIMPLE_CONFIG(svnapot, SVNAPOT);
>  KVM_ISA_EXT_SIMPLE_CONFIG(svpbmt, SVPBMT);
> +KVM_ISA_EXT_SIMPLE_CONFIG(zabha, ZABHA);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zacas, ZACAS);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zawrs, ZAWRS);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zba, ZBA);
> @@ -977,6 +985,7 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zfh, ZFH);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zfhmin, ZFHMIN);
>  KVM_ISA_EXT_SUBLIST_CONFIG(zicbom, ZICBOM);
>  KVM_ISA_EXT_SUBLIST_CONFIG(zicboz, ZICBOZ);
> +KVM_ISA_EXT_SIMPLE_CONFIG(ziccrse, ZICCRSE);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zicntr, ZICNTR);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zicond, ZICOND);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zicsr, ZICSR);
> @@ -1021,8 +1030,10 @@ struct vcpu_reg_list *vcpu_configs[] = {
>  	&config_ssnpm,
>  	&config_sstc,
>  	&config_svinval,
> +	&config_svvptc,

Same comment as above.

>  	&config_svnapot,
>  	&config_svpbmt,
> +	&config_zabha,
>  	&config_zacas,
>  	&config_zawrs,
>  	&config_zba,
> @@ -1042,6 +1053,7 @@ struct vcpu_reg_list *vcpu_configs[] = {
>  	&config_zfhmin,
>  	&config_zicbom,
>  	&config_zicboz,
> +	&config_ziccrse,
>  	&config_zicntr,
>  	&config_zicond,
>  	&config_zicsr,
> -- 
> 2.34.1
> 

Otherwise,

Reviewed-by: Andrew Jones <ajones at ventanamicro.com>

Thanks,
drew


From conor.dooley at microchip.com  Thu Nov 28 02:36:16 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Thu, 28 Nov 2024 10:36:16 +0000
Subject: [PATCH v1 08/11] clk: move meson clk-regmap implementation to
 common code
In-Reply-To: <430bde3b35382e640843e32a9f351326.sboyd@kernel.org>
References: <20241002-private-unequal-33cfa6101338@spud>
 <20241002-hula-unwashed-1c4ddbadbec2@spud>
 <2b49c4df-a34a-42c5-8d44-9e47da630fe8@linaro.org>
 <1jwmiqsks3.fsf@starbuckisacylon.baylibre.com>
 <20241003-tacking-ladylike-dfe2b633e647@spud>
 <20241106-freefall-slider-db379b05821e@spud>
 <430bde3b35382e640843e32a9f351326.sboyd@kernel.org>
Message-ID: <20241128-monstrous-embargo-a665d921410d@wendy>

On Thu, Nov 14, 2024 at 05:29:54PM -0800, Stephen Boyd wrote:
> Quoting Conor Dooley (2024-11-06 04:56:25)
> > My use case doesn't
> > actually need the registration code changes either as, currently, only reg
> > gets set at runtime, but leaving that out is a level of incomplete I'd not
> > let myself away with.
> > Obviously shoving the extra members into the clk structs has the downside
> > of taking up a pointer and a offset worth of memory for each clock of
> > that type registered, but it is substantially easier to support devices
> > with multiple regmaps that way. Probably moot though since the approach you
> > suggested in the thread linked above that implements a clk_hw_get_regmap()
> > has to store a pointer to the regmap's identifier which would take up an
> > identical amount of memory.
> 
> We don't need to store the regmap identifier in the struct clk. We can
> store it in the 'struct clk_init_data' with some new field, and only do
> that when/if we actually need to. We would need to pass the init data to
> the clk_ops::init() callback though. We currently knock that out during
> registration so that clk_hw->init is NULL. Probably we can just set that
> to NULL after the init routine runs in __clk_core_init().
> 
> Long story short, don't add something to 'struct clk_core', 'struct
> clk', or 'struct clk_hw' for these details. We can have a 'struct
> clk_regmap_hw' that everyone else can build upon:
> 
>   struct clk_regmap_hw {
>         struct regmap *regmap;
>         struct clk_hw hw;
>   };

What's the point of this? I don't understand why you want to do this over
what clk_divider et al already do, where clk_hw and the iomem pointer
are in the struct itself.

> 
> and then set the regmap pointer during registration in
> clk_hw_init_regmap().
> 
> int clk_hw_init_regmap(struct clk_hw *hw)
> {
> 	struct device *dev;
> 	struct regmap *regmap;
> 	struct clk_regmap_hw *rhw;
> 
> 	rhw = clk_hw_to_clk_regmap_hw(hw);
> 
> 	dev = clk_hw_get_dev(hw);
> 	if (!dev)
> 		return -EINVAL;
> 
> 	regmap = dev_get_regmap(dev, hw->init->regmap_name);
> 	if (!regmap)
> 		return -EINVAL; // Print helpful message
> 	rhw->regmap = regmap;
> 
> 	return 0;
> }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241128/c09e9202/attachment.sig>

From tglx at linutronix.de  Thu Nov 28 02:39:11 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Thu, 28 Nov 2024 11:39:11 +0100
Subject: [PATCH v2] arm64: kexec: Check if IRQ is already masked before
 masking
In-Reply-To: <20241127152236.26122-1-farbere@amazon.com>
References: <20241127152236.26122-1-farbere@amazon.com>
Message-ID: <87o71zy75c.ffs@tglx>

On Wed, Nov 27 2024 at 15:22, Eliav Farber wrote:
> diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
> index 80ceb5bd2680..54d0bd1bd449 100644
> --- a/arch/arm/kernel/machine_kexec.c
> +++ b/arch/arm/kernel/machine_kexec.c
> @@ -142,11 +142,8 @@ static void machine_kexec_mask_interrupts(void)
>  		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
>  			chip->irq_eoi(&desc->irq_data);
>  
> -		if (chip->irq_mask)
> -			chip->irq_mask(&desc->irq_data);
> -
> -		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
> -			chip->irq_disable(&desc->irq_data);
> +		irq_set_status_flags(i, IRQ_DISABLE_UNLAZY);
> +		irq_disable(desc);

This is just wrong. If the interrupt was torn down, then its state is
deactivated and it was masked already. So the EOI handling and the
mask/disable dance are neither required nor make sense.

So this whole thing should be:

		chip = irq_desc_get_chip(desc);
-		if (!chip)
+		if (!chip || !irqd_is_started(&desc->irq_data))
                	continue;

But what's worse is that we have 4 almost identical variants of the same
code.

So instead of exposing core functionality and "fixing" up four variants,
can we please have a consolidated version of this function in the core
code:
                struct irq_chip *chip;
                int check_eoi = 1;

		chip = irq_desc_get_chip(desc);
		if (!chip || !irqd_is_started(&desc->irq_data))
                	continue;

                if (IS_ENABLED(CONFIG_.....)) {
                        /*
                         * Add a sensible comment which explains this.
                         */
                	check_eoi = irq_set_irqchip_state(....);
                }

		if (check_eoi && ....)
                	chip->irq_eoi(&desc->irq_data);

		irq_shutdown(desc);

No?

Thanks,

        tglx


From tglx at linutronix.de  Thu Nov 28 02:43:20 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Thu, 28 Nov 2024 11:43:20 +0100
Subject: [PATCH v2] arm64: kexec: Check if IRQ is already masked before
 masking
In-Reply-To: <20241127152236.26122-1-farbere@amazon.com>
References: <20241127152236.26122-1-farbere@amazon.com>
Message-ID: <87ldx3y6yf.ffs@tglx>

On Wed, Nov 27 2024 at 15:22, Eliav Farber wrote:

As a related note. The subject line is not really matching what the
patch does. It want's to be split into a core change and one patch per
architecture.

> This patch replaces the direct invocation of the irq_mask() and

git grep 'This patch' Documentation/process/

> irq_disable() hooks with simplified code that leverages the
> irq_disable() kernel infrastructure. This higher-level function checks
> the interrupt's state to prevent redundant operations. Additionally, the
> IRQ_DISABLE_UNLAZY status flag is set to ensure that, for interrupt
> chips lacking an irq_disable callback, the disable operation is handled
> using the lazy approach.

Not that it matters much anymore, but the last sentence does not make
sense:

  Set the UNLAZY flag so disable is handled using the LAZY approach ...

Thanks,

        tglx


From alex at ghiti.fr  Thu Nov 28 04:38:38 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Thu, 28 Nov 2024 13:38:38 +0100
Subject: [PATCH fixes] riscv: mm: Do not call pmd dtor on vmemmap page
 table teardown
In-Reply-To: <20241120131203.1859787-1-bjorn@kernel.org>
References: <20241120131203.1859787-1-bjorn@kernel.org>
Message-ID: <a1350ae3-d414-49bc-9407-277841ebd734@ghiti.fr>

Hi Bj?rn,

On 20/11/2024 14:12, Bj?rn T?pel wrote:
> From: Bj?rn T?pel <bjorn at rivosinc.com>
>
> The vmemmap's, which is used for RV64 with SPARSEMEM_VMEMMAP, page
> tables are populated using pmd (page middle directory) hugetables.
> However, the pmd allocation is not using the generic mechanism used by
> the VMA code (e.g. pmd_alloc()), or the RISC-V specific
> create_pgd_mapping()/alloc_pmd_late(). Instead, the vmemmap page table
> code allocates a page, and calls vmemmap_set_pmd(). This results in
> that the pmd ctor is *not* called, nor would it make sense to do so.
>
> Now, when tearing down a vmemmap page table pmd, the cleanup code
> would unconditionally, and incorrectly call the pmd dtor, which
> results in a crash (best case).
>
> This issue was found when running the HMM selftests:
>
>    | tools/testing/selftests/mm# ./test_hmm.sh smoke
>    | ... # when unloading the test_hmm.ko module
>    | page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10915b
>    | flags: 0x1000000000000000(node=0|zone=1)
>    | raw: 1000000000000000 0000000000000000 dead000000000122 0000000000000000
>    | raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
>    | page dumped because: VM_BUG_ON_PAGE(ptdesc->pmd_huge_pte)
>    | ------------[ cut here ]------------
>    | kernel BUG at include/linux/mm.h:3080!
>    | Kernel BUG [#1]
>    | Modules linked in: test_hmm(-) sch_fq_codel fuse drm drm_panel_orientation_quirks backlight dm_mod
>    | CPU: 1 UID: 0 PID: 514 Comm: modprobe Tainted: G        W          6.12.0-00982-gf2a4f1682d07 #2
>    | Tainted: [W]=WARN
>    | Hardware name: riscv-virtio qemu/qemu, BIOS 2024.10 10/01/2024
>    | epc : remove_pgd_mapping+0xbec/0x1070
>    |  ra : remove_pgd_mapping+0xbec/0x1070
>    | epc : ffffffff80010a68 ra : ffffffff80010a68 sp : ff20000000a73940
>    |  gp : ffffffff827b2d88 tp : ff6000008785da40 t0 : ffffffff80fbce04
>    |  t1 : 0720072007200720 t2 : 706d756420656761 s0 : ff20000000a73a50
>    |  s1 : ff6000008915cff8 a0 : 0000000000000039 a1 : 0000000000000008
>    |  a2 : ff600003fff0de20 a3 : 0000000000000000 a4 : 0000000000000000
>    |  a5 : 0000000000000000 a6 : c0000000ffffefff a7 : ffffffff824469b8
>    |  s2 : ff1c0000022456c0 s3 : ff1ffffffdbfffff s4 : ff6000008915c000
>    |  s5 : ff6000008915c000 s6 : ff6000008915c000 s7 : ff1ffffffdc00000
>    |  s8 : 0000000000000001 s9 : ff1ffffffdc00000 s10: ffffffff819a31f0
>    |  s11: ffffffffffffffff t3 : ffffffff8000c950 t4 : ff60000080244f00
>    |  t5 : ff60000080244000 t6 : ff20000000a73708
>    | status: 0000000200000120 badaddr: ffffffff80010a68 cause: 0000000000000003
>    | [<ffffffff80010a68>] remove_pgd_mapping+0xbec/0x1070
>    | [<ffffffff80fd238e>] vmemmap_free+0x14/0x1e
>    | [<ffffffff8032e698>] section_deactivate+0x220/0x452
>    | [<ffffffff8032ef7e>] sparse_remove_section+0x4a/0x58
>    | [<ffffffff802f8700>] __remove_pages+0x7e/0xba
>    | [<ffffffff803760d8>] memunmap_pages+0x2bc/0x3fe
>    | [<ffffffff02a3ca28>] dmirror_device_remove_chunks+0x2ea/0x518 [test_hmm]
>    | [<ffffffff02a3e026>] hmm_dmirror_exit+0x3e/0x1018 [test_hmm]
>    | [<ffffffff80102c14>] __riscv_sys_delete_module+0x15a/0x2a6
>    | [<ffffffff80fd020c>] do_trap_ecall_u+0x1f2/0x266
>    | [<ffffffff80fde0a2>] _new_vmalloc_restore_context_a0+0xc6/0xd2
>    | Code: bf51 7597 0184 8593 76a5 854a 4097 0029 80e7 2c00 (9002) 7597
>    | ---[ end trace 0000000000000000 ]---
>    | Kernel panic - not syncing: Fatal exception in interrupt
>
> Add a check to avoid calling the pmd dtor, if the calling context is
> vmemmap_free().
>
> Fixes: c75a74f4ba19 ("riscv: mm: Add memory hotplugging support")
> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>
> ---
>   arch/riscv/mm/init.c | 7 ++++---
>   1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 0e8c20adcd98..fc53ce748c80 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -1566,7 +1566,7 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
>   	pmd_clear(pmd);
>   }
>   
> -static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
> +static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud, bool is_vmemmap)
>   {
>   	struct page *page = pud_page(*pud);
>   	struct ptdesc *ptdesc = page_ptdesc(page);
> @@ -1579,7 +1579,8 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
>   			return;
>   	}
>   
> -	pagetable_pmd_dtor(ptdesc);
> +	if (!is_vmemmap)
> +		pagetable_pmd_dtor(ptdesc);
>   	if (PageReserved(page))
>   		free_reserved_page(page);
>   	else
> @@ -1703,7 +1704,7 @@ static void __meminit remove_pud_mapping(pud_t *pud_base, unsigned long addr, un
>   		remove_pmd_mapping(pmd_base, addr, next, is_vmemmap, altmap);
>   
>   		if (pgtable_l4_enabled)
> -			free_pmd_table(pmd_base, pudp);
> +			free_pmd_table(pmd_base, pudp, is_vmemmap);
>   	}
>   }
>   
>
> base-commit: 57f7c7dc78cd09622b12920d92b40c1ce11b234e


Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From conor.dooley at microchip.com  Thu Nov 28 04:56:55 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Thu, 28 Nov 2024 12:56:55 +0000
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241103145153.105097-14-alexghiti@rivosinc.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com>
Message-ID: <20241128-whoever-wildfire-2a3110c5fd46@wendy>

On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> In order to produce a generic kernel, a user can select
> CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> spinlock implementation if Zabha or Ziccrse are not present.
> 
> Note that we can't use alternatives here because the discovery of
> extensions is done too late and we need to start with the qspinlock
> implementation because the ticket spinlock implementation would pollute
> the spinlock value, so let's use static keys.
> 
> This is largely based on Guo's work and Leonardo reviews at [1].
> 
> Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>

This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
breaks boot on polarfire soc. It dies before outputting anything to the
console. My .config has:

# CONFIG_RISCV_TICKET_SPINLOCKS is not set
# CONFIG_RISCV_QUEUED_SPINLOCKS is not set
CONFIG_RISCV_COMBO_SPINLOCKS=y
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241128/4f55c99f/attachment.sig>

From alex at ghiti.fr  Thu Nov 28 05:02:40 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Thu, 28 Nov 2024 14:02:40 +0100
Subject: [PATCH] riscv: kprobes: Fix incorrect address calculation
In-Reply-To: <20241119111056.2554419-1-namcao@linutronix.de>
References: <20241119111056.2554419-1-namcao@linutronix.de>
Message-ID: <7662be43-16e6-4695-9bc4-077e1dd3ba12@ghiti.fr>

Hi Nam,

On 19/11/2024 12:10, Nam Cao wrote:
> p->ainsn.api.insn is a pointer to u32, therefore arithmetic operations are
> multiplied by four. This is clearly undesirable for this case.
>
> Cast it to (void *) first before any calculation.
>
> Below is a sample before/after. The dumped memory is two kprobe slots, the
> first slot has
>
>    - c.addiw a0, 0x1c (0x7125)
>    - ebreak           (0x00100073)
>
> and the second slot has:
>
>    - c.addiw a0, -4   (0x7135)
>    - ebreak           (0x00100073)
>
> Before this patch:
>
> (gdb) x/16xh 0xff20000000135000
> 0xff20000000135000:	0x7125	0x0000	0x0000	0x0000	0x7135	0x0010	0x0000	0x0000
> 0xff20000000135010:	0x0073	0x0010	0x0000	0x0000	0x0000	0x0000	0x0000	0x0000
>
> After this patch:
>
> (gdb) x/16xh 0xff20000000125000
> 0xff20000000125000:	0x7125	0x0073	0x0010	0x0000	0x7135	0x0073	0x0010	0x0000
> 0xff20000000125010:	0x0000	0x0000	0x0000	0x0000	0x0000	0x0000	0x0000	0x0000
>
> Fixes: b1756750a397 ("riscv: kprobes: Use patch_text_nosync() for insn slots")
> Signed-off-by: Nam Cao <namcao at linutronix.de>
> Cc: stable at vger.kernel.org
> ---
>   arch/riscv/kernel/probes/kprobes.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c
> index 474a65213657..d2dacea1aedd 100644
> --- a/arch/riscv/kernel/probes/kprobes.c
> +++ b/arch/riscv/kernel/probes/kprobes.c
> @@ -30,7 +30,7 @@ static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
>   	p->ainsn.api.restore = (unsigned long)p->addr + len;
>   
>   	patch_text_nosync(p->ainsn.api.insn, &p->opcode, len);
> -	patch_text_nosync(p->ainsn.api.insn + len, &insn, GET_INSN_LENGTH(insn));
> +	patch_text_nosync((void *)p->ainsn.api.insn + len, &insn, GET_INSN_LENGTH(insn));
>   }
>   
>   static void __kprobes arch_prepare_simulate(struct kprobe *p)

This looks good to me, how did you find this issue?

You can add:

Reviewed-by: Alexandre Ghiti <alexghiti at rivosinc.com>

Thanks,

Alex



From toke at redhat.com  Thu Nov 28 05:07:20 2024
From: toke at redhat.com (Toke =?utf-8?Q?H=C3=B8iland-J=C3=B8rgensen?=)
Date: Thu, 28 Nov 2024 14:07:20 +0100
Subject: [PATCH bpf v2] tools: Override makefile ARCH variable if
 defined, but empty
In-Reply-To: <20241127101748.165693-1-bjorn@kernel.org>
References: <20241127101748.165693-1-bjorn@kernel.org>
Message-ID: <87o71zik1j.fsf@toke.dk>

Bj?rn T?pel <bjorn at kernel.org> writes:

> From: Bj?rn T?pel <bjorn at rivosinc.com>
>
> There are a number of tools (bpftool, selftests), that require a
> "bootstrap" build. Here, a bootstrap build is a build host variant of
> a target. E.g., assume that you're performing a bpftool cross-build on
> x86 to riscv, a bootstrap build would then be an x86 variant of
> bpftool. The typical way to perform the host build variant, is to pass
> "ARCH=" in a sub-make. However, if a variable has been set with a
> command argument, then ordinary assignments in the makefile are
> ignored.
>
> This side-effect results in that ARCH, and variables depending on ARCH
> are not set.
>
> Workaround by overriding ARCH to the host arch, if ARCH is empty.
>
> Fixes: 8859b0da5aac ("tools/bpftool: Fix cross-build")
> Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
> Tested-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> Reviewed-by: Namhyung Kim <namhyung at kernel.org>
> Acked-by: Quentin Monnet <qmo at kernel.org>
> Signed-off-by: Bj?rn T?pel <bjorn at rivosinc.com>

Reviewed-by: Toke H?iland-J?rgensen <toke at redhat.com>



From alex at ghiti.fr  Thu Nov 28 05:10:53 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Thu, 28 Nov 2024 14:10:53 +0100
Subject: [PATCH 2/8] drivers/perf: riscv: Fix Platform firmware event data
In-Reply-To: <20241119-pmu_event_info-v1-2-a4f9691421f8@rivosinc.com>
References: <20241119-pmu_event_info-v1-0-a4f9691421f8@rivosinc.com>
 <20241119-pmu_event_info-v1-2-a4f9691421f8@rivosinc.com>
Message-ID: <77b7b44f-e05a-4845-8d45-0e0d831bb8e7@ghiti.fr>

Hi Atish,

On 19/11/2024 21:29, Atish Patra wrote:
> Platform firmware event data field is allowed to be 62 bits for
> Linux as uppper most two bits are reserved to indicate SBI fw or
> platform specific firmware events.
> However, the event data field is masked as per the hardware raw
> event mask which is not correct.
>
> Fix the platform firmware event data field with proper mask.
>
> Fixes: f0c9363db2dd ("perf/riscv-sbi: Add platform specific firmware event handling")
>
> Signed-off-by: Atish Patra <atishp at rivosinc.com>
> ---
>   arch/riscv/include/asm/sbi.h |  1 +
>   drivers/perf/riscv_pmu_sbi.c | 12 +++++-------
>   2 files changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
> index 98f631b051db..9be38b05f4ad 100644
> --- a/arch/riscv/include/asm/sbi.h
> +++ b/arch/riscv/include/asm/sbi.h
> @@ -158,6 +158,7 @@ struct riscv_pmu_snapshot_data {
>   };
>   
>   #define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
> +#define RISCV_PMU_PLAT_FW_EVENT_MASK GENMASK_ULL(61, 0)
>   #define RISCV_PMU_RAW_EVENT_IDX 0x20000
>   #define RISCV_PLAT_FW_EVENT	0xFFFF
>   
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index cb98efa9b106..50cbdbf66bb7 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -508,7 +508,6 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
>   {
>   	u32 type = event->attr.type;
>   	u64 config = event->attr.config;
> -	u64 raw_config_val;
>   	int ret;
>   
>   	/*
> @@ -529,21 +528,20 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
>   	case PERF_TYPE_RAW:
>   		/*
>   		 * As per SBI specification, the upper 16 bits must be unused
> -		 * for a raw event.
> +		 * for a hardware raw event.
>   		 * Bits 63:62 are used to distinguish between raw events
>   		 * 00 - Hardware raw event
>   		 * 10 - SBI firmware events
>   		 * 11 - Risc-V platform specific firmware event
>   		 */
> -		raw_config_val = config & RISCV_PMU_RAW_EVENT_MASK;
> +
>   		switch (config >> 62) {
>   		case 0:
>   			ret = RISCV_PMU_RAW_EVENT_IDX;
> -			*econfig = raw_config_val;
> +			*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
>   			break;
>   		case 2:
> -			ret = (raw_config_val & 0xFFFF) |
> -				(SBI_PMU_EVENT_TYPE_FW << 16);
> +			ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
>   			break;
>   		case 3:
>   			/*
> @@ -552,7 +550,7 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
>   			 * Event data - raw event encoding
>   			 */
>   			ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
> -			*econfig = raw_config_val;
> +			*econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
>   			break;
>   		}
>   		break;
>

It seems independent from the other patches, so I guess we should take 
it for 6.13 rcX.

Let me know if that's not the case.

Thanks,

Alex



From will at kernel.org  Thu Nov 28 05:41:36 2024
From: will at kernel.org (Will Deacon)
Date: Thu, 28 Nov 2024 13:41:36 +0000
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241128-whoever-wildfire-2a3110c5fd46@wendy>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com>
 <20241128-whoever-wildfire-2a3110c5fd46@wendy>
Message-ID: <20241128134135.GA3460@willie-the-truck>

On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > In order to produce a generic kernel, a user can select
> > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > spinlock implementation if Zabha or Ziccrse are not present.
> > 
> > Note that we can't use alternatives here because the discovery of
> > extensions is done too late and we need to start with the qspinlock
> > implementation because the ticket spinlock implementation would pollute
> > the spinlock value, so let's use static keys.
> > 
> > This is largely based on Guo's work and Leonardo reviews at [1].
> > 
> > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > Signed-off-by: Guo Ren <guoren at kernel.org>
> > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> 
> This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> breaks boot on polarfire soc. It dies before outputting anything to the
> console. My .config has:
> 
> # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> CONFIG_RISCV_COMBO_SPINLOCKS=y

I pointed out some of the fragility during review:

https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/

so I'm kinda surprised it got merged tbh :/

Will


From conor.dooley at microchip.com  Thu Nov 28 06:14:53 2024
From: conor.dooley at microchip.com (Conor Dooley)
Date: Thu, 28 Nov 2024 14:14:53 +0000
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241128134135.GA3460@willie-the-truck>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com>
 <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck>
Message-ID: <20241128-uncivil-removed-4e105d1397c9@wendy>

On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > In order to produce a generic kernel, a user can select
> > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > spinlock implementation if Zabha or Ziccrse are not present.
> > > 
> > > Note that we can't use alternatives here because the discovery of
> > > extensions is done too late and we need to start with the qspinlock
> > > implementation because the ticket spinlock implementation would pollute
> > > the spinlock value, so let's use static keys.
> > > 
> > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > 
> > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > 
> > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > breaks boot on polarfire soc. It dies before outputting anything to the
> > console. My .config has:
> > 
> > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > CONFIG_RISCV_COMBO_SPINLOCKS=y
> 
> I pointed out some of the fragility during review:
> 
> https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> 
> so I'm kinda surprised it got merged tbh :/

Maybe it could be reverted rather than having a broken boot with the
default settings in -rc1.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241128/36e2d549/attachment.sig>

From zhangkai at iscas.ac.cn  Thu Nov 28 06:24:27 2024
From: zhangkai at iscas.ac.cn (laokz)
Date: Thu, 28 Nov 2024 22:24:27 +0800
Subject: [PATCH v2] riscv: module: use a plain variable for list_head
 instead of a pointer
In-Reply-To: <20241128-0e953467c518d79d12dbf202@orel>
References: <20241127142519.3038691-1-cleger@rivosinc.com>
	 <980b98978ab4ee912b37cb101ad43bce20b56dcb.camel@iscas.ac.cn>
	 <20241128-0e953467c518d79d12dbf202@orel>
Message-ID: <c5971ce3de4e5f59e8013b1c6a5bf4158c69e6b8.camel@iscas.ac.cn>

On Thu, 2024-11-28 at 09:32 +0100, Andrew Jones wrote:
> On Thu, Nov 28, 2024 at 09:01:52AM +0800, laokz wrote:
> > On Wed, 2024-11-27 at 15:25 +0100, Cl?ment L?ger wrote:
> > > rel_head's list_head member, rel_entry, doesn't need to be
> > > allocated,
> > > its storage can just be part of the allocated rel_head. Remove
> > > the
> > 
> > Oh my poor English. OK, it's more better than just add the lost
> > kfree.
> > 
> 
> It wasn't the English I was correcting. That was fine, but just
> saying
> the object could be "a plain variable" wasn't giving any
> justification
> for the change and, to me, even implied that rel_entry was locally
> scoped. So, when I first skimmed the patch and saw that it was
> getting
> appended to a list, I almost stated the patch was wrong. It was clear
> after looking closer, but it could have been clear the first time
> through if the commit message had better guided me.

Thanks for the explanation.
laokz

> Thanks,
> drew



From alex at ghiti.fr  Thu Nov 28 06:50:09 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Thu, 28 Nov 2024 15:50:09 +0100
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241128-uncivil-removed-4e105d1397c9@wendy>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com>
 <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck>
 <20241128-uncivil-removed-4e105d1397c9@wendy>
Message-ID: <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr>

On 28/11/2024 15:14, Conor Dooley wrote:
> On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
>> On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
>>> On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
>>>> In order to produce a generic kernel, a user can select
>>>> CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
>>>> spinlock implementation if Zabha or Ziccrse are not present.
>>>>
>>>> Note that we can't use alternatives here because the discovery of
>>>> extensions is done too late and we need to start with the qspinlock
>>>> implementation because the ticket spinlock implementation would pollute
>>>> the spinlock value, so let's use static keys.
>>>>
>>>> This is largely based on Guo's work and Leonardo reviews at [1].
>>>>
>>>> Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
>>>> Signed-off-by: Guo Ren <guoren at kernel.org>
>>>> Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
>>> This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
>>> breaks boot on polarfire soc. It dies before outputting anything to the
>>> console. My .config has:
>>>
>>> # CONFIG_RISCV_TICKET_SPINLOCKS is not set
>>> # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
>>> CONFIG_RISCV_COMBO_SPINLOCKS=y
>> I pointed out some of the fragility during review:
>>
>> https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
>>
>> so I'm kinda surprised it got merged tbh :/
> Maybe it could be reverted rather than having a broken boot with the
> default settings in -rc1.


No need to rush before we know what's happening,I guess you bisected to 
this commit right?

I don't have this soc, so can you provide $stval/$sepc/$scause, a 
config, a kernel, anything?

Does the polarfire soc provide Ziccrse?


>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From lkp at intel.com  Thu Nov 28 08:07:36 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 29 Nov 2024 00:07:36 +0800
Subject: [PATCH v3 3/3] clk: spacemit: Add clock support for Spacemit K1
 SoC
In-Reply-To: <20241126143125.9980-7-heylenay@4d2.org>
References: <20241126143125.9980-7-heylenay@4d2.org>
Message-ID: <202411282305.iJ9x0lmj-lkp@intel.com>

Hi Haylen,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 2d5404caa8c7bb5c4e0435f94b28834ae5456623]

url:    https://github.com/intel-lab-lkp/linux/commits/Haylen-Chu/dt-bindings-clock-spacemit-Add-clock-controllers-of-Spacemit-K1-SoC/20241128-101248
base:   2d5404caa8c7bb5c4e0435f94b28834ae5456623
patch link:    https://lore.kernel.org/r/20241126143125.9980-7-heylenay%404d2.org
patch subject: [PATCH v3 3/3] clk: spacemit: Add clock support for Spacemit K1 SoC
config: loongarch-allyesconfig (https://download.01.org/0day-ci/archive/20241128/202411282305.iJ9x0lmj-lkp at intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241128/202411282305.iJ9x0lmj-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411282305.iJ9x0lmj-lkp at intel.com/

All warnings (new ones prefixed by >>):

   drivers/clk/spacemit/ccu_pll.c: In function 'ccu_pll_set_rate':
>> drivers/clk/spacemit/ccu_pll.c:128:23: warning: variable 'old_rate' set but not used [-Wunused-but-set-variable]
     128 |         unsigned long old_rate;
         |                       ^~~~~~~~
--
   drivers/clk/spacemit/ccu_mix.c: In function 'ccu_mix_set_rate':
>> drivers/clk/spacemit/ccu_mix.c:180:23: warning: variable 'best_rate' set but not used [-Wunused-but-set-variable]
     180 |         unsigned long best_rate = 0;
         |                       ^~~~~~~~~
--
   drivers/clk/spacemit/ccu_ddn.c: In function 'clk_ddn_set_rate':
>> drivers/clk/spacemit/ccu_ddn.c:115:23: warning: variable 'prev_rate' set but not used [-Wunused-but-set-variable]
     115 |         unsigned long prev_rate, rate = 0;
         |                       ^~~~~~~~~


vim +/old_rate +128 drivers/clk/spacemit/ccu_pll.c

   115	
   116	/*
   117	 * pll rate change requires sequence:
   118	 * clock off -> change rate setting -> clock on
   119	 * This function doesn't really change rate, but cache the config
   120	 */
   121	static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
   122				       unsigned long parent_rate)
   123	{
   124		struct ccu_pll *p = hw_to_ccu_pll(hw);
   125		struct ccu_common *common = &p->common;
   126		struct ccu_pll_config *params = &p->pll;
   127		struct ccu_pll_rate_tbl *entry;
 > 128		unsigned long old_rate;
   129		bool found = false;
   130		u32 mask, val;
   131		int i;
   132	
   133		if (ccu_pll_is_enabled(hw)) {
   134			pr_err("%s %s is enabled, ignore the setrate!\n",
   135			       __func__, __clk_get_name(hw->clk));
   136			return 0;
   137		}
   138	
   139		old_rate = __get_vco_freq(hw);
   140	
   141		for (i = 0; i < params->tbl_size; i++) {
   142			if (rate == params->rate_tbl[i].rate) {
   143				found = true;
   144				entry = &params->rate_tbl[i];
   145				break;
   146			}
   147		}
   148		WARN_ON_ONCE(!found);
   149	
   150		mask = PLL_SWCR1_REG5_MASK | PLL_SWCR1_REG6_MASK;
   151		mask |= PLL_SWCR1_REG7_MASK | PLL_SWCR1_REG8_MASK;
   152		val |= entry->reg5 << PLL_SWCR1_REG5_OFF;
   153		val |= entry->reg6 << PLL_SWCR1_REG6_OFF;
   154		val |= entry->reg7 << PLL_SWCR1_REG7_OFF;
   155		val |= entry->reg8 << PLL_SWCR1_REG8_OFF;
   156		ccu_update(swcr1, common, mask, val);
   157	
   158		mask = PLL_SWCR3_DIV_INT_MASK | PLL_SWCR3_DIV_FRC_MASK;
   159		val = entry->div_int << PLL_SWCR3_DIV_INT_OFF;
   160		val |= entry->div_frac << PLL_SWCR3_DIV_FRC_OFF;
   161		ccu_update(swcr3, common, mask, val);
   162	
   163		return 0;
   164	}
   165	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From conor at kernel.org  Thu Nov 28 08:19:31 2024
From: conor at kernel.org (Conor Dooley)
Date: Thu, 28 Nov 2024 16:19:31 +0000
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com>
 <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck>
 <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr>
Message-ID: <20241128-goggles-laundry-d94c23ab39a4@spud>

On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> On 28/11/2024 15:14, Conor Dooley wrote:
> > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > In order to produce a generic kernel, a user can select
> > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > 
> > > > > Note that we can't use alternatives here because the discovery of
> > > > > extensions is done too late and we need to start with the qspinlock
> > > > > implementation because the ticket spinlock implementation would pollute
> > > > > the spinlock value, so let's use static keys.
> > > > > 
> > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > 
> > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > console. My .config has:
> > > > 
> > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > I pointed out some of the fragility during review:
> > > 
> > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > 
> > > so I'm kinda surprised it got merged tbh :/
> > Maybe it could be reverted rather than having a broken boot with the
> > default settings in -rc1.
> 
> 
> No need to rush before we know what's happening,I guess you bisected to this
> commit right?

The symptom is a failure to boot, without any console output, of course
I bisected it before blaming something specific. But I don't think it is
"rushing" as having -rc1 broken with an option's default is a massive pain
in the arse when it comes to testing.

> I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> kernel, anything?

I don't have the former cos it died immediately on boot. config is
attached. It reproduces in QEMU so you don't need any hardware.

> Does the polarfire soc provide Ziccrse?

I don't think that is relevant because ziccrse is not listed in the dts,
so the kernel should not be assuming that LR/SC has a forward progress
guarantee. It's not even getting as far as riscv_spinlock_init() given
several things before that should be emitting logs, so it doesn't even
get to make any decisions about Ziccrse.
-------------- next part --------------
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_GENERIC_IRQ_DEBUGFS=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BPF_SYSCALL=y
CONFIG_PREEMPT_RT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_CGROUP_BPF=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_SYSFS_SYSCALL is not set
CONFIG_PROFILING=y
CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
CONFIG_ARCH_MICROCHIP=y
CONFIG_ARCH_RENESAS=y
CONFIG_ARCH_SOPHGO=y
CONFIG_SOC_STARFIVE=y
CONFIG_ARCH_THEAD=y
CONFIG_ARCH_VIRT=y
CONFIG_NONPORTABLE=y
CONFIG_SMP=y
CONFIG_RANDOMIZE_BASE=y
CONFIG_CMDLINE="earlycon keep_bootcon reboot=cold"
CONFIG_HIBERNATION=y
CONFIG_CPU_FREQ=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
CONFIG_ACPI=y
CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NETLINK_DIAG=y
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_PCI=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCIE_XILINX=y
CONFIG_PCIE_MICROCHIP_HOST=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_DEBUG_DRIVER=y
CONFIG_AX45MP_L2_CACHE=y
CONFIG_SIFIVE_CCACHE=y
CONFIG_EFI_ZBOOT=y
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_SPI_NOR=y
# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
CONFIG_OF_OVERLAY=y
CONFIG_ZRAM=y
CONFIG_ZRAM_MEMORY_TRACKING=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_NVME=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=y
CONFIG_SCSI_VIRTIO=y
CONFIG_ATA=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_NETDEVICES=y
CONFIG_VIRTIO_NET=y
CONFIG_MACB=y
CONFIG_E1000E=y
CONFIG_R8169=y
CONFIG_MICROSEMI_PHY=y
CONFIG_VITESSE_PHY=y
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_JOYDEV=m
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_SENSEHAT=m
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_HW_RANDOM_POLARFIRE_SOC=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MICROCHIP_CORE=y
CONFIG_SPI=y
CONFIG_SPI_MICROCHIP_CORE=y
CONFIG_SPI_MICROCHIP_CORE_QSPI=y
CONFIG_SPI_SIFIVE=y
# CONFIG_PTP_1588_CLOCK is not set
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_POLARFIRE_SOC=y
CONFIG_GPIO_SIFIVE=y
CONFIG_AUXDISPLAY=y
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_MAX9867=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PLATFORM=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_STORAGE=y
CONFIG_USB_UAS=y
CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_POLARFIRE_SOC=y
CONFIG_USB_INVENTRA_DMA=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_CADENCE=y
CONFIG_MMC_SPI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_PWM=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_PCF2123=y
CONFIG_DMADEVICES=y
CONFIG_SF_PDMA=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_MAILBOX=y
CONFIG_POLARFIRE_SOC_MAILBOX=y
CONFIG_RPMSG_CHAR=y
CONFIG_RPMSG_CTRL=y
CONFIG_RPMSG_VIRTIO=y
CONFIG_POLARFIRE_SOC_SYS_CTRL=y
CONFIG_IIO=y
CONFIG_ADXL345_SPI=y
CONFIG_MCP320X=y
CONFIG_MCP3564=y
CONFIG_PAC1934=y
CONFIG_SD_ADC_MODULATOR=y
CONFIG_HTS221=m
CONFIG_IIO_ST_LSM6DSX=m
CONFIG_IIO_ST_MAGN_3AXIS=m
CONFIG_IIO_ST_PRESS=m
CONFIG_PWM=y
CONFIG_PWM_DEBUG=y
CONFIG_PWM_MICROCHIP_CORE=y
CONFIG_LIBNVDIMM=y
CONFIG_FPGA=y
CONFIG_FPGA_BRIDGE=y
CONFIG_FPGA_REGION=y
CONFIG_FPGA_MGR_MICROCHIP_SPI=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_HUGETLBFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4_1=y
CONFIG_NFS_V4_2=y
CONFIG_NFS_V4_1_MIGRATION=y
CONFIG_ROOT_NFS=y
CONFIG_9P_FS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=m
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CRYPTO_DEV_VIRTIO=y
CONFIG_PRINTK_TIME=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_VM_PGFLAGS=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_PER_CPU_MAPS=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_WQ_WATCHDOG=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PLIST=y
CONFIG_DEBUG_SG=y
# CONFIG_RCU_TRACE is not set
CONFIG_RCU_EQS_DEBUG=y
CONFIG_SAMPLES=y
CONFIG_MEMTEST=y
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241128/18667215/attachment.sig>

From farbere at amazon.com  Thu Nov 28 12:10:26 2024
From: farbere at amazon.com (Eliav Farber)
Date: Thu, 28 Nov 2024 20:10:26 +0000
Subject: [PATCH v3 1/2] kexec: Consolidate machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241128201027.10396-1-farbere@amazon.com>
References: <20241128201027.10396-1-farbere@amazon.com>
Message-ID: <20241128201027.10396-2-farbere@amazon.com>

Move the machine_kexec_mask_interrupts function to a common location in
kernel/kexec_core.c, removing duplicate implementations from architecture
specific files (arch/arm, arch/arm64, arch/powerpc, and arch/riscv).

This consolidation reduces code duplication and improves maintainability.

The unified function includes an architecture-specific behavior for
CONFIG_ARM64 by conditionally clearing the active interrupt state before
handling other interrupt masking operations.

Signed-off-by: Eliav Farber <farbere at amazon.com>
---
V2 -> V3: This patch is new and didn't exist in V2.

 arch/arm/kernel/machine_kexec.c   | 23 ----------------------
 arch/arm64/kernel/machine_kexec.c | 31 ------------------------------
 arch/powerpc/include/asm/kexec.h  |  1 -
 arch/powerpc/kexec/core.c         | 22 ---------------------
 arch/riscv/kernel/machine_kexec.c | 23 ----------------------
 include/linux/kexec.h             |  2 ++
 kernel/kexec_core.c               | 32 +++++++++++++++++++++++++++++++
 7 files changed, 34 insertions(+), 100 deletions(-)

diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 80ceb5bd2680..dd430477e7c1 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -127,29 +127,6 @@ void crash_smp_send_stop(void)
 	cpus_stopped = 1;
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 void machine_crash_shutdown(struct pt_regs *regs)
 {
 	local_irq_disable();
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 82e2203d86a3..6f121a0164a4 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -207,37 +207,6 @@ void machine_kexec(struct kimage *kimage)
 	BUG(); /* Should never get here. */
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-		int ret;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		/*
-		 * First try to remove the active state. If this
-		 * fails, try to EOI the interrupt.
-		 */
-		ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
-
-		if (ret && irqd_irq_inprogress(&desc->irq_data) &&
-		    chip->irq_eoi)
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 /**
  * machine_crash_shutdown - shutdown non-crashing cpus and save registers
  */
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 270ee93a0f7d..601e569303e1 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -61,7 +61,6 @@ struct pt_regs;
 extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
 					  master to copy new code to 0 */
 extern void default_machine_kexec(struct kimage *image);
-extern void machine_kexec_mask_interrupts(void);
 
 void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer,
 			 unsigned long start_address) __noreturn;
diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
index b8333a49ea5d..58a930a47422 100644
--- a/arch/powerpc/kexec/core.c
+++ b/arch/powerpc/kexec/core.c
@@ -22,28 +22,6 @@
 #include <asm/setup.h>
 #include <asm/firmware.h>
 
-void machine_kexec_mask_interrupts(void) {
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 #ifdef CONFIG_CRASH_DUMP
 void machine_crash_shutdown(struct pt_regs *regs)
 {
diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
index 3c830a6f7ef4..2306ce3e5f22 100644
--- a/arch/riscv/kernel/machine_kexec.c
+++ b/arch/riscv/kernel/machine_kexec.c
@@ -114,29 +114,6 @@ void machine_shutdown(void)
 #endif
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 /*
  * machine_crash_shutdown - Prepare to kexec after a kernel crash
  *
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index f0e9f8eda7a3..9dac0524c0be 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -375,6 +375,8 @@ extern void machine_kexec(struct kimage *image);
 extern int machine_kexec_prepare(struct kimage *image);
 extern void machine_kexec_cleanup(struct kimage *image);
 extern int kernel_kexec(void);
+extern void machine_kexec_mask_interrupts(void);
+
 extern struct page *kimage_alloc_control_pages(struct kimage *image,
 						unsigned int order);
 
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index c0caa14880c3..6e1e420946e0 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -1072,3 +1072,35 @@ int kernel_kexec(void)
 	kexec_unlock();
 	return error;
 }
+
+void machine_kexec_mask_interrupts(void)
+{
+	unsigned int i;
+	struct irq_desc *desc;
+
+	for_each_irq_desc(i, desc) {
+		struct irq_chip *chip;
+		int check_eoi = 1;
+
+		chip = irq_desc_get_chip(desc);
+		if (!chip)
+			continue;
+
+		if (IS_ENABLED(CONFIG_ARM64)) {
+			/*
+			 * First try to remove the active state. If this fails, try to EOI the
+			 * interrupt.
+			 */
+			check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
+		}
+
+		if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
+			chip->irq_eoi(&desc->irq_data);
+
+		if (chip->irq_mask)
+			chip->irq_mask(&desc->irq_data);
+
+		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
+			chip->irq_disable(&desc->irq_data);
+	}
+}
-- 
2.40.1



From farbere at amazon.com  Thu Nov 28 12:10:25 2024
From: farbere at amazon.com (Eliav Farber)
Date: Thu, 28 Nov 2024 20:10:25 +0000
Subject: [PATCH v3 0/2] Improve interrupt handling during machine kexec
Message-ID: <20241128201027.10396-1-farbere@amazon.com>

This patch series focuses on improving the machine_kexec_mask_interrupts()
function by consolidating its implementation and optimizing its behavior to
avoid redundant interrupt masking.

Patch Summary:
[PATCH v3 1/2] Move machine_kexec_mask_interrupts() to kexec_core.c,
               removing duplicate architecture-specific implementations.
[PATCH v3 2/2] Refine machine_kexec_mask_interrupts() to avoid re-masking
               already-masked interrupts, resolving specific warnings
               triggered in GPIO IRQ flows.

Eliav Farber (2):
  kexec: Consolidate machine_kexec_mask_interrupts() implementation
  kexec: Prevent redundant IRQ masking by checking state before shutdown

 arch/arm/kernel/machine_kexec.c   | 23 -----------------------
 arch/arm64/kernel/machine_kexec.c | 31 -------------------------------
 arch/powerpc/include/asm/kexec.h  |  1 -
 arch/powerpc/kexec/core.c         | 22 ----------------------
 arch/riscv/kernel/machine_kexec.c | 23 -----------------------
 include/linux/irq.h               |  3 +++
 include/linux/kexec.h             |  2 ++
 kernel/irq/internals.h            |  1 -
 kernel/kexec_core.c               | 28 ++++++++++++++++++++++++++++
 9 files changed, 33 insertions(+), 101 deletions(-)

-- 
2.40.1



From farbere at amazon.com  Thu Nov 28 12:10:27 2024
From: farbere at amazon.com (Eliav Farber)
Date: Thu, 28 Nov 2024 20:10:27 +0000
Subject: [PATCH v3 2/2] kexec: Prevent redundant IRQ masking by checking state before shutdown
In-Reply-To: <20241128201027.10396-1-farbere@amazon.com>
References: <20241128201027.10396-1-farbere@amazon.com>
Message-ID: <20241128201027.10396-3-farbere@amazon.com>

During machine kexec, the function machine_kexec_mask_interrupts() is
responsible for disabling or masking all interrupts. While the irq_disable
hook ensures that an already-disabled IRQ is not disabled again, the
current implementation unconditionally invokes the irq_mask() function for
every interrupt descriptor, even when the interrupt is already masked.

A specific issue was observed in the crash kernel flow after unbinding a
device (prior to kexec) that used a GPIO as an IRQ source. The warning was
triggered by the gpiochip_disable_irq() function, which attempted to clear
the FLAG_IRQ_IS_ENABLED flag when FLAG_USED_AS_IRQ was not set:

```
void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset)
{
	struct gpio_desc *desc = gpiochip_get_desc(gc, offset);

	if (!IS_ERR(desc) &&
	    !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags)))
		clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
}
```

This issue surfaced after commit a8173820f441 ("gpio: gpiolib: Allow GPIO
IRQs to lazy disable") introduced lazy disablement for GPIO IRQs. It
replaced disable/enable hooks with mask/unmask hooks. Unlike the disable
hook, the mask hook doesn't handle already-masked IRQs.

When a GPIO-IRQ driver is unbound, the IRQ is released, triggering
__irq_disable() and irq_state_set_masked(). A subsequent call to
machine_kexec_mask_interrupts() re-invokes chip->irq_mask(). This results
in a call chain, including gpiochip_irq_mask() and gpiochip_disable_irq().
Since FLAG_USED_AS_IRQ was cleared earlier, a warning occurs.

This patch addresses the issue by:
 - Replacing the calls to irq_mask() and irq_disable() hooks with a
   simplified call to irq_shutdown().
 - Checking if the interrupt is started (irqd_is_started) before calling
   the shutdown.

As part of this change, the irq_shutdown() declaration was moved from
kernel/irq/internals.h to include/linux/irq.h to make it accessible
outside the kernel/irq/ directory, as the former can only be included
within that directory.

Signed-off-by: Eliav Farber <farbere at amazon.com>
---
V2 -> V3:
 - Check if IRQ is started using irqd_is_started().
 - Use irq_shutdown() instead of irq_disable().

 include/linux/irq.h    | 3 +++
 kernel/irq/internals.h | 1 -
 kernel/kexec_core.c    | 8 ++------
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index fa711f80957b..48a3df728c47 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -694,6 +694,9 @@ extern int irq_chip_request_resources_parent(struct irq_data *data);
 extern void irq_chip_release_resources_parent(struct irq_data *data);
 #endif
 
+/* Shut down the interrupt */
+extern void irq_shutdown(struct irq_desc *desc);
+
 /* Handling of unhandled and spurious interrupts: */
 extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
 
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index fe0272cd84a5..1f9287b1ccb7 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -88,7 +88,6 @@ extern int irq_activate(struct irq_desc *desc);
 extern int irq_activate_and_startup(struct irq_desc *desc, bool resend);
 extern int irq_startup(struct irq_desc *desc, bool resend, bool force);
 
-extern void irq_shutdown(struct irq_desc *desc);
 extern void irq_shutdown_and_deactivate(struct irq_desc *desc);
 extern void irq_enable(struct irq_desc *desc);
 extern void irq_disable(struct irq_desc *desc);
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 6e1e420946e0..928b4387502b 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -1083,7 +1083,7 @@ void machine_kexec_mask_interrupts(void)
 		int check_eoi = 1;
 
 		chip = irq_desc_get_chip(desc);
-		if (!chip)
+		if (!chip || !irqd_is_started(&desc->irq_data))
 			continue;
 
 		if (IS_ENABLED(CONFIG_ARM64)) {
@@ -1097,10 +1097,6 @@ void machine_kexec_mask_interrupts(void)
 		if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
 			chip->irq_eoi(&desc->irq_data);
 
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
+		irq_shutdown(desc);
 	}
 }
-- 
2.40.1



From guoren at kernel.org  Thu Nov 28 16:55:08 2024
From: guoren at kernel.org (Guo Ren)
Date: Fri, 29 Nov 2024 08:55:08 +0800
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241128-goggles-laundry-d94c23ab39a4@spud>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com> <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck> <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr> <20241128-goggles-laundry-d94c23ab39a4@spud>
Message-ID: <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>

On Fri, Nov 29, 2024 at 12:19?AM Conor Dooley <conor at kernel.org> wrote:
>
> On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> > On 28/11/2024 15:14, Conor Dooley wrote:
> > > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > > In order to produce a generic kernel, a user can select
> > > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > >
> > > > > > Note that we can't use alternatives here because the discovery of
> > > > > > extensions is done too late and we need to start with the qspinlock
> > > > > > implementation because the ticket spinlock implementation would pollute
> > > > > > the spinlock value, so let's use static keys.
> > > > > >
> > > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > >
> > > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > > console. My .config has:
> > > > >
> > > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > > I pointed out some of the fragility during review:
> > > >
> > > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > >
> > > > so I'm kinda surprised it got merged tbh :/
> > > Maybe it could be reverted rather than having a broken boot with the
> > > default settings in -rc1.
> >
> >
> > No need to rush before we know what's happening,I guess you bisected to this
> > commit right?
>
> The symptom is a failure to boot, without any console output, of course
> I bisected it before blaming something specific. But I don't think it is
> "rushing" as having -rc1 broken with an option's default is a massive pain
> in the arse when it comes to testing.
>
> > I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> > kernel, anything?
>
> I don't have the former cos it died immediately on boot. config is
> attached. It reproduces in QEMU so you don't need any hardware.
If QEMU could reproduce, could you provide a dmesg by the below method?

Qemu cmd append: -s -S
ref: https://qemu-project.gitlab.io/qemu/system/gdb.html

Connect gdb and in console:
1. file vmlinux
2. source ./Documentation/admin-guide/kdump/gdbmacros.txt
3. dmesg

Then, we could get the kernel's early boot logs from memory.

>
> > Does the polarfire soc provide Ziccrse?
>
> I don't think that is relevant because ziccrse is not listed in the dts,
> so the kernel should not be assuming that LR/SC has a forward progress
> guarantee. It's not even getting as far as riscv_spinlock_init() given
> several things before that should be emitting logs, so it doesn't even
> get to make any decisions about Ziccrse.



-- 
Best Regards
 Guo Ren


From lkp at intel.com  Thu Nov 28 18:46:18 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 29 Nov 2024 10:46:18 +0800
Subject: [PATCH v3 1/2] kexec: Consolidate
 machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241128201027.10396-2-farbere@amazon.com>
References: <20241128201027.10396-2-farbere@amazon.com>
Message-ID: <202411291047.R9P698b2-lkp@intel.com>

Hi Eliav,

kernel test robot noticed the following build errors:

[auto build test ERROR on powerpc/next]
[also build test ERROR on powerpc/fixes tip/irq/core arm64/for-next/core linus/master v6.12 next-20241128]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Eliav-Farber/kexec-Consolidate-machine_kexec_mask_interrupts-implementation/20241129-041259
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
patch link:    https://lore.kernel.org/r/20241128201027.10396-2-farbere%40amazon.com
patch subject: [PATCH v3 1/2] kexec: Consolidate machine_kexec_mask_interrupts() implementation
config: x86_64-rhel-9.4 (https://download.01.org/0day-ci/archive/20241129/202411291047.R9P698b2-lkp at intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241129/202411291047.R9P698b2-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411291047.R9P698b2-lkp at intel.com/

All error/warnings (new ones prefixed by >>):

   kernel/kexec_core.c: In function 'machine_kexec_mask_interrupts':
>> kernel/kexec_core.c:1085:24: error: implicit declaration of function 'irq_desc_get_chip' [-Werror=implicit-function-declaration]
    1085 |                 chip = irq_desc_get_chip(desc);
         |                        ^~~~~~~~~~~~~~~~~
>> kernel/kexec_core.c:1085:22: warning: assignment to 'struct irq_chip *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    1085 |                 chip = irq_desc_get_chip(desc);
         |                      ^
>> kernel/kexec_core.c:1097:38: error: invalid use of undefined type 'struct irq_chip'
    1097 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                      ^~
>> kernel/kexec_core.c:1097:51: error: implicit declaration of function 'irqd_irq_inprogress' [-Werror=implicit-function-declaration]
    1097 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                                   ^~~~~~~~~~~~~~~~~~~
>> kernel/kexec_core.c:1097:76: error: invalid use of undefined type 'struct irq_desc'
    1097 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                                                            ^~
   kernel/kexec_core.c:1098:29: error: invalid use of undefined type 'struct irq_chip'
    1098 |                         chip->irq_eoi(&desc->irq_data);
         |                             ^~
   kernel/kexec_core.c:1098:44: error: invalid use of undefined type 'struct irq_desc'
    1098 |                         chip->irq_eoi(&desc->irq_data);
         |                                            ^~
   kernel/kexec_core.c:1100:25: error: invalid use of undefined type 'struct irq_chip'
    1100 |                 if (chip->irq_mask)
         |                         ^~
   kernel/kexec_core.c:1101:29: error: invalid use of undefined type 'struct irq_chip'
    1101 |                         chip->irq_mask(&desc->irq_data);
         |                             ^~
   kernel/kexec_core.c:1101:45: error: invalid use of undefined type 'struct irq_desc'
    1101 |                         chip->irq_mask(&desc->irq_data);
         |                                             ^~
   kernel/kexec_core.c:1103:25: error: invalid use of undefined type 'struct irq_chip'
    1103 |                 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
         |                         ^~
   kernel/kexec_core.c:1103:43: error: implicit declaration of function 'irqd_irq_disabled'; did you mean 'arch_irqs_disabled'? [-Werror=implicit-function-declaration]
    1103 |                 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
         |                                           ^~~~~~~~~~~~~~~~~
         |                                           arch_irqs_disabled
   kernel/kexec_core.c:1103:66: error: invalid use of undefined type 'struct irq_desc'
    1103 |                 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
         |                                                                  ^~
   kernel/kexec_core.c:1104:29: error: invalid use of undefined type 'struct irq_chip'
    1104 |                         chip->irq_disable(&desc->irq_data);
         |                             ^~
   kernel/kexec_core.c:1104:48: error: invalid use of undefined type 'struct irq_desc'
    1104 |                         chip->irq_disable(&desc->irq_data);
         |                                                ^~
   cc1: some warnings being treated as errors


vim +/irq_desc_get_chip +1085 kernel/kexec_core.c

  1075	
  1076	void machine_kexec_mask_interrupts(void)
  1077	{
  1078		unsigned int i;
  1079		struct irq_desc *desc;
  1080	
  1081		for_each_irq_desc(i, desc) {
  1082			struct irq_chip *chip;
  1083			int check_eoi = 1;
  1084	
> 1085			chip = irq_desc_get_chip(desc);
  1086			if (!chip)
  1087				continue;
  1088	
  1089			if (IS_ENABLED(CONFIG_ARM64)) {
  1090				/*
  1091				 * First try to remove the active state. If this fails, try to EOI the
  1092				 * interrupt.
  1093				 */
  1094				check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
  1095			}
  1096	
> 1097			if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From guoren at kernel.org  Thu Nov 28 18:58:52 2024
From: guoren at kernel.org (Guo Ren)
Date: Fri, 29 Nov 2024 10:58:52 +0800
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com> <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck> <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr> <20241128-goggles-laundry-d94c23ab39a4@spud>
 <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>
Message-ID: <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com>

On Fri, Nov 29, 2024 at 8:55?AM Guo Ren <guoren at kernel.org> wrote:
>
> On Fri, Nov 29, 2024 at 12:19?AM Conor Dooley <conor at kernel.org> wrote:
> >
> > On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> > > On 28/11/2024 15:14, Conor Dooley wrote:
> > > > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > > > In order to produce a generic kernel, a user can select
> > > > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > > >
> > > > > > > Note that we can't use alternatives here because the discovery of
> > > > > > > extensions is done too late and we need to start with the qspinlock
> > > > > > > implementation because the ticket spinlock implementation would pollute
> > > > > > > the spinlock value, so let's use static keys.
> > > > > > >
> > > > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > > >
> > > > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > > > console. My .config has:
> > > > > >
> > > > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > > > I pointed out some of the fragility during review:
> > > > >
> > > > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > > >
> > > > > so I'm kinda surprised it got merged tbh :/
> > > > Maybe it could be reverted rather than having a broken boot with the
> > > > default settings in -rc1.
> > >
> > >
> > > No need to rush before we know what's happening,I guess you bisected to this
> > > commit right?
> >
> > The symptom is a failure to boot, without any console output, of course
> > I bisected it before blaming something specific. But I don't think it is
> > "rushing" as having -rc1 broken with an option's default is a massive pain
> > in the arse when it comes to testing.
> >
> > > I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> > > kernel, anything?
> >
> > I don't have the former cos it died immediately on boot. config is
> > attached. It reproduces in QEMU so you don't need any hardware.
> If QEMU could reproduce, could you provide a dmesg by the below method?
>
> Qemu cmd append: -s -S
> ref: https://qemu-project.gitlab.io/qemu/system/gdb.html
>
> Connect gdb and in console:
> 1. file vmlinux
> 2. source ./Documentation/admin-guide/kdump/gdbmacros.txt
> 3. dmesg
>
> Then, we could get the kernel's early boot logs from memory.
I've reproduced it on qemu, thx for the config.

Reading symbols from ../build-rv64lp64/vmlinux...
(gdb) tar rem:1234
Remote debugging using :1234
ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
/home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
49              atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
(gdb) bt
#0  ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
/home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
#1  arch_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
/home/guoren/source/kernel/linux/arch/riscv/include/asm/spinlock.h:28
#2  do_raw_spin_lock (lock=lock at entry=0xffffffff81b9a5b8 <text_mutex>)
at /home/guoren/source/kernel/linux/kernel/locking/spinlock_debug.c:116
#3  0xffffffff80b2ea0e in __raw_spin_lock_irqsave
(lock=0xffffffff81b9a5b8 <text_mutex>) at
/home/guoren/source/kernel/linux/include/linux/spinlock_api_smp.h:111
#4  _raw_spin_lock_irqsave (lock=lock at entry=0xffffffff81b9a5b8
<text_mutex>) at
/home/guoren/source/kernel/linux/kernel/locking/spinlock.c:162
#5  0xffffffff80b27c54 in rt_mutex_slowtrylock
(lock=0xffffffff81b9a5b8 <text_mutex>) at
/home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1393
#6  0xffffffff80b295ea in rt_mutex_try_acquire
(lock=0xffffffff81b9a5b8 <text_mutex>) at
/home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:319
#7  __rt_mutex_lock (state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
/home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1805
#8  __mutex_lock_common (ip=18446744071562135170, nest_lock=0x0,
subclass=0, state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
/home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:518
#9  mutex_lock_nested (lock=0xffffffff81b9a5b8 <text_mutex>,
subclass=subclass at entry=0) at
/home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:529
#10 0xffffffff80010682 in arch_jump_label_transform_queue
(entry=entry at entry=0xffffffff8158da28, type=<optimized out>) at
/home/guoren/source/kernel/linux/arch/riscv/kernel/jump_label.c:39
#11 0xffffffff801d86b2 in __jump_label_update
(key=key at entry=0xffffffff81a1abb0 <qspinlock_key>,
entry=0xffffffff8158da28, stop=stop at entry=0xffffffff815a5e68
<__tracepoint_ptr_initcall_finish>, init=init at entry=true)
    at /home/guoren/source/kernel/linux/kernel/jump_label.c:513
#12 0xffffffff801d890c in jump_label_update
(key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
/home/guoren/source/kernel/linux/kernel/jump_label.c:920
#13 0xffffffff801d8be8 in static_key_disable_cpuslocked
(key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
/home/guoren/source/kernel/linux/kernel/jump_label.c:240
#14 0xffffffff801d8c04 in static_key_disable
(key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
/home/guoren/source/kernel/linux/kernel/jump_label.c:248
#15 0xffffffff80c04a1a in riscv_spinlock_init () at
/home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:271
#16 setup_arch (cmdline_p=cmdline_p at entry=0xffffffff81a03e88) at
/home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:336
#17 0xffffffff80c007a2 in start_kernel () at
/home/guoren/source/kernel/linux/init/main.c:922
#18 0xffffffff80001164 in _start_kernel ()
Backtrace stopped: frame did not save the PC
(gdb) p /x lock
$1 = 0xffffffff81b9a5b8
(gdb) p /x *lock
$2 = {{val = {counter = 0x20000}, {locked = 0x0, pending = 0x0},
{locked_pending = 0x0, tail = 0x2}}}

>
> >
> > > Does the polarfire soc provide Ziccrse?
> >
> > I don't think that is relevant because ziccrse is not listed in the dts,
> > so the kernel should not be assuming that LR/SC has a forward progress
> > guarantee. It's not even getting as far as riscv_spinlock_init() given
> > several things before that should be emitting logs, so it doesn't even
> > get to make any decisions about Ziccrse.
>
>
>
> --
> Best Regards
>  Guo Ren



-- 
Best Regards
 Guo Ren


From lkp at intel.com  Thu Nov 28 20:30:58 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 29 Nov 2024 12:30:58 +0800
Subject: [PATCH v3 1/2] kexec: Consolidate
 machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241128201027.10396-2-farbere@amazon.com>
References: <20241128201027.10396-2-farbere@amazon.com>
Message-ID: <202411291225.18ZMjZcQ-lkp@intel.com>

Hi Eliav,

kernel test robot noticed the following build errors:

[auto build test ERROR on powerpc/next]
[also build test ERROR on powerpc/fixes tip/irq/core arm64/for-next/core linus/master v6.12 next-20241128]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Eliav-Farber/kexec-Consolidate-machine_kexec_mask_interrupts-implementation/20241129-041259
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
patch link:    https://lore.kernel.org/r/20241128201027.10396-2-farbere%40amazon.com
patch subject: [PATCH v3 1/2] kexec: Consolidate machine_kexec_mask_interrupts() implementation
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20241129/202411291225.18ZMjZcQ-lkp at intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241129/202411291225.18ZMjZcQ-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411291225.18ZMjZcQ-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from kernel/kexec_core.c:9:
   In file included from include/linux/btf.h:8:
   In file included from include/linux/bpfptr.h:6:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> kernel/kexec_core.c:1085:10: error: call to undeclared function 'irq_desc_get_chip'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1085 |                 chip = irq_desc_get_chip(desc);
         |                        ^
>> kernel/kexec_core.c:1085:8: error: incompatible integer to pointer conversion assigning to 'struct irq_chip *' from 'int' [-Wint-conversion]
    1085 |                 chip = irq_desc_get_chip(desc);
         |                      ^ ~~~~~~~~~~~~~~~~~~~~~~~
>> kernel/kexec_core.c:1097:24: error: incomplete definition of type 'struct irq_chip'
    1097 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                  ~~~~^
   kernel/kexec_core.c:1082:10: note: forward declaration of 'struct irq_chip'
    1082 |                 struct irq_chip *chip;
         |                        ^
>> kernel/kexec_core.c:1097:37: error: call to undeclared function 'irqd_irq_inprogress'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1097 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                                   ^
>> kernel/kexec_core.c:1097:62: error: incomplete definition of type 'struct irq_desc'
    1097 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                                                        ~~~~^
   include/linux/irqnr.h:10:15: note: forward declaration of 'struct irq_desc'
      10 | extern struct irq_desc *irq_to_desc(unsigned int irq);
         |               ^
   kernel/kexec_core.c:1098:8: error: incomplete definition of type 'struct irq_chip'
    1098 |                         chip->irq_eoi(&desc->irq_data);
         |                         ~~~~^
   kernel/kexec_core.c:1082:10: note: forward declaration of 'struct irq_chip'
    1082 |                 struct irq_chip *chip;
         |                        ^
   kernel/kexec_core.c:1098:23: error: incomplete definition of type 'struct irq_desc'
    1098 |                         chip->irq_eoi(&desc->irq_data);
         |                                        ~~~~^
   include/linux/irqnr.h:10:15: note: forward declaration of 'struct irq_desc'
      10 | extern struct irq_desc *irq_to_desc(unsigned int irq);
         |               ^
   kernel/kexec_core.c:1100:11: error: incomplete definition of type 'struct irq_chip'
    1100 |                 if (chip->irq_mask)
         |                     ~~~~^
   kernel/kexec_core.c:1082:10: note: forward declaration of 'struct irq_chip'
    1082 |                 struct irq_chip *chip;
         |                        ^
   kernel/kexec_core.c:1101:8: error: incomplete definition of type 'struct irq_chip'
    1101 |                         chip->irq_mask(&desc->irq_data);
         |                         ~~~~^
   kernel/kexec_core.c:1082:10: note: forward declaration of 'struct irq_chip'
    1082 |                 struct irq_chip *chip;
         |                        ^
   kernel/kexec_core.c:1101:24: error: incomplete definition of type 'struct irq_desc'
    1101 |                         chip->irq_mask(&desc->irq_data);
         |                                         ~~~~^
   include/linux/irqnr.h:10:15: note: forward declaration of 'struct irq_desc'
      10 | extern struct irq_desc *irq_to_desc(unsigned int irq);
         |               ^
   kernel/kexec_core.c:1103:11: error: incomplete definition of type 'struct irq_chip'
    1103 |                 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
         |                     ~~~~^
   kernel/kexec_core.c:1082:10: note: forward declaration of 'struct irq_chip'
    1082 |                 struct irq_chip *chip;
         |                        ^
   kernel/kexec_core.c:1103:29: error: call to undeclared function 'irqd_irq_disabled'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1103 |                 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
         |                                           ^
   kernel/kexec_core.c:1103:29: note: did you mean 'arch_irqs_disabled'?
   arch/x86/include/asm/irqflags.h:145:28: note: 'arch_irqs_disabled' declared here
     145 | static __always_inline int arch_irqs_disabled(void)
         |                            ^
   kernel/kexec_core.c:1103:52: error: incomplete definition of type 'struct irq_desc'
    1103 |                 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
         |                                                              ~~~~^
   include/linux/irqnr.h:10:15: note: forward declaration of 'struct irq_desc'
      10 | extern struct irq_desc *irq_to_desc(unsigned int irq);
         |               ^
   kernel/kexec_core.c:1104:8: error: incomplete definition of type 'struct irq_chip'
    1104 |                         chip->irq_disable(&desc->irq_data);
         |                         ~~~~^
   kernel/kexec_core.c:1082:10: note: forward declaration of 'struct irq_chip'
    1082 |                 struct irq_chip *chip;
         |                        ^
   kernel/kexec_core.c:1104:27: error: incomplete definition of type 'struct irq_desc'
    1104 |                         chip->irq_disable(&desc->irq_data);
         |                                            ~~~~^
   include/linux/irqnr.h:10:15: note: forward declaration of 'struct irq_desc'
      10 | extern struct irq_desc *irq_to_desc(unsigned int irq);
         |               ^
   4 warnings and 15 errors generated.


vim +/irq_desc_get_chip +1085 kernel/kexec_core.c

  1075	
  1076	void machine_kexec_mask_interrupts(void)
  1077	{
  1078		unsigned int i;
  1079		struct irq_desc *desc;
  1080	
  1081		for_each_irq_desc(i, desc) {
  1082			struct irq_chip *chip;
  1083			int check_eoi = 1;
  1084	
> 1085			chip = irq_desc_get_chip(desc);
  1086			if (!chip)
  1087				continue;
  1088	
  1089			if (IS_ENABLED(CONFIG_ARM64)) {
  1090				/*
  1091				 * First try to remove the active state. If this fails, try to EOI the
  1092				 * interrupt.
  1093				 */
  1094				check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
  1095			}
  1096	
> 1097			if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From lkp at intel.com  Thu Nov 28 20:42:13 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 29 Nov 2024 12:42:13 +0800
Subject: [PATCH v3 2/2] kexec: Prevent redundant IRQ masking by checking
 state before shutdown
In-Reply-To: <20241128201027.10396-3-farbere@amazon.com>
References: <20241128201027.10396-3-farbere@amazon.com>
Message-ID: <202411291251.RwA1dKZL-lkp@intel.com>

Hi Eliav,

kernel test robot noticed the following build errors:

[auto build test ERROR on powerpc/next]
[also build test ERROR on powerpc/fixes tip/irq/core arm64/for-next/core linus/master v6.12 next-20241128]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Eliav-Farber/kexec-Consolidate-machine_kexec_mask_interrupts-implementation/20241129-041259
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
patch link:    https://lore.kernel.org/r/20241128201027.10396-3-farbere%40amazon.com
patch subject: [PATCH v3 2/2] kexec: Prevent redundant IRQ masking by checking state before shutdown
config: x86_64-rhel-9.4 (https://download.01.org/0day-ci/archive/20241129/202411291251.RwA1dKZL-lkp at intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241129/202411291251.RwA1dKZL-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411291251.RwA1dKZL-lkp at intel.com/

All errors (new ones prefixed by >>):

   kernel/kexec_core.c: In function 'machine_kexec_mask_interrupts':
   kernel/kexec_core.c:1085:24: error: implicit declaration of function 'irq_desc_get_chip' [-Werror=implicit-function-declaration]
    1085 |                 chip = irq_desc_get_chip(desc);
         |                        ^~~~~~~~~~~~~~~~~
   kernel/kexec_core.c:1085:22: warning: assignment to 'struct irq_chip *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    1085 |                 chip = irq_desc_get_chip(desc);
         |                      ^
>> kernel/kexec_core.c:1086:31: error: implicit declaration of function 'irqd_is_started' [-Werror=implicit-function-declaration]
    1086 |                 if (!chip || !irqd_is_started(&desc->irq_data))
         |                               ^~~~~~~~~~~~~~~
   kernel/kexec_core.c:1086:52: error: invalid use of undefined type 'struct irq_desc'
    1086 |                 if (!chip || !irqd_is_started(&desc->irq_data))
         |                                                    ^~
   kernel/kexec_core.c:1097:38: error: invalid use of undefined type 'struct irq_chip'
    1097 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                      ^~
   kernel/kexec_core.c:1097:51: error: implicit declaration of function 'irqd_irq_inprogress' [-Werror=implicit-function-declaration]
    1097 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                                   ^~~~~~~~~~~~~~~~~~~
   kernel/kexec_core.c:1097:76: error: invalid use of undefined type 'struct irq_desc'
    1097 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                                                            ^~
   kernel/kexec_core.c:1098:29: error: invalid use of undefined type 'struct irq_chip'
    1098 |                         chip->irq_eoi(&desc->irq_data);
         |                             ^~
   kernel/kexec_core.c:1098:44: error: invalid use of undefined type 'struct irq_desc'
    1098 |                         chip->irq_eoi(&desc->irq_data);
         |                                            ^~
>> kernel/kexec_core.c:1100:17: error: implicit declaration of function 'irq_shutdown'; did you mean 'timer_shutdown'? [-Werror=implicit-function-declaration]
    1100 |                 irq_shutdown(desc);
         |                 ^~~~~~~~~~~~
         |                 timer_shutdown
   cc1: some warnings being treated as errors


vim +/irqd_is_started +1086 kernel/kexec_core.c

  1075	
  1076	void machine_kexec_mask_interrupts(void)
  1077	{
  1078		unsigned int i;
  1079		struct irq_desc *desc;
  1080	
  1081		for_each_irq_desc(i, desc) {
  1082			struct irq_chip *chip;
  1083			int check_eoi = 1;
  1084	
  1085			chip = irq_desc_get_chip(desc);
> 1086			if (!chip || !irqd_is_started(&desc->irq_data))
  1087				continue;
  1088	
  1089			if (IS_ENABLED(CONFIG_ARM64)) {
  1090				/*
  1091				 * First try to remove the active state. If this fails, try to EOI the
  1092				 * interrupt.
  1093				 */
  1094				check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
  1095			}
  1096	
  1097			if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
  1098				chip->irq_eoi(&desc->irq_data);
  1099	
> 1100			irq_shutdown(desc);

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From guoren at kernel.org  Thu Nov 28 22:28:08 2024
From: guoren at kernel.org (Guo Ren)
Date: Fri, 29 Nov 2024 14:28:08 +0800
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com> <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck> <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr> <20241128-goggles-laundry-d94c23ab39a4@spud>
 <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com> <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com>
Message-ID: <CAJF2gTSX82rGp-9xZHvg1Y3SpO516YCcqSBLKFgWEQ5G-iWR4A@mail.gmail.com>

Hi Conor & Alexandre,

On Fri, Nov 29, 2024 at 10:58?AM Guo Ren <guoren at kernel.org> wrote:
>
> On Fri, Nov 29, 2024 at 8:55?AM Guo Ren <guoren at kernel.org> wrote:
> >
> > On Fri, Nov 29, 2024 at 12:19?AM Conor Dooley <conor at kernel.org> wrote:
> > >
> > > On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> > > > On 28/11/2024 15:14, Conor Dooley wrote:
> > > > > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > > > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > > > > In order to produce a generic kernel, a user can select
> > > > > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > > > >
> > > > > > > > Note that we can't use alternatives here because the discovery of
> > > > > > > > extensions is done too late and we need to start with the qspinlock
> > > > > > > > implementation because the ticket spinlock implementation would pollute
> > > > > > > > the spinlock value, so let's use static keys.
> > > > > > > >
> > > > > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > > > >
> > > > > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > > > > console. My .config has:
> > > > > > >
> > > > > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > > > > I pointed out some of the fragility during review:
> > > > > >
> > > > > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > > > >
> > > > > > so I'm kinda surprised it got merged tbh :/
> > > > > Maybe it could be reverted rather than having a broken boot with the
> > > > > default settings in -rc1.
> > > >
> > > >
> > > > No need to rush before we know what's happening,I guess you bisected to this
> > > > commit right?
> > >
> > > The symptom is a failure to boot, without any console output, of course
> > > I bisected it before blaming something specific. But I don't think it is
> > > "rushing" as having -rc1 broken with an option's default is a massive pain
> > > in the arse when it comes to testing.
> > >
> > > > I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> > > > kernel, anything?
> > >
> > > I don't have the former cos it died immediately on boot. config is
> > > attached. It reproduces in QEMU so you don't need any hardware.
> > If QEMU could reproduce, could you provide a dmesg by the below method?
> >
> > Qemu cmd append: -s -S
> > ref: https://qemu-project.gitlab.io/qemu/system/gdb.html
> >
> > Connect gdb and in console:
> > 1. file vmlinux
> > 2. source ./Documentation/admin-guide/kdump/gdbmacros.txt
> > 3. dmesg
> >
> > Then, we could get the kernel's early boot logs from memory.
> I've reproduced it on qemu, thx for the config.
>
> Reading symbols from ../build-rv64lp64/vmlinux...
> (gdb) tar rem:1234
> Remote debugging using :1234
> ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> 49              atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
> (gdb) bt
> #0  ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> #1  arch_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> /home/guoren/source/kernel/linux/arch/riscv/include/asm/spinlock.h:28
> #2  do_raw_spin_lock (lock=lock at entry=0xffffffff81b9a5b8 <text_mutex>)
> at /home/guoren/source/kernel/linux/kernel/locking/spinlock_debug.c:116
> #3  0xffffffff80b2ea0e in __raw_spin_lock_irqsave
> (lock=0xffffffff81b9a5b8 <text_mutex>) at
> /home/guoren/source/kernel/linux/include/linux/spinlock_api_smp.h:111
> #4  _raw_spin_lock_irqsave (lock=lock at entry=0xffffffff81b9a5b8
> <text_mutex>) at
> /home/guoren/source/kernel/linux/kernel/locking/spinlock.c:162
> #5  0xffffffff80b27c54 in rt_mutex_slowtrylock
> (lock=0xffffffff81b9a5b8 <text_mutex>) at
> /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1393
> #6  0xffffffff80b295ea in rt_mutex_try_acquire
> (lock=0xffffffff81b9a5b8 <text_mutex>) at
> /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:319
> #7  __rt_mutex_lock (state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1805
> #8  __mutex_lock_common (ip=18446744071562135170, nest_lock=0x0,
> subclass=0, state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:518
> #9  mutex_lock_nested (lock=0xffffffff81b9a5b8 <text_mutex>,
> subclass=subclass at entry=0) at
> /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:529
> #10 0xffffffff80010682 in arch_jump_label_transform_queue
> (entry=entry at entry=0xffffffff8158da28, type=<optimized out>) at
> /home/guoren/source/kernel/linux/arch/riscv/kernel/jump_label.c:39
> #11 0xffffffff801d86b2 in __jump_label_update
> (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>,
> entry=0xffffffff8158da28, stop=stop at entry=0xffffffff815a5e68
> <__tracepoint_ptr_initcall_finish>, init=init at entry=true)
>     at /home/guoren/source/kernel/linux/kernel/jump_label.c:513
> #12 0xffffffff801d890c in jump_label_update
> (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> /home/guoren/source/kernel/linux/kernel/jump_label.c:920
> #13 0xffffffff801d8be8 in static_key_disable_cpuslocked
> (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> /home/guoren/source/kernel/linux/kernel/jump_label.c:240
> #14 0xffffffff801d8c04 in static_key_disable
> (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> /home/guoren/source/kernel/linux/kernel/jump_label.c:248
> #15 0xffffffff80c04a1a in riscv_spinlock_init () at
> /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:271
> #16 setup_arch (cmdline_p=cmdline_p at entry=0xffffffff81a03e88) at
> /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:336
> #17 0xffffffff80c007a2 in start_kernel () at
> /home/guoren/source/kernel/linux/init/main.c:922
> #18 0xffffffff80001164 in _start_kernel ()
> Backtrace stopped: frame did not save the PC
> (gdb) p /x lock
> $1 = 0xffffffff81b9a5b8
> (gdb) p /x *lock
> $2 = {{val = {counter = 0x20000}, {locked = 0x0, pending = 0x0},
> {locked_pending = 0x0, tail = 0x2}}}

I have for you here a fast fixup for reference. (PS: I'm digging into
the root cause mentioned by Will Deacon.)

diff --git a/arch/riscv/include/asm/text-patching.h
b/arch/riscv/include/asm/text-patching.h
index 7228e266b9a1..0439609f1cff 100644
--- a/arch/riscv/include/asm/text-patching.h
+++ b/arch/riscv/include/asm/text-patching.h
@@ -12,5 +12,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len);
 int patch_text(void *addr, u32 *insns, size_t len);

 extern int riscv_patch_in_stop_machine;
+extern int riscv_patch_in_spinlock_init;

 #endif /* _ASM_RISCV_PATCH_H */
diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
index 6eee6f736f68..d9a5a5c1933d 100644
--- a/arch/riscv/kernel/jump_label.c
+++ b/arch/riscv/kernel/jump_label.c
@@ -36,9 +36,11 @@ bool arch_jump_label_transform_queue(struct
jump_entry *entry,
                insn = RISCV_INSN_NOP;
        }

-       mutex_lock(&text_mutex);
+       if (!riscv_patch_in_spinlock_init)
+               mutex_lock(&text_mutex);
        patch_insn_write(addr, &insn, sizeof(insn));
-       mutex_unlock(&text_mutex);
+       if (!riscv_patch_in_spinlock_init)
+               mutex_unlock(&text_mutex);

        return true;
 }
diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
index db13c9ddf9e3..ab009cf855c2 100644
--- a/arch/riscv/kernel/patch.c
+++ b/arch/riscv/kernel/patch.c
@@ -24,6 +24,7 @@ struct patch_insn {
 };

 int riscv_patch_in_stop_machine = false;
+int riscv_patch_in_spinlock_init = false;

 #ifdef CONFIG_MMU

@@ -131,7 +132,7 @@ static int __patch_insn_write(void *addr, const
void *insn, size_t len)
         * safe but triggers a lockdep failure, so just elide it for that
         * specific case.
         */
-       if (!riscv_patch_in_stop_machine)
+       if (!riscv_patch_in_stop_machine && !riscv_patch_in_spinlock_init)
                lockdep_assert_held(&text_mutex);

        preempt_disable();
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 016b48fcd6f2..87ddf1702be4 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -268,7 +268,9 @@ static void __init riscv_spinlock_init(void)
        }
 #if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
        else {
+               riscv_patch_in_spinlock_init = 1;
                static_branch_disable(&qspinlock_key);
+               riscv_patch_in_spinlock_init = 0;
                pr_info("Ticket spinlock: enabled\n");
                return;
        }



-- 
Best Regards
 Guo Ren


From dan.carpenter at linaro.org  Thu Nov 28 22:56:30 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Fri, 29 Nov 2024 09:56:30 +0300
Subject: [bug report] mailbox: Introduce support for T-head TH1520 Mailbox
 driver
Message-ID: <a99e72be-8490-4960-ad26-cbfef6af238f@stanley.mountain>

Hello Michal Wilczynski,

Commit 5d4d263e1c6b ("mailbox: Introduce support for T-head TH1520
Mailbox driver") from Nov 4, 2024 (linux-next), leads to the
following Smatch static checker warning:

drivers/mailbox/mailbox-th1520.c:535 th1520_mbox_suspend_noirq() error: buffer overflow 'ctx->intr_mask' 3 <= 3
drivers/mailbox/mailbox-th1520.c:548 th1520_mbox_resume_noirq() error: buffer overflow 'ctx->intr_mask' 3 <= 3

drivers/mailbox/mailbox-th1520.c
    525 static int __maybe_unused th1520_mbox_suspend_noirq(struct device *dev)
    526 {
    527         struct th1520_mbox_priv *priv = dev_get_drvdata(dev);
    528         struct th1520_mbox_context *ctx = priv->ctx;
    529         u32 i;
    530         /*
    531          * ONLY interrupt mask bit should be stored and restores.
    532          * INFO data all assumed to be lost.
    533          */
    534         for (i = 0; i < TH_1520_MBOX_CHANS; i++) {
--> 535                 ctx->intr_mask[i] =

The ctx->intr_mask[] array has TH_1520_MBOX_CHANS - 1 elements so this is
memory corruption.

    536                         ioread32(priv->local_icu[i] + TH_1520_MBOX_MASK);
    537         }
    538         return 0;
    539 }

regards,
dan carpenter


From marcin.grad at completesolutions.pl  Fri Nov 29 00:50:45 2024
From: marcin.grad at completesolutions.pl (Marcin Gard)
Date: Fri, 29 Nov 2024 08:50:45 GMT
Subject: =?UTF-8?Q?Prosz=C4=99_o_kontakt?=
Message-ID: <20241129084500-0.1.f2.1v0r7.0.ghf1g7ia4b@completesolutions.pl>

Dzie? dobry,

Czy jest mo?liwo?? nawi?zania wsp??pracy z Pa?stwem?

Z ch?ci? porozmawiam z osob? zajmuj?c? si? dzia?aniami zwi?zanymi ze sprzeda??.

Pomagamy skutecznie pozyskiwa? nowych klient?w.

Zapraszam do kontaktu.


Pozdrawiam serdecznie
Marcin Gard


From unicorn_wang at outlook.com  Fri Nov 29 01:51:39 2024
From: unicorn_wang at outlook.com (Chen Wang)
Date: Fri, 29 Nov 2024 17:51:39 +0800
Subject: [PATCH 2/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver
In-Reply-To: <20241112212055.GA1859446@bhelgaas>
References: <20241112212055.GA1859446@bhelgaas>
Message-ID: <MAXPR01MB3984C307B163E615811A25AAFE2A2@MAXPR01MB3984.INDPRD01.PROD.OUTLOOK.COM>

Hello~

On 2024/11/13 5:20, Bjorn Helgaas wrote:
> On Mon, Nov 11, 2024 at 01:59:56PM +0800, Chen Wang wrote:
>> From: Chen Wang <unicorn_wang at outlook.com>
>>
>> Add support for PCIe controller in SG2042 SoC. The controller
>> uses the Cadence PCIe core programmed by pcie-cadence*.c. The
>> PCIe controller will work in host mode only.
>> +++ b/drivers/pci/controller/cadence/Kconfig
>> @@ -67,4 +67,15 @@ config PCI_J721E_EP
>>   	  Say Y here if you want to support the TI J721E PCIe platform
>>   	  controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe
>>   	  core.
>> +
>> +config PCIE_SG2042
>> +	bool "Sophgo SG2042 PCIe controller (host mode)"
>> +	depends on ARCH_SOPHGO || COMPILE_TEST
>> +	depends on OF
>> +	select PCIE_CADENCE_HOST
>> +	help
>> +	  Say Y here if you want to support the Sophgo SG2042 PCIe platform
>> +	  controller in host mode. Sophgo SG2042 PCIe controller uses Cadence
>> +	  PCIe core.
> Reorder to keep these menu items in alphabetical order by vendor.

Sorry, I don't understand your question. I think the menu items in this 
Kconfig file are already sorted alphabetically.

>> +++ b/drivers/pci/controller/cadence/pcie-sg2042.c
>> + * SG2042 PCIe controller supports two ways to report MSI:
>> + * - Method A, the PICe controller implements an MSI interrupt controller inside,
>> + *   and connect to PLIC upward through one interrupt line. Provides
>> + *   memory-mapped msi address, and by programming the upper 32 bits of the
>> + *   address to zero, it can be compatible with old pcie devices that only
>> + *   support 32-bit msi address.
>> + * - Method B, the PICe controller connects to PLIC upward through an
>> + *   independent MSI controller "sophgo,sg2042-msi" on the SOC. The MSI
>> + *   controller provides multiple(up to 32) interrupt sources to PLIC.
>> + *   Compared with the first method, the advantage is that the interrupt source
>> + *   is expanded, but because for SG2042, the msi address provided by the MSI
>> + *   controller is fixed and only supports 64-bit address(> 2^32), it is not
>> + *   compatible with old pcie devices that only support 32-bit msi address.
>> + * Method A & B can be configured in DTS with property "sophgo,internal-msi",
>> + * default is Method B.
> s/PICe/PCIe/ (multiple)
> s/msi/MSI/ (multiple)
> s/pcie/PCIe/ (multiple)
>
> Wrap comment (and code below) to fit in 80 columns.  Add blank lines
> between paragraphs.
Got, will change.
>
>> +#define SG2042_CDNS_PLAT_CPU_TO_BUS_ADDR	0xCFFFFFFFFF
> Remove (see below).
Yes, after some testing, seems this address fixup is not need, will 
remove it.
>> +static void sg2042_pcie_msi_irq_compose_msi_msg(struct irq_data *d,
>> +						struct msi_msg *msg)
>> +{
>> +	struct sg2042_pcie *pcie = irq_data_get_irq_chip_data(d);
>> +	struct device *dev = pcie->cdns_pcie->dev;
>> +
>> +	msg->address_lo = lower_32_bits(pcie->msi_phys) + BYTE_NUM_PER_MSI_VEC * d->hwirq;
>> +	msg->address_hi = upper_32_bits(pcie->msi_phys);
>> +	msg->data = 1;
>> +
>> +	pcie->num_applied_vecs = d->hwirq;
> This looks questionable.  How do you know d->hwirq increases every
> time this is called?
Thanks, it's a bug, I will fix it.
>> +	dev_info(dev, "compose msi msg hwirq[%d] address_hi[%#x] address_lo[%#x]\n",
>> +		 (int)d->hwirq, msg->address_hi, msg->address_lo);
> This seems too verbose to be a dev_info().  Maybe a dev_dbg() or
> remove it altogether.
Will change it to dev_dbg.
>> + * We use the usual two domain structure, the top one being a generic PCI/MSI
>> + * domain, the bottom one being SG2042-specific and handling the actual HW
>> + * interrupt allocation.
>> + * At the same time, for internal MSI controller(Method A), bottom chip uses a
>> + * chained handler to handle the controller's MSI IRQ edge triggered.
> Add blank line between paragraphs.
OK.
>
>> +static int sg2042_pcie_setup_msi_external(struct sg2042_pcie *pcie)
>> +{
>> +	struct device *dev = pcie->cdns_pcie->dev;
>> +	struct device_node *np = dev->of_node;
>> +	struct irq_domain *parent_domain;
>> +	struct device_node *parent_np;
>> +
>> +	if (!of_find_property(np, "interrupt-parent", NULL)) {
>> +		dev_err(dev, "Can't find interrupt-parent!\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	parent_np = of_irq_find_parent(np);
>> +	if (!parent_np) {
>> +		dev_err(dev, "Can't find node of interrupt-parent!\n");
> Can you use some kind of %pOF format to include more information here?
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/core-api/printk-formats.rst?id=v6.11#n463

Thanks, will double check this.

[......]

>> +	if (pcie->link_id == 1) {
>> +		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_LOW,
>> +			     lower_32_bits(pcie->msi_phys));
>> +		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_HIGH,
>> +			     upper_32_bits(pcie->msi_phys));
>> +
>> +		regmap_read(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, &value);
>> +		value = (value & REG_LINK1_MSI_ADDR_SIZE_MASK) | MAX_MSI_IRQS;
>> +		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, value);
>> +	} else {
>> +		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_LOW,
>> +			     lower_32_bits(pcie->msi_phys));
>> +		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_HIGH,
>> +			     upper_32_bits(pcie->msi_phys));
>> +
>> +		regmap_read(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, &value);
>> +		value = (value & REG_LINK0_MSI_ADDR_SIZE_MASK) | (MAX_MSI_IRQS << 16);
>> +		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, value);
>> +	}
> Lot of pcie->link_id checking going on here.  Consider saving these
> offsets in the struct sg2042_pcie so you don't need to test
> everywhere.

Actually, there are not many places in the code to check link_id. If to 
add storage information in struct sg2042_pcie, at least four? u32 are 
needed. And this logic will only be called one time in the probe. So I 
think it is better to keep the current method. What do you think?

[......]




From alexghiti at rivosinc.com  Fri Nov 29 02:31:44 2024
From: alexghiti at rivosinc.com (Alexandre Ghiti)
Date: Fri, 29 Nov 2024 11:31:44 +0100
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <CAJF2gTSX82rGp-9xZHvg1Y3SpO516YCcqSBLKFgWEQ5G-iWR4A@mail.gmail.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com> <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck> <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr> <20241128-goggles-laundry-d94c23ab39a4@spud>
 <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>
 <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com> <CAJF2gTSX82rGp-9xZHvg1Y3SpO516YCcqSBLKFgWEQ5G-iWR4A@mail.gmail.com>
Message-ID: <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com>

Hi everyone,

On Fri, Nov 29, 2024 at 7:28?AM Guo Ren <guoren at kernel.org> wrote:
>
> Hi Conor & Alexandre,
>
> On Fri, Nov 29, 2024 at 10:58?AM Guo Ren <guoren at kernel.org> wrote:
> >
> > On Fri, Nov 29, 2024 at 8:55?AM Guo Ren <guoren at kernel.org> wrote:
> > >
> > > On Fri, Nov 29, 2024 at 12:19?AM Conor Dooley <conor at kernel.org> wrote:
> > > >
> > > > On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> > > > > On 28/11/2024 15:14, Conor Dooley wrote:
> > > > > > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > > > > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > > > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > > > > > In order to produce a generic kernel, a user can select
> > > > > > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > > > > >
> > > > > > > > > Note that we can't use alternatives here because the discovery of
> > > > > > > > > extensions is done too late and we need to start with the qspinlock
> > > > > > > > > implementation because the ticket spinlock implementation would pollute
> > > > > > > > > the spinlock value, so let's use static keys.
> > > > > > > > >
> > > > > > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > > > > >
> > > > > > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > > > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > > > > > console. My .config has:
> > > > > > > >
> > > > > > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > > > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > > > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > > > > > I pointed out some of the fragility during review:
> > > > > > >
> > > > > > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > > > > >
> > > > > > > so I'm kinda surprised it got merged tbh :/
> > > > > > Maybe it could be reverted rather than having a broken boot with the
> > > > > > default settings in -rc1.
> > > > >
> > > > >
> > > > > No need to rush before we know what's happening,I guess you bisected to this
> > > > > commit right?
> > > >
> > > > The symptom is a failure to boot, without any console output, of course
> > > > I bisected it before blaming something specific. But I don't think it is
> > > > "rushing" as having -rc1 broken with an option's default is a massive pain
> > > > in the arse when it comes to testing.
> > > >
> > > > > I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> > > > > kernel, anything?
> > > >
> > > > I don't have the former cos it died immediately on boot. config is
> > > > attached. It reproduces in QEMU so you don't need any hardware.
> > > If QEMU could reproduce, could you provide a dmesg by the below method?
> > >
> > > Qemu cmd append: -s -S
> > > ref: https://qemu-project.gitlab.io/qemu/system/gdb.html
> > >
> > > Connect gdb and in console:
> > > 1. file vmlinux
> > > 2. source ./Documentation/admin-guide/kdump/gdbmacros.txt
> > > 3. dmesg
> > >
> > > Then, we could get the kernel's early boot logs from memory.
> > I've reproduced it on qemu, thx for the config.
> >
> > Reading symbols from ../build-rv64lp64/vmlinux...
> > (gdb) tar rem:1234
> > Remote debugging using :1234
> > ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > 49              atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
> > (gdb) bt
> > #0  ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > #1  arch_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > /home/guoren/source/kernel/linux/arch/riscv/include/asm/spinlock.h:28
> > #2  do_raw_spin_lock (lock=lock at entry=0xffffffff81b9a5b8 <text_mutex>)
> > at /home/guoren/source/kernel/linux/kernel/locking/spinlock_debug.c:116
> > #3  0xffffffff80b2ea0e in __raw_spin_lock_irqsave
> > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > /home/guoren/source/kernel/linux/include/linux/spinlock_api_smp.h:111
> > #4  _raw_spin_lock_irqsave (lock=lock at entry=0xffffffff81b9a5b8
> > <text_mutex>) at
> > /home/guoren/source/kernel/linux/kernel/locking/spinlock.c:162
> > #5  0xffffffff80b27c54 in rt_mutex_slowtrylock
> > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1393
> > #6  0xffffffff80b295ea in rt_mutex_try_acquire
> > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:319
> > #7  __rt_mutex_lock (state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1805
> > #8  __mutex_lock_common (ip=18446744071562135170, nest_lock=0x0,
> > subclass=0, state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:518
> > #9  mutex_lock_nested (lock=0xffffffff81b9a5b8 <text_mutex>,
> > subclass=subclass at entry=0) at
> > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:529
> > #10 0xffffffff80010682 in arch_jump_label_transform_queue
> > (entry=entry at entry=0xffffffff8158da28, type=<optimized out>) at
> > /home/guoren/source/kernel/linux/arch/riscv/kernel/jump_label.c:39
> > #11 0xffffffff801d86b2 in __jump_label_update
> > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>,
> > entry=0xffffffff8158da28, stop=stop at entry=0xffffffff815a5e68
> > <__tracepoint_ptr_initcall_finish>, init=init at entry=true)
> >     at /home/guoren/source/kernel/linux/kernel/jump_label.c:513
> > #12 0xffffffff801d890c in jump_label_update
> > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > /home/guoren/source/kernel/linux/kernel/jump_label.c:920
> > #13 0xffffffff801d8be8 in static_key_disable_cpuslocked
> > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > /home/guoren/source/kernel/linux/kernel/jump_label.c:240
> > #14 0xffffffff801d8c04 in static_key_disable
> > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > /home/guoren/source/kernel/linux/kernel/jump_label.c:248
> > #15 0xffffffff80c04a1a in riscv_spinlock_init () at
> > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:271
> > #16 setup_arch (cmdline_p=cmdline_p at entry=0xffffffff81a03e88) at
> > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:336
> > #17 0xffffffff80c007a2 in start_kernel () at
> > /home/guoren/source/kernel/linux/init/main.c:922
> > #18 0xffffffff80001164 in _start_kernel ()
> > Backtrace stopped: frame did not save the PC
> > (gdb) p /x lock
> > $1 = 0xffffffff81b9a5b8
> > (gdb) p /x *lock
> > $2 = {{val = {counter = 0x20000}, {locked = 0x0, pending = 0x0},
> > {locked_pending = 0x0, tail = 0x2}}}
>
> I have for you here a fast fixup for reference. (PS: I'm digging into
> the root cause mentioned by Will Deacon.)
>
> diff --git a/arch/riscv/include/asm/text-patching.h
> b/arch/riscv/include/asm/text-patching.h
> index 7228e266b9a1..0439609f1cff 100644
> --- a/arch/riscv/include/asm/text-patching.h
> +++ b/arch/riscv/include/asm/text-patching.h
> @@ -12,5 +12,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len);
>  int patch_text(void *addr, u32 *insns, size_t len);
>
>  extern int riscv_patch_in_stop_machine;
> +extern int riscv_patch_in_spinlock_init;
>
>  #endif /* _ASM_RISCV_PATCH_H */
> diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
> index 6eee6f736f68..d9a5a5c1933d 100644
> --- a/arch/riscv/kernel/jump_label.c
> +++ b/arch/riscv/kernel/jump_label.c
> @@ -36,9 +36,11 @@ bool arch_jump_label_transform_queue(struct
> jump_entry *entry,
>                 insn = RISCV_INSN_NOP;
>         }
>
> -       mutex_lock(&text_mutex);
> +       if (!riscv_patch_in_spinlock_init)
> +               mutex_lock(&text_mutex);
>         patch_insn_write(addr, &insn, sizeof(insn));
> -       mutex_unlock(&text_mutex);
> +       if (!riscv_patch_in_spinlock_init)
> +               mutex_unlock(&text_mutex);
>
>         return true;
>  }
> diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
> index db13c9ddf9e3..ab009cf855c2 100644
> --- a/arch/riscv/kernel/patch.c
> +++ b/arch/riscv/kernel/patch.c
> @@ -24,6 +24,7 @@ struct patch_insn {
>  };
>
>  int riscv_patch_in_stop_machine = false;
> +int riscv_patch_in_spinlock_init = false;
>
>  #ifdef CONFIG_MMU
>
> @@ -131,7 +132,7 @@ static int __patch_insn_write(void *addr, const
> void *insn, size_t len)
>          * safe but triggers a lockdep failure, so just elide it for that
>          * specific case.
>          */
> -       if (!riscv_patch_in_stop_machine)
> +       if (!riscv_patch_in_stop_machine && !riscv_patch_in_spinlock_init)
>                 lockdep_assert_held(&text_mutex);
>
>         preempt_disable();
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index 016b48fcd6f2..87ddf1702be4 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -268,7 +268,9 @@ static void __init riscv_spinlock_init(void)
>         }
>  #if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
>         else {
> +               riscv_patch_in_spinlock_init = 1;
>                 static_branch_disable(&qspinlock_key);
> +               riscv_patch_in_spinlock_init = 0;
>                 pr_info("Ticket spinlock: enabled\n");
>                 return;
>         }
>
>
>
> --
> Best Regards
>  Guo Ren

Thanks Guo for looking into this.

Your solution is not very pretty but I don't have anything better :/
Unless introducing a static_branch_XXX_nolock() API? I gave it a try
and it fixes the issue, but not sure this will be accepted.

The thing is the usage of static branches is temporary, we'll use
alternatives when I finish working on getting the extensions very
early from the ACPI tables (I have a poc that works, just needs some
cleaning).

So let's say that I make this early extension parsing my priority for
6.14, can we live with Guo's hack in this release? Or should we revert
this commit?

Thanks,

Alex


From conor at kernel.org  Fri Nov 29 03:18:24 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 29 Nov 2024 11:18:24 +0000
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com>
References: <20241103145153.105097-14-alexghiti@rivosinc.com>
 <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck>
 <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr>
 <20241128-goggles-laundry-d94c23ab39a4@spud>
 <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>
 <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com>
 <CAJF2gTSX82rGp-9xZHvg1Y3SpO516YCcqSBLKFgWEQ5G-iWR4A@mail.gmail.com>
 <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com>
Message-ID: <20241129-encrust-thumping-b6c6a3399b98@spud>

On Fri, Nov 29, 2024 at 11:31:44AM +0100, Alexandre Ghiti wrote:
> Hi everyone,
> 
> On Fri, Nov 29, 2024 at 7:28?AM Guo Ren <guoren at kernel.org> wrote:
> >
> > Hi Conor & Alexandre,
> >
> > On Fri, Nov 29, 2024 at 10:58?AM Guo Ren <guoren at kernel.org> wrote:
> > >
> > > On Fri, Nov 29, 2024 at 8:55?AM Guo Ren <guoren at kernel.org> wrote:
> > > >
> > > > On Fri, Nov 29, 2024 at 12:19?AM Conor Dooley <conor at kernel.org> wrote:
> > > > >
> > > > > On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> > > > > > On 28/11/2024 15:14, Conor Dooley wrote:
> > > > > > > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > > > > > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > > > > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > > > > > > In order to produce a generic kernel, a user can select
> > > > > > > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > > > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > > > > > >
> > > > > > > > > > Note that we can't use alternatives here because the discovery of
> > > > > > > > > > extensions is done too late and we need to start with the qspinlock
> > > > > > > > > > implementation because the ticket spinlock implementation would pollute
> > > > > > > > > > the spinlock value, so let's use static keys.
> > > > > > > > > >
> > > > > > > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > > > > > >
> > > > > > > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > > > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > > > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > > > > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > > > > > > console. My .config has:
> > > > > > > > >
> > > > > > > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > > > > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > > > > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > > > > > > I pointed out some of the fragility during review:
> > > > > > > >
> > > > > > > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > > > > > >
> > > > > > > > so I'm kinda surprised it got merged tbh :/
> > > > > > > Maybe it could be reverted rather than having a broken boot with the
> > > > > > > default settings in -rc1.
> > > > > >
> > > > > >
> > > > > > No need to rush before we know what's happening,I guess you bisected to this
> > > > > > commit right?
> > > > >
> > > > > The symptom is a failure to boot, without any console output, of course
> > > > > I bisected it before blaming something specific. But I don't think it is
> > > > > "rushing" as having -rc1 broken with an option's default is a massive pain
> > > > > in the arse when it comes to testing.
> > > > >
> > > > > > I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> > > > > > kernel, anything?
> > > > >
> > > > > I don't have the former cos it died immediately on boot. config is
> > > > > attached. It reproduces in QEMU so you don't need any hardware.
> > > > If QEMU could reproduce, could you provide a dmesg by the below method?
> > > >
> > > > Qemu cmd append: -s -S
> > > > ref: https://qemu-project.gitlab.io/qemu/system/gdb.html
> > > >
> > > > Connect gdb and in console:
> > > > 1. file vmlinux
> > > > 2. source ./Documentation/admin-guide/kdump/gdbmacros.txt
> > > > 3. dmesg
> > > >
> > > > Then, we could get the kernel's early boot logs from memory.
> > > I've reproduced it on qemu, thx for the config.
> > >
> > > Reading symbols from ../build-rv64lp64/vmlinux...
> > > (gdb) tar rem:1234
> > > Remote debugging using :1234
> > > ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > 49              atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
> > > (gdb) bt
> > > #0  ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > #1  arch_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/arch/riscv/include/asm/spinlock.h:28
> > > #2  do_raw_spin_lock (lock=lock at entry=0xffffffff81b9a5b8 <text_mutex>)
> > > at /home/guoren/source/kernel/linux/kernel/locking/spinlock_debug.c:116
> > > #3  0xffffffff80b2ea0e in __raw_spin_lock_irqsave
> > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/include/linux/spinlock_api_smp.h:111
> > > #4  _raw_spin_lock_irqsave (lock=lock at entry=0xffffffff81b9a5b8
> > > <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/spinlock.c:162
> > > #5  0xffffffff80b27c54 in rt_mutex_slowtrylock
> > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1393
> > > #6  0xffffffff80b295ea in rt_mutex_try_acquire
> > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:319
> > > #7  __rt_mutex_lock (state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1805
> > > #8  __mutex_lock_common (ip=18446744071562135170, nest_lock=0x0,
> > > subclass=0, state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:518
> > > #9  mutex_lock_nested (lock=0xffffffff81b9a5b8 <text_mutex>,
> > > subclass=subclass at entry=0) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:529
> > > #10 0xffffffff80010682 in arch_jump_label_transform_queue
> > > (entry=entry at entry=0xffffffff8158da28, type=<optimized out>) at
> > > /home/guoren/source/kernel/linux/arch/riscv/kernel/jump_label.c:39
> > > #11 0xffffffff801d86b2 in __jump_label_update
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>,
> > > entry=0xffffffff8158da28, stop=stop at entry=0xffffffff815a5e68
> > > <__tracepoint_ptr_initcall_finish>, init=init at entry=true)
> > >     at /home/guoren/source/kernel/linux/kernel/jump_label.c:513
> > > #12 0xffffffff801d890c in jump_label_update
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > /home/guoren/source/kernel/linux/kernel/jump_label.c:920
> > > #13 0xffffffff801d8be8 in static_key_disable_cpuslocked
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > /home/guoren/source/kernel/linux/kernel/jump_label.c:240
> > > #14 0xffffffff801d8c04 in static_key_disable
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > /home/guoren/source/kernel/linux/kernel/jump_label.c:248
> > > #15 0xffffffff80c04a1a in riscv_spinlock_init () at
> > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:271
> > > #16 setup_arch (cmdline_p=cmdline_p at entry=0xffffffff81a03e88) at
> > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:336
> > > #17 0xffffffff80c007a2 in start_kernel () at
> > > /home/guoren/source/kernel/linux/init/main.c:922
> > > #18 0xffffffff80001164 in _start_kernel ()
> > > Backtrace stopped: frame did not save the PC
> > > (gdb) p /x lock
> > > $1 = 0xffffffff81b9a5b8
> > > (gdb) p /x *lock
> > > $2 = {{val = {counter = 0x20000}, {locked = 0x0, pending = 0x0},
> > > {locked_pending = 0x0, tail = 0x2}}}
> >
> > I have for you here a fast fixup for reference. (PS: I'm digging into
> > the root cause mentioned by Will Deacon.)
> >
> > diff --git a/arch/riscv/include/asm/text-patching.h
> > b/arch/riscv/include/asm/text-patching.h
> > index 7228e266b9a1..0439609f1cff 100644
> > --- a/arch/riscv/include/asm/text-patching.h
> > +++ b/arch/riscv/include/asm/text-patching.h
> > @@ -12,5 +12,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len);
> >  int patch_text(void *addr, u32 *insns, size_t len);
> >
> >  extern int riscv_patch_in_stop_machine;
> > +extern int riscv_patch_in_spinlock_init;
> >
> >  #endif /* _ASM_RISCV_PATCH_H */
> > diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
> > index 6eee6f736f68..d9a5a5c1933d 100644
> > --- a/arch/riscv/kernel/jump_label.c
> > +++ b/arch/riscv/kernel/jump_label.c
> > @@ -36,9 +36,11 @@ bool arch_jump_label_transform_queue(struct
> > jump_entry *entry,
> >                 insn = RISCV_INSN_NOP;
> >         }
> >
> > -       mutex_lock(&text_mutex);
> > +       if (!riscv_patch_in_spinlock_init)
> > +               mutex_lock(&text_mutex);
> >         patch_insn_write(addr, &insn, sizeof(insn));
> > -       mutex_unlock(&text_mutex);
> > +       if (!riscv_patch_in_spinlock_init)
> > +               mutex_unlock(&text_mutex);
> >
> >         return true;
> >  }
> > diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
> > index db13c9ddf9e3..ab009cf855c2 100644
> > --- a/arch/riscv/kernel/patch.c
> > +++ b/arch/riscv/kernel/patch.c
> > @@ -24,6 +24,7 @@ struct patch_insn {
> >  };
> >
> >  int riscv_patch_in_stop_machine = false;
> > +int riscv_patch_in_spinlock_init = false;
> >
> >  #ifdef CONFIG_MMU
> >
> > @@ -131,7 +132,7 @@ static int __patch_insn_write(void *addr, const
> > void *insn, size_t len)
> >          * safe but triggers a lockdep failure, so just elide it for that
> >          * specific case.
> >          */
> > -       if (!riscv_patch_in_stop_machine)
> > +       if (!riscv_patch_in_stop_machine && !riscv_patch_in_spinlock_init)
> >                 lockdep_assert_held(&text_mutex);
> >
> >         preempt_disable();
> > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > index 016b48fcd6f2..87ddf1702be4 100644
> > --- a/arch/riscv/kernel/setup.c
> > +++ b/arch/riscv/kernel/setup.c
> > @@ -268,7 +268,9 @@ static void __init riscv_spinlock_init(void)
> >         }
> >  #if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
> >         else {
> > +               riscv_patch_in_spinlock_init = 1;
> >                 static_branch_disable(&qspinlock_key);
> > +               riscv_patch_in_spinlock_init = 0;
> >                 pr_info("Ticket spinlock: enabled\n");
> >                 return;
> >         }
> >
> >
> >
> > --
> > Best Regards
> >  Guo Ren
> 
> Thanks Guo for looking into this.
> 
> Your solution is not very pretty but I don't have anything better :/
> Unless introducing a static_branch_XXX_nolock() API? I gave it a try
> and it fixes the issue, but not sure this will be accepted.
> 
> The thing is the usage of static branches is temporary, we'll use
> alternatives when I finish working on getting the extensions very
> early from the ACPI tables (I have a poc that works, just needs some
> cleaning).
> 
> So let's say that I make this early extension parsing my priority for
> 6.14, can we live with Guo's hack in this release? Or should we revert
> this commit?

I tried this diff, and it doesn't actually fix the problem - either in
QEMU or in hardware. I'll do some more poking.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241129/47effa45/attachment.sig>

From farbere at amazon.com  Fri Nov 29 03:31:17 2024
From: farbere at amazon.com (Eliav Farber)
Date: Fri, 29 Nov 2024 11:31:17 +0000
Subject: [PATCH v4 0/2] Improve interrupt handling during machine kexec
Message-ID: <20241129113119.26669-1-farbere@amazon.com>

This patch series focuses on improving the machine_kexec_mask_interrupts()
function by consolidating its implementation and optimizing its behavior to
avoid redundant interrupt masking.

Patch Summary:
[PATCH v4 1/2] Move machine_kexec_mask_interrupts() to kexec_core.c,
               removing duplicate architecture-specific implementations.
[PATCH v4 2/2] Refine machine_kexec_mask_interrupts() to avoid re-masking
               already-masked interrupts, resolving specific warnings
               triggered in GPIO IRQ flows.

Changes between v3 and v4:
 - Add missing <linux/irqdesc.h> and <linux/irq.h> includes.

Eliav Farber (2):
  kexec: Consolidate machine_kexec_mask_interrupts() implementation
  kexec: Prevent redundant IRQ masking by checking state before shutdown

 arch/arm/kernel/machine_kexec.c   | 23 -----------------------
 arch/arm64/kernel/machine_kexec.c | 31 -------------------------------
 arch/powerpc/include/asm/kexec.h  |  1 -
 arch/powerpc/kexec/core.c         | 22 ----------------------
 arch/riscv/kernel/machine_kexec.c | 23 -----------------------
 include/linux/irq.h               |  3 +++
 include/linux/kexec.h             |  2 ++
 kernel/irq/internals.h            |  1 -
 kernel/kexec_core.c               | 30 ++++++++++++++++++++++++++++++
 9 files changed, 35 insertions(+), 101 deletions(-)

-- 
2.40.1



From farbere at amazon.com  Fri Nov 29 03:31:19 2024
From: farbere at amazon.com (Eliav Farber)
Date: Fri, 29 Nov 2024 11:31:19 +0000
Subject: [PATCH v4 2/2] kexec: Prevent redundant IRQ masking by checking state before shutdown
In-Reply-To: <20241129113119.26669-1-farbere@amazon.com>
References: <20241129113119.26669-1-farbere@amazon.com>
Message-ID: <20241129113119.26669-3-farbere@amazon.com>

During machine kexec, the function machine_kexec_mask_interrupts() is
responsible for disabling or masking all interrupts. While the irq_disable
hook ensures that an already-disabled IRQ is not disabled again, the
current implementation unconditionally invokes the irq_mask() function for
every interrupt descriptor, even when the interrupt is already masked.

A specific issue was observed in the crash kernel flow after unbinding a
device (prior to kexec) that used a GPIO as an IRQ source. The warning was
triggered by the gpiochip_disable_irq() function, which attempted to clear
the FLAG_IRQ_IS_ENABLED flag when FLAG_USED_AS_IRQ was not set:

```
void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset)
{
	struct gpio_desc *desc = gpiochip_get_desc(gc, offset);

	if (!IS_ERR(desc) &&
	    !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags)))
		clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
}
```

This issue surfaced after commit a8173820f441 ("gpio: gpiolib: Allow GPIO
IRQs to lazy disable") introduced lazy disablement for GPIO IRQs. It
replaced disable/enable hooks with mask/unmask hooks. Unlike the disable
hook, the mask hook doesn't handle already-masked IRQs.

When a GPIO-IRQ driver is unbound, the IRQ is released, triggering
__irq_disable() and irq_state_set_masked(). A subsequent call to
machine_kexec_mask_interrupts() re-invokes chip->irq_mask(). This results
in a call chain, including gpiochip_irq_mask() and gpiochip_disable_irq().
Since FLAG_USED_AS_IRQ was cleared earlier, a warning occurs.

This patch addresses the issue by:
 - Replacing the calls to irq_mask() and irq_disable() hooks with a
   simplified call to irq_shutdown().
 - Checking if the interrupt is started (irqd_is_started) before calling
   the shutdown.

As part of this change, the irq_shutdown() declaration was moved from
kernel/irq/internals.h to include/linux/irq.h to make it accessible
outside the kernel/irq/ directory, as the former can only be included
within that directory.

Signed-off-by: Eliav Farber <farbere at amazon.com>
---
V4 -> V3: Add missing <linux/irq.h> include.

 include/linux/irq.h    | 3 +++
 kernel/irq/internals.h | 1 -
 kernel/kexec_core.c    | 9 +++------
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index fa711f80957b..48a3df728c47 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -694,6 +694,9 @@ extern int irq_chip_request_resources_parent(struct irq_data *data);
 extern void irq_chip_release_resources_parent(struct irq_data *data);
 #endif
 
+/* Shut down the interrupt */
+extern void irq_shutdown(struct irq_desc *desc);
+
 /* Handling of unhandled and spurious interrupts: */
 extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
 
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index fe0272cd84a5..1f9287b1ccb7 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -88,7 +88,6 @@ extern int irq_activate(struct irq_desc *desc);
 extern int irq_activate_and_startup(struct irq_desc *desc, bool resend);
 extern int irq_startup(struct irq_desc *desc, bool resend, bool force);
 
-extern void irq_shutdown(struct irq_desc *desc);
 extern void irq_shutdown_and_deactivate(struct irq_desc *desc);
 extern void irq_enable(struct irq_desc *desc);
 extern void irq_disable(struct irq_desc *desc);
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 777191458544..09c8e9814cd2 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -41,6 +41,7 @@
 #include <linux/objtool.h>
 #include <linux/kmsg_dump.h>
 #include <linux/irqdesc.h>
+#include <linux/irq.h>
 
 #include <asm/page.h>
 #include <asm/sections.h>
@@ -1084,7 +1085,7 @@ void machine_kexec_mask_interrupts(void)
 		int check_eoi = 1;
 
 		chip = irq_desc_get_chip(desc);
-		if (!chip)
+		if (!chip || !irqd_is_started(&desc->irq_data))
 			continue;
 
 		if (IS_ENABLED(CONFIG_ARM64)) {
@@ -1098,10 +1099,6 @@ void machine_kexec_mask_interrupts(void)
 		if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
 			chip->irq_eoi(&desc->irq_data);
 
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
+		irq_shutdown(desc);
 	}
 }
-- 
2.40.1



From farbere at amazon.com  Fri Nov 29 03:31:18 2024
From: farbere at amazon.com (Eliav Farber)
Date: Fri, 29 Nov 2024 11:31:18 +0000
Subject: [PATCH v4 1/2] kexec: Consolidate machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241129113119.26669-1-farbere@amazon.com>
References: <20241129113119.26669-1-farbere@amazon.com>
Message-ID: <20241129113119.26669-2-farbere@amazon.com>

Move the machine_kexec_mask_interrupts function to a common location in
kernel/kexec_core.c, removing duplicate implementations from architecture
specific files (arch/arm, arch/arm64, arch/powerpc, and arch/riscv).

This consolidation reduces code duplication and improves maintainability.

The unified function includes an architecture-specific behavior for
CONFIG_ARM64 by conditionally clearing the active interrupt state before
handling other interrupt masking operations.

Signed-off-by: Eliav Farber <farbere at amazon.com>
---
V4 -> V3: Add missing <linux/irqdec.h> include.

 arch/arm/kernel/machine_kexec.c   | 23 ---------------------
 arch/arm64/kernel/machine_kexec.c | 31 -----------------------------
 arch/powerpc/include/asm/kexec.h  |  1 -
 arch/powerpc/kexec/core.c         | 22 ---------------------
 arch/riscv/kernel/machine_kexec.c | 23 ---------------------
 include/linux/kexec.h             |  2 ++
 kernel/kexec_core.c               | 33 +++++++++++++++++++++++++++++++
 7 files changed, 35 insertions(+), 100 deletions(-)

diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 80ceb5bd2680..dd430477e7c1 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -127,29 +127,6 @@ void crash_smp_send_stop(void)
 	cpus_stopped = 1;
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 void machine_crash_shutdown(struct pt_regs *regs)
 {
 	local_irq_disable();
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 82e2203d86a3..6f121a0164a4 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -207,37 +207,6 @@ void machine_kexec(struct kimage *kimage)
 	BUG(); /* Should never get here. */
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-		int ret;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		/*
-		 * First try to remove the active state. If this
-		 * fails, try to EOI the interrupt.
-		 */
-		ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
-
-		if (ret && irqd_irq_inprogress(&desc->irq_data) &&
-		    chip->irq_eoi)
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 /**
  * machine_crash_shutdown - shutdown non-crashing cpus and save registers
  */
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 270ee93a0f7d..601e569303e1 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -61,7 +61,6 @@ struct pt_regs;
 extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
 					  master to copy new code to 0 */
 extern void default_machine_kexec(struct kimage *image);
-extern void machine_kexec_mask_interrupts(void);
 
 void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer,
 			 unsigned long start_address) __noreturn;
diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
index b8333a49ea5d..58a930a47422 100644
--- a/arch/powerpc/kexec/core.c
+++ b/arch/powerpc/kexec/core.c
@@ -22,28 +22,6 @@
 #include <asm/setup.h>
 #include <asm/firmware.h>
 
-void machine_kexec_mask_interrupts(void) {
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 #ifdef CONFIG_CRASH_DUMP
 void machine_crash_shutdown(struct pt_regs *regs)
 {
diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
index 3c830a6f7ef4..2306ce3e5f22 100644
--- a/arch/riscv/kernel/machine_kexec.c
+++ b/arch/riscv/kernel/machine_kexec.c
@@ -114,29 +114,6 @@ void machine_shutdown(void)
 #endif
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 /*
  * machine_crash_shutdown - Prepare to kexec after a kernel crash
  *
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index f0e9f8eda7a3..9dac0524c0be 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -375,6 +375,8 @@ extern void machine_kexec(struct kimage *image);
 extern int machine_kexec_prepare(struct kimage *image);
 extern void machine_kexec_cleanup(struct kimage *image);
 extern int kernel_kexec(void);
+extern void machine_kexec_mask_interrupts(void);
+
 extern struct page *kimage_alloc_control_pages(struct kimage *image,
 						unsigned int order);
 
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index c0caa14880c3..777191458544 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -40,6 +40,7 @@
 #include <linux/hugetlb.h>
 #include <linux/objtool.h>
 #include <linux/kmsg_dump.h>
+#include <linux/irqdesc.h>
 
 #include <asm/page.h>
 #include <asm/sections.h>
@@ -1072,3 +1073,35 @@ int kernel_kexec(void)
 	kexec_unlock();
 	return error;
 }
+
+void machine_kexec_mask_interrupts(void)
+{
+	unsigned int i;
+	struct irq_desc *desc;
+
+	for_each_irq_desc(i, desc) {
+		struct irq_chip *chip;
+		int check_eoi = 1;
+
+		chip = irq_desc_get_chip(desc);
+		if (!chip)
+			continue;
+
+		if (IS_ENABLED(CONFIG_ARM64)) {
+			/*
+			 * First try to remove the active state. If this fails, try to EOI the
+			 * interrupt.
+			 */
+			check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
+		}
+
+		if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
+			chip->irq_eoi(&desc->irq_data);
+
+		if (chip->irq_mask)
+			chip->irq_mask(&desc->irq_data);
+
+		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
+			chip->irq_disable(&desc->irq_data);
+	}
+}
-- 
2.40.1



From conor at kernel.org  Fri Nov 29 03:43:44 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 29 Nov 2024 11:43:44 +0000
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241129-encrust-thumping-b6c6a3399b98@spud>
References: <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck>
 <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr>
 <20241128-goggles-laundry-d94c23ab39a4@spud>
 <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>
 <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com>
 <CAJF2gTSX82rGp-9xZHvg1Y3SpO516YCcqSBLKFgWEQ5G-iWR4A@mail.gmail.com>
 <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com>
 <20241129-encrust-thumping-b6c6a3399b98@spud>
Message-ID: <20241129-clay-trimester-91a0f281a95d@spud>

On Fri, Nov 29, 2024 at 11:18:24AM +0000, Conor Dooley wrote:
> On Fri, Nov 29, 2024 at 11:31:44AM +0100, Alexandre Ghiti wrote:
> > Hi everyone,
> > 
> > On Fri, Nov 29, 2024 at 7:28?AM Guo Ren <guoren at kernel.org> wrote:
> > >
> > > Hi Conor & Alexandre,
> > >
> > > On Fri, Nov 29, 2024 at 10:58?AM Guo Ren <guoren at kernel.org> wrote:
> > > >
> > > > On Fri, Nov 29, 2024 at 8:55?AM Guo Ren <guoren at kernel.org> wrote:
> > > > >
> > > > > On Fri, Nov 29, 2024 at 12:19?AM Conor Dooley <conor at kernel.org> wrote:
> > > > > >
> > > > > > On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> > > > > > > On 28/11/2024 15:14, Conor Dooley wrote:
> > > > > > > > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > > > > > > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > > > > > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > > > > > > > In order to produce a generic kernel, a user can select
> > > > > > > > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > > > > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > > > > > > >
> > > > > > > > > > > Note that we can't use alternatives here because the discovery of
> > > > > > > > > > > extensions is done too late and we need to start with the qspinlock
> > > > > > > > > > > implementation because the ticket spinlock implementation would pollute
> > > > > > > > > > > the spinlock value, so let's use static keys.
> > > > > > > > > > >
> > > > > > > > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > > > > > > >
> > > > > > > > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > > > > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > > > > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > > > > > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > > > > > > > console. My .config has:
> > > > > > > > > >
> > > > > > > > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > > > > > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > > > > > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > > > > > > > I pointed out some of the fragility during review:
> > > > > > > > >
> > > > > > > > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > > > > > > >
> > > > > > > > > so I'm kinda surprised it got merged tbh :/
> > > > > > > > Maybe it could be reverted rather than having a broken boot with the
> > > > > > > > default settings in -rc1.
> > > > > > >
> > > > > > >
> > > > > > > No need to rush before we know what's happening,I guess you bisected to this
> > > > > > > commit right?
> > > > > >
> > > > > > The symptom is a failure to boot, without any console output, of course
> > > > > > I bisected it before blaming something specific. But I don't think it is
> > > > > > "rushing" as having -rc1 broken with an option's default is a massive pain
> > > > > > in the arse when it comes to testing.
> > > > > >
> > > > > > > I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> > > > > > > kernel, anything?
> > > > > >
> > > > > > I don't have the former cos it died immediately on boot. config is
> > > > > > attached. It reproduces in QEMU so you don't need any hardware.
> > > > > If QEMU could reproduce, could you provide a dmesg by the below method?
> > > > >
> > > > > Qemu cmd append: -s -S
> > > > > ref: https://qemu-project.gitlab.io/qemu/system/gdb.html
> > > > >
> > > > > Connect gdb and in console:
> > > > > 1. file vmlinux
> > > > > 2. source ./Documentation/admin-guide/kdump/gdbmacros.txt
> > > > > 3. dmesg
> > > > >
> > > > > Then, we could get the kernel's early boot logs from memory.
> > > > I've reproduced it on qemu, thx for the config.
> > > >
> > > > Reading symbols from ../build-rv64lp64/vmlinux...
> > > > (gdb) tar rem:1234
> > > > Remote debugging using :1234
> > > > ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > > 49              atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
> > > > (gdb) bt
> > > > #0  ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > > #1  arch_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/arch/riscv/include/asm/spinlock.h:28
> > > > #2  do_raw_spin_lock (lock=lock at entry=0xffffffff81b9a5b8 <text_mutex>)
> > > > at /home/guoren/source/kernel/linux/kernel/locking/spinlock_debug.c:116
> > > > #3  0xffffffff80b2ea0e in __raw_spin_lock_irqsave
> > > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/include/linux/spinlock_api_smp.h:111
> > > > #4  _raw_spin_lock_irqsave (lock=lock at entry=0xffffffff81b9a5b8
> > > > <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/spinlock.c:162
> > > > #5  0xffffffff80b27c54 in rt_mutex_slowtrylock
> > > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1393
> > > > #6  0xffffffff80b295ea in rt_mutex_try_acquire
> > > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:319
> > > > #7  __rt_mutex_lock (state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1805
> > > > #8  __mutex_lock_common (ip=18446744071562135170, nest_lock=0x0,
> > > > subclass=0, state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:518
> > > > #9  mutex_lock_nested (lock=0xffffffff81b9a5b8 <text_mutex>,
> > > > subclass=subclass at entry=0) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:529
> > > > #10 0xffffffff80010682 in arch_jump_label_transform_queue
> > > > (entry=entry at entry=0xffffffff8158da28, type=<optimized out>) at
> > > > /home/guoren/source/kernel/linux/arch/riscv/kernel/jump_label.c:39
> > > > #11 0xffffffff801d86b2 in __jump_label_update
> > > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>,
> > > > entry=0xffffffff8158da28, stop=stop at entry=0xffffffff815a5e68
> > > > <__tracepoint_ptr_initcall_finish>, init=init at entry=true)
> > > >     at /home/guoren/source/kernel/linux/kernel/jump_label.c:513
> > > > #12 0xffffffff801d890c in jump_label_update
> > > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > > /home/guoren/source/kernel/linux/kernel/jump_label.c:920
> > > > #13 0xffffffff801d8be8 in static_key_disable_cpuslocked
> > > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > > /home/guoren/source/kernel/linux/kernel/jump_label.c:240
> > > > #14 0xffffffff801d8c04 in static_key_disable
> > > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > > /home/guoren/source/kernel/linux/kernel/jump_label.c:248
> > > > #15 0xffffffff80c04a1a in riscv_spinlock_init () at
> > > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:271
> > > > #16 setup_arch (cmdline_p=cmdline_p at entry=0xffffffff81a03e88) at
> > > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:336
> > > > #17 0xffffffff80c007a2 in start_kernel () at
> > > > /home/guoren/source/kernel/linux/init/main.c:922
> > > > #18 0xffffffff80001164 in _start_kernel ()
> > > > Backtrace stopped: frame did not save the PC
> > > > (gdb) p /x lock
> > > > $1 = 0xffffffff81b9a5b8
> > > > (gdb) p /x *lock
> > > > $2 = {{val = {counter = 0x20000}, {locked = 0x0, pending = 0x0},
> > > > {locked_pending = 0x0, tail = 0x2}}}
> > >
> > > I have for you here a fast fixup for reference. (PS: I'm digging into
> > > the root cause mentioned by Will Deacon.)
> > >
> > > diff --git a/arch/riscv/include/asm/text-patching.h
> > > b/arch/riscv/include/asm/text-patching.h
> > > index 7228e266b9a1..0439609f1cff 100644
> > > --- a/arch/riscv/include/asm/text-patching.h
> > > +++ b/arch/riscv/include/asm/text-patching.h
> > > @@ -12,5 +12,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len);
> > >  int patch_text(void *addr, u32 *insns, size_t len);
> > >
> > >  extern int riscv_patch_in_stop_machine;
> > > +extern int riscv_patch_in_spinlock_init;
> > >
> > >  #endif /* _ASM_RISCV_PATCH_H */
> > > diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
> > > index 6eee6f736f68..d9a5a5c1933d 100644
> > > --- a/arch/riscv/kernel/jump_label.c
> > > +++ b/arch/riscv/kernel/jump_label.c
> > > @@ -36,9 +36,11 @@ bool arch_jump_label_transform_queue(struct
> > > jump_entry *entry,
> > >                 insn = RISCV_INSN_NOP;
> > >         }
> > >
> > > -       mutex_lock(&text_mutex);
> > > +       if (!riscv_patch_in_spinlock_init)
> > > +               mutex_lock(&text_mutex);
> > >         patch_insn_write(addr, &insn, sizeof(insn));
> > > -       mutex_unlock(&text_mutex);
> > > +       if (!riscv_patch_in_spinlock_init)
> > > +               mutex_unlock(&text_mutex);
> > >
> > >         return true;
> > >  }
> > > diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
> > > index db13c9ddf9e3..ab009cf855c2 100644
> > > --- a/arch/riscv/kernel/patch.c
> > > +++ b/arch/riscv/kernel/patch.c
> > > @@ -24,6 +24,7 @@ struct patch_insn {
> > >  };
> > >
> > >  int riscv_patch_in_stop_machine = false;
> > > +int riscv_patch_in_spinlock_init = false;
> > >
> > >  #ifdef CONFIG_MMU
> > >
> > > @@ -131,7 +132,7 @@ static int __patch_insn_write(void *addr, const
> > > void *insn, size_t len)
> > >          * safe but triggers a lockdep failure, so just elide it for that
> > >          * specific case.
> > >          */
> > > -       if (!riscv_patch_in_stop_machine)
> > > +       if (!riscv_patch_in_stop_machine && !riscv_patch_in_spinlock_init)
> > >                 lockdep_assert_held(&text_mutex);
> > >
> > >         preempt_disable();
> > > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > > index 016b48fcd6f2..87ddf1702be4 100644
> > > --- a/arch/riscv/kernel/setup.c
> > > +++ b/arch/riscv/kernel/setup.c
> > > @@ -268,7 +268,9 @@ static void __init riscv_spinlock_init(void)
> > >         }
> > >  #if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
> > >         else {
> > > +               riscv_patch_in_spinlock_init = 1;
> > >                 static_branch_disable(&qspinlock_key);
> > > +               riscv_patch_in_spinlock_init = 0;
> > >                 pr_info("Ticket spinlock: enabled\n");
> > >                 return;
> > >         }
> > >
> > >
> > >
> > > --
> > > Best Regards
> > >  Guo Ren
> > 
> > Thanks Guo for looking into this.
> > 
> > Your solution is not very pretty but I don't have anything better :/
> > Unless introducing a static_branch_XXX_nolock() API? I gave it a try
> > and it fixes the issue, but not sure this will be accepted.
> > 
> > The thing is the usage of static branches is temporary, we'll use
> > alternatives when I finish working on getting the extensions very
> > early from the ACPI tables (I have a poc that works, just needs some
> > cleaning).
> > 
> > So let's say that I make this early extension parsing my priority for
> > 6.14, can we live with Guo's hack in this release? Or should we revert
> > this commit?
> 
> I tried this diff, and it doesn't actually fix the problem - either in
> QEMU or in hardware. I'll do some more poking.

Looks like it might have been my fault, typo while hand-applying the
diff pasted above cos it was corrupted :/ Rebuilding..

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241129/db6d51cf/attachment.sig>

From conor at kernel.org  Fri Nov 29 03:55:24 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 29 Nov 2024 11:55:24 +0000
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <20241129-clay-trimester-91a0f281a95d@spud>
References: <20241128134135.GA3460@willie-the-truck>
 <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr>
 <20241128-goggles-laundry-d94c23ab39a4@spud>
 <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>
 <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com>
 <CAJF2gTSX82rGp-9xZHvg1Y3SpO516YCcqSBLKFgWEQ5G-iWR4A@mail.gmail.com>
 <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com>
 <20241129-encrust-thumping-b6c6a3399b98@spud>
 <20241129-clay-trimester-91a0f281a95d@spud>
Message-ID: <20241129-proxy-mantra-f58352723906@spud>

On Fri, Nov 29, 2024 at 11:43:44AM +0000, Conor Dooley wrote:
> On Fri, Nov 29, 2024 at 11:18:24AM +0000, Conor Dooley wrote:
> > 
> > I tried this diff, and it doesn't actually fix the problem - either in
> > QEMU or in hardware. I'll do some more poking.
> 
> Looks like it might have been my fault, typo while hand-applying the
> diff pasted above cos it was corrupted :/ Rebuilding..


sans-typo, the diff does make it boot, my bad.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241129/62e6a658/attachment.sig>

From namcao at linutronix.de  Fri Nov 29 04:19:29 2024
From: namcao at linutronix.de (Nam Cao)
Date: Fri, 29 Nov 2024 19:19:29 +0700
Subject: [PATCH] riscv: kprobes: Fix incorrect address calculation
In-Reply-To: <7662be43-16e6-4695-9bc4-077e1dd3ba12@ghiti.fr>
References: <20241119111056.2554419-1-namcao@linutronix.de>
 <7662be43-16e6-4695-9bc4-077e1dd3ba12@ghiti.fr>
Message-ID: <20241129121929.tOHlWxwS@linutronix.de>

Hi Alex,

On Thu, Nov 28, 2024 at 02:02:40PM +0100, Alexandre Ghiti wrote:
> On 19/11/2024 12:10, Nam Cao wrote:
> > p->ainsn.api.insn is a pointer to u32, therefore arithmetic operations are
> > multiplied by four. This is clearly undesirable for this case.
> > 
> > Cast it to (void *) first before any calculation.
...
> This looks good to me, how did you find this issue?

I found it while working on RV monitors (Documentation/trace/rv) which
use kprobes. The monitors exploded on riscv.

Best regards,
Nam


From m.wilczynski at samsung.com  Fri Nov 29 04:37:01 2024
From: m.wilczynski at samsung.com (Michal Wilczynski)
Date: Fri, 29 Nov 2024 13:37:01 +0100
Subject: [bug report] mailbox: Introduce support for T-head TH1520
 Mailbox driver
In-Reply-To: <a99e72be-8490-4960-ad26-cbfef6af238f@stanley.mountain>
References: <CGME20241129065640eucas1p2dc23ee4309b01cb0e7a0f7ae7e5408a1@eucas1p2.samsung.com>
	<a99e72be-8490-4960-ad26-cbfef6af238f@stanley.mountain>
Message-ID: <9b61b713-7c0b-47d6-b6a0-dbef5c17adc2@samsung.com>



On 11/29/24 07:56, Dan Carpenter wrote:
> Hello Michal Wilczynski,

Hi Dan,

> 
> Commit 5d4d263e1c6b ("mailbox: Introduce support for T-head TH1520
> Mailbox driver") from Nov 4, 2024 (linux-next), leads to the
> following Smatch static checker warning:
> 
> drivers/mailbox/mailbox-th1520.c:535 th1520_mbox_suspend_noirq() error: buffer overflow 'ctx->intr_mask' 3 <= 3
> drivers/mailbox/mailbox-th1520.c:548 th1520_mbox_resume_noirq() error: buffer overflow 'ctx->intr_mask' 3 <= 3
> 
> drivers/mailbox/mailbox-th1520.c
>     525 static int __maybe_unused th1520_mbox_suspend_noirq(struct device *dev)
>     526 {
>     527         struct th1520_mbox_priv *priv = dev_get_drvdata(dev);
>     528         struct th1520_mbox_context *ctx = priv->ctx;
>     529         u32 i;
>     530         /*
>     531          * ONLY interrupt mask bit should be stored and restores.
>     532          * INFO data all assumed to be lost.
>     533          */
>     534         for (i = 0; i < TH_1520_MBOX_CHANS; i++) {
> --> 535                 ctx->intr_mask[i] =
> 
> The ctx->intr_mask[] array has TH_1520_MBOX_CHANS - 1 elements so this is
> memory corruption.

Thanks, yeah it seems like the array should just be bigger to accomodate
for all registers interrupt masks. This kind of slipped from the vendor
code, and I haven't noticed it. Will send a patch fixing this.

> 
>     536                         ioread32(priv->local_icu[i] + TH_1520_MBOX_MASK);
>     537         }
>     538         return 0;
>     539 }
> 
> regards,
> dan carpenter
> 


From guoren at kernel.org  Fri Nov 29 04:50:04 2024
From: guoren at kernel.org (Guo Ren)
Date: Fri, 29 Nov 2024 20:50:04 +0800
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com> <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck> <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr> <20241128-goggles-laundry-d94c23ab39a4@spud>
 <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>
 <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com>
 <CAJF2gTSX82rGp-9xZHvg1Y3SpO516YCcqSBLKFgWEQ5G-iWR4A@mail.gmail.com> <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com>
Message-ID: <CAJF2gTR8qhnjv0VNCy+DeWck84MioeAZ3iEuNqSjM81KigNEwA@mail.gmail.com>

On Fri, Nov 29, 2024 at 6:32?PM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
>
> Hi everyone,
>
> On Fri, Nov 29, 2024 at 7:28?AM Guo Ren <guoren at kernel.org> wrote:
> >
> > Hi Conor & Alexandre,
> >
> > On Fri, Nov 29, 2024 at 10:58?AM Guo Ren <guoren at kernel.org> wrote:
> > >
> > > On Fri, Nov 29, 2024 at 8:55?AM Guo Ren <guoren at kernel.org> wrote:
> > > >
> > > > On Fri, Nov 29, 2024 at 12:19?AM Conor Dooley <conor at kernel.org> wrote:
> > > > >
> > > > > On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> > > > > > On 28/11/2024 15:14, Conor Dooley wrote:
> > > > > > > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > > > > > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > > > > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > > > > > > In order to produce a generic kernel, a user can select
> > > > > > > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > > > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > > > > > >
> > > > > > > > > > Note that we can't use alternatives here because the discovery of
> > > > > > > > > > extensions is done too late and we need to start with the qspinlock
> > > > > > > > > > implementation because the ticket spinlock implementation would pollute
> > > > > > > > > > the spinlock value, so let's use static keys.
> > > > > > > > > >
> > > > > > > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > > > > > >
> > > > > > > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > > > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > > > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > > > > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > > > > > > console. My .config has:
> > > > > > > > >
> > > > > > > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > > > > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > > > > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > > > > > > I pointed out some of the fragility during review:
> > > > > > > >
> > > > > > > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > > > > > >
> > > > > > > > so I'm kinda surprised it got merged tbh :/
> > > > > > > Maybe it could be reverted rather than having a broken boot with the
> > > > > > > default settings in -rc1.
> > > > > >
> > > > > >
> > > > > > No need to rush before we know what's happening,I guess you bisected to this
> > > > > > commit right?
> > > > >
> > > > > The symptom is a failure to boot, without any console output, of course
> > > > > I bisected it before blaming something specific. But I don't think it is
> > > > > "rushing" as having -rc1 broken with an option's default is a massive pain
> > > > > in the arse when it comes to testing.
> > > > >
> > > > > > I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> > > > > > kernel, anything?
> > > > >
> > > > > I don't have the former cos it died immediately on boot. config is
> > > > > attached. It reproduces in QEMU so you don't need any hardware.
> > > > If QEMU could reproduce, could you provide a dmesg by the below method?
> > > >
> > > > Qemu cmd append: -s -S
> > > > ref: https://qemu-project.gitlab.io/qemu/system/gdb.html
> > > >
> > > > Connect gdb and in console:
> > > > 1. file vmlinux
> > > > 2. source ./Documentation/admin-guide/kdump/gdbmacros.txt
> > > > 3. dmesg
> > > >
> > > > Then, we could get the kernel's early boot logs from memory.
> > > I've reproduced it on qemu, thx for the config.
> > >
> > > Reading symbols from ../build-rv64lp64/vmlinux...
> > > (gdb) tar rem:1234
> > > Remote debugging using :1234
> > > ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > 49              atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
> > > (gdb) bt
> > > #0  ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > #1  arch_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/arch/riscv/include/asm/spinlock.h:28
> > > #2  do_raw_spin_lock (lock=lock at entry=0xffffffff81b9a5b8 <text_mutex>)
> > > at /home/guoren/source/kernel/linux/kernel/locking/spinlock_debug.c:116
> > > #3  0xffffffff80b2ea0e in __raw_spin_lock_irqsave
> > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/include/linux/spinlock_api_smp.h:111
> > > #4  _raw_spin_lock_irqsave (lock=lock at entry=0xffffffff81b9a5b8
> > > <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/spinlock.c:162
> > > #5  0xffffffff80b27c54 in rt_mutex_slowtrylock
> > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1393
> > > #6  0xffffffff80b295ea in rt_mutex_try_acquire
> > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:319
> > > #7  __rt_mutex_lock (state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1805
> > > #8  __mutex_lock_common (ip=18446744071562135170, nest_lock=0x0,
> > > subclass=0, state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:518
> > > #9  mutex_lock_nested (lock=0xffffffff81b9a5b8 <text_mutex>,
> > > subclass=subclass at entry=0) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:529
> > > #10 0xffffffff80010682 in arch_jump_label_transform_queue
> > > (entry=entry at entry=0xffffffff8158da28, type=<optimized out>) at
> > > /home/guoren/source/kernel/linux/arch/riscv/kernel/jump_label.c:39
> > > #11 0xffffffff801d86b2 in __jump_label_update
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>,
> > > entry=0xffffffff8158da28, stop=stop at entry=0xffffffff815a5e68
> > > <__tracepoint_ptr_initcall_finish>, init=init at entry=true)
> > >     at /home/guoren/source/kernel/linux/kernel/jump_label.c:513
> > > #12 0xffffffff801d890c in jump_label_update
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > /home/guoren/source/kernel/linux/kernel/jump_label.c:920
> > > #13 0xffffffff801d8be8 in static_key_disable_cpuslocked
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > /home/guoren/source/kernel/linux/kernel/jump_label.c:240
> > > #14 0xffffffff801d8c04 in static_key_disable
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > /home/guoren/source/kernel/linux/kernel/jump_label.c:248
> > > #15 0xffffffff80c04a1a in riscv_spinlock_init () at
> > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:271
> > > #16 setup_arch (cmdline_p=cmdline_p at entry=0xffffffff81a03e88) at
> > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:336
> > > #17 0xffffffff80c007a2 in start_kernel () at
> > > /home/guoren/source/kernel/linux/init/main.c:922
> > > #18 0xffffffff80001164 in _start_kernel ()
> > > Backtrace stopped: frame did not save the PC
> > > (gdb) p /x lock
> > > $1 = 0xffffffff81b9a5b8
> > > (gdb) p /x *lock
> > > $2 = {{val = {counter = 0x20000}, {locked = 0x0, pending = 0x0},
> > > {locked_pending = 0x0, tail = 0x2}}}
> >
> > I have for you here a fast fixup for reference. (PS: I'm digging into
> > the root cause mentioned by Will Deacon.)
> >
> > diff --git a/arch/riscv/include/asm/text-patching.h
> > b/arch/riscv/include/asm/text-patching.h
> > index 7228e266b9a1..0439609f1cff 100644
> > --- a/arch/riscv/include/asm/text-patching.h
> > +++ b/arch/riscv/include/asm/text-patching.h
> > @@ -12,5 +12,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len);
> >  int patch_text(void *addr, u32 *insns, size_t len);
> >
> >  extern int riscv_patch_in_stop_machine;
> > +extern int riscv_patch_in_spinlock_init;
> >
> >  #endif /* _ASM_RISCV_PATCH_H */
> > diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
> > index 6eee6f736f68..d9a5a5c1933d 100644
> > --- a/arch/riscv/kernel/jump_label.c
> > +++ b/arch/riscv/kernel/jump_label.c
> > @@ -36,9 +36,11 @@ bool arch_jump_label_transform_queue(struct
> > jump_entry *entry,
> >                 insn = RISCV_INSN_NOP;
> >         }
> >
> > -       mutex_lock(&text_mutex);
> > +       if (!riscv_patch_in_spinlock_init)
> > +               mutex_lock(&text_mutex);
> >         patch_insn_write(addr, &insn, sizeof(insn));
> > -       mutex_unlock(&text_mutex);
> > +       if (!riscv_patch_in_spinlock_init)
> > +               mutex_unlock(&text_mutex);
> >
> >         return true;
> >  }
> > diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
> > index db13c9ddf9e3..ab009cf855c2 100644
> > --- a/arch/riscv/kernel/patch.c
> > +++ b/arch/riscv/kernel/patch.c
> > @@ -24,6 +24,7 @@ struct patch_insn {
> >  };
> >
> >  int riscv_patch_in_stop_machine = false;
> > +int riscv_patch_in_spinlock_init = false;
> >
> >  #ifdef CONFIG_MMU
> >
> > @@ -131,7 +132,7 @@ static int __patch_insn_write(void *addr, const
> > void *insn, size_t len)
> >          * safe but triggers a lockdep failure, so just elide it for that
> >          * specific case.
> >          */
> > -       if (!riscv_patch_in_stop_machine)
> > +       if (!riscv_patch_in_stop_machine && !riscv_patch_in_spinlock_init)
> >                 lockdep_assert_held(&text_mutex);
> >
> >         preempt_disable();
> > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > index 016b48fcd6f2..87ddf1702be4 100644
> > --- a/arch/riscv/kernel/setup.c
> > +++ b/arch/riscv/kernel/setup.c
> > @@ -268,7 +268,9 @@ static void __init riscv_spinlock_init(void)
> >         }
> >  #if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
> >         else {
> > +               riscv_patch_in_spinlock_init = 1;
> >                 static_branch_disable(&qspinlock_key);
> > +               riscv_patch_in_spinlock_init = 0;
> >                 pr_info("Ticket spinlock: enabled\n");
> >                 return;
> >         }
> >
> >
> >
> > --
> > Best Regards
> >  Guo Ren
>
> Thanks Guo for looking into this.
>
> Your solution is not very pretty but I don't have anything better :/
> Unless introducing a static_branch_XXX_nolock() API? I gave it a try
> and it fixes the issue, but not sure this will be accepted.
>
> The thing is the usage of static branches is temporary, we'll use
> alternatives when I finish working on getting the extensions very
> early from the ACPI tables (I have a poc that works, just needs some
> cleaning).
>
> So let's say that I make this early extension parsing my priority for
> 6.14, can we live with Guo's hack in this release? Or should we revert
> this commit?
I almost get the root cause. Please give me a while.

>
> Thanks,
>
> Alex




--
Best Regards
 Guo Ren


From tglx at linutronix.de  Fri Nov 29 05:30:41 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 29 Nov 2024 14:30:41 +0100
Subject: [PATCH v4 1/2] kexec: Consolidate
 machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241129113119.26669-2-farbere@amazon.com>
References: <20241129113119.26669-1-farbere@amazon.com>
 <20241129113119.26669-2-farbere@amazon.com>
Message-ID: <87zfliw4ji.ffs@tglx>

On Fri, Nov 29 2024 at 11:31, Eliav Farber wrote:
> Move the machine_kexec_mask_interrupts function to a common location in
> kernel/kexec_core.c, removing duplicate implementations from architecture
> specific files (arch/arm, arch/arm64, arch/powerpc, and arch/riscv).

Can you please move this into kernel/irq/kexec.c?

It's pure interrupt core internal code and there is no point to make
core internal functions visible to random other code just because.

> +void machine_kexec_mask_interrupts(void)
> +{
> +	unsigned int i;
> +	struct irq_desc *desc;

	struct irq_desc *desc;
        unsigned int i;

please

> +	for_each_irq_desc(i, desc) {
> +		struct irq_chip *chip;
> +		int check_eoi = 1;
> +
> +		chip = irq_desc_get_chip(desc);
> +		if (!chip)
> +			continue;
> +
> +		if (IS_ENABLED(CONFIG_ARM64)) {

This should not be CONFIG_ARM64. Add something like:

config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
	bool

and select this from ARM64?

> +			/*
> +			 * First try to remove the active state. If this fails, try to EOI the
> +			 * interrupt.

This comment does not really explain what this is about. I know you
copied it from the ARM64 implementation, but it should explain what this
actually means. Something like:

         First try to remove the active state from an interrupt which is
         forwarded to a VM. If the interrupt is not forwarded, try to
         EOI the interrupt.

or something like that.

> +			 */
> +			check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);

Looking deeper. This function actually cannot be called from this
context. It does:

          irq_get_desc_buslock(irq, &flags, 0);

which means for any interrupt which has an actual buslock implementation
it will end up in a sleepable function and deadlock in the worst case.

Marc?

> +		}
> +
> +		if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
> +			chip->irq_eoi(&desc->irq_data);

Thanks,

        tglx


From tglx at linutronix.de  Fri Nov 29 05:32:17 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 29 Nov 2024 14:32:17 +0100
Subject: [PATCH v4 2/2] kexec: Prevent redundant IRQ masking by checking
 state before shutdown
In-Reply-To: <20241129113119.26669-3-farbere@amazon.com>
References: <20241129113119.26669-1-farbere@amazon.com>
 <20241129113119.26669-3-farbere@amazon.com>
Message-ID: <87wmgmw4gu.ffs@tglx>

On Fri, Nov 29 2024 at 11:31, Eliav Farber wrote:
>
> This patch addresses the issue by:

Again:  git grep 'This patch' Documentation/process/



From arikalo at gmail.com  Fri Nov 29 06:43:19 2024
From: arikalo at gmail.com (Aleksandar Rikalo)
Date: Fri, 29 Nov 2024 15:43:19 +0100
Subject: [PATCH] riscv: Rewrite AMO instructions via lr and sc.
Message-ID: <20241129144319.74257-1-arikalo@gmail.com>

From: Chao-ying Fu <cfu at mips.com>

Use lr and sc to implement all atomic functions. Some CPUs have
native support for lr and sc, but emulate AMO instructions through
trap handlers that are slow.

Add config RISCV_ISA_ZALRSC_ONLY.

Signed-off-by: Chao-ying Fu <cfu at mips.com>
Signed-off-by: Aleksandar Rikalo <arikalo at gmail.com>
---
 arch/riscv/Kconfig               | 10 ++++++
 arch/riscv/include/asm/atomic.h  | 52 +++++++++++++++++++++++++++++++-
 arch/riscv/include/asm/bitops.h  | 45 +++++++++++++++++++++++++++
 arch/riscv/include/asm/cmpxchg.h | 16 ++++++++++
 arch/riscv/include/asm/futex.h   | 46 ++++++++++++++++++++++++++++
 5 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index cc63aef41e94..767538c27875 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -715,6 +715,16 @@ config RISCV_ISA_ZACAS
 
 	  If you don't know what to do here, say Y.
 
+config RISCV_ISA_ZALRSC_ONLY
+	bool "Zalrsc extension support only"
+	default n
+	help
+	   Use lr and sc to build all atomic functions. Some CPUs have
+	   native support for lr and sc, but emulate amo instructions through
+	   trap handlers that are slow.
+
+	   If you don't know what to do here, say n.
+
 config TOOLCHAIN_HAS_ZBB
 	bool
 	default y
diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
index 5b96c2f61adb..f484babecb9e 100644
--- a/arch/riscv/include/asm/atomic.h
+++ b/arch/riscv/include/asm/atomic.h
@@ -50,6 +50,7 @@ static __always_inline void arch_atomic64_set(atomic64_t *v, s64 i)
  * have the AQ or RL bits set.  These don't return anything, so there's only
  * one version to worry about.
  */
+#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
 #define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix)		\
 static __always_inline							\
 void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v)	\
@@ -59,7 +60,23 @@ void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v)	\
 		: "+A" (v->counter)					\
 		: "r" (I)						\
 		: "memory");						\
-}									\
+}
+#else
+#define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix)		\
+static __always_inline							\
+void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v)	\
+{									\
+	register c_type ret, temp;					\
+	__asm__ __volatile__ (						\
+		"1:	lr." #asm_type " %1, %0\n"			\
+		"	" #asm_op " %2, %1, %3\n"			\
+		"	sc." #asm_type " %2, %2, %0\n"			\
+		"	bnez %2, 1b\n"					\
+		: "+A" (v->counter), "=&r" (ret), "=&r" (temp)		\
+		: "r" (I)						\
+		: "memory");						\
+}
+#endif
 
 #ifdef CONFIG_GENERIC_ATOMIC64
 #define ATOMIC_OPS(op, asm_op, I)					\
@@ -84,6 +101,7 @@ ATOMIC_OPS(xor, xor,  i)
  * There's two flavors of these: the arithmatic ops have both fetch and return
  * versions, while the logical ops only have fetch versions.
  */
+#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
 #define ATOMIC_FETCH_OP(op, asm_op, I, asm_type, c_type, prefix)	\
 static __always_inline							\
 c_type arch_atomic##prefix##_fetch_##op##_relaxed(c_type i,		\
@@ -108,6 +126,38 @@ c_type arch_atomic##prefix##_fetch_##op(c_type i, atomic##prefix##_t *v)	\
 		: "memory");						\
 	return ret;							\
 }
+#else
+#define ATOMIC_FETCH_OP(op, asm_op, I, asm_type, c_type, prefix)	\
+static __always_inline							\
+c_type arch_atomic##prefix##_fetch_##op##_relaxed(c_type i,		\
+					     atomic##prefix##_t *v)	\
+{									\
+	register c_type ret, temp;					\
+	__asm__ __volatile__ (						\
+		"1:	lr." #asm_type " %1, %0\n"			\
+		"	" #asm_op " %2, %1, %3\n"			\
+		"	sc." #asm_type " %2, %2, %0\n"			\
+		"	bnez %2, 1b\n"					\
+		: "+A" (v->counter), "=&r" (ret), "=&r" (temp)		\
+		: "r" (I)						\
+		: "memory");						\
+	return ret;							\
+}									\
+static __always_inline							\
+c_type arch_atomic##prefix##_fetch_##op(c_type i, atomic##prefix##_t *v)	\
+{									\
+	register c_type ret, temp;					\
+	__asm__ __volatile__ (						\
+		"1:	lr." #asm_type ".aqrl %1, %0\n"			\
+		"	" #asm_op " %2, %1, %3\n"			\
+		"	sc." #asm_type ".aqrl %2, %2, %0\n"		\
+		"	bnez %2, 1b\n"					\
+		: "+A" (v->counter), "=&r" (ret), "=&r" (temp)		\
+		: "r" (I)						\
+		: "memory");						\
+	return ret;							\
+}
+#endif
 
 #define ATOMIC_OP_RETURN(op, asm_op, c_op, I, asm_type, c_type, prefix)	\
 static __always_inline							\
diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
index fae152ea0508..b51cb18f7d9e 100644
--- a/arch/riscv/include/asm/bitops.h
+++ b/arch/riscv/include/asm/bitops.h
@@ -187,12 +187,17 @@ static __always_inline int variable_fls(unsigned int x)
 
 #if (BITS_PER_LONG == 64)
 #define __AMO(op)	"amo" #op ".d"
+#define __LR	"lr.d"
+#define __SC	"sc.d"
 #elif (BITS_PER_LONG == 32)
 #define __AMO(op)	"amo" #op ".w"
+#define __LR	"lr.w"
+#define __SC	"sc.w"
 #else
 #error "Unexpected BITS_PER_LONG"
 #endif
 
+#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
 #define __test_and_op_bit_ord(op, mod, nr, addr, ord)		\
 ({								\
 	unsigned long __res, __mask;				\
@@ -211,6 +216,33 @@ static __always_inline int variable_fls(unsigned int x)
 		: "+A" (addr[BIT_WORD(nr)])			\
 		: "r" (mod(BIT_MASK(nr)))			\
 		: "memory");
+#else
+#define __test_and_op_bit_ord(op, mod, nr, addr, ord)		\
+({								\
+	unsigned long __res, __mask, __temp;			\
+	__mask = BIT_MASK(nr);					\
+	__asm__ __volatile__ (					\
+		"1: " __LR #ord " %0, %1\n"			\
+		#op " %2, %0, %3\n"				\
+		__SC #ord " %2, %2, %1\n"			\
+		"bnez %2, 1b\n"					\
+		: "=&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=&r" (__temp)	\
+		: "r" (mod(__mask))				\
+		: "memory");					\
+	((__res & __mask) != 0);				\
+})
+
+#define __op_bit_ord(op, mod, nr, addr, ord)			\
+	unsigned long __res, __temp;				\
+	__asm__ __volatile__ (					\
+		"1: " __LR #ord " %0, %1\n"			\
+		#op " %2, %0, %3\n"				\
+		__SC #ord " %2, %2, %1\n"			\
+		"bnez %2, 1b\n"					\
+		: "=&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=&r" (__temp)	\
+		: "r" (mod(BIT_MASK(nr)))			\
+		: "memory")
+#endif
 
 #define __test_and_op_bit(op, mod, nr, addr) 			\
 	__test_and_op_bit_ord(op, mod, nr, addr, .aqrl)
@@ -354,12 +386,25 @@ static inline void arch___clear_bit_unlock(
 static inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,
 		volatile unsigned long *addr)
 {
+#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
 	unsigned long res;
 	__asm__ __volatile__ (
 		__AMO(xor) ".rl %0, %2, %1"
 		: "=r" (res), "+A" (*addr)
 		: "r" (__NOP(mask))
 		: "memory");
+#else
+	unsigned long res, temp;
+
+	__asm__ __volatile__ (
+		"1: " __LR ".rl %0, %1\n"
+		"xor %2, %0, %3\n"
+		__SC ".rl %2, %2, %1\n"
+		"bnez %2, 1b\n"
+		: "=&r" (res), "+A" (*addr), "=&r" (temp)
+		: "r" (__NOP(mask))
+		: "memory");
+#endif
 	return (res & BIT(7)) != 0;
 }
 
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 4cadc56220fe..881082b05110 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -51,6 +51,7 @@
 	}									\
 })
 
+#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
 #define __arch_xchg(sfx, prepend, append, r, p, n)			\
 ({									\
 	__asm__ __volatile__ (						\
@@ -61,6 +62,21 @@
 		: "r" (n)						\
 		: "memory");						\
 })
+#else
+#define __arch_xchg(sfx, prepend, append, r, p, n)			\
+({									\
+	__typeof__(*(__ptr)) temp;					\
+	__asm__ __volatile__ (						\
+		prepend							\
+		"1:	lr" sfx " %0, %1\n"				\
+		"	sc" sfx " %2, %3, %1\n"				\
+		"	bnez %2, 1b\n"					\
+		append							\
+		: "=&r" (r), "+A" (*(p)), "=&r" (temp)			\
+		: "r" (n)						\
+		: "memory");						\
+})
+#endif
 
 #define _arch_xchg(ptr, new, sc_sfx, swap_sfx, prepend,			\
 		   sc_append, swap_append)				\
diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
index fc8130f995c1..47297f47ec35 100644
--- a/arch/riscv/include/asm/futex.h
+++ b/arch/riscv/include/asm/futex.h
@@ -19,6 +19,7 @@
 #define __disable_user_access()		do { } while (0)
 #endif
 
+#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
 {								\
 	__enable_user_access();					\
@@ -32,16 +33,39 @@
 	: "memory");						\
 	__disable_user_access();				\
 }
+#else
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
+{								\
+	__enable_user_access();					\
+	__asm__ __volatile__ (					\
+	"1:	lr.w.aqrl %[ov], %[u]\n"			\
+	"	" insn "\n"					\
+	"	sc.w.aqrl %[t], %[t], %[u]\n"			\
+	"	bnez %[t], 1b\n"				\
+	"2:\n"							\
+	_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %[r])			\
+	: [r] "+r" (ret), [ov] "=&r" (oldval),			\
+	  [t] "=&r" (temp), [u] "+m" (*uaddr)			\
+	: [op] "Jr" (oparg)					\
+	: "memory");						\
+	__disable_user_access();				\
+}
+#endif
 
 static inline int
 arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
 {
+#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
 	int oldval = 0, ret = 0;
+#else
+	int oldval = 0, ret = 0, temp = 0;
+#endif
 
 	if (!access_ok(uaddr, sizeof(u32)))
 		return -EFAULT;
 
 	switch (op) {
+#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
 	case FUTEX_OP_SET:
 		__futex_atomic_op("amoswap.w.aqrl %[ov],%z[op],%[u]",
 				  ret, oldval, uaddr, oparg);
@@ -62,6 +86,28 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
 		__futex_atomic_op("amoxor.w.aqrl %[ov],%z[op],%[u]",
 				  ret, oldval, uaddr, oparg);
 		break;
+#else
+	case FUTEX_OP_SET:
+		__futex_atomic_op("mv %[t], %z[op]",
+				  ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ADD:
+		__futex_atomic_op("add %[t], %[ov], %z[op]",
+				  ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_OR:
+		__futex_atomic_op("or %[t], %[ov], %z[op]",
+				  ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP_ANDN:
+		__futex_atomic_op("and %[t], %[ov], %z[op]",
+				  ret, oldval, uaddr, ~oparg);
+		break;
+	case FUTEX_OP_XOR:
+		__futex_atomic_op("xor %[t], %[ov], %z[op]",
+				  ret, oldval, uaddr, oparg);
+		break;
+#endif
 	default:
 		ret = -ENOSYS;
 	}
-- 
2.25.1



From guoren at kernel.org  Fri Nov 29 07:12:54 2024
From: guoren at kernel.org (Guo Ren)
Date: Fri, 29 Nov 2024 23:12:54 +0800
Subject: [PATCH] riscv: Rewrite AMO instructions via lr and sc.
In-Reply-To: <20241129144319.74257-1-arikalo@gmail.com>
References: <20241129144319.74257-1-arikalo@gmail.com>
Message-ID: <CAJF2gTRO5Q=CMT8N5nVOF9oOvDb7CtakeemOkX1-v_w-WPuaXQ@mail.gmail.com>

On Fri, Nov 29, 2024 at 10:43?PM Aleksandar Rikalo <arikalo at gmail.com> wrote:
>
> From: Chao-ying Fu <cfu at mips.com>
>
> Use lr and sc to implement all atomic functions. Some CPUs have
> native support for lr and sc, but emulate AMO instructions through
> trap handlers that are slow.
>
> Add config RISCV_ISA_ZALRSC_ONLY.
>
> Signed-off-by: Chao-ying Fu <cfu at mips.com>
> Signed-off-by: Aleksandar Rikalo <arikalo at gmail.com>
> ---
>  arch/riscv/Kconfig               | 10 ++++++
>  arch/riscv/include/asm/atomic.h  | 52 +++++++++++++++++++++++++++++++-
>  arch/riscv/include/asm/bitops.h  | 45 +++++++++++++++++++++++++++
>  arch/riscv/include/asm/cmpxchg.h | 16 ++++++++++
>  arch/riscv/include/asm/futex.h   | 46 ++++++++++++++++++++++++++++
>  5 files changed, 168 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index cc63aef41e94..767538c27875 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -715,6 +715,16 @@ config RISCV_ISA_ZACAS
>
>           If you don't know what to do here, say Y.
>
> +config RISCV_ISA_ZALRSC_ONLY
> +       bool "Zalrsc extension support only"
> +       default n
> +       help
> +          Use lr and sc to build all atomic functions. Some CPUs have
> +          native support for lr and sc, but emulate amo instructions through
> +          trap handlers that are slow.
What's the actual hardware?
Is it emulated in m-mode?
Where is the code?

> +
> +          If you don't know what to do here, say n.
> +
>  config TOOLCHAIN_HAS_ZBB
>         bool
>         default y
> diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
> index 5b96c2f61adb..f484babecb9e 100644
> --- a/arch/riscv/include/asm/atomic.h
> +++ b/arch/riscv/include/asm/atomic.h
> @@ -50,6 +50,7 @@ static __always_inline void arch_atomic64_set(atomic64_t *v, s64 i)
>   * have the AQ or RL bits set.  These don't return anything, so there's only
>   * one version to worry about.
>   */
> +#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
>  #define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix)             \
>  static __always_inline                                                 \
>  void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v)       \
> @@ -59,7 +60,23 @@ void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v)     \
>                 : "+A" (v->counter)                                     \
>                 : "r" (I)                                               \
>                 : "memory");                                            \
> -}                                                                      \
> +}
> +#else
> +#define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix)             \
> +static __always_inline                                                 \
> +void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v)       \
> +{                                                                      \
> +       register c_type ret, temp;                                      \
> +       __asm__ __volatile__ (                                          \
> +               "1:     lr." #asm_type " %1, %0\n"                      \
> +               "       " #asm_op " %2, %1, %3\n"                       \
> +               "       sc." #asm_type " %2, %2, %0\n"                  \
> +               "       bnez %2, 1b\n"                                  \
> +               : "+A" (v->counter), "=&r" (ret), "=&r" (temp)          \
> +               : "r" (I)                                               \
> +               : "memory");                                            \
> +}
> +#endif
>
>  #ifdef CONFIG_GENERIC_ATOMIC64
>  #define ATOMIC_OPS(op, asm_op, I)                                      \
> @@ -84,6 +101,7 @@ ATOMIC_OPS(xor, xor,  i)
>   * There's two flavors of these: the arithmatic ops have both fetch and return
>   * versions, while the logical ops only have fetch versions.
>   */
> +#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
>  #define ATOMIC_FETCH_OP(op, asm_op, I, asm_type, c_type, prefix)       \
>  static __always_inline                                                 \
>  c_type arch_atomic##prefix##_fetch_##op##_relaxed(c_type i,            \
> @@ -108,6 +126,38 @@ c_type arch_atomic##prefix##_fetch_##op(c_type i, atomic##prefix##_t *v)   \
>                 : "memory");                                            \
>         return ret;                                                     \
>  }
> +#else
> +#define ATOMIC_FETCH_OP(op, asm_op, I, asm_type, c_type, prefix)       \
> +static __always_inline                                                 \
> +c_type arch_atomic##prefix##_fetch_##op##_relaxed(c_type i,            \
> +                                            atomic##prefix##_t *v)     \
> +{                                                                      \
> +       register c_type ret, temp;                                      \
> +       __asm__ __volatile__ (                                          \
> +               "1:     lr." #asm_type " %1, %0\n"                      \
> +               "       " #asm_op " %2, %1, %3\n"                       \
> +               "       sc." #asm_type " %2, %2, %0\n"                  \
> +               "       bnez %2, 1b\n"                                  \
> +               : "+A" (v->counter), "=&r" (ret), "=&r" (temp)          \
> +               : "r" (I)                                               \
> +               : "memory");                                            \
> +       return ret;                                                     \
> +}                                                                      \
> +static __always_inline                                                 \
> +c_type arch_atomic##prefix##_fetch_##op(c_type i, atomic##prefix##_t *v)       \
> +{                                                                      \
> +       register c_type ret, temp;                                      \
> +       __asm__ __volatile__ (                                          \
> +               "1:     lr." #asm_type ".aqrl %1, %0\n"                 \
> +               "       " #asm_op " %2, %1, %3\n"                       \
> +               "       sc." #asm_type ".aqrl %2, %2, %0\n"             \
> +               "       bnez %2, 1b\n"                                  \
> +               : "+A" (v->counter), "=&r" (ret), "=&r" (temp)          \
> +               : "r" (I)                                               \
> +               : "memory");                                            \
> +       return ret;                                                     \
> +}
> +#endif
>
>  #define ATOMIC_OP_RETURN(op, asm_op, c_op, I, asm_type, c_type, prefix)        \
>  static __always_inline                                                 \
> diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
> index fae152ea0508..b51cb18f7d9e 100644
> --- a/arch/riscv/include/asm/bitops.h
> +++ b/arch/riscv/include/asm/bitops.h
> @@ -187,12 +187,17 @@ static __always_inline int variable_fls(unsigned int x)
>
>  #if (BITS_PER_LONG == 64)
>  #define __AMO(op)      "amo" #op ".d"
> +#define __LR   "lr.d"
> +#define __SC   "sc.d"
>  #elif (BITS_PER_LONG == 32)
>  #define __AMO(op)      "amo" #op ".w"
> +#define __LR   "lr.w"
> +#define __SC   "sc.w"
>  #else
>  #error "Unexpected BITS_PER_LONG"
>  #endif
>
> +#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
>  #define __test_and_op_bit_ord(op, mod, nr, addr, ord)          \
>  ({                                                             \
>         unsigned long __res, __mask;                            \
> @@ -211,6 +216,33 @@ static __always_inline int variable_fls(unsigned int x)
>                 : "+A" (addr[BIT_WORD(nr)])                     \
>                 : "r" (mod(BIT_MASK(nr)))                       \
>                 : "memory");
> +#else
> +#define __test_and_op_bit_ord(op, mod, nr, addr, ord)          \
> +({                                                             \
> +       unsigned long __res, __mask, __temp;                    \
> +       __mask = BIT_MASK(nr);                                  \
> +       __asm__ __volatile__ (                                  \
> +               "1: " __LR #ord " %0, %1\n"                     \
> +               #op " %2, %0, %3\n"                             \
> +               __SC #ord " %2, %2, %1\n"                       \
> +               "bnez %2, 1b\n"                                 \
> +               : "=&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=&r" (__temp)      \
> +               : "r" (mod(__mask))                             \
> +               : "memory");                                    \
> +       ((__res & __mask) != 0);                                \
> +})
> +
> +#define __op_bit_ord(op, mod, nr, addr, ord)                   \
> +       unsigned long __res, __temp;                            \
> +       __asm__ __volatile__ (                                  \
> +               "1: " __LR #ord " %0, %1\n"                     \
> +               #op " %2, %0, %3\n"                             \
> +               __SC #ord " %2, %2, %1\n"                       \
> +               "bnez %2, 1b\n"                                 \
> +               : "=&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=&r" (__temp)      \
> +               : "r" (mod(BIT_MASK(nr)))                       \
> +               : "memory")
> +#endif
>
>  #define __test_and_op_bit(op, mod, nr, addr)                   \
>         __test_and_op_bit_ord(op, mod, nr, addr, .aqrl)
> @@ -354,12 +386,25 @@ static inline void arch___clear_bit_unlock(
>  static inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,
>                 volatile unsigned long *addr)
>  {
> +#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
>         unsigned long res;
>         __asm__ __volatile__ (
>                 __AMO(xor) ".rl %0, %2, %1"
>                 : "=r" (res), "+A" (*addr)
>                 : "r" (__NOP(mask))
>                 : "memory");
> +#else
> +       unsigned long res, temp;
> +
> +       __asm__ __volatile__ (
> +               "1: " __LR ".rl %0, %1\n"
> +               "xor %2, %0, %3\n"
> +               __SC ".rl %2, %2, %1\n"
> +               "bnez %2, 1b\n"
> +               : "=&r" (res), "+A" (*addr), "=&r" (temp)
> +               : "r" (__NOP(mask))
> +               : "memory");
> +#endif
>         return (res & BIT(7)) != 0;
>  }
>
> diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
> index 4cadc56220fe..881082b05110 100644
> --- a/arch/riscv/include/asm/cmpxchg.h
> +++ b/arch/riscv/include/asm/cmpxchg.h
> @@ -51,6 +51,7 @@
>         }                                                                       \
>  })
>
> +#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
>  #define __arch_xchg(sfx, prepend, append, r, p, n)                     \
>  ({                                                                     \
>         __asm__ __volatile__ (                                          \
> @@ -61,6 +62,21 @@
>                 : "r" (n)                                               \
>                 : "memory");                                            \
>  })
> +#else
> +#define __arch_xchg(sfx, prepend, append, r, p, n)                     \
> +({                                                                     \
> +       __typeof__(*(__ptr)) temp;                                      \
> +       __asm__ __volatile__ (                                          \
> +               prepend                                                 \
> +               "1:     lr" sfx " %0, %1\n"                             \
> +               "       sc" sfx " %2, %3, %1\n"                         \
> +               "       bnez %2, 1b\n"                                  \
> +               append                                                  \
> +               : "=&r" (r), "+A" (*(p)), "=&r" (temp)                  \
> +               : "r" (n)                                               \
> +               : "memory");                                            \
> +})
> +#endif
>
>  #define _arch_xchg(ptr, new, sc_sfx, swap_sfx, prepend,                        \
>                    sc_append, swap_append)                              \
> diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
> index fc8130f995c1..47297f47ec35 100644
> --- a/arch/riscv/include/asm/futex.h
> +++ b/arch/riscv/include/asm/futex.h
> @@ -19,6 +19,7 @@
>  #define __disable_user_access()                do { } while (0)
>  #endif
>
> +#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
>  #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)     \
>  {                                                              \
>         __enable_user_access();                                 \
> @@ -32,16 +33,39 @@
>         : "memory");                                            \
>         __disable_user_access();                                \
>  }
> +#else
> +#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)     \
> +{                                                              \
> +       __enable_user_access();                                 \
> +       __asm__ __volatile__ (                                  \
> +       "1:     lr.w.aqrl %[ov], %[u]\n"                        \
> +       "       " insn "\n"                                     \
> +       "       sc.w.aqrl %[t], %[t], %[u]\n"                   \
> +       "       bnez %[t], 1b\n"                                \
> +       "2:\n"                                                  \
> +       _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %[r])                  \
> +       : [r] "+r" (ret), [ov] "=&r" (oldval),                  \
> +         [t] "=&r" (temp), [u] "+m" (*uaddr)                   \
> +       : [op] "Jr" (oparg)                                     \
> +       : "memory");                                            \
> +       __disable_user_access();                                \
> +}
> +#endif
>
>  static inline int
>  arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
>  {
> +#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
>         int oldval = 0, ret = 0;
> +#else
> +       int oldval = 0, ret = 0, temp = 0;
> +#endif
>
>         if (!access_ok(uaddr, sizeof(u32)))
>                 return -EFAULT;
>
>         switch (op) {
> +#ifndef CONFIG_RISCV_ISA_ZALRSC_ONLY
>         case FUTEX_OP_SET:
>                 __futex_atomic_op("amoswap.w.aqrl %[ov],%z[op],%[u]",
>                                   ret, oldval, uaddr, oparg);
> @@ -62,6 +86,28 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
>                 __futex_atomic_op("amoxor.w.aqrl %[ov],%z[op],%[u]",
>                                   ret, oldval, uaddr, oparg);
>                 break;
> +#else
> +       case FUTEX_OP_SET:
> +               __futex_atomic_op("mv %[t], %z[op]",
> +                                 ret, oldval, uaddr, oparg);
> +               break;
> +       case FUTEX_OP_ADD:
> +               __futex_atomic_op("add %[t], %[ov], %z[op]",
> +                                 ret, oldval, uaddr, oparg);
> +               break;
> +       case FUTEX_OP_OR:
> +               __futex_atomic_op("or %[t], %[ov], %z[op]",
> +                                 ret, oldval, uaddr, oparg);
> +               break;
> +       case FUTEX_OP_ANDN:
> +               __futex_atomic_op("and %[t], %[ov], %z[op]",
> +                                 ret, oldval, uaddr, ~oparg);
> +               break;
> +       case FUTEX_OP_XOR:
> +               __futex_atomic_op("xor %[t], %[ov], %z[op]",
> +                                 ret, oldval, uaddr, oparg);
> +               break;
> +#endif
>         default:
>                 ret = -ENOSYS;
>         }
> --
> 2.25.1
>


-- 
Best Regards
 Guo Ren


From lkp at intel.com  Fri Nov 29 07:31:50 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 29 Nov 2024 23:31:50 +0800
Subject: [PATCH v3 3/3] clk: spacemit: Add clock support for Spacemit K1
 SoC
In-Reply-To: <20241126143125.9980-7-heylenay@4d2.org>
References: <20241126143125.9980-7-heylenay@4d2.org>
Message-ID: <202411292351.6EVdr1rF-lkp@intel.com>

Hi Haylen,

kernel test robot noticed the following build errors:

[auto build test ERROR on 2d5404caa8c7bb5c4e0435f94b28834ae5456623]

url:    https://github.com/intel-lab-lkp/linux/commits/Haylen-Chu/dt-bindings-clock-spacemit-Add-clock-controllers-of-Spacemit-K1-SoC/20241128-101248
base:   2d5404caa8c7bb5c4e0435f94b28834ae5456623
patch link:    https://lore.kernel.org/r/20241126143125.9980-7-heylenay%404d2.org
patch subject: [PATCH v3 3/3] clk: spacemit: Add clock support for Spacemit K1 SoC
config: parisc-allmodconfig (https://download.01.org/0day-ci/archive/20241129/202411292351.6EVdr1rF-lkp at intel.com/config)
compiler: hppa-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241129/202411292351.6EVdr1rF-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411292351.6EVdr1rF-lkp at intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

ERROR: modpost: missing MODULE_LICENSE() in drivers/clk/spacemit/ccu_pll.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/clk/spacemit/ccu_pll.o
ERROR: modpost: missing MODULE_LICENSE() in drivers/clk/spacemit/ccu_mix.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/clk/spacemit/ccu_mix.o
ERROR: modpost: missing MODULE_LICENSE() in drivers/clk/spacemit/ccu_ddn.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/clk/spacemit/ccu_ddn.o
>> ERROR: modpost: "spacemit_ccu_mix_ops" [drivers/clk/spacemit/ccu-k1.ko] undefined!
>> ERROR: modpost: "spacemit_ccu_ddn_ops" [drivers/clk/spacemit/ccu-k1.ko] undefined!
>> ERROR: modpost: "spacemit_ccu_pll_ops" [drivers/clk/spacemit/ccu-k1.ko] undefined!

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From lkp at intel.com  Fri Nov 29 07:31:51 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 29 Nov 2024 23:31:51 +0800
Subject: [PATCH v4 1/2] kexec: Consolidate
 machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241129113119.26669-2-farbere@amazon.com>
References: <20241129113119.26669-2-farbere@amazon.com>
Message-ID: <202411292359.4rjP3LuE-lkp@intel.com>

Hi Eliav,

kernel test robot noticed the following build errors:

[auto build test ERROR on powerpc/next]
[also build test ERROR on powerpc/fixes tip/irq/core arm64/for-next/core linus/master v6.12 next-20241128]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Eliav-Farber/kexec-Consolidate-machine_kexec_mask_interrupts-implementation/20241129-193342
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
patch link:    https://lore.kernel.org/r/20241129113119.26669-2-farbere%40amazon.com
patch subject: [PATCH v4 1/2] kexec: Consolidate machine_kexec_mask_interrupts() implementation
config: i386-buildonly-randconfig-003-20241129 (https://download.01.org/0day-ci/archive/20241129/202411292359.4rjP3LuE-lkp at intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241129/202411292359.4rjP3LuE-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411292359.4rjP3LuE-lkp at intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from kernel/kexec_core.c:43:
>> include/linux/irqdesc.h:68:33: error: field 'irq_common_data' has incomplete type
      68 |         struct irq_common_data  irq_common_data;
         |                                 ^~~~~~~~~~~~~~~
>> include/linux/irqdesc.h:69:33: error: field 'irq_data' has incomplete type
      69 |         struct irq_data         irq_data;
         |                                 ^~~~~~~~
>> include/linux/irqdesc.h:71:9: error: unknown type name 'irq_flow_handler_t'
      71 |         irq_flow_handler_t      handle_irq;
         |         ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/list.h:5,
                    from include/linux/smp.h:12,
                    from include/linux/lockdep.h:14,
                    from include/linux/spinlock.h:63,
                    from include/linux/mmzone.h:8,
                    from include/linux/gfp.h:7,
                    from include/linux/mm.h:7,
                    from include/linux/bpfptr.h:6,
                    from include/linux/btf.h:8,
                    from kernel/kexec_core.c:9:
   include/linux/irqdesc.h: In function 'irq_data_to_desc':
>> include/linux/irqdesc.h:139:33: error: invalid use of undefined type 'struct irq_data'
     139 |         return container_of(data->common, struct irq_desc, irq_common_data);
         |                                 ^~
   include/linux/container_of.h:19:33: note: in definition of macro 'container_of'
      19 |         void *__mptr = (void *)(ptr);                                   \
         |                                 ^~~
   In file included from include/linux/init.h:5,
                    from include/linux/printk.h:6,
                    from include/asm-generic/bug.h:22,
                    from arch/x86/include/asm/bug.h:99,
                    from include/linux/bug.h:5,
                    from include/linux/mmdebug.h:5,
                    from include/linux/mm.h:6:
>> include/linux/irqdesc.h:139:33: error: invalid use of undefined type 'struct irq_data'
     139 |         return container_of(data->common, struct irq_desc, irq_common_data);
         |                                 ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/irqdesc.h:139:16: note: in expansion of macro 'container_of'
     139 |         return container_of(data->common, struct irq_desc, irq_common_data);
         |                ^~~~~~~~~~~~
>> include/linux/irqdesc.h:139:33: error: invalid use of undefined type 'struct irq_data'
     139 |         return container_of(data->common, struct irq_desc, irq_common_data);
         |                                 ^~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |                       __same_type(*(ptr), void),                        \
         |                       ^~~~~~~~~~~
   include/linux/irqdesc.h:139:16: note: in expansion of macro 'container_of'
     139 |         return container_of(data->common, struct irq_desc, irq_common_data);
         |                ^~~~~~~~~~~~
   include/linux/compiler_types.h:464:27: error: expression in static assertion is not an integer
     464 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:20:9: note: in expansion of macro 'static_assert'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:20:23: note: in expansion of macro '__same_type'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/irqdesc.h:139:16: note: in expansion of macro 'container_of'
     139 |         return container_of(data->common, struct irq_desc, irq_common_data);
         |                ^~~~~~~~~~~~
   include/linux/irqdesc.h: In function 'generic_handle_irq_desc':
>> include/linux/irqdesc.h:173:9: error: called object is not a function or function pointer
     173 |         desc->handle_irq(desc);
         |         ^~~~
   include/linux/irqdesc.h: At top level:
   include/linux/irqdesc.h:208:43: error: unknown type name 'irq_flow_handler_t'; did you mean 'irq_handler_t'?
     208 |                                           irq_flow_handler_t handler)
         |                                           ^~~~~~~~~~~~~~~~~~
         |                                           irq_handler_t
   include/linux/irqdesc.h:230:34: error: unknown type name 'irq_flow_handler_t'; did you mean 'irq_handler_t'?
     230 |                                  irq_flow_handler_t handler, const char *name)
         |                                  ^~~~~~~~~~~~~~~~~~
         |                                  irq_handler_t
   include/linux/irqdesc.h: In function 'irq_balancing_disabled':
>> include/linux/irqdesc.h:243:42: error: 'IRQ_NO_BALANCING_MASK' undeclared (first use in this function); did you mean 'IRQF_NOBALANCING'?
     243 |         return irq_check_status_bit(irq, IRQ_NO_BALANCING_MASK);
         |                                          ^~~~~~~~~~~~~~~~~~~~~
         |                                          IRQF_NOBALANCING
   include/linux/irqdesc.h:243:42: note: each undeclared identifier is reported only once for each function it appears in
   include/linux/irqdesc.h: In function 'irq_is_percpu':
>> include/linux/irqdesc.h:248:42: error: 'IRQ_PER_CPU' undeclared (first use in this function); did you mean 'IRQF_PERCPU'?
     248 |         return irq_check_status_bit(irq, IRQ_PER_CPU);
         |                                          ^~~~~~~~~~~
         |                                          IRQF_PERCPU
   include/linux/irqdesc.h: In function 'irq_is_percpu_devid':
>> include/linux/irqdesc.h:253:42: error: 'IRQ_PER_CPU_DEVID' undeclared (first use in this function)
     253 |         return irq_check_status_bit(irq, IRQ_PER_CPU_DEVID);
         |                                          ^~~~~~~~~~~~~~~~~
   kernel/kexec_core.c: In function 'machine_kexec_mask_interrupts':
   kernel/kexec_core.c:1098:38: error: invalid use of undefined type 'struct irq_chip'
    1098 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                      ^~
   kernel/kexec_core.c:1098:51: error: implicit declaration of function 'irqd_irq_inprogress' [-Werror=implicit-function-declaration]
    1098 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                                   ^~~~~~~~~~~~~~~~~~~
   kernel/kexec_core.c:1099:29: error: invalid use of undefined type 'struct irq_chip'
    1099 |                         chip->irq_eoi(&desc->irq_data);
         |                             ^~
   kernel/kexec_core.c:1101:25: error: invalid use of undefined type 'struct irq_chip'
    1101 |                 if (chip->irq_mask)
         |                         ^~
   kernel/kexec_core.c:1102:29: error: invalid use of undefined type 'struct irq_chip'
    1102 |                         chip->irq_mask(&desc->irq_data);
         |                             ^~
   kernel/kexec_core.c:1104:25: error: invalid use of undefined type 'struct irq_chip'
    1104 |                 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
         |                         ^~
   kernel/kexec_core.c:1104:43: error: implicit declaration of function 'irqd_irq_disabled'; did you mean 'arch_irqs_disabled'? [-Werror=implicit-function-declaration]
    1104 |                 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
         |                                           ^~~~~~~~~~~~~~~~~
         |                                           arch_irqs_disabled
   kernel/kexec_core.c:1105:29: error: invalid use of undefined type 'struct irq_chip'
    1105 |                         chip->irq_disable(&desc->irq_data);
         |                             ^~
   include/linux/irqdesc.h: In function 'irq_desc_get_chip':
>> include/linux/irqdesc.h:155:1: warning: control reaches end of non-void function [-Wreturn-type]
     155 | }
         | ^
   cc1: some warnings being treated as errors


vim +/irq_common_data +68 include/linux/irqdesc.h

86d2a2f51fbada Bitao Hu                  2024-04-11   31  
e144710b302525 Thomas Gleixner           2010-10-01   32  /**
e144710b302525 Thomas Gleixner           2010-10-01   33   * struct irq_desc - interrupt descriptor
0d0b4c866bcce6 Jiang Liu                 2015-06-01   34   * @irq_common_data:	per irq and chip data passed down to chip functions
e144710b302525 Thomas Gleixner           2010-10-01   35   * @kstat_irqs:		irq stats per cpu
770767787c2304 Geert Uytterhoeven        2011-04-10   36   * @handle_irq:		highlevel irq-events handler
e144710b302525 Thomas Gleixner           2010-10-01   37   * @action:		the irq action chain
80ebc420ec59a7 Yunfeng Ye                2019-09-18   38   * @status_use_accessors: status information
dbec07bac614a6 Thomas Gleixner           2011-02-07   39   * @core_internal_state__do_not_mess_with_it: core internal status information
e144710b302525 Thomas Gleixner           2010-10-01   40   * @depth:		disable-depth, for nested irq_disable() calls
0911f124bf5535 Geert Uytterhoeven        2011-04-10   41   * @wake_depth:		enable depth, for multiple irq_set_irq_wake() callers
030fc443aef663 Waiman Long               2019-02-12   42   * @tot_count:		stats field for non-percpu irqs
e144710b302525 Thomas Gleixner           2010-10-01   43   * @irq_count:		stats field to detect stalled irqs
e144710b302525 Thomas Gleixner           2010-10-01   44   * @last_unhandled:	aging timer for unhandled count
e144710b302525 Thomas Gleixner           2010-10-01   45   * @irqs_unhandled:	stats field for spurious unhandled interrupts
1e77d0a1ed7417 Thomas Gleixner           2013-03-07   46   * @threads_handled:	stats field for deferred spurious detection of threaded handlers
a359f757965aaf Ingo Molnar               2021-03-22   47   * @threads_handled_last: comparator field for deferred spurious detection of threaded handlers
e144710b302525 Thomas Gleixner           2010-10-01   48   * @lock:		locking for SMP
770767787c2304 Geert Uytterhoeven        2011-04-10   49   * @affinity_hint:	hint to user space for preferred irq affinity
cd7eab44e9946c Ben Hutchings             2011-01-19   50   * @affinity_notify:	context for notification of affinity changes
e144710b302525 Thomas Gleixner           2010-10-01   51   * @pending_mask:	pending rebalanced interrupts
b5faba21a6805c Thomas Gleixner           2011-02-23   52   * @threads_oneshot:	bitfield to handle shared oneshot threads
e144710b302525 Thomas Gleixner           2010-10-01   53   * @threads_active:	number of irqaction threads currently running
e144710b302525 Thomas Gleixner           2010-10-01   54   * @wait_for_threads:	wait queue for sync_irq to wait for threaded handlers
cab303be91dc47 Thomas Gleixner           2014-08-28   55   * @nr_actions:		number of installed actions on this descriptor
cab303be91dc47 Thomas Gleixner           2014-08-28   56   * @no_suspend_depth:	number of irqactions on a irq descriptor with
cab303be91dc47 Thomas Gleixner           2014-08-28   57   *			IRQF_NO_SUSPEND set
cab303be91dc47 Thomas Gleixner           2014-08-28   58   * @force_resume_depth:	number of irqactions on a irq descriptor with
cab303be91dc47 Thomas Gleixner           2014-08-28   59   *			IRQF_FORCE_RESUME set
425a5072dcd1bd Thomas Gleixner           2015-12-13   60   * @rcu:		rcu head for delayed free
ecb3f394c5dba8 Craig Gallek              2016-09-13   61   * @kobj:		kobject used to represent this struct in sysfs
9114014cf4e6df Thomas Gleixner           2017-06-29   62   * @request_mutex:	mutex to protect request/free before locking desc->lock
e144710b302525 Thomas Gleixner           2010-10-01   63   * @dir:		/proc/irq/ procfs entry
087cdfb662ae50 Thomas Gleixner           2017-06-20   64   * @debugfs_file:	dentry for the debugfs file
e144710b302525 Thomas Gleixner           2010-10-01   65   * @name:		flow handler name for /proc/interrupts output
e144710b302525 Thomas Gleixner           2010-10-01   66   */
e144710b302525 Thomas Gleixner           2010-10-01   67  struct irq_desc {
0d0b4c866bcce6 Jiang Liu                 2015-06-01  @68  	struct irq_common_data	irq_common_data;
e144710b302525 Thomas Gleixner           2010-10-01  @69  	struct irq_data		irq_data;
86d2a2f51fbada Bitao Hu                  2024-04-11   70  	struct irqstat __percpu	*kstat_irqs;
e144710b302525 Thomas Gleixner           2010-10-01  @71  	irq_flow_handler_t	handle_irq;
e144710b302525 Thomas Gleixner           2010-10-01   72  	struct irqaction	*action;	/* IRQ action list */
a6967caf00ebbb Thomas Gleixner           2011-02-10   73  	unsigned int		status_use_accessors;
dbec07bac614a6 Thomas Gleixner           2011-02-07   74  	unsigned int		core_internal_state__do_not_mess_with_it;
e144710b302525 Thomas Gleixner           2010-10-01   75  	unsigned int		depth;		/* nested irq disables */
e144710b302525 Thomas Gleixner           2010-10-01   76  	unsigned int		wake_depth;	/* nested wake enables */
1136b072896990 Thomas Gleixner           2019-02-08   77  	unsigned int		tot_count;
e144710b302525 Thomas Gleixner           2010-10-01   78  	unsigned int		irq_count;	/* For detecting broken IRQs */
e144710b302525 Thomas Gleixner           2010-10-01   79  	unsigned long		last_unhandled;	/* Aging timer for unhandled count */
e144710b302525 Thomas Gleixner           2010-10-01   80  	unsigned int		irqs_unhandled;
1e77d0a1ed7417 Thomas Gleixner           2013-03-07   81  	atomic_t		threads_handled;
1e77d0a1ed7417 Thomas Gleixner           2013-03-07   82  	int			threads_handled_last;
e144710b302525 Thomas Gleixner           2010-10-01   83  	raw_spinlock_t		lock;
31d9d9b6d83030 Marc Zyngier              2011-09-23   84  	struct cpumask		*percpu_enabled;
222df54fd8b764 Marc Zyngier              2016-04-11   85  	const struct cpumask	*percpu_affinity;
e144710b302525 Thomas Gleixner           2010-10-01   86  #ifdef CONFIG_SMP
e144710b302525 Thomas Gleixner           2010-10-01   87  	const struct cpumask	*affinity_hint;
cd7eab44e9946c Ben Hutchings             2011-01-19   88  	struct irq_affinity_notify *affinity_notify;
e144710b302525 Thomas Gleixner           2010-10-01   89  #ifdef CONFIG_GENERIC_PENDING_IRQ
e144710b302525 Thomas Gleixner           2010-10-01   90  	cpumask_var_t		pending_mask;
e144710b302525 Thomas Gleixner           2010-10-01   91  #endif
e144710b302525 Thomas Gleixner           2010-10-01   92  #endif
b5faba21a6805c Thomas Gleixner           2011-02-23   93  	unsigned long		threads_oneshot;
e144710b302525 Thomas Gleixner           2010-10-01   94  	atomic_t		threads_active;
e144710b302525 Thomas Gleixner           2010-10-01   95  	wait_queue_head_t       wait_for_threads;
cab303be91dc47 Thomas Gleixner           2014-08-28   96  #ifdef CONFIG_PM_SLEEP
cab303be91dc47 Thomas Gleixner           2014-08-28   97  	unsigned int		nr_actions;
cab303be91dc47 Thomas Gleixner           2014-08-28   98  	unsigned int		no_suspend_depth;
17f480342026e5 Rafael J. Wysocki         2015-02-27   99  	unsigned int		cond_suspend_depth;
cab303be91dc47 Thomas Gleixner           2014-08-28  100  	unsigned int		force_resume_depth;
cab303be91dc47 Thomas Gleixner           2014-08-28  101  #endif
e144710b302525 Thomas Gleixner           2010-10-01  102  #ifdef CONFIG_PROC_FS
e144710b302525 Thomas Gleixner           2010-10-01  103  	struct proc_dir_entry	*dir;
425a5072dcd1bd Thomas Gleixner           2015-12-13  104  #endif
087cdfb662ae50 Thomas Gleixner           2017-06-20  105  #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
087cdfb662ae50 Thomas Gleixner           2017-06-20  106  	struct dentry		*debugfs_file;
07557ccb8c83f3 Thomas Gleixner           2017-09-13  107  	const char		*dev_name;
087cdfb662ae50 Thomas Gleixner           2017-06-20  108  #endif
425a5072dcd1bd Thomas Gleixner           2015-12-13  109  #ifdef CONFIG_SPARSE_IRQ
425a5072dcd1bd Thomas Gleixner           2015-12-13  110  	struct rcu_head		rcu;
ecb3f394c5dba8 Craig Gallek              2016-09-13  111  	struct kobject		kobj;
e144710b302525 Thomas Gleixner           2010-10-01  112  #endif
9114014cf4e6df Thomas Gleixner           2017-06-29  113  	struct mutex		request_mutex;
293a7a0a165c4f Thomas Gleixner           2012-10-16  114  	int			parent_irq;
b6873807a7143b Sebastian Andrzej Siewior 2011-07-11  115  	struct module		*owner;
e144710b302525 Thomas Gleixner           2010-10-01  116  	const char		*name;
bc06a9e0874239 Shanker Donthineni        2023-05-19  117  #ifdef CONFIG_HARDIRQS_SW_RESEND
bc06a9e0874239 Shanker Donthineni        2023-05-19  118  	struct hlist_node	resend_node;
bc06a9e0874239 Shanker Donthineni        2023-05-19  119  #endif
e144710b302525 Thomas Gleixner           2010-10-01  120  } ____cacheline_internodealigned_in_smp;
e144710b302525 Thomas Gleixner           2010-10-01  121  
a899418167264c Thomas Gleixner           2015-07-05  122  #ifdef CONFIG_SPARSE_IRQ
a899418167264c Thomas Gleixner           2015-07-05  123  extern void irq_lock_sparse(void);
a899418167264c Thomas Gleixner           2015-07-05  124  extern void irq_unlock_sparse(void);
a899418167264c Thomas Gleixner           2015-07-05  125  #else
a899418167264c Thomas Gleixner           2015-07-05  126  static inline void irq_lock_sparse(void) { }
a899418167264c Thomas Gleixner           2015-07-05  127  static inline void irq_unlock_sparse(void) { }
e144710b302525 Thomas Gleixner           2010-10-01  128  extern struct irq_desc irq_desc[NR_IRQS];
e144710b302525 Thomas Gleixner           2010-10-01  129  #endif
e144710b302525 Thomas Gleixner           2010-10-01  130  
501e2db67fa426 Thomas Gleixner           2020-12-10  131  static inline unsigned int irq_desc_kstat_cpu(struct irq_desc *desc,
501e2db67fa426 Thomas Gleixner           2020-12-10  132  					      unsigned int cpu)
501e2db67fa426 Thomas Gleixner           2020-12-10  133  {
86d2a2f51fbada Bitao Hu                  2024-04-11  134  	return desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, cpu) : 0;
501e2db67fa426 Thomas Gleixner           2020-12-10  135  }
501e2db67fa426 Thomas Gleixner           2020-12-10  136  
7bbf1dd24b17b9 Jiang Liu                 2015-06-01  137  static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
7bbf1dd24b17b9 Jiang Liu                 2015-06-01  138  {
755d119a620497 Thomas Gleixner           2015-09-16 @139  	return container_of(data->common, struct irq_desc, irq_common_data);
7bbf1dd24b17b9 Jiang Liu                 2015-06-01  140  }
7bbf1dd24b17b9 Jiang Liu                 2015-06-01  141  
304adf8a8fff97 Jiang Liu                 2015-06-04  142  static inline unsigned int irq_desc_get_irq(struct irq_desc *desc)
304adf8a8fff97 Jiang Liu                 2015-06-04  143  {
304adf8a8fff97 Jiang Liu                 2015-06-04  144  	return desc->irq_data.irq;
304adf8a8fff97 Jiang Liu                 2015-06-04  145  }
304adf8a8fff97 Jiang Liu                 2015-06-04  146  
d9936bb3952a08 Thomas Gleixner           2011-03-11  147  static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc)
d9936bb3952a08 Thomas Gleixner           2011-03-11  148  {
d9936bb3952a08 Thomas Gleixner           2011-03-11  149  	return &desc->irq_data;
d9936bb3952a08 Thomas Gleixner           2011-03-11  150  }
d9936bb3952a08 Thomas Gleixner           2011-03-11  151  
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  152  static inline struct irq_chip *irq_desc_get_chip(struct irq_desc *desc)
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  153  {
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  154  	return desc->irq_data.chip;
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10 @155  }
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  156  
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  157  static inline void *irq_desc_get_chip_data(struct irq_desc *desc)
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  158  {
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  159  	return desc->irq_data.chip_data;
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  160  }
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  161  
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  162  static inline void *irq_desc_get_handler_data(struct irq_desc *desc)
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  163  {
af7080e040d223 Jiang Liu                 2015-06-01  164  	return desc->irq_common_data.handler_data;
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  165  }
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  166  
e144710b302525 Thomas Gleixner           2010-10-01  167  /*
e144710b302525 Thomas Gleixner           2010-10-01  168   * Architectures call this to let the generic IRQ layer
6584d84c3e504c Huang Shijie              2015-09-01  169   * handle an interrupt.
e144710b302525 Thomas Gleixner           2010-10-01  170   */
bd0b9ac405e179 Thomas Gleixner           2015-09-14  171  static inline void generic_handle_irq_desc(struct irq_desc *desc)
e144710b302525 Thomas Gleixner           2010-10-01  172  {
bd0b9ac405e179 Thomas Gleixner           2015-09-14 @173  	desc->handle_irq(desc);
e144710b302525 Thomas Gleixner           2010-10-01  174  }
e144710b302525 Thomas Gleixner           2010-10-01  175  
a3016b26ee6ee1 Marc Zyngier              2021-05-04  176  int handle_irq_desc(struct irq_desc *desc);
fe12bc2c996d3e Thomas Gleixner           2011-05-18  177  int generic_handle_irq(unsigned int irq);
509853f9e1e7b1 Sebastian Andrzej Siewior 2022-02-11  178  int generic_handle_irq_safe(unsigned int irq);
e144710b302525 Thomas Gleixner           2010-10-01  179  
e1c054918c6c7a Marc Zyngier              2021-05-12  180  #ifdef CONFIG_IRQ_DOMAIN
76ba59f8366f2d Marc Zyngier              2014-08-26  181  /*
76ba59f8366f2d Marc Zyngier              2014-08-26  182   * Convert a HW interrupt number to a logical one using a IRQ domain,
76ba59f8366f2d Marc Zyngier              2014-08-26  183   * and handle the result interrupt number. Return -EINVAL if
9626d18a20e166 Marc Zyngier              2021-05-04  184   * conversion failed.
76ba59f8366f2d Marc Zyngier              2014-08-26  185   */
8240ef50d48643 Marc Zyngier              2021-05-12  186  int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq);
6a164c64699984 Sebastian Andrzej Siewior 2022-05-09  187  int generic_handle_domain_irq_safe(struct irq_domain *domain, unsigned int hwirq);
0953fb263714e1 Mark Rutland              2021-10-20  188  int generic_handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq);
76ba59f8366f2d Marc Zyngier              2014-08-26  189  #endif
76ba59f8366f2d Marc Zyngier              2014-08-26  190  
e144710b302525 Thomas Gleixner           2010-10-01  191  /* Test to see if a driver has successfully requested an irq */
f61ae4fb66a4f7 Thomas Gleixner           2015-08-02  192  static inline int irq_desc_has_action(struct irq_desc *desc)
e144710b302525 Thomas Gleixner           2010-10-01  193  {
a313357e704f26 Thomas Gleixner           2020-12-10  194  	return desc && desc->action != NULL;
f61ae4fb66a4f7 Thomas Gleixner           2015-08-02  195  }
f61ae4fb66a4f7 Thomas Gleixner           2015-08-02  196  
bbc9d21fc0071c Thomas Gleixner           2015-06-23  197  /**
bbc9d21fc0071c Thomas Gleixner           2015-06-23  198   * irq_set_handler_locked - Set irq handler from a locked region
bbc9d21fc0071c Thomas Gleixner           2015-06-23  199   * @data:	Pointer to the irq_data structure which identifies the irq
bbc9d21fc0071c Thomas Gleixner           2015-06-23  200   * @handler:	Flow control handler function for this interrupt
bbc9d21fc0071c Thomas Gleixner           2015-06-23  201   *
bbc9d21fc0071c Thomas Gleixner           2015-06-23  202   * Sets the handler in the irq descriptor associated to @data.
bbc9d21fc0071c Thomas Gleixner           2015-06-23  203   *
bbc9d21fc0071c Thomas Gleixner           2015-06-23  204   * Must be called with irq_desc locked and valid parameters. Typical
bbc9d21fc0071c Thomas Gleixner           2015-06-23  205   * call site is the irq_set_type() callback.
bbc9d21fc0071c Thomas Gleixner           2015-06-23  206   */
bbc9d21fc0071c Thomas Gleixner           2015-06-23  207  static inline void irq_set_handler_locked(struct irq_data *data,
bbc9d21fc0071c Thomas Gleixner           2015-06-23  208  					  irq_flow_handler_t handler)
bbc9d21fc0071c Thomas Gleixner           2015-06-23  209  {
bbc9d21fc0071c Thomas Gleixner           2015-06-23  210  	struct irq_desc *desc = irq_data_to_desc(data);
bbc9d21fc0071c Thomas Gleixner           2015-06-23  211  
bbc9d21fc0071c Thomas Gleixner           2015-06-23  212  	desc->handle_irq = handler;
bbc9d21fc0071c Thomas Gleixner           2015-06-23  213  }
bbc9d21fc0071c Thomas Gleixner           2015-06-23  214  
bbc9d21fc0071c Thomas Gleixner           2015-06-23  215  /**
bbc9d21fc0071c Thomas Gleixner           2015-06-23  216   * irq_set_chip_handler_name_locked - Set chip, handler and name from a locked region
bbc9d21fc0071c Thomas Gleixner           2015-06-23  217   * @data:	Pointer to the irq_data structure for which the chip is set
bbc9d21fc0071c Thomas Gleixner           2015-06-23  218   * @chip:	Pointer to the new irq chip
bbc9d21fc0071c Thomas Gleixner           2015-06-23  219   * @handler:	Flow control handler function for this interrupt
bbc9d21fc0071c Thomas Gleixner           2015-06-23  220   * @name:	Name of the interrupt
bbc9d21fc0071c Thomas Gleixner           2015-06-23  221   *
bbc9d21fc0071c Thomas Gleixner           2015-06-23  222   * Replace the irq chip at the proper hierarchy level in @data and
bbc9d21fc0071c Thomas Gleixner           2015-06-23  223   * sets the handler and name in the associated irq descriptor.
bbc9d21fc0071c Thomas Gleixner           2015-06-23  224   *
bbc9d21fc0071c Thomas Gleixner           2015-06-23  225   * Must be called with irq_desc locked and valid parameters.
bbc9d21fc0071c Thomas Gleixner           2015-06-23  226   */
bbc9d21fc0071c Thomas Gleixner           2015-06-23  227  static inline void
ef6e5d61eb7a0a Michael Walle             2022-07-06  228  irq_set_chip_handler_name_locked(struct irq_data *data,
ef6e5d61eb7a0a Michael Walle             2022-07-06  229  				 const struct irq_chip *chip,
bbc9d21fc0071c Thomas Gleixner           2015-06-23  230  				 irq_flow_handler_t handler, const char *name)
bbc9d21fc0071c Thomas Gleixner           2015-06-23  231  {
bbc9d21fc0071c Thomas Gleixner           2015-06-23  232  	struct irq_desc *desc = irq_data_to_desc(data);
bbc9d21fc0071c Thomas Gleixner           2015-06-23  233  
bbc9d21fc0071c Thomas Gleixner           2015-06-23  234  	desc->handle_irq = handler;
bbc9d21fc0071c Thomas Gleixner           2015-06-23  235  	desc->name = name;
ef6e5d61eb7a0a Michael Walle             2022-07-06  236  	data->chip = (struct irq_chip *)chip;
bbc9d21fc0071c Thomas Gleixner           2015-06-23  237  }
bbc9d21fc0071c Thomas Gleixner           2015-06-23  238  
fdd029630434b4 Thomas Gleixner           2020-12-10  239  bool irq_check_status_bit(unsigned int irq, unsigned int bitmask);
fdd029630434b4 Thomas Gleixner           2020-12-10  240  
4ce413d1840b25 Will Deacon               2017-12-01  241  static inline bool irq_balancing_disabled(unsigned int irq)
e144710b302525 Thomas Gleixner           2010-10-01  242  {
fdd029630434b4 Thomas Gleixner           2020-12-10 @243  	return irq_check_status_bit(irq, IRQ_NO_BALANCING_MASK);
e144710b302525 Thomas Gleixner           2010-10-01  244  }
781295762defc7 Thomas Gleixner           2011-02-10  245  
4ce413d1840b25 Will Deacon               2017-12-01  246  static inline bool irq_is_percpu(unsigned int irq)
7f4a8e7b1943c1 Vinayak Kale              2013-12-04  247  {
fdd029630434b4 Thomas Gleixner           2020-12-10 @248  	return irq_check_status_bit(irq, IRQ_PER_CPU);
7f4a8e7b1943c1 Vinayak Kale              2013-12-04  249  }
7f4a8e7b1943c1 Vinayak Kale              2013-12-04  250  
4ce413d1840b25 Will Deacon               2017-12-01  251  static inline bool irq_is_percpu_devid(unsigned int irq)
08395c7f4d9f58 Julien Thierry            2017-10-13  252  {
fdd029630434b4 Thomas Gleixner           2020-12-10 @253  	return irq_check_status_bit(irq, IRQ_PER_CPU_DEVID);
08395c7f4d9f58 Julien Thierry            2017-10-13  254  }
08395c7f4d9f58 Julien Thierry            2017-10-13  255  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From lkp at intel.com  Fri Nov 29 07:53:07 2024
From: lkp at intel.com (kernel test robot)
Date: Fri, 29 Nov 2024 23:53:07 +0800
Subject: [PATCH v4 1/2] kexec: Consolidate
 machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241129113119.26669-2-farbere@amazon.com>
References: <20241129113119.26669-2-farbere@amazon.com>
Message-ID: <202411292312.KnEWhcVS-lkp@intel.com>

Hi Eliav,

kernel test robot noticed the following build errors:

[auto build test ERROR on powerpc/next]
[also build test ERROR on powerpc/fixes tip/irq/core arm64/for-next/core linus/master v6.12 next-20241128]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Eliav-Farber/kexec-Consolidate-machine_kexec_mask_interrupts-implementation/20241129-193342
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
patch link:    https://lore.kernel.org/r/20241129113119.26669-2-farbere%40amazon.com
patch subject: [PATCH v4 1/2] kexec: Consolidate machine_kexec_mask_interrupts() implementation
config: i386-buildonly-randconfig-002-20241129 (https://download.01.org/0day-ci/archive/20241129/202411292312.KnEWhcVS-lkp at intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241129/202411292312.KnEWhcVS-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411292312.KnEWhcVS-lkp at intel.com/

All errors (new ones prefixed by >>):

   In file included from kernel/kexec_core.c:9:
   In file included from include/linux/btf.h:8:
   In file included from include/linux/bpfptr.h:6:
   In file included from include/linux/mm.h:2223:
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
   In file included from kernel/kexec_core.c:43:
>> include/linux/irqdesc.h:68:25: error: field has incomplete type 'struct irq_common_data'
      68 |         struct irq_common_data  irq_common_data;
         |                                 ^
   include/linux/irqdesc.h:68:9: note: forward declaration of 'struct irq_common_data'
      68 |         struct irq_common_data  irq_common_data;
         |                ^
>> include/linux/irqdesc.h:69:19: error: field has incomplete type 'struct irq_data'
      69 |         struct irq_data         irq_data;
         |                                 ^
   include/linux/irqdesc.h:69:9: note: forward declaration of 'struct irq_data'
      69 |         struct irq_data         irq_data;
         |                ^
   include/linux/irqdesc.h:71:2: error: unknown type name 'irq_flow_handler_t'; did you mean 'irq_handler_t'?
      71 |         irq_flow_handler_t      handle_irq;
         |         ^~~~~~~~~~~~~~~~~~
         |         irq_handler_t
   include/linux/interrupt.h:104:23: note: 'irq_handler_t' declared here
     104 | typedef irqreturn_t (*irq_handler_t)(int, void *);
         |                       ^
   In file included from kernel/kexec_core.c:43:
>> include/linux/irqdesc.h:139:26: error: incomplete definition of type 'struct irq_data'
     139 |         return container_of(data->common, struct irq_desc, irq_common_data);
         |                             ~~~~^
   include/linux/container_of.h:19:26: note: expanded from macro 'container_of'
      19 |         void *__mptr = (void *)(ptr);                                   \
         |                                 ^~~
   include/linux/irqdesc.h:69:9: note: forward declaration of 'struct irq_data'
      69 |         struct irq_data         irq_data;
         |                ^
>> include/linux/irqdesc.h:139:26: error: incomplete definition of type 'struct irq_data'
     139 |         return container_of(data->common, struct irq_desc, irq_common_data);
         |                             ~~~~^
   include/linux/container_of.h:20:30: note: expanded from macro 'container_of'
      20 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                                     ^~~
   include/linux/compiler_types.h:464:63: note: expanded from macro '__same_type'
     464 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                                                               ^
   include/linux/build_bug.h:77:50: note: expanded from macro 'static_assert'
      77 | #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
         |                                                  ^~~~
   include/linux/build_bug.h:78:56: note: expanded from macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/irqdesc.h:69:9: note: forward declaration of 'struct irq_data'
      69 |         struct irq_data         irq_data;
         |                ^
>> include/linux/irqdesc.h:139:26: error: incomplete definition of type 'struct irq_data'
     139 |         return container_of(data->common, struct irq_desc, irq_common_data);
         |                             ~~~~^
   include/linux/container_of.h:21:23: note: expanded from macro 'container_of'
      21 |                       __same_type(*(ptr), void),                        \
         |                                     ^~~
   include/linux/compiler_types.h:464:63: note: expanded from macro '__same_type'
     464 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                                                               ^
   include/linux/build_bug.h:77:50: note: expanded from macro 'static_assert'
      77 | #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
         |                                                  ^~~~
   include/linux/build_bug.h:78:56: note: expanded from macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/irqdesc.h:69:9: note: forward declaration of 'struct irq_data'
      69 |         struct irq_data         irq_data;
         |                ^
>> include/linux/irqdesc.h:173:23: error: too few arguments to function call, expected 2, have 1
     173 |         desc->handle_irq(desc);
         |         ~~~~~~~~~~~~~~~~     ^
   include/linux/irqdesc.h:208:8: error: unknown type name 'irq_flow_handler_t'; did you mean 'irq_handler_t'?
     208 |                                           irq_flow_handler_t handler)
         |                                           ^~~~~~~~~~~~~~~~~~
         |                                           irq_handler_t
   include/linux/interrupt.h:104:23: note: 'irq_handler_t' declared here
     104 | typedef irqreturn_t (*irq_handler_t)(int, void *);
         |                       ^
   In file included from kernel/kexec_core.c:43:
   include/linux/irqdesc.h:230:6: error: unknown type name 'irq_flow_handler_t'; did you mean 'irq_handler_t'?
     230 |                                  irq_flow_handler_t handler, const char *name)
         |                                  ^~~~~~~~~~~~~~~~~~
         |                                  irq_handler_t
   include/linux/interrupt.h:104:23: note: 'irq_handler_t' declared here
     104 | typedef irqreturn_t (*irq_handler_t)(int, void *);
         |                       ^
   In file included from kernel/kexec_core.c:43:
   include/linux/irqdesc.h:236:6: error: incomplete definition of type 'struct irq_data'
     236 |         data->chip = (struct irq_chip *)chip;
         |         ~~~~^
   include/linux/irqdesc.h:69:9: note: forward declaration of 'struct irq_data'
      69 |         struct irq_data         irq_data;
         |                ^
>> include/linux/irqdesc.h:243:35: error: use of undeclared identifier 'IRQ_NO_BALANCING_MASK'
     243 |         return irq_check_status_bit(irq, IRQ_NO_BALANCING_MASK);
         |                                          ^
>> include/linux/irqdesc.h:248:35: error: use of undeclared identifier 'IRQ_PER_CPU'; did you mean 'MEM_PERCPU'?
     248 |         return irq_check_status_bit(irq, IRQ_PER_CPU);
         |                                          ^~~~~~~~~~~
         |                                          MEM_PERCPU
   include/linux/bpf.h:650:2: note: 'MEM_PERCPU' declared here
     650 |         MEM_PERCPU              = BIT(4 + BPF_BASE_TYPE_BITS),
         |         ^
   In file included from kernel/kexec_core.c:43:
>> include/linux/irqdesc.h:253:35: error: use of undeclared identifier 'IRQ_PER_CPU_DEVID'
     253 |         return irq_check_status_bit(irq, IRQ_PER_CPU_DEVID);
         |                                          ^
   kernel/kexec_core.c:1098:24: error: incomplete definition of type 'struct irq_chip'
    1098 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                  ~~~~^
   include/linux/irqdesc.h:152:22: note: forward declaration of 'struct irq_chip'
     152 | static inline struct irq_chip *irq_desc_get_chip(struct irq_desc *desc)
         |                      ^
   kernel/kexec_core.c:1098:37: error: call to undeclared function 'irqd_irq_inprogress'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    1098 |                 if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
         |                                                   ^
   kernel/kexec_core.c:1099:8: error: incomplete definition of type 'struct irq_chip'
    1099 |                         chip->irq_eoi(&desc->irq_data);
         |                         ~~~~^
   include/linux/irqdesc.h:152:22: note: forward declaration of 'struct irq_chip'
     152 | static inline struct irq_chip *irq_desc_get_chip(struct irq_desc *desc)
         |                      ^
   kernel/kexec_core.c:1101:11: error: incomplete definition of type 'struct irq_chip'
    1101 |                 if (chip->irq_mask)
         |                     ~~~~^
   include/linux/irqdesc.h:152:22: note: forward declaration of 'struct irq_chip'
     152 | static inline struct irq_chip *irq_desc_get_chip(struct irq_desc *desc)
         |                      ^
   kernel/kexec_core.c:1102:8: error: incomplete definition of type 'struct irq_chip'
    1102 |                         chip->irq_mask(&desc->irq_data);
         |                         ~~~~^
   include/linux/irqdesc.h:152:22: note: forward declaration of 'struct irq_chip'
     152 | static inline struct irq_chip *irq_desc_get_chip(struct irq_desc *desc)
         |                      ^
   kernel/kexec_core.c:1104:11: error: incomplete definition of type 'struct irq_chip'
    1104 |                 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
         |                     ~~~~^
   include/linux/irqdesc.h:152:22: note: forward declaration of 'struct irq_chip'
     152 | static inline struct irq_chip *irq_desc_get_chip(struct irq_desc *desc)
         |                      ^
   fatal error: too many errors emitted, stopping now [-ferror-limit=]
   1 warning and 20 errors generated.


vim +68 include/linux/irqdesc.h

86d2a2f51fbada Bitao Hu                  2024-04-11   31  
e144710b302525 Thomas Gleixner           2010-10-01   32  /**
e144710b302525 Thomas Gleixner           2010-10-01   33   * struct irq_desc - interrupt descriptor
0d0b4c866bcce6 Jiang Liu                 2015-06-01   34   * @irq_common_data:	per irq and chip data passed down to chip functions
e144710b302525 Thomas Gleixner           2010-10-01   35   * @kstat_irqs:		irq stats per cpu
770767787c2304 Geert Uytterhoeven        2011-04-10   36   * @handle_irq:		highlevel irq-events handler
e144710b302525 Thomas Gleixner           2010-10-01   37   * @action:		the irq action chain
80ebc420ec59a7 Yunfeng Ye                2019-09-18   38   * @status_use_accessors: status information
dbec07bac614a6 Thomas Gleixner           2011-02-07   39   * @core_internal_state__do_not_mess_with_it: core internal status information
e144710b302525 Thomas Gleixner           2010-10-01   40   * @depth:		disable-depth, for nested irq_disable() calls
0911f124bf5535 Geert Uytterhoeven        2011-04-10   41   * @wake_depth:		enable depth, for multiple irq_set_irq_wake() callers
030fc443aef663 Waiman Long               2019-02-12   42   * @tot_count:		stats field for non-percpu irqs
e144710b302525 Thomas Gleixner           2010-10-01   43   * @irq_count:		stats field to detect stalled irqs
e144710b302525 Thomas Gleixner           2010-10-01   44   * @last_unhandled:	aging timer for unhandled count
e144710b302525 Thomas Gleixner           2010-10-01   45   * @irqs_unhandled:	stats field for spurious unhandled interrupts
1e77d0a1ed7417 Thomas Gleixner           2013-03-07   46   * @threads_handled:	stats field for deferred spurious detection of threaded handlers
a359f757965aaf Ingo Molnar               2021-03-22   47   * @threads_handled_last: comparator field for deferred spurious detection of threaded handlers
e144710b302525 Thomas Gleixner           2010-10-01   48   * @lock:		locking for SMP
770767787c2304 Geert Uytterhoeven        2011-04-10   49   * @affinity_hint:	hint to user space for preferred irq affinity
cd7eab44e9946c Ben Hutchings             2011-01-19   50   * @affinity_notify:	context for notification of affinity changes
e144710b302525 Thomas Gleixner           2010-10-01   51   * @pending_mask:	pending rebalanced interrupts
b5faba21a6805c Thomas Gleixner           2011-02-23   52   * @threads_oneshot:	bitfield to handle shared oneshot threads
e144710b302525 Thomas Gleixner           2010-10-01   53   * @threads_active:	number of irqaction threads currently running
e144710b302525 Thomas Gleixner           2010-10-01   54   * @wait_for_threads:	wait queue for sync_irq to wait for threaded handlers
cab303be91dc47 Thomas Gleixner           2014-08-28   55   * @nr_actions:		number of installed actions on this descriptor
cab303be91dc47 Thomas Gleixner           2014-08-28   56   * @no_suspend_depth:	number of irqactions on a irq descriptor with
cab303be91dc47 Thomas Gleixner           2014-08-28   57   *			IRQF_NO_SUSPEND set
cab303be91dc47 Thomas Gleixner           2014-08-28   58   * @force_resume_depth:	number of irqactions on a irq descriptor with
cab303be91dc47 Thomas Gleixner           2014-08-28   59   *			IRQF_FORCE_RESUME set
425a5072dcd1bd Thomas Gleixner           2015-12-13   60   * @rcu:		rcu head for delayed free
ecb3f394c5dba8 Craig Gallek              2016-09-13   61   * @kobj:		kobject used to represent this struct in sysfs
9114014cf4e6df Thomas Gleixner           2017-06-29   62   * @request_mutex:	mutex to protect request/free before locking desc->lock
e144710b302525 Thomas Gleixner           2010-10-01   63   * @dir:		/proc/irq/ procfs entry
087cdfb662ae50 Thomas Gleixner           2017-06-20   64   * @debugfs_file:	dentry for the debugfs file
e144710b302525 Thomas Gleixner           2010-10-01   65   * @name:		flow handler name for /proc/interrupts output
e144710b302525 Thomas Gleixner           2010-10-01   66   */
e144710b302525 Thomas Gleixner           2010-10-01   67  struct irq_desc {
0d0b4c866bcce6 Jiang Liu                 2015-06-01  @68  	struct irq_common_data	irq_common_data;
e144710b302525 Thomas Gleixner           2010-10-01  @69  	struct irq_data		irq_data;
86d2a2f51fbada Bitao Hu                  2024-04-11   70  	struct irqstat __percpu	*kstat_irqs;
e144710b302525 Thomas Gleixner           2010-10-01  @71  	irq_flow_handler_t	handle_irq;
e144710b302525 Thomas Gleixner           2010-10-01   72  	struct irqaction	*action;	/* IRQ action list */
a6967caf00ebbb Thomas Gleixner           2011-02-10   73  	unsigned int		status_use_accessors;
dbec07bac614a6 Thomas Gleixner           2011-02-07   74  	unsigned int		core_internal_state__do_not_mess_with_it;
e144710b302525 Thomas Gleixner           2010-10-01   75  	unsigned int		depth;		/* nested irq disables */
e144710b302525 Thomas Gleixner           2010-10-01   76  	unsigned int		wake_depth;	/* nested wake enables */
1136b072896990 Thomas Gleixner           2019-02-08   77  	unsigned int		tot_count;
e144710b302525 Thomas Gleixner           2010-10-01   78  	unsigned int		irq_count;	/* For detecting broken IRQs */
e144710b302525 Thomas Gleixner           2010-10-01   79  	unsigned long		last_unhandled;	/* Aging timer for unhandled count */
e144710b302525 Thomas Gleixner           2010-10-01   80  	unsigned int		irqs_unhandled;
1e77d0a1ed7417 Thomas Gleixner           2013-03-07   81  	atomic_t		threads_handled;
1e77d0a1ed7417 Thomas Gleixner           2013-03-07   82  	int			threads_handled_last;
e144710b302525 Thomas Gleixner           2010-10-01   83  	raw_spinlock_t		lock;
31d9d9b6d83030 Marc Zyngier              2011-09-23   84  	struct cpumask		*percpu_enabled;
222df54fd8b764 Marc Zyngier              2016-04-11   85  	const struct cpumask	*percpu_affinity;
e144710b302525 Thomas Gleixner           2010-10-01   86  #ifdef CONFIG_SMP
e144710b302525 Thomas Gleixner           2010-10-01   87  	const struct cpumask	*affinity_hint;
cd7eab44e9946c Ben Hutchings             2011-01-19   88  	struct irq_affinity_notify *affinity_notify;
e144710b302525 Thomas Gleixner           2010-10-01   89  #ifdef CONFIG_GENERIC_PENDING_IRQ
e144710b302525 Thomas Gleixner           2010-10-01   90  	cpumask_var_t		pending_mask;
e144710b302525 Thomas Gleixner           2010-10-01   91  #endif
e144710b302525 Thomas Gleixner           2010-10-01   92  #endif
b5faba21a6805c Thomas Gleixner           2011-02-23   93  	unsigned long		threads_oneshot;
e144710b302525 Thomas Gleixner           2010-10-01   94  	atomic_t		threads_active;
e144710b302525 Thomas Gleixner           2010-10-01   95  	wait_queue_head_t       wait_for_threads;
cab303be91dc47 Thomas Gleixner           2014-08-28   96  #ifdef CONFIG_PM_SLEEP
cab303be91dc47 Thomas Gleixner           2014-08-28   97  	unsigned int		nr_actions;
cab303be91dc47 Thomas Gleixner           2014-08-28   98  	unsigned int		no_suspend_depth;
17f480342026e5 Rafael J. Wysocki         2015-02-27   99  	unsigned int		cond_suspend_depth;
cab303be91dc47 Thomas Gleixner           2014-08-28  100  	unsigned int		force_resume_depth;
cab303be91dc47 Thomas Gleixner           2014-08-28  101  #endif
e144710b302525 Thomas Gleixner           2010-10-01  102  #ifdef CONFIG_PROC_FS
e144710b302525 Thomas Gleixner           2010-10-01  103  	struct proc_dir_entry	*dir;
425a5072dcd1bd Thomas Gleixner           2015-12-13  104  #endif
087cdfb662ae50 Thomas Gleixner           2017-06-20  105  #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
087cdfb662ae50 Thomas Gleixner           2017-06-20  106  	struct dentry		*debugfs_file;
07557ccb8c83f3 Thomas Gleixner           2017-09-13  107  	const char		*dev_name;
087cdfb662ae50 Thomas Gleixner           2017-06-20  108  #endif
425a5072dcd1bd Thomas Gleixner           2015-12-13  109  #ifdef CONFIG_SPARSE_IRQ
425a5072dcd1bd Thomas Gleixner           2015-12-13  110  	struct rcu_head		rcu;
ecb3f394c5dba8 Craig Gallek              2016-09-13  111  	struct kobject		kobj;
e144710b302525 Thomas Gleixner           2010-10-01  112  #endif
9114014cf4e6df Thomas Gleixner           2017-06-29  113  	struct mutex		request_mutex;
293a7a0a165c4f Thomas Gleixner           2012-10-16  114  	int			parent_irq;
b6873807a7143b Sebastian Andrzej Siewior 2011-07-11  115  	struct module		*owner;
e144710b302525 Thomas Gleixner           2010-10-01  116  	const char		*name;
bc06a9e0874239 Shanker Donthineni        2023-05-19  117  #ifdef CONFIG_HARDIRQS_SW_RESEND
bc06a9e0874239 Shanker Donthineni        2023-05-19  118  	struct hlist_node	resend_node;
bc06a9e0874239 Shanker Donthineni        2023-05-19  119  #endif
e144710b302525 Thomas Gleixner           2010-10-01  120  } ____cacheline_internodealigned_in_smp;
e144710b302525 Thomas Gleixner           2010-10-01  121  
a899418167264c Thomas Gleixner           2015-07-05  122  #ifdef CONFIG_SPARSE_IRQ
a899418167264c Thomas Gleixner           2015-07-05  123  extern void irq_lock_sparse(void);
a899418167264c Thomas Gleixner           2015-07-05  124  extern void irq_unlock_sparse(void);
a899418167264c Thomas Gleixner           2015-07-05  125  #else
a899418167264c Thomas Gleixner           2015-07-05  126  static inline void irq_lock_sparse(void) { }
a899418167264c Thomas Gleixner           2015-07-05  127  static inline void irq_unlock_sparse(void) { }
e144710b302525 Thomas Gleixner           2010-10-01  128  extern struct irq_desc irq_desc[NR_IRQS];
e144710b302525 Thomas Gleixner           2010-10-01  129  #endif
e144710b302525 Thomas Gleixner           2010-10-01  130  
501e2db67fa426 Thomas Gleixner           2020-12-10  131  static inline unsigned int irq_desc_kstat_cpu(struct irq_desc *desc,
501e2db67fa426 Thomas Gleixner           2020-12-10  132  					      unsigned int cpu)
501e2db67fa426 Thomas Gleixner           2020-12-10  133  {
86d2a2f51fbada Bitao Hu                  2024-04-11  134  	return desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, cpu) : 0;
501e2db67fa426 Thomas Gleixner           2020-12-10  135  }
501e2db67fa426 Thomas Gleixner           2020-12-10  136  
7bbf1dd24b17b9 Jiang Liu                 2015-06-01  137  static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
7bbf1dd24b17b9 Jiang Liu                 2015-06-01  138  {
755d119a620497 Thomas Gleixner           2015-09-16 @139  	return container_of(data->common, struct irq_desc, irq_common_data);
7bbf1dd24b17b9 Jiang Liu                 2015-06-01  140  }
7bbf1dd24b17b9 Jiang Liu                 2015-06-01  141  
304adf8a8fff97 Jiang Liu                 2015-06-04  142  static inline unsigned int irq_desc_get_irq(struct irq_desc *desc)
304adf8a8fff97 Jiang Liu                 2015-06-04  143  {
304adf8a8fff97 Jiang Liu                 2015-06-04  144  	return desc->irq_data.irq;
304adf8a8fff97 Jiang Liu                 2015-06-04  145  }
304adf8a8fff97 Jiang Liu                 2015-06-04  146  
d9936bb3952a08 Thomas Gleixner           2011-03-11  147  static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc)
d9936bb3952a08 Thomas Gleixner           2011-03-11  148  {
d9936bb3952a08 Thomas Gleixner           2011-03-11  149  	return &desc->irq_data;
d9936bb3952a08 Thomas Gleixner           2011-03-11  150  }
d9936bb3952a08 Thomas Gleixner           2011-03-11  151  
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  152  static inline struct irq_chip *irq_desc_get_chip(struct irq_desc *desc)
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  153  {
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  154  	return desc->irq_data.chip;
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  155  }
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  156  
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  157  static inline void *irq_desc_get_chip_data(struct irq_desc *desc)
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  158  {
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  159  	return desc->irq_data.chip_data;
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  160  }
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  161  
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  162  static inline void *irq_desc_get_handler_data(struct irq_desc *desc)
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  163  {
af7080e040d223 Jiang Liu                 2015-06-01  164  	return desc->irq_common_data.handler_data;
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  165  }
a0cd9ca2b907d7 Thomas Gleixner           2011-02-10  166  
e144710b302525 Thomas Gleixner           2010-10-01  167  /*
e144710b302525 Thomas Gleixner           2010-10-01  168   * Architectures call this to let the generic IRQ layer
6584d84c3e504c Huang Shijie              2015-09-01  169   * handle an interrupt.
e144710b302525 Thomas Gleixner           2010-10-01  170   */
bd0b9ac405e179 Thomas Gleixner           2015-09-14  171  static inline void generic_handle_irq_desc(struct irq_desc *desc)
e144710b302525 Thomas Gleixner           2010-10-01  172  {
bd0b9ac405e179 Thomas Gleixner           2015-09-14 @173  	desc->handle_irq(desc);
e144710b302525 Thomas Gleixner           2010-10-01  174  }
e144710b302525 Thomas Gleixner           2010-10-01  175  
a3016b26ee6ee1 Marc Zyngier              2021-05-04  176  int handle_irq_desc(struct irq_desc *desc);
fe12bc2c996d3e Thomas Gleixner           2011-05-18  177  int generic_handle_irq(unsigned int irq);
509853f9e1e7b1 Sebastian Andrzej Siewior 2022-02-11  178  int generic_handle_irq_safe(unsigned int irq);
e144710b302525 Thomas Gleixner           2010-10-01  179  
e1c054918c6c7a Marc Zyngier              2021-05-12  180  #ifdef CONFIG_IRQ_DOMAIN
76ba59f8366f2d Marc Zyngier              2014-08-26  181  /*
76ba59f8366f2d Marc Zyngier              2014-08-26  182   * Convert a HW interrupt number to a logical one using a IRQ domain,
76ba59f8366f2d Marc Zyngier              2014-08-26  183   * and handle the result interrupt number. Return -EINVAL if
9626d18a20e166 Marc Zyngier              2021-05-04  184   * conversion failed.
76ba59f8366f2d Marc Zyngier              2014-08-26  185   */
8240ef50d48643 Marc Zyngier              2021-05-12  186  int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq);
6a164c64699984 Sebastian Andrzej Siewior 2022-05-09  187  int generic_handle_domain_irq_safe(struct irq_domain *domain, unsigned int hwirq);
0953fb263714e1 Mark Rutland              2021-10-20  188  int generic_handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq);
76ba59f8366f2d Marc Zyngier              2014-08-26  189  #endif
76ba59f8366f2d Marc Zyngier              2014-08-26  190  
e144710b302525 Thomas Gleixner           2010-10-01  191  /* Test to see if a driver has successfully requested an irq */
f61ae4fb66a4f7 Thomas Gleixner           2015-08-02  192  static inline int irq_desc_has_action(struct irq_desc *desc)
e144710b302525 Thomas Gleixner           2010-10-01  193  {
a313357e704f26 Thomas Gleixner           2020-12-10  194  	return desc && desc->action != NULL;
f61ae4fb66a4f7 Thomas Gleixner           2015-08-02  195  }
f61ae4fb66a4f7 Thomas Gleixner           2015-08-02  196  
bbc9d21fc0071c Thomas Gleixner           2015-06-23  197  /**
bbc9d21fc0071c Thomas Gleixner           2015-06-23  198   * irq_set_handler_locked - Set irq handler from a locked region
bbc9d21fc0071c Thomas Gleixner           2015-06-23  199   * @data:	Pointer to the irq_data structure which identifies the irq
bbc9d21fc0071c Thomas Gleixner           2015-06-23  200   * @handler:	Flow control handler function for this interrupt
bbc9d21fc0071c Thomas Gleixner           2015-06-23  201   *
bbc9d21fc0071c Thomas Gleixner           2015-06-23  202   * Sets the handler in the irq descriptor associated to @data.
bbc9d21fc0071c Thomas Gleixner           2015-06-23  203   *
bbc9d21fc0071c Thomas Gleixner           2015-06-23  204   * Must be called with irq_desc locked and valid parameters. Typical
bbc9d21fc0071c Thomas Gleixner           2015-06-23  205   * call site is the irq_set_type() callback.
bbc9d21fc0071c Thomas Gleixner           2015-06-23  206   */
bbc9d21fc0071c Thomas Gleixner           2015-06-23  207  static inline void irq_set_handler_locked(struct irq_data *data,
bbc9d21fc0071c Thomas Gleixner           2015-06-23  208  					  irq_flow_handler_t handler)
bbc9d21fc0071c Thomas Gleixner           2015-06-23  209  {
bbc9d21fc0071c Thomas Gleixner           2015-06-23  210  	struct irq_desc *desc = irq_data_to_desc(data);
bbc9d21fc0071c Thomas Gleixner           2015-06-23  211  
bbc9d21fc0071c Thomas Gleixner           2015-06-23  212  	desc->handle_irq = handler;
bbc9d21fc0071c Thomas Gleixner           2015-06-23  213  }
bbc9d21fc0071c Thomas Gleixner           2015-06-23  214  
bbc9d21fc0071c Thomas Gleixner           2015-06-23  215  /**
bbc9d21fc0071c Thomas Gleixner           2015-06-23  216   * irq_set_chip_handler_name_locked - Set chip, handler and name from a locked region
bbc9d21fc0071c Thomas Gleixner           2015-06-23  217   * @data:	Pointer to the irq_data structure for which the chip is set
bbc9d21fc0071c Thomas Gleixner           2015-06-23  218   * @chip:	Pointer to the new irq chip
bbc9d21fc0071c Thomas Gleixner           2015-06-23  219   * @handler:	Flow control handler function for this interrupt
bbc9d21fc0071c Thomas Gleixner           2015-06-23  220   * @name:	Name of the interrupt
bbc9d21fc0071c Thomas Gleixner           2015-06-23  221   *
bbc9d21fc0071c Thomas Gleixner           2015-06-23  222   * Replace the irq chip at the proper hierarchy level in @data and
bbc9d21fc0071c Thomas Gleixner           2015-06-23  223   * sets the handler and name in the associated irq descriptor.
bbc9d21fc0071c Thomas Gleixner           2015-06-23  224   *
bbc9d21fc0071c Thomas Gleixner           2015-06-23  225   * Must be called with irq_desc locked and valid parameters.
bbc9d21fc0071c Thomas Gleixner           2015-06-23  226   */
bbc9d21fc0071c Thomas Gleixner           2015-06-23  227  static inline void
ef6e5d61eb7a0a Michael Walle             2022-07-06  228  irq_set_chip_handler_name_locked(struct irq_data *data,
ef6e5d61eb7a0a Michael Walle             2022-07-06  229  				 const struct irq_chip *chip,
bbc9d21fc0071c Thomas Gleixner           2015-06-23  230  				 irq_flow_handler_t handler, const char *name)
bbc9d21fc0071c Thomas Gleixner           2015-06-23  231  {
bbc9d21fc0071c Thomas Gleixner           2015-06-23  232  	struct irq_desc *desc = irq_data_to_desc(data);
bbc9d21fc0071c Thomas Gleixner           2015-06-23  233  
bbc9d21fc0071c Thomas Gleixner           2015-06-23  234  	desc->handle_irq = handler;
bbc9d21fc0071c Thomas Gleixner           2015-06-23  235  	desc->name = name;
ef6e5d61eb7a0a Michael Walle             2022-07-06 @236  	data->chip = (struct irq_chip *)chip;
bbc9d21fc0071c Thomas Gleixner           2015-06-23  237  }
bbc9d21fc0071c Thomas Gleixner           2015-06-23  238  
fdd029630434b4 Thomas Gleixner           2020-12-10  239  bool irq_check_status_bit(unsigned int irq, unsigned int bitmask);
fdd029630434b4 Thomas Gleixner           2020-12-10  240  
4ce413d1840b25 Will Deacon               2017-12-01  241  static inline bool irq_balancing_disabled(unsigned int irq)
e144710b302525 Thomas Gleixner           2010-10-01  242  {
fdd029630434b4 Thomas Gleixner           2020-12-10 @243  	return irq_check_status_bit(irq, IRQ_NO_BALANCING_MASK);
e144710b302525 Thomas Gleixner           2010-10-01  244  }
781295762defc7 Thomas Gleixner           2011-02-10  245  
4ce413d1840b25 Will Deacon               2017-12-01  246  static inline bool irq_is_percpu(unsigned int irq)
7f4a8e7b1943c1 Vinayak Kale              2013-12-04  247  {
fdd029630434b4 Thomas Gleixner           2020-12-10 @248  	return irq_check_status_bit(irq, IRQ_PER_CPU);
7f4a8e7b1943c1 Vinayak Kale              2013-12-04  249  }
7f4a8e7b1943c1 Vinayak Kale              2013-12-04  250  
4ce413d1840b25 Will Deacon               2017-12-01  251  static inline bool irq_is_percpu_devid(unsigned int irq)
08395c7f4d9f58 Julien Thierry            2017-10-13  252  {
fdd029630434b4 Thomas Gleixner           2020-12-10 @253  	return irq_check_status_bit(irq, IRQ_PER_CPU_DEVID);
08395c7f4d9f58 Julien Thierry            2017-10-13  254  }
08395c7f4d9f58 Julien Thierry            2017-10-13  255  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From guoren at kernel.org  Fri Nov 29 08:05:31 2024
From: guoren at kernel.org (Guo Ren)
Date: Sat, 30 Nov 2024 00:05:31 +0800
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <CAJF2gTR8qhnjv0VNCy+DeWck84MioeAZ3iEuNqSjM81KigNEwA@mail.gmail.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com> <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck> <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr> <20241128-goggles-laundry-d94c23ab39a4@spud>
 <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>
 <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com>
 <CAJF2gTSX82rGp-9xZHvg1Y3SpO516YCcqSBLKFgWEQ5G-iWR4A@mail.gmail.com>
 <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com> <CAJF2gTR8qhnjv0VNCy+DeWck84MioeAZ3iEuNqSjM81KigNEwA@mail.gmail.com>
Message-ID: <CAJF2gTQKS7F+_6F+zTLtHWcBQZxDUsuoP8=ithxdAav6mhpz4Q@mail.gmail.com>

Hi Alexandre & Conor

On Fri, Nov 29, 2024 at 8:50?PM Guo Ren <guoren at kernel.org> wrote:
>
> On Fri, Nov 29, 2024 at 6:32?PM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
> >
> > Hi everyone,
> >
> > On Fri, Nov 29, 2024 at 7:28?AM Guo Ren <guoren at kernel.org> wrote:
> > >
> > > Hi Conor & Alexandre,
> > >
> > > On Fri, Nov 29, 2024 at 10:58?AM Guo Ren <guoren at kernel.org> wrote:
> > > >
> > > > On Fri, Nov 29, 2024 at 8:55?AM Guo Ren <guoren at kernel.org> wrote:
> > > > >
> > > > > On Fri, Nov 29, 2024 at 12:19?AM Conor Dooley <conor at kernel.org> wrote:
> > > > > >
> > > > > > On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> > > > > > > On 28/11/2024 15:14, Conor Dooley wrote:
> > > > > > > > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > > > > > > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > > > > > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > > > > > > > In order to produce a generic kernel, a user can select
> > > > > > > > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > > > > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > > > > > > >
> > > > > > > > > > > Note that we can't use alternatives here because the discovery of
> > > > > > > > > > > extensions is done too late and we need to start with the qspinlock
> > > > > > > > > > > implementation because the ticket spinlock implementation would pollute
> > > > > > > > > > > the spinlock value, so let's use static keys.
> > > > > > > > > > >
> > > > > > > > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > > > > > > >
> > > > > > > > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > > > > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > > > > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > > > > > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > > > > > > > console. My .config has:
> > > > > > > > > >
> > > > > > > > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > > > > > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > > > > > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > > > > > > > I pointed out some of the fragility during review:
> > > > > > > > >
> > > > > > > > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > > > > > > >
> > > > > > > > > so I'm kinda surprised it got merged tbh :/
> > > > > > > > Maybe it could be reverted rather than having a broken boot with the
> > > > > > > > default settings in -rc1.
> > > > > > >
> > > > > > >
> > > > > > > No need to rush before we know what's happening,I guess you bisected to this
> > > > > > > commit right?
> > > > > >
> > > > > > The symptom is a failure to boot, without any console output, of course
> > > > > > I bisected it before blaming something specific. But I don't think it is
> > > > > > "rushing" as having -rc1 broken with an option's default is a massive pain
> > > > > > in the arse when it comes to testing.
> > > > > >
> > > > > > > I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> > > > > > > kernel, anything?
> > > > > >
> > > > > > I don't have the former cos it died immediately on boot. config is
> > > > > > attached. It reproduces in QEMU so you don't need any hardware.
> > > > > If QEMU could reproduce, could you provide a dmesg by the below method?
> > > > >
> > > > > Qemu cmd append: -s -S
> > > > > ref: https://qemu-project.gitlab.io/qemu/system/gdb.html
> > > > >
> > > > > Connect gdb and in console:
> > > > > 1. file vmlinux
> > > > > 2. source ./Documentation/admin-guide/kdump/gdbmacros.txt
> > > > > 3. dmesg
> > > > >
> > > > > Then, we could get the kernel's early boot logs from memory.
> > > > I've reproduced it on qemu, thx for the config.
> > > >
> > > > Reading symbols from ../build-rv64lp64/vmlinux...
> > > > (gdb) tar rem:1234
> > > > Remote debugging using :1234
> > > > ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > > 49              atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
> > > > (gdb) bt
> > > > #0  ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > > #1  arch_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/arch/riscv/include/asm/spinlock.h:28
> > > > #2  do_raw_spin_lock (lock=lock at entry=0xffffffff81b9a5b8 <text_mutex>)
> > > > at /home/guoren/source/kernel/linux/kernel/locking/spinlock_debug.c:116
> > > > #3  0xffffffff80b2ea0e in __raw_spin_lock_irqsave
> > > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/include/linux/spinlock_api_smp.h:111
> > > > #4  _raw_spin_lock_irqsave (lock=lock at entry=0xffffffff81b9a5b8
> > > > <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/spinlock.c:162
> > > > #5  0xffffffff80b27c54 in rt_mutex_slowtrylock
> > > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1393
> > > > #6  0xffffffff80b295ea in rt_mutex_try_acquire
> > > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:319
> > > > #7  __rt_mutex_lock (state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1805
> > > > #8  __mutex_lock_common (ip=18446744071562135170, nest_lock=0x0,
> > > > subclass=0, state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:518
> > > > #9  mutex_lock_nested (lock=0xffffffff81b9a5b8 <text_mutex>,
> > > > subclass=subclass at entry=0) at
> > > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:529
> > > > #10 0xffffffff80010682 in arch_jump_label_transform_queue
> > > > (entry=entry at entry=0xffffffff8158da28, type=<optimized out>) at
> > > > /home/guoren/source/kernel/linux/arch/riscv/kernel/jump_label.c:39
> > > > #11 0xffffffff801d86b2 in __jump_label_update
> > > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>,
> > > > entry=0xffffffff8158da28, stop=stop at entry=0xffffffff815a5e68
> > > > <__tracepoint_ptr_initcall_finish>, init=init at entry=true)
> > > >     at /home/guoren/source/kernel/linux/kernel/jump_label.c:513
> > > > #12 0xffffffff801d890c in jump_label_update
> > > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > > /home/guoren/source/kernel/linux/kernel/jump_label.c:920
> > > > #13 0xffffffff801d8be8 in static_key_disable_cpuslocked
> > > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > > /home/guoren/source/kernel/linux/kernel/jump_label.c:240
> > > > #14 0xffffffff801d8c04 in static_key_disable
> > > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > > /home/guoren/source/kernel/linux/kernel/jump_label.c:248
> > > > #15 0xffffffff80c04a1a in riscv_spinlock_init () at
> > > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:271
> > > > #16 setup_arch (cmdline_p=cmdline_p at entry=0xffffffff81a03e88) at
> > > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:336
> > > > #17 0xffffffff80c007a2 in start_kernel () at
> > > > /home/guoren/source/kernel/linux/init/main.c:922
> > > > #18 0xffffffff80001164 in _start_kernel ()
> > > > Backtrace stopped: frame did not save the PC
> > > > (gdb) p /x lock
> > > > $1 = 0xffffffff81b9a5b8
> > > > (gdb) p /x *lock
> > > > $2 = {{val = {counter = 0x20000}, {locked = 0x0, pending = 0x0},
> > > > {locked_pending = 0x0, tail = 0x2}}}
> > >
> > > I have for you here a fast fixup for reference. (PS: I'm digging into
> > > the root cause mentioned by Will Deacon.)
> > >
> > > diff --git a/arch/riscv/include/asm/text-patching.h
> > > b/arch/riscv/include/asm/text-patching.h
> > > index 7228e266b9a1..0439609f1cff 100644
> > > --- a/arch/riscv/include/asm/text-patching.h
> > > +++ b/arch/riscv/include/asm/text-patching.h
> > > @@ -12,5 +12,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len);
> > >  int patch_text(void *addr, u32 *insns, size_t len);
> > >
> > >  extern int riscv_patch_in_stop_machine;
> > > +extern int riscv_patch_in_spinlock_init;
> > >
> > >  #endif /* _ASM_RISCV_PATCH_H */
> > > diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
> > > index 6eee6f736f68..d9a5a5c1933d 100644
> > > --- a/arch/riscv/kernel/jump_label.c
> > > +++ b/arch/riscv/kernel/jump_label.c
> > > @@ -36,9 +36,11 @@ bool arch_jump_label_transform_queue(struct
> > > jump_entry *entry,
> > >                 insn = RISCV_INSN_NOP;
> > >         }
> > >
> > > -       mutex_lock(&text_mutex);
> > > +       if (!riscv_patch_in_spinlock_init)
> > > +               mutex_lock(&text_mutex);
> > >         patch_insn_write(addr, &insn, sizeof(insn));
> > > -       mutex_unlock(&text_mutex);
> > > +       if (!riscv_patch_in_spinlock_init)
> > > +               mutex_unlock(&text_mutex);
> > >
> > >         return true;
> > >  }
> > > diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
> > > index db13c9ddf9e3..ab009cf855c2 100644
> > > --- a/arch/riscv/kernel/patch.c
> > > +++ b/arch/riscv/kernel/patch.c
> > > @@ -24,6 +24,7 @@ struct patch_insn {
> > >  };
> > >
> > >  int riscv_patch_in_stop_machine = false;
> > > +int riscv_patch_in_spinlock_init = false;
> > >
> > >  #ifdef CONFIG_MMU
> > >
> > > @@ -131,7 +132,7 @@ static int __patch_insn_write(void *addr, const
> > > void *insn, size_t len)
> > >          * safe but triggers a lockdep failure, so just elide it for that
> > >          * specific case.
> > >          */
> > > -       if (!riscv_patch_in_stop_machine)
> > > +       if (!riscv_patch_in_stop_machine && !riscv_patch_in_spinlock_init)
> > >                 lockdep_assert_held(&text_mutex);
> > >
> > >         preempt_disable();
> > > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > > index 016b48fcd6f2..87ddf1702be4 100644
> > > --- a/arch/riscv/kernel/setup.c
> > > +++ b/arch/riscv/kernel/setup.c
> > > @@ -268,7 +268,9 @@ static void __init riscv_spinlock_init(void)
> > >         }
> > >  #if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
> > >         else {
> > > +               riscv_patch_in_spinlock_init = 1;
> > >                 static_branch_disable(&qspinlock_key);
> > > +               riscv_patch_in_spinlock_init = 0;
> > >                 pr_info("Ticket spinlock: enabled\n");
> > >                 return;
> > >         }
> > >
> > >
> > >
> > > --
> > > Best Regards
> > >  Guo Ren
> >
> > Thanks Guo for looking into this.
> >
> > Your solution is not very pretty but I don't have anything better :/
> > Unless introducing a static_branch_XXX_nolock() API? I gave it a try
> > and it fixes the issue, but not sure this will be accepted.
> >
> > The thing is the usage of static branches is temporary, we'll use
> > alternatives when I finish working on getting the extensions very
> > early from the ACPI tables (I have a poc that works, just needs some
> > cleaning).
> >
> > So let's say that I make this early extension parsing my priority for
> > 6.14, can we live with Guo's hack in this release? Or should we revert
> > this commit?
> I almost get the root cause. Please give me a while.
Here is the root cause (CONFIG_RT_MUTEXES=y):

When CONFIG_RT_MUTEXES=y, rt_mutex_try_acquire would change from
rt_mutex_cmpxchg_acquire to rt_mutex_slowtrylock.

rt_mutex_slowtrylock()
        *raw_spin_lock_irqsave(&lock->wait_lock, flags);*
        ret = __rt_mutex_slowtrylock(lock);
        *raw_spin_unlock_irqrestore(&lock->wait_lock, flags);*

Because queued_spin_#ops to ticket_#ops is changed one by one by
jump_label, spinlock usage would cause a deadlock during the change.

That means in arch/riscv/kernel/jump_label.c:
arch_jump_label_transform_queue() ->
mutex_lock(&text_mutex); -> raw_spin_lock  -> queued_spin_lock
                                         | -> raw_spin_unlock ->
queued_spin_unlock
patch_insn_write -> change the raw_spin_lock to ticket_lock
mutex_unlock(&text_mutex);
...
arch_jump_label_transform_queue() ->
mutex_lock(&text_mutex); -> raw_spin_lock -> ticket_lock
                                         | -> raw_spin_unlock; ->
queued_spin_unlock // *cause the problem*
patch_insn_write  ->  change the raw_spin_unlock to ticket_unlock
mutex_unlock(&text_mutex);
...
arch_jump_label_transform_queue() ->
mutex_lock(&text_mutex); -> raw_spin_lock -> ticket_lock // *deadlock*
                                         | -> raw_spin_unlock -> ticket_unlock
patch_insn_write -> change other raw_spin_#op -> ticket_#op
mutex_unlock(&text_mutex);

So, the solution is to disable mutex usage of
arch_jump_label_transform_queue() during spinlock_init, just like we
have done for stop_machine.

Ps:
The plan of improvement (remove the jump_label):
Use the Alternative to improve the performance of combo_spinlock's
ticket_lock (there is no branch jump for ticket_lock) and reduce its
code size.

--
Best Regards
 Guo Ren


From patchwork-bot+netdevbpf at kernel.org  Fri Nov 29 08:20:30 2024
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 29 Nov 2024 16:20:30 +0000
Subject: [PATCH bpf v2] tools: Override makefile ARCH variable if defined,
 but empty
In-Reply-To: <20241127101748.165693-1-bjorn@kernel.org>
References: <20241127101748.165693-1-bjorn@kernel.org>
Message-ID: <173289723001.2112878.15562925301764191816.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to bpf/bpf.git (master)
by Daniel Borkmann <daniel at iogearbox.net>:

On Wed, 27 Nov 2024 11:17:46 +0100 you wrote:
> From: Bj?rn T?pel <bjorn at rivosinc.com>
> 
> There are a number of tools (bpftool, selftests), that require a
> "bootstrap" build. Here, a bootstrap build is a build host variant of
> a target. E.g., assume that you're performing a bpftool cross-build on
> x86 to riscv, a bootstrap build would then be an x86 variant of
> bpftool. The typical way to perform the host build variant, is to pass
> "ARCH=" in a sub-make. However, if a variable has been set with a
> command argument, then ordinary assignments in the makefile are
> ignored.
> 
> [...]

Here is the summary with links:
  - [bpf,v2] tools: Override makefile ARCH variable if defined, but empty
    https://git.kernel.org/bpf/bpf/c/537a2525eaf7

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From conor at kernel.org  Fri Nov 29 08:29:14 2024
From: conor at kernel.org (Conor Dooley)
Date: Fri, 29 Nov 2024 16:29:14 +0000
Subject: [PATCH] riscv: Rewrite AMO instructions via lr and sc.
In-Reply-To: <20241129144319.74257-1-arikalo@gmail.com>
References: <20241129144319.74257-1-arikalo@gmail.com>
Message-ID: <20241129-antivirus-blunderer-efcbd49cfeb6@spud>

Hey,

On Fri, Nov 29, 2024 at 03:43:19PM +0100, Aleksandar Rikalo wrote:
> From: Chao-ying Fu <cfu at mips.com>
> 
> Use lr and sc to implement all atomic functions. Some CPUs have
> native support for lr and sc, but emulate AMO instructions through
> trap handlers that are slow.
> 
> Add config RISCV_ISA_ZALRSC_ONLY.
> 
> Signed-off-by: Chao-ying Fu <cfu at mips.com>
> Signed-off-by: Aleksandar Rikalo <arikalo at gmail.com>
> ---
>  arch/riscv/Kconfig               | 10 ++++++
>  arch/riscv/include/asm/atomic.h  | 52 +++++++++++++++++++++++++++++++-
>  arch/riscv/include/asm/bitops.h  | 45 +++++++++++++++++++++++++++
>  arch/riscv/include/asm/cmpxchg.h | 16 ++++++++++
>  arch/riscv/include/asm/futex.h   | 46 ++++++++++++++++++++++++++++
>  5 files changed, 168 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index cc63aef41e94..767538c27875 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -715,6 +715,16 @@ config RISCV_ISA_ZACAS
>  
>  	  If you don't know what to do here, say Y.
>  
> +config RISCV_ISA_ZALRSC_ONLY
> +	bool "Zalrsc extension support only"

I don't agree with the naming of and description for this option.
From the description below I'd imagine that you only care about a
platform where use of AMO instructions is only undesirable, but overall
the option implies that it can be used to build a kernel that can be
used on systems that only implement Zalrsc, which, even with your patch
applied, it cannot. I think, if we are going to merge something like this,
we should go the whole way and permit platforms that don't even emulate
the a extension. If not, the Kconfig option should be explicitly clear
that the a extension is still mandatory.

> +	default n

"default n" is the default, you shouldn't need this line.

> +	help
> +	   Use lr and sc to build all atomic functions. Some CPUs have
> +	   native support for lr and sc, but emulate amo instructions through
> +	   trap handlers that are slow.

Since you mention trap handlers here, it sounds like it may not be the
CPU itself that emulates it, but rather firmware?

Cheers,
Conor.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-riscv/attachments/20241129/2ca9e1ca/attachment.sig>

From helgaas at kernel.org  Fri Nov 29 11:50:00 2024
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 29 Nov 2024 13:50:00 -0600
Subject: [PATCH 2/5] PCI: sg2042: Add Sophgo SG2042 PCIe driver
In-Reply-To: <MAXPR01MB3984C307B163E615811A25AAFE2A2@MAXPR01MB3984.INDPRD01.PROD.OUTLOOK.COM>
Message-ID: <20241129195000.GA2770247@bhelgaas>

On Fri, Nov 29, 2024 at 05:51:39PM +0800, Chen Wang wrote:
> On 2024/11/13 5:20, Bjorn Helgaas wrote:
> > On Mon, Nov 11, 2024 at 01:59:56PM +0800, Chen Wang wrote:
> > > From: Chen Wang <unicorn_wang at outlook.com>
> > > 
> > > Add support for PCIe controller in SG2042 SoC. The controller
> > > uses the Cadence PCIe core programmed by pcie-cadence*.c. The
> > > PCIe controller will work in host mode only.
> > > +++ b/drivers/pci/controller/cadence/Kconfig
> > > @@ -67,4 +67,15 @@ config PCI_J721E_EP
> > >   	  Say Y here if you want to support the TI J721E PCIe platform
> > >   	  controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe
> > >   	  core.
> > > +
> > > +config PCIE_SG2042
> > > +	bool "Sophgo SG2042 PCIe controller (host mode)"
> > > +	depends on ARCH_SOPHGO || COMPILE_TEST
> > > +	depends on OF
> > > +	select PCIE_CADENCE_HOST
> > > +	help
> > > +	  Say Y here if you want to support the Sophgo SG2042 PCIe platform
> > > +	  controller in host mode. Sophgo SG2042 PCIe controller uses Cadence
> > > +	  PCIe core.
> >
> > Reorder to keep these menu items in alphabetical order by vendor.
> 
> Sorry, I don't understand your question. I think the menu items in this
> Kconfig file are already sorted alphabetically.

Here's what menuconfig looks like after this patch:

  [*] Cadence platform PCIe controller (host mode)
  [*] Cadence platform PCIe controller (endpoint mode)
  [*] TI J721E PCIe controller (host mode)
  [*] TI J721E PCIe controller (endpoint mode)
  [ ] Sophgo SG2042 PCIe controller (host mode) (NEW)

"Sophgo" sorts *before* "TI".

> > > +	if (pcie->link_id == 1) {
> > > +		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_LOW,
> > > +			     lower_32_bits(pcie->msi_phys));
> > > +		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_HIGH,
> > > +			     upper_32_bits(pcie->msi_phys));
> > > +
> > > +		regmap_read(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, &value);
> > > +		value = (value & REG_LINK1_MSI_ADDR_SIZE_MASK) | MAX_MSI_IRQS;
> > > +		regmap_write(pcie->syscon, REG_LINK1_MSI_ADDR_SIZE, value);
> > > +	} else {
> > > +		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_LOW,
> > > +			     lower_32_bits(pcie->msi_phys));
> > > +		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_HIGH,
> > > +			     upper_32_bits(pcie->msi_phys));
> > > +
> > > +		regmap_read(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, &value);
> > > +		value = (value & REG_LINK0_MSI_ADDR_SIZE_MASK) | (MAX_MSI_IRQS << 16);
> > > +		regmap_write(pcie->syscon, REG_LINK0_MSI_ADDR_SIZE, value);
> > > +	}
> >
> > Lot of pcie->link_id checking going on here.  Consider saving these
> > offsets in the struct sg2042_pcie so you don't need to test
> > everywhere.
> 
> Actually, there are not many places in the code to check link_id. If to add
> storage information in struct sg2042_pcie, at least four? u32 are needed.
> And this logic will only be called one time in the probe. So I think it is
> better to keep the current method. What do you think?

1) I don't think "link_id" is a very good name since it appears to
refer to one of two PCIe Root Ports.  mvebu uses "marvell,pcie-port"
which looks like a similar usage, although unnecessarily
Marvell-specific.  And arch/arm/boot/dts/marvell/armada-370-db.dts has
separate stanzas for two Root Ports, without needing a property to
distinguish them, which would be even better.  I'm not sure why
arch/arm/boot/dts/marvell/armada-370.dtsi needs "marvell,pcie-port"
even though it also has separate stanzas.

2) I think checking pcie->link_id is likely to be harder to maintain
in the future, e.g., if a new chip adds more Root Ports, you'll have
to touch each use.

Bjorn


From guoren at kernel.org  Fri Nov 29 16:40:01 2024
From: guoren at kernel.org (Guo Ren)
Date: Sat, 30 Nov 2024 08:40:01 +0800
Subject: [PATCH v6 13/13] riscv: Add qspinlock support
In-Reply-To: <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com>
References: <20241103145153.105097-1-alexghiti@rivosinc.com>
 <20241103145153.105097-14-alexghiti@rivosinc.com> <20241128-whoever-wildfire-2a3110c5fd46@wendy>
 <20241128134135.GA3460@willie-the-truck> <20241128-uncivil-removed-4e105d1397c9@wendy>
 <90533aa9-186a-4f75-b3c5-d93d6682056b@ghiti.fr> <20241128-goggles-laundry-d94c23ab39a4@spud>
 <CAJF2gTST0kduYpuqd4mX0byetWMRJT-AAyH0GGiaysZG64Byhw@mail.gmail.com>
 <CAJF2gTRQg=w3sGN0Sdzf+_adRo44z4H6Zd6=C6qXq+ARR5BjSg@mail.gmail.com>
 <CAJF2gTSX82rGp-9xZHvg1Y3SpO516YCcqSBLKFgWEQ5G-iWR4A@mail.gmail.com> <CAHVXubgXiD5Bi6ytyDHXXOONovWHZTSvr4+oADCvuic5ObGXpQ@mail.gmail.com>
Message-ID: <CAJF2gTQwYTGinBmCSgVUoPv0_q4EPt_+WiyfUA1HViAKgUzxAg@mail.gmail.com>

On Fri, Nov 29, 2024 at 6:32?PM Alexandre Ghiti <alexghiti at rivosinc.com> wrote:
>
> Hi everyone,
>
> On Fri, Nov 29, 2024 at 7:28?AM Guo Ren <guoren at kernel.org> wrote:
> >
> > Hi Conor & Alexandre,
> >
> > On Fri, Nov 29, 2024 at 10:58?AM Guo Ren <guoren at kernel.org> wrote:
> > >
> > > On Fri, Nov 29, 2024 at 8:55?AM Guo Ren <guoren at kernel.org> wrote:
> > > >
> > > > On Fri, Nov 29, 2024 at 12:19?AM Conor Dooley <conor at kernel.org> wrote:
> > > > >
> > > > > On Thu, Nov 28, 2024 at 03:50:09PM +0100, Alexandre Ghiti wrote:
> > > > > > On 28/11/2024 15:14, Conor Dooley wrote:
> > > > > > > On Thu, Nov 28, 2024 at 01:41:36PM +0000, Will Deacon wrote:
> > > > > > > > On Thu, Nov 28, 2024 at 12:56:55PM +0000, Conor Dooley wrote:
> > > > > > > > > On Sun, Nov 03, 2024 at 03:51:53PM +0100, Alexandre Ghiti wrote:
> > > > > > > > > > In order to produce a generic kernel, a user can select
> > > > > > > > > > CONFIG_COMBO_SPINLOCKS which will fallback at runtime to the ticket
> > > > > > > > > > spinlock implementation if Zabha or Ziccrse are not present.
> > > > > > > > > >
> > > > > > > > > > Note that we can't use alternatives here because the discovery of
> > > > > > > > > > extensions is done too late and we need to start with the qspinlock
> > > > > > > > > > implementation because the ticket spinlock implementation would pollute
> > > > > > > > > > the spinlock value, so let's use static keys.
> > > > > > > > > >
> > > > > > > > > > This is largely based on Guo's work and Leonardo reviews at [1].
> > > > > > > > > >
> > > > > > > > > > Link: https://lore.kernel.org/linux-riscv/20231225125847.2778638-1-guoren at kernel.org/ [1]
> > > > > > > > > > Signed-off-by: Guo Ren <guoren at kernel.org>
> > > > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti at rivosinc.com>
> > > > > > > > > This patch (now commit ab83647fadae2 ("riscv: Add qspinlock support"))
> > > > > > > > > breaks boot on polarfire soc. It dies before outputting anything to the
> > > > > > > > > console. My .config has:
> > > > > > > > >
> > > > > > > > > # CONFIG_RISCV_TICKET_SPINLOCKS is not set
> > > > > > > > > # CONFIG_RISCV_QUEUED_SPINLOCKS is not set
> > > > > > > > > CONFIG_RISCV_COMBO_SPINLOCKS=y
> > > > > > > > I pointed out some of the fragility during review:
> > > > > > > >
> > > > > > > > https://lore.kernel.org/all/20241111164259.GA20042 at willie-the-truck/
> > > > > > > >
> > > > > > > > so I'm kinda surprised it got merged tbh :/
> > > > > > > Maybe it could be reverted rather than having a broken boot with the
> > > > > > > default settings in -rc1.
> > > > > >
> > > > > >
> > > > > > No need to rush before we know what's happening,I guess you bisected to this
> > > > > > commit right?
> > > > >
> > > > > The symptom is a failure to boot, without any console output, of course
> > > > > I bisected it before blaming something specific. But I don't think it is
> > > > > "rushing" as having -rc1 broken with an option's default is a massive pain
> > > > > in the arse when it comes to testing.
> > > > >
> > > > > > I don't have this soc, so can you provide $stval/$sepc/$scause, a config, a
> > > > > > kernel, anything?
> > > > >
> > > > > I don't have the former cos it died immediately on boot. config is
> > > > > attached. It reproduces in QEMU so you don't need any hardware.
> > > > If QEMU could reproduce, could you provide a dmesg by the below method?
> > > >
> > > > Qemu cmd append: -s -S
> > > > ref: https://qemu-project.gitlab.io/qemu/system/gdb.html
> > > >
> > > > Connect gdb and in console:
> > > > 1. file vmlinux
> > > > 2. source ./Documentation/admin-guide/kdump/gdbmacros.txt
> > > > 3. dmesg
> > > >
> > > > Then, we could get the kernel's early boot logs from memory.
> > > I've reproduced it on qemu, thx for the config.
> > >
> > > Reading symbols from ../build-rv64lp64/vmlinux...
> > > (gdb) tar rem:1234
> > > Remote debugging using :1234
> > > ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > 49              atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
> > > (gdb) bt
> > > #0  ticket_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/include/asm-generic/ticket_spinlock.h:49
> > > #1  arch_spin_lock (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/arch/riscv/include/asm/spinlock.h:28
> > > #2  do_raw_spin_lock (lock=lock at entry=0xffffffff81b9a5b8 <text_mutex>)
> > > at /home/guoren/source/kernel/linux/kernel/locking/spinlock_debug.c:116
> > > #3  0xffffffff80b2ea0e in __raw_spin_lock_irqsave
> > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/include/linux/spinlock_api_smp.h:111
> > > #4  _raw_spin_lock_irqsave (lock=lock at entry=0xffffffff81b9a5b8
> > > <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/spinlock.c:162
> > > #5  0xffffffff80b27c54 in rt_mutex_slowtrylock
> > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1393
> > > #6  0xffffffff80b295ea in rt_mutex_try_acquire
> > > (lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:319
> > > #7  __rt_mutex_lock (state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex.c:1805
> > > #8  __mutex_lock_common (ip=18446744071562135170, nest_lock=0x0,
> > > subclass=0, state=2, lock=0xffffffff81b9a5b8 <text_mutex>) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:518
> > > #9  mutex_lock_nested (lock=0xffffffff81b9a5b8 <text_mutex>,
> > > subclass=subclass at entry=0) at
> > > /home/guoren/source/kernel/linux/kernel/locking/rtmutex_api.c:529
> > > #10 0xffffffff80010682 in arch_jump_label_transform_queue
> > > (entry=entry at entry=0xffffffff8158da28, type=<optimized out>) at
> > > /home/guoren/source/kernel/linux/arch/riscv/kernel/jump_label.c:39
> > > #11 0xffffffff801d86b2 in __jump_label_update
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>,
> > > entry=0xffffffff8158da28, stop=stop at entry=0xffffffff815a5e68
> > > <__tracepoint_ptr_initcall_finish>, init=init at entry=true)
> > >     at /home/guoren/source/kernel/linux/kernel/jump_label.c:513
> > > #12 0xffffffff801d890c in jump_label_update
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > /home/guoren/source/kernel/linux/kernel/jump_label.c:920
> > > #13 0xffffffff801d8be8 in static_key_disable_cpuslocked
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > /home/guoren/source/kernel/linux/kernel/jump_label.c:240
> > > #14 0xffffffff801d8c04 in static_key_disable
> > > (key=key at entry=0xffffffff81a1abb0 <qspinlock_key>) at
> > > /home/guoren/source/kernel/linux/kernel/jump_label.c:248
> > > #15 0xffffffff80c04a1a in riscv_spinlock_init () at
> > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:271
> > > #16 setup_arch (cmdline_p=cmdline_p at entry=0xffffffff81a03e88) at
> > > /home/guoren/source/kernel/linux/arch/riscv/kernel/setup.c:336
> > > #17 0xffffffff80c007a2 in start_kernel () at
> > > /home/guoren/source/kernel/linux/init/main.c:922
> > > #18 0xffffffff80001164 in _start_kernel ()
> > > Backtrace stopped: frame did not save the PC
> > > (gdb) p /x lock
> > > $1 = 0xffffffff81b9a5b8
> > > (gdb) p /x *lock
> > > $2 = {{val = {counter = 0x20000}, {locked = 0x0, pending = 0x0},
> > > {locked_pending = 0x0, tail = 0x2}}}
> >
> > I have for you here a fast fixup for reference. (PS: I'm digging into
> > the root cause mentioned by Will Deacon.)
> >
> > diff --git a/arch/riscv/include/asm/text-patching.h
> > b/arch/riscv/include/asm/text-patching.h
> > index 7228e266b9a1..0439609f1cff 100644
> > --- a/arch/riscv/include/asm/text-patching.h
> > +++ b/arch/riscv/include/asm/text-patching.h
> > @@ -12,5 +12,6 @@ int patch_text_set_nosync(void *addr, u8 c, size_t len);
> >  int patch_text(void *addr, u32 *insns, size_t len);
> >
> >  extern int riscv_patch_in_stop_machine;
> > +extern int riscv_patch_in_spinlock_init;
> >
> >  #endif /* _ASM_RISCV_PATCH_H */
> > diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
> > index 6eee6f736f68..d9a5a5c1933d 100644
> > --- a/arch/riscv/kernel/jump_label.c
> > +++ b/arch/riscv/kernel/jump_label.c
> > @@ -36,9 +36,11 @@ bool arch_jump_label_transform_queue(struct
> > jump_entry *entry,
> >                 insn = RISCV_INSN_NOP;
> >         }
> >
> > -       mutex_lock(&text_mutex);
> > +       if (!riscv_patch_in_spinlock_init)
> > +               mutex_lock(&text_mutex);
> >         patch_insn_write(addr, &insn, sizeof(insn));
> > -       mutex_unlock(&text_mutex);
> > +       if (!riscv_patch_in_spinlock_init)
> > +               mutex_unlock(&text_mutex);
> >
> >         return true;
> >  }
> > diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
> > index db13c9ddf9e3..ab009cf855c2 100644
> > --- a/arch/riscv/kernel/patch.c
> > +++ b/arch/riscv/kernel/patch.c
> > @@ -24,6 +24,7 @@ struct patch_insn {
> >  };
> >
> >  int riscv_patch_in_stop_machine = false;
> > +int riscv_patch_in_spinlock_init = false;
> >
> >  #ifdef CONFIG_MMU
> >
> > @@ -131,7 +132,7 @@ static int __patch_insn_write(void *addr, const
> > void *insn, size_t len)
> >          * safe but triggers a lockdep failure, so just elide it for that
> >          * specific case.
> >          */
> > -       if (!riscv_patch_in_stop_machine)
> > +       if (!riscv_patch_in_stop_machine && !riscv_patch_in_spinlock_init)
> >                 lockdep_assert_held(&text_mutex);
> >
> >         preempt_disable();
> > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > index 016b48fcd6f2..87ddf1702be4 100644
> > --- a/arch/riscv/kernel/setup.c
> > +++ b/arch/riscv/kernel/setup.c
> > @@ -268,7 +268,9 @@ static void __init riscv_spinlock_init(void)
> >         }
> >  #if defined(CONFIG_RISCV_COMBO_SPINLOCKS)
> >         else {
> > +               riscv_patch_in_spinlock_init = 1;
> >                 static_branch_disable(&qspinlock_key);
> > +               riscv_patch_in_spinlock_init = 0;
> >                 pr_info("Ticket spinlock: enabled\n");
> >                 return;
> >         }
> >
> >
> >
> > --
> > Best Regards
> >  Guo Ren
>
> Thanks Guo for looking into this.
>
> Your solution is not very pretty but I don't have anything better :/
Here is another solution (Only one file modified, maybe better):

diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
index 6eee6f736f68..654ed159c830 100644
--- a/arch/riscv/kernel/jump_label.c
+++ b/arch/riscv/kernel/jump_label.c
@@ -36,9 +36,15 @@ bool arch_jump_label_transform_queue(struct
jump_entry *entry,
                insn = RISCV_INSN_NOP;
        }

-       mutex_lock(&text_mutex);
-       patch_insn_write(addr, &insn, sizeof(insn));
-       mutex_unlock(&text_mutex);
+       if (early_boot_irqs_disabled) {
+               riscv_patch_in_stop_machine = 1;
+               patch_insn_write(addr, &insn, sizeof(insn));
+               riscv_patch_in_stop_machine = 0;
+       } else {
+               mutex_lock(&text_mutex);
+               patch_insn_write(addr, &insn, sizeof(insn));
+               mutex_unlock(&text_mutex);
+       }

        return true;
 }

> Unless introducing a static_branch_XXX_nolock() API? I gave it a try
> and it fixes the issue, but not sure this will be accepted.
>
> The thing is the usage of static branches is temporary, we'll use
> alternatives when I finish working on getting the extensions very
The "alternatives" also need patch codes one by one, which means it
will meet the same problem as the jump_label.

So, you will still provide a patch like the one above for the
alternative implementation.

> early from the ACPI tables (I have a poc that works, just needs some
> cleaning).
>
> So let's say that I make this early extension parsing my priority for
> 6.14, can we live with Guo's hack in this release? Or should we revert
> this commit?
>
> Thanks,
>
> Alex
--
Best Regards
 Guo Ren


From minda.chen at starfivetech.com  Fri Nov 29 23:09:02 2024
From: minda.chen at starfivetech.com (Minda Chen)
Date: Sat, 30 Nov 2024 07:09:02 +0000
Subject: [PATCH v5 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable
 usb0 host function
In-Reply-To: <971ae8a4-1add-45ed-8daf-951aef013e64@freeshell.de>
References: <20241126075740.17419-1-e@freeshell.de>
 <CAJM55Z9wWCaS+FxZ=Gg_RfXXafNEJZC1zHZoPWQ2Y9QYDf9OyA@mail.gmail.com>
 <eb06c8e0-ebda-47b9-94f6-6e6eca21097d@freeshell.de>
 <CAJM55Z_Cy2aAfWY-6csKBuv3AJ44h4fCCvJ0ZSbLOYcKw6g=bA@mail.gmail.com>
 <SHXPR01MB086308813C0B311845FDA2C7E629A@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>
 <971ae8a4-1add-45ed-8daf-951aef013e64@freeshell.de>
Message-ID: <SHXPR01MB0863161110FDD8A8A1152251E62BA@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn>



> -----????-----
> ???: E Shattow <e at freeshell.de>
> ????: 2024?11?28? 16:01
> ???: Minda Chen <minda.chen at starfivetech.com>; Emil Renner Berthing
> <emil.renner.berthing at canonical.com>; Jisheng Zhang <jszhang at kernel.org>
> ??: Emil Renner Berthing <kernel at esmil.dk>; Conor Dooley
> <conor at kernel.org>; Rob Herring <robh at kernel.org>; Krzysztof Kozlowski
> <krzk+dt at kernel.org>; Paul Walmsley <paul.walmsley at sifive.com>; Palmer
> Dabbelt <palmer at dabbelt.com>; Albert Ou <aou at eecs.berkeley.edu>;
> linux-riscv at lists.infradead.org; devicetree at vger.kernel.org;
> linux-kernel at vger.kernel.org; Hal Feng <hal.feng at starfivetech.com>
> ??: Re: [PATCH v5 0/1] riscv: dts: starfive: jh7110-milkv-mars: enable usb0
> host function
> 
> Re-sending my reply plain text not HTML format. -E
> 
> On 11/27/24 17:31, Minda Chen wrote:
> >> E Shattow wrote:
> >>> Hi Emil, thanks for taking time to review!
> >>>
> >>> Added CC: Minda Chen, Hal Feng
> >>>
> >>> Please Minda and Hal can you follow-up on Emil's comments as well?
> >>>
> >>> On 11/27/24 03:00, Emil Renner Berthing wrote:
> >>>> E Shattow wrote:
> >>>>> Enable host mode JH7110 on-chip USB for Milk-V Mars by setting
> >>>>> host mode and connect vbus pinctrl.
> >>>>>
> >>>>> This functionality depends on setting the USB over-current
> >>>>> register to disable at bootloader phase, for example U-Boot:
> >>>>> https://patchwork.ozlabs.org/project/uboot/patch/20241012031328.42
> >>>>> 6
> >>>>> 8-6-minda.chen at starfivetech.com/
> >>>> Hi E,
> >>>>
> >>>> Ideally the JH7110 pinctrl driver would be updated, so Linux can do
> >>>> this itself and doesn't need to rely on u-boot doing it. I already
> >>>> asked for this
> >> here:
> >>
> https://lore.kernel.org/all/CAJM55Z-+Cxdebcn4MLXfQdOVhx4c2SQ+zMH8cjn
> >>>> -Yq35xO8g0A at mail.gmail.com/
> >>> Yes, I agree, and Linux is not the only consumer of devicetree. I
> >>> would like USB function to work for users of Linux and U-Boot on
> >>> these boards by copying what the vendor Board Support Package does
> >>> what is shipped with the products. If it is more in-depth than this
> >>> I will defer to Hal or Minda.
> >>>
> >>>
> >>> For some wider context, upstream U-Boot is about to adopt the
> >>> dt-rebasing via Hal's OF_UPSTREAM for JH7110 boards series and then
> >>> also there is a patch set from Minda Chen to add the on-chip JH7110
> >>> USB support to U-Boot, and so then and there it will depend on these
> >>> dts changes. If you have Milk-V Mars then already there are three of
> >>> four USB-A receptacle ports which are functional on PCIe-connected
> >>> VL805 USB chipset.
> >>>
> >>>>> If the over-current register is not prepared for us then the
> >>>>> result is no change in functional outcome with this patch applied;
> >>>>> there is an error visible to the user and this additional usb
> >>>>> configuration fails (same as it is now). On Milk-V Mars with four
> >>>>> USB-A ports this applies to one of the ports and the remaining
> >>>>> three
> >> VL805-connected ports via PCIe are not changed.
> >>>> Thanks for the patches. I don't quite understand when you write "no
> >>>> change in functional outcome with this patch applied". The USB-C
> >>>> port is already configured as a peripheral, and I just tried
> >>>> setting up an ethernet gadget on my VF2 running 6.12 and that works
> >>>> quite well. Does it not work on the Milk-V Mars board? If it does
> >>>> then these
> >> patches would break that functionality.
> >>>> Here is the script I used for that:
> >>>> https://paste.c-net.org/BravoLonely
> >>>>
> >>>> At the very least you'll need to explain in the commit message
> >>>> itself why changing the USB-C port from peripheral mode to host
> >>>> mode is OK. But ideally maybe you could make it work in OTG mode,
> >>>> so userspace can choose how they want to use the port. The same
> >>>> goes for the
> >> PINE64 board too.
> >>>> /Emil
> >>> USB-C port on Mars is not wired for data here, that is only true for
> >>> VisionFive2. If the user wants to use their USB-A receptacle as OTG
> >>> port I will not object to a future improvement, but here we want the
> >>> basic expectations of users covered that they should have four
> >>> working USB-A receptacle ports in U-Boot (and possibly in Linux,
> >>> depending on the overcurrent register wherever it is set). This is
> >>> what I am meaning, there may be somebody using a male-male USB-A
> >>> USB-A cable for OTG but more likely is that people just want to plug
> >>> in USB peripherals to host ports and use their mouse / keyboard /
> >>> flash memory, I
> >> think.
> >>
> >> You're right, sorry. I'm so used to the JH7110 boards being similar,
> >> but this is actually one of the few differences between the Mars and
> >> VF2 that was not caught when the Mars dts was first upstreamed.
> >>
> >> Yes, with 4 similar USB-A ports you'd definitely expect all of them
> >> to work in host mode. With an explanation like the above in the
> >> commit message I (now) think your changes makes sense.
> >>
> >> Thanks!
> >> /Emil
> >>
> Hi Minda, thanks for taking time to review and explain the multiple USB
> configurations.
> 
> > Thanks. E Shadow
> >
> > The USB and PCIe0 setting in some JH7110 boards.
> >                   PCIe0
> cadence USB controller
> > VF2:       connect with VL805 USB3.0 ( 4 USB 3.0 type A ports)
> (USB 2.0)Type C port(role: peripheral)
> > Milkv mars  connect with VL805 USB3.0 ( 3 USB 3.0 type A ports)
> (USB 2.0)1 Type A port (role:host)
> > Milkv cm    PCIe slot											(USB
> 2.0)micro B port (role:host)
> > Star64       disabled?pcie PHY0 connect to cadence USB?         1 usb
> 3.0 port + USB 2.0 hub (role:host)
> >
> > H E Shadow
> > I see you also add star64 USB configuration. I hope also add this to
> > star64 board dts base on V6.13-rc1. Thanks.
> 
> Yes, on Star64 board I see there is one "blue colour" USB-A port and three
> "black colour" USB-A port. The product webpage
> https://wiki.pine64.org/wiki/STAR64 does say "1? USB3.0 Dedicated Host port
> / 3? USB2.0 Host port".
> 
> > &pcie0 {
> > 	status = "disabled";
> > };
> 
> For JH7110 is it allowed to have PCIe0 "okay" PCIe1 "okay" and also have USB
> 2.0?? We disable this PCIe0 here because of JH7110 USB3.0 design on Mars
> and on Star64?? Can JH7110 have USB 3.0 and USB 2.0 together (does
> Star64 do this, or is it USB 2.0 hub attach to JH7110 USB 3.0?)
> 
Now you can see only JH7110 contain 2 pcie 2.0 combo PHY and 1 USB 2.0 PHY
Only PCIe0 PHY can move to Cadence USB 3.0 Controller.
So if enable Cadence USB 3.0 port. Only PCIe1 can be used.
Two solution
2 PCIe + USB 2.0 eg: VF2/ milk-v mars board.
1 PCIe + USB 3.0/ 2.0 eg: star64/starfive devkits board.

> > &pciephy0 {
> > 	starfive,sys-syscon = <&sys_syscon 0x18>;
> > 	starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>;
> > 	status = "okay";
> > };
> 
> Minda, I need your help to make a good description of these numbers 0x18
> 0x148 0x1f4, for the patch to Linux.
> 
JH7110 syscon/stgcon register offset.
Maybe move this to the PHY code is better.

> 
> First is 'starfive,sys-sycon':
> 
> JH7110 Technical Reference Manual, Table 7. "SYS SYSCONSAIF SYSCFG 24
> Register Description"
> 
> https://doc-en.rvspace.org/JH7110/TRM/JH7110_TRM/sys_syscon.html#sys_sys
> con__table_c3l_fqs_wsb
> 
> Register SYS SYSCONSAIF SYSCFG 24 at offset 0x18 why is this needed?
> Your patch series for Linux 6.12 "Fix configuration for on-chip USB 2.0
> support"
> 
> https://lore.kernel.org/lkml/20241015070444.20972-1-minda.chen at starfivete
> ch.com/
> 
> changes u0_pdrstn_split_sw_usbpipe_plugen in the driver and why do we
> need this now in the Star64 USB 3.0 dts for Linux 6.13?? Is this needed
> for USB function only u0_pdrstn_split_sw_usbpipe_plugen or is more from
> this register important here ?? And, can you make an explanation so I
> can learn what is the purpose of "u0_pdrstn_split_sw_usbpipe_plugen" or
> any other part of this register we need here (for USB)?
> 
The bit mean split pcie PHY from cadence USB. So if use USB 2.0 only. The bit
must be set. But if PHY connect to Cadence USB. The bit must be cleared.
I think the bit should reset to 1 for the PHY default connect to PCIe but the reset
Value is 0. And it is a little issue in JH7110 IC.

> 
> Next is 'stg-syscon':
> 
> JH7110 Technical Reference Manual, Table 82. "STG SYSCONSAIF SYSCFG 328
> Register Description"
> 
> https://doc-en.rvspace.org/JH7110/TRM/JH7110_TRM/stg_syscon.html#stg_sy
> scon__table_mc4_n5s_wsb
> 
> Register STG SYSCONSAIF SYSCFG 328 at offset 0x148 what is this?
> Something PCIe?? Does this have to do with wires on the board going from
> USB-A port to PCIe? What is the explanation why we need this for USB?
> 
> 
> JH7110 Technical Reference Manual, Table 125. "STG SYSCONSAIF SYSCFG 500
> Register Description"
> 
> https://doc-en.rvspace.org/JH7110/TRM/JH7110_TRM/stg_syscon.html#stg_sy
> scon__table_njd_45s_wsb
> 
> Register STG SYSCONSAIF SYSCFG 500 at offset 0x1f4 is more usb3 bitfield
> names, what is a general description why this is needed? Is this "all
> the Cadence IP USB3 things" ?
> 
The USB 3.0 PHY stg syscon setting. To make Cadence USB 3.0 work. Must set
Some syscon register.  It is belong to JH7110 IC.
You can check this in PCIe PHY code.

> The documentation devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml
> is not enough information to make a good description. "Total 2 registers
> offset" is a description of the place where the numbers exist for the
> schema but does not say if there is an ordering first,last and the
> expected register names in JH7110 TRM.? Is there more than one
> possibility? or else, will it 100% be exactly STG SYSCONSAIF SYSCFG
> registers 328 and 500 at offsets 0x148 and 0x1f4?
> 
> 
> > &usb0 {
> > 	pinctrl-names = "default";
> > 	pinctrl-0 = <&usb_pins>;
> > 	dr_mode = "host";
> > 	status = "okay";
> > };
> >
> > &usb_cdns3 {
> > 	phys = <&usbphy0>, <&pciephy0>;
> > 	phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy";
> > };
> >
> >>> There is no USB-C port on Star64.
> >>>
> >>>>> Changes since v4:
> >>>>>    - Rebase on latest master
> >>>>>
> >>>>> Changes since v3:
> >>>>>    - Rebase on linux-next/master
> >>>>>    - use tabs for code indent
> >>>>>
> >>>>> Changes since v2:
> >>>>>    - Rebase on 6.12
> >>>>>
> >>>>> E Shattow (1):
> >>>>>     riscv: dts: starfive: jh7110-milkv-mars: enable usb0 host
> >>>>> function
> >>>>>
> >>>>>    .../boot/dts/starfive/jh7110-milkv-mars.dts    | 18
> >> +++++++++++++++++-
> >>>>>    1 file changed, 17 insertions(+), 1 deletion(-)
> >>>>>
> >>>>> --
> >>>>> 2.45.2
> >>>>>
> >>> Thanks again Emil.? -E
> >>>
> 
> For Emil, my patches of Star64 and Mars are limited in scope to do the
> work of turning up host mode and adding the necessary vbus GPIO
> assignment;? so it's not wrong, and given the advice from Minda it's
> also not the complete support for all USB-A ports that I would like. I
> can extend this series to also include this adjacent USB 3.0
> configuration, or follow up in another series that is specific in topic
> for USB 3.0? Where I'm at on this is the host mode and GPIO
> configuration clearly belongs in dts but I have questions about this
> additional (USB 3.0 specific) configuration. And if we do, what do you
> think about the addition of syscon register offset values in devicetree,
> should they be #define'd somewhere? When it is the vbus GPIO there's
> literal sequential number of GPIO's so I did not find it was any problem
> to use the value. But, when I read "0x1f4" I think, what is that?
> 
> 
> Best regards,
> 
> -E Shattow "Shadow"


From dan.carpenter at linaro.org  Sat Nov 30 02:07:23 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Sat, 30 Nov 2024 13:07:23 +0300
Subject: [PATCH] mailbox: mpfs: fix copy and paste bug in probe
Message-ID: <9e760329-80ed-4bf7-8d4f-dbb16a736497@stanley.mountain>

This code accidentally checks ->ctrl_base instead of ->mbox_base so the
error handling can never be triggered.

Fixes: a4123ffab9ec ("mailbox: mpfs: support new, syscon based, devicetree configuration")
Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>
---
 drivers/mailbox/mailbox-mpfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
index 4df546e3b7ea..d5d9effece97 100644
--- a/drivers/mailbox/mailbox-mpfs.c
+++ b/drivers/mailbox/mailbox-mpfs.c
@@ -251,7 +251,7 @@ static inline int mpfs_mbox_syscon_probe(struct mpfs_mbox *mbox, struct platform
 		return PTR_ERR(mbox->sysreg_scb);
 
 	mbox->mbox_base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(mbox->ctrl_base))
+	if (IS_ERR(mbox->mbox_base))
 		return PTR_ERR(mbox->mbox_base);
 
 	return 0;
-- 
2.45.2



From dan.carpenter at linaro.org  Sat Nov 30 02:07:39 2024
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Sat, 30 Nov 2024 13:07:39 +0300
Subject: [PATCH] mailbox: th1520: Fix a NULL vs IS_ERR() bug
Message-ID: <bda05d7b-5a6e-4f57-a124-ba56f51da031@stanley.mountain>

The devm_ioremap() function doesn't return error pointers, it returns
NULL.  Update the error checking to match.

Fixes: 5d4d263e1c6b ("mailbox: Introduce support for T-head TH1520 Mailbox driver")
Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>
---
 drivers/mailbox/mailbox-th1520.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mailbox/mailbox-th1520.c b/drivers/mailbox/mailbox-th1520.c
index 4e84640ac3b8..e16e7c85ee3c 100644
--- a/drivers/mailbox/mailbox-th1520.c
+++ b/drivers/mailbox/mailbox-th1520.c
@@ -387,8 +387,10 @@ static void __iomem *th1520_map_mmio(struct platform_device *pdev,
 
 	mapped = devm_ioremap(&pdev->dev, res->start + offset,
 			      resource_size(res) - offset);
-	if (IS_ERR(mapped))
+	if (!mapped) {
 		dev_err(&pdev->dev, "Failed to map resource: %s\n", res_name);
+		return ERR_PTR(-ENOMEM);
+	}
 
 	return mapped;
 }
-- 
2.45.2



From guoren at kernel.org  Sat Nov 30 03:53:55 2024
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 30 Nov 2024 06:53:55 -0500
Subject: [PATCH] riscv: Fixup boot failure when CONFIG_RT_MUTEXES=y
Message-ID: <20241130115355.3316160-1-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

When CONFIG_RT_MUTEXES=y, mutex_lock->rt_mutex_try_acquire would
change from rt_mutex_cmpxchg_acquire to rt_mutex_slowtrylock():
	raw_spin_lock_irqsave(&lock->wait_lock, flags);
	ret = __rt_mutex_slowtrylock(lock);
	raw_spin_unlock_irqrestore(&lock->wait_lock, flags);

Because queued_spin_#ops to ticket_#ops is changed one by one by
jump_label, raw_spin_lock/unlock would cause a deadlock during the
changing.

That means in arch/riscv/kernel/jump_label.c:
1.
arch_jump_label_transform_queue() ->
mutex_lock(&text_mutex); +-> raw_spin_lock  -> queued_spin_lock
			 |-> raw_spin_unlock -> queued_spin_unlock
patch_insn_write -> change the raw_spin_lock to ticket_lock
mutex_unlock(&text_mutex);
...

2. /* Dirty the lock value */
arch_jump_label_transform_queue() ->
mutex_lock(&text_mutex); +-> raw_spin_lock -> *ticket_lock*
                         |-> raw_spin_unlock -> *queued_spin_unlock*
			  /* BUG: ticket_lock with queued_spin_unlock */
patch_insn_write  ->  change the raw_spin_unlock to ticket_unlock
mutex_unlock(&text_mutex);
...

3. /* Dead lock */
arch_jump_label_transform_queue() ->
mutex_lock(&text_mutex); +-> raw_spin_lock -> ticket_lock /* deadlock! */
                         |-> raw_spin_unlock -> ticket_unlock
patch_insn_write -> change other raw_spin_#op -> ticket_#op
mutex_unlock(&text_mutex);

So, the solution is to disable mutex usage of
arch_jump_label_transform_queue() during early_boot_irqs_disabled, just
like we have done for stop_machine.

Reported-by: Conor Dooley <conor at kernel.org>
Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Fixes: ab83647fadae ("riscv: Add qspinlock support")
Link: https://lore.kernel.org/linux-riscv/CAJF2gTQwYTGinBmCSgVUoPv0_q4EPt_+WiyfUA1HViAKgUzxAg at mail.gmail.com/T/#mf488e6347817fca03bb93a7d34df33d8615b3775
Cc: Palmer Dabbelt <palmer at dabbelt.com>
Cc: Alexandre Ghiti <alexghiti at rivosinc.com>
---
 arch/riscv/kernel/jump_label.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
index 6eee6f736f68..654ed159c830 100644
--- a/arch/riscv/kernel/jump_label.c
+++ b/arch/riscv/kernel/jump_label.c
@@ -36,9 +36,15 @@ bool arch_jump_label_transform_queue(struct jump_entry *entry,
 		insn = RISCV_INSN_NOP;
 	}
 
-	mutex_lock(&text_mutex);
-	patch_insn_write(addr, &insn, sizeof(insn));
-	mutex_unlock(&text_mutex);
+	if (early_boot_irqs_disabled) {
+		riscv_patch_in_stop_machine = 1;
+		patch_insn_write(addr, &insn, sizeof(insn));
+		riscv_patch_in_stop_machine = 0;
+	} else {
+		mutex_lock(&text_mutex);
+		patch_insn_write(addr, &insn, sizeof(insn));
+		mutex_unlock(&text_mutex);
+	}
 
 	return true;
 }
-- 
2.40.1



From guoren at kernel.org  Sat Nov 30 04:02:30 2024
From: guoren at kernel.org (Guo Ren)
Date: Sat, 30 Nov 2024 20:02:30 +0800
Subject: [PATCH] riscv: Fixup boot failure when CONFIG_RT_MUTEXES=y
In-Reply-To: <20241130115355.3316160-1-guoren@kernel.org>
References: <20241130115355.3316160-1-guoren@kernel.org>
Message-ID: <CAJF2gTQhfr-wsj2VZwwP7sWq=yp9HtT_kzzr68xh1VpKLSbybQ@mail.gmail.com>

On Sat, Nov 30, 2024 at 7:54?PM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> When CONFIG_RT_MUTEXES=y, mutex_lock->rt_mutex_try_acquire would
Correct: CONFIG_DEBUG_RT_MUTEXES=y

> change from rt_mutex_cmpxchg_acquire to rt_mutex_slowtrylock():
>         raw_spin_lock_irqsave(&lock->wait_lock, flags);
>         ret = __rt_mutex_slowtrylock(lock);
>         raw_spin_unlock_irqrestore(&lock->wait_lock, flags);
>
> Because queued_spin_#ops to ticket_#ops is changed one by one by
> jump_label, raw_spin_lock/unlock would cause a deadlock during the
> changing.
>
> That means in arch/riscv/kernel/jump_label.c:
> 1.
> arch_jump_label_transform_queue() ->
> mutex_lock(&text_mutex); +-> raw_spin_lock  -> queued_spin_lock
>                          |-> raw_spin_unlock -> queued_spin_unlock
> patch_insn_write -> change the raw_spin_lock to ticket_lock
> mutex_unlock(&text_mutex);
> ...
>
> 2. /* Dirty the lock value */
> arch_jump_label_transform_queue() ->
> mutex_lock(&text_mutex); +-> raw_spin_lock -> *ticket_lock*
>                          |-> raw_spin_unlock -> *queued_spin_unlock*
>                           /* BUG: ticket_lock with queued_spin_unlock */
> patch_insn_write  ->  change the raw_spin_unlock to ticket_unlock
> mutex_unlock(&text_mutex);
> ...
>
> 3. /* Dead lock */
> arch_jump_label_transform_queue() ->
> mutex_lock(&text_mutex); +-> raw_spin_lock -> ticket_lock /* deadlock! */
>                          |-> raw_spin_unlock -> ticket_unlock
> patch_insn_write -> change other raw_spin_#op -> ticket_#op
> mutex_unlock(&text_mutex);
>
> So, the solution is to disable mutex usage of
> arch_jump_label_transform_queue() during early_boot_irqs_disabled, just
> like we have done for stop_machine.
>
> Reported-by: Conor Dooley <conor at kernel.org>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Fixes: ab83647fadae ("riscv: Add qspinlock support")
> Link: https://lore.kernel.org/linux-riscv/CAJF2gTQwYTGinBmCSgVUoPv0_q4EPt_+WiyfUA1HViAKgUzxAg at mail.gmail.com/T/#mf488e6347817fca03bb93a7d34df33d8615b3775
> Cc: Palmer Dabbelt <palmer at dabbelt.com>
> Cc: Alexandre Ghiti <alexghiti at rivosinc.com>
> ---
>  arch/riscv/kernel/jump_label.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
> index 6eee6f736f68..654ed159c830 100644
> --- a/arch/riscv/kernel/jump_label.c
> +++ b/arch/riscv/kernel/jump_label.c
> @@ -36,9 +36,15 @@ bool arch_jump_label_transform_queue(struct jump_entry *entry,
>                 insn = RISCV_INSN_NOP;
>         }
>
> -       mutex_lock(&text_mutex);
> -       patch_insn_write(addr, &insn, sizeof(insn));
> -       mutex_unlock(&text_mutex);
> +       if (early_boot_irqs_disabled) {
> +               riscv_patch_in_stop_machine = 1;
> +               patch_insn_write(addr, &insn, sizeof(insn));
> +               riscv_patch_in_stop_machine = 0;
> +       } else {
> +               mutex_lock(&text_mutex);
> +               patch_insn_write(addr, &insn, sizeof(insn));
> +               mutex_unlock(&text_mutex);
> +       }
>
>         return true;
>  }
> --
> 2.40.1
>


-- 
Best Regards
 Guo Ren


From Markus.Elfring at web.de  Sat Nov 30 04:34:23 2024
From: Markus.Elfring at web.de (Markus Elfring)
Date: Sat, 30 Nov 2024 13:34:23 +0100
Subject: [PATCH] mailbox: th1520: Fix a NULL vs IS_ERR() bug
In-Reply-To: <bda05d7b-5a6e-4f57-a124-ba56f51da031@stanley.mountain>
References: <bda05d7b-5a6e-4f57-a124-ba56f51da031@stanley.mountain>
Message-ID: <6fd72d7d-8a6d-46b0-a7aa-08111093738a@web.de>

> The devm_ioremap() function doesn't return error pointers, it returns
> NULL.  Update the error checking to match.

  on execution failure?


Regards,
Markus


From guoren at kernel.org  Sat Nov 30 07:33:10 2024
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 30 Nov 2024 10:33:10 -0500
Subject: [RESEND PATCH] riscv: Fixup boot failure when CONFIG_DEBUG_RT_MUTEXES=y
Message-ID: <20241130153310.3349484-1-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

When CONFIG_DEBUG_RT_MUTEXES=y, mutex_lock->rt_mutex_try_acquire
would change from rt_mutex_cmpxchg_acquire to
rt_mutex_slowtrylock():
	raw_spin_lock_irqsave(&lock->wait_lock, flags);
	ret = __rt_mutex_slowtrylock(lock);
	raw_spin_unlock_irqrestore(&lock->wait_lock, flags);

Because queued_spin_#ops to ticket_#ops is changed one by one by
jump_label, raw_spin_lock/unlock would cause a deadlock during the
changing.

That means in arch/riscv/kernel/jump_label.c:
1.
arch_jump_label_transform_queue() ->
mutex_lock(&text_mutex); +-> raw_spin_lock  -> queued_spin_lock
			 |-> raw_spin_unlock -> queued_spin_unlock
patch_insn_write -> change the raw_spin_lock to ticket_lock
mutex_unlock(&text_mutex);
...

2. /* Dirty the lock value */
arch_jump_label_transform_queue() ->
mutex_lock(&text_mutex); +-> raw_spin_lock -> *ticket_lock*
                         |-> raw_spin_unlock -> *queued_spin_unlock*
			  /* BUG: ticket_lock with queued_spin_unlock */
patch_insn_write  ->  change the raw_spin_unlock to ticket_unlock
mutex_unlock(&text_mutex);
...

3. /* Dead lock */
arch_jump_label_transform_queue() ->
mutex_lock(&text_mutex); +-> raw_spin_lock -> ticket_lock /* deadlock! */
                         |-> raw_spin_unlock -> ticket_unlock
patch_insn_write -> change other raw_spin_#op -> ticket_#op
mutex_unlock(&text_mutex);

So, the solution is to disable mutex usage of
arch_jump_label_transform_queue() during early_boot_irqs_disabled, just
like we have done for stop_machine.

Reported-by: Conor Dooley <conor at kernel.org>
Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Fixes: ab83647fadae ("riscv: Add qspinlock support")
Link: https://lore.kernel.org/linux-riscv/CAJF2gTQwYTGinBmCSgVUoPv0_q4EPt_+WiyfUA1HViAKgUzxAg at mail.gmail.com/T/#mf488e6347817fca03bb93a7d34df33d8615b3775
Cc: Palmer Dabbelt <palmer at dabbelt.com>
Cc: Alexandre Ghiti <alexghiti at rivosinc.com>
---
 arch/riscv/kernel/jump_label.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
index 6eee6f736f68..654ed159c830 100644
--- a/arch/riscv/kernel/jump_label.c
+++ b/arch/riscv/kernel/jump_label.c
@@ -36,9 +36,15 @@ bool arch_jump_label_transform_queue(struct jump_entry *entry,
 		insn = RISCV_INSN_NOP;
 	}
 
-	mutex_lock(&text_mutex);
-	patch_insn_write(addr, &insn, sizeof(insn));
-	mutex_unlock(&text_mutex);
+	if (early_boot_irqs_disabled) {
+		riscv_patch_in_stop_machine = 1;
+		patch_insn_write(addr, &insn, sizeof(insn));
+		riscv_patch_in_stop_machine = 0;
+	} else {
+		mutex_lock(&text_mutex);
+		patch_insn_write(addr, &insn, sizeof(insn));
+		mutex_unlock(&text_mutex);
+	}
 
 	return true;
 }
-- 
2.40.1



From guoren at kernel.org  Sat Nov 30 07:36:15 2024
From: guoren at kernel.org (Guo Ren)
Date: Sat, 30 Nov 2024 23:36:15 +0800
Subject: [PATCH] riscv: Fixup boot failure when CONFIG_RT_MUTEXES=y
In-Reply-To: <CAJF2gTQhfr-wsj2VZwwP7sWq=yp9HtT_kzzr68xh1VpKLSbybQ@mail.gmail.com>
References: <20241130115355.3316160-1-guoren@kernel.org> <CAJF2gTQhfr-wsj2VZwwP7sWq=yp9HtT_kzzr68xh1VpKLSbybQ@mail.gmail.com>
Message-ID: <CAJF2gTRcaZhHdETFk9KbL1rUdO-U4dX8Ydta7ViAUQ3unrbScg@mail.gmail.com>

On Sat, Nov 30, 2024 at 8:02?PM Guo Ren <guoren at kernel.org> wrote:
>
> On Sat, Nov 30, 2024 at 7:54?PM <guoren at kernel.org> wrote:
> >
> > From: Guo Ren <guoren at linux.alibaba.com>
> >
> > When CONFIG_RT_MUTEXES=y, mutex_lock->rt_mutex_try_acquire would
> Correct: CONFIG_DEBUG_RT_MUTEXES=y
Abandoned.

Here is the RESEND PATCH:
https://lore.kernel.org/linux-riscv/20241130153310.3349484-1-guoren at kernel.org/

>
> > change from rt_mutex_cmpxchg_acquire to rt_mutex_slowtrylock():
> >         raw_spin_lock_irqsave(&lock->wait_lock, flags);
> >         ret = __rt_mutex_slowtrylock(lock);
> >         raw_spin_unlock_irqrestore(&lock->wait_lock, flags);
> >
> > Because queued_spin_#ops to ticket_#ops is changed one by one by
> > jump_label, raw_spin_lock/unlock would cause a deadlock during the
> > changing.
> >
> > That means in arch/riscv/kernel/jump_label.c:
> > 1.
> > arch_jump_label_transform_queue() ->
> > mutex_lock(&text_mutex); +-> raw_spin_lock  -> queued_spin_lock
> >                          |-> raw_spin_unlock -> queued_spin_unlock
> > patch_insn_write -> change the raw_spin_lock to ticket_lock
> > mutex_unlock(&text_mutex);
> > ...
> >
> > 2. /* Dirty the lock value */
> > arch_jump_label_transform_queue() ->
> > mutex_lock(&text_mutex); +-> raw_spin_lock -> *ticket_lock*
> >                          |-> raw_spin_unlock -> *queued_spin_unlock*
> >                           /* BUG: ticket_lock with queued_spin_unlock */
> > patch_insn_write  ->  change the raw_spin_unlock to ticket_unlock
> > mutex_unlock(&text_mutex);
> > ...
> >
> > 3. /* Dead lock */
> > arch_jump_label_transform_queue() ->
> > mutex_lock(&text_mutex); +-> raw_spin_lock -> ticket_lock /* deadlock! */
> >                          |-> raw_spin_unlock -> ticket_unlock
> > patch_insn_write -> change other raw_spin_#op -> ticket_#op
> > mutex_unlock(&text_mutex);
> >
> > So, the solution is to disable mutex usage of
> > arch_jump_label_transform_queue() during early_boot_irqs_disabled, just
> > like we have done for stop_machine.
> >
> > Reported-by: Conor Dooley <conor at kernel.org>
> > Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> > Signed-off-by: Guo Ren <guoren at kernel.org>
> > Fixes: ab83647fadae ("riscv: Add qspinlock support")
> > Link: https://lore.kernel.org/linux-riscv/CAJF2gTQwYTGinBmCSgVUoPv0_q4EPt_+WiyfUA1HViAKgUzxAg at mail.gmail.com/T/#mf488e6347817fca03bb93a7d34df33d8615b3775
> > Cc: Palmer Dabbelt <palmer at dabbelt.com>
> > Cc: Alexandre Ghiti <alexghiti at rivosinc.com>
> > ---
> >  arch/riscv/kernel/jump_label.c | 12 +++++++++---
> >  1 file changed, 9 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c
> > index 6eee6f736f68..654ed159c830 100644
> > --- a/arch/riscv/kernel/jump_label.c
> > +++ b/arch/riscv/kernel/jump_label.c
> > @@ -36,9 +36,15 @@ bool arch_jump_label_transform_queue(struct jump_entry *entry,
> >                 insn = RISCV_INSN_NOP;
> >         }
> >
> > -       mutex_lock(&text_mutex);
> > -       patch_insn_write(addr, &insn, sizeof(insn));
> > -       mutex_unlock(&text_mutex);
> > +       if (early_boot_irqs_disabled) {
> > +               riscv_patch_in_stop_machine = 1;
> > +               patch_insn_write(addr, &insn, sizeof(insn));
> > +               riscv_patch_in_stop_machine = 0;
> > +       } else {
> > +               mutex_lock(&text_mutex);
> > +               patch_insn_write(addr, &insn, sizeof(insn));
> > +               mutex_unlock(&text_mutex);
> > +       }
> >
> >         return true;
> >  }
> > --
> > 2.40.1
> >
>
>
> --
> Best Regards
>  Guo Ren



-- 
Best Regards
 Guo Ren


From farbere at amazon.com  Sat Nov 30 12:11:42 2024
From: farbere at amazon.com (Eliav Farber)
Date: Sat, 30 Nov 2024 20:11:42 +0000
Subject: [PATCH v5 1/2] kexec: Consolidate machine_kexec_mask_interrupts() implementation
In-Reply-To: <20241130201143.48808-1-farbere@amazon.com>
References: <20241130201143.48808-1-farbere@amazon.com>
Message-ID: <20241130201143.48808-2-farbere@amazon.com>

Consolidate the machine_kexec_mask_interrupts implementation into a common
function located in a new file: kernel/irq/kexec.c. This removes duplicate
implementations from architecture-specific files in arch/arm, arch/arm64,
arch/powerpc, and arch/riscv, reducing code duplication and improving
maintainability.

The new implementation retains architecture-specific behavior for
CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD, which was previously implemented
for ARM64. When enabled (currently for ARM64), it clears the active state
of interrupts forwarded to virtual machines (VMs) before handling other
interrupt masking operations.

Signed-off-by: Eliav Farber <farbere at amazon.com>
---
V4 -> V5:
 - The function machine_kexec_mask_interrupts() has been moved
   from kernel/kexec_core.c to a new file kernel/irq/kexec.c.
 - A new configuration option, GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD, has been
   added.
 - The parameters for the machine_kexec_mask_interrupts() function have
   been defined in reverse Christmas Tree style.
 - The comment explaining the call to irq_set_irqchip_state() has been
   improved for clarity.

 arch/arm/kernel/machine_kexec.c   | 23 ------------------
 arch/arm64/Kconfig                |  1 +
 arch/arm64/kernel/machine_kexec.c | 31 ------------------------
 arch/powerpc/include/asm/kexec.h  |  1 -
 arch/powerpc/kexec/core.c         | 22 -----------------
 arch/powerpc/kexec/core_32.c      |  1 +
 arch/riscv/kernel/machine_kexec.c | 23 ------------------
 include/linux/irq.h               |  3 +++
 kernel/irq/Kconfig                |  9 +++++++
 kernel/irq/Makefile               |  2 +-
 kernel/irq/kexec.c                | 40 +++++++++++++++++++++++++++++++
 11 files changed, 55 insertions(+), 101 deletions(-)
 create mode 100644 kernel/irq/kexec.c

diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 80ceb5bd2680..dd430477e7c1 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -127,29 +127,6 @@ void crash_smp_send_stop(void)
 	cpus_stopped = 1;
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 void machine_crash_shutdown(struct pt_regs *regs)
 {
 	local_irq_disable();
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index d743737bf9ce..359b9dcb35b9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -150,6 +150,7 @@ config ARM64
 	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_IOREMAP
 	select GENERIC_IRQ_IPI
+	select GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IRQ_SHOW_LEVEL
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 82e2203d86a3..6f121a0164a4 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -207,37 +207,6 @@ void machine_kexec(struct kimage *kimage)
 	BUG(); /* Should never get here. */
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-		int ret;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		/*
-		 * First try to remove the active state. If this
-		 * fails, try to EOI the interrupt.
-		 */
-		ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
-
-		if (ret && irqd_irq_inprogress(&desc->irq_data) &&
-		    chip->irq_eoi)
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 /**
  * machine_crash_shutdown - shutdown non-crashing cpus and save registers
  */
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 270ee93a0f7d..601e569303e1 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -61,7 +61,6 @@ struct pt_regs;
 extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
 					  master to copy new code to 0 */
 extern void default_machine_kexec(struct kimage *image);
-extern void machine_kexec_mask_interrupts(void);
 
 void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer,
 			 unsigned long start_address) __noreturn;
diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
index b8333a49ea5d..58a930a47422 100644
--- a/arch/powerpc/kexec/core.c
+++ b/arch/powerpc/kexec/core.c
@@ -22,28 +22,6 @@
 #include <asm/setup.h>
 #include <asm/firmware.h>
 
-void machine_kexec_mask_interrupts(void) {
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 #ifdef CONFIG_CRASH_DUMP
 void machine_crash_shutdown(struct pt_regs *regs)
 {
diff --git a/arch/powerpc/kexec/core_32.c b/arch/powerpc/kexec/core_32.c
index c95f96850c9e..deb28eb44f30 100644
--- a/arch/powerpc/kexec/core_32.c
+++ b/arch/powerpc/kexec/core_32.c
@@ -7,6 +7,7 @@
  * Copyright (C) 2005 IBM Corporation.
  */
 
+#include <linux/irq.h>
 #include <linux/kexec.h>
 #include <linux/mm.h>
 #include <linux/string.h>
diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
index 3c830a6f7ef4..2306ce3e5f22 100644
--- a/arch/riscv/kernel/machine_kexec.c
+++ b/arch/riscv/kernel/machine_kexec.c
@@ -114,29 +114,6 @@ void machine_shutdown(void)
 #endif
 }
 
-static void machine_kexec_mask_interrupts(void)
-{
-	unsigned int i;
-	struct irq_desc *desc;
-
-	for_each_irq_desc(i, desc) {
-		struct irq_chip *chip;
-
-		chip = irq_desc_get_chip(desc);
-		if (!chip)
-			continue;
-
-		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
-			chip->irq_eoi(&desc->irq_data);
-
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
-	}
-}
-
 /*
  * machine_crash_shutdown - Prepare to kexec after a kernel crash
  *
diff --git a/include/linux/irq.h b/include/linux/irq.h
index fa711f80957b..25f51bf3c351 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -694,6 +694,9 @@ extern int irq_chip_request_resources_parent(struct irq_data *data);
 extern void irq_chip_release_resources_parent(struct irq_data *data);
 #endif
 
+/* Disable or mask interrupts during a kernel kexec */
+extern void machine_kexec_mask_interrupts(void);
+
 /* Handling of unhandled and spurious interrupts: */
 extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
 
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 529adb1f5859..5967accb8e87 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -154,3 +154,12 @@ config DEPRECATED_IRQ_CPU_ONOFFLINE
 	bool
 	depends on CAVIUM_OCTEON_SOC
 	default CAVIUM_OCTEON_SOC
+
+config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
+	bool "Clear forwarded VM interrupts during kexec"
+	default n
+	help
+	  When enabled, this option allows the kernel to clear the active state
+	  of interrupts that are forwarded to virtual machines (VMs) during a
+	  machine kexec. For interrupts that are not forwarded, if supported,
+	  the kernel will attempt to trigger an End of Interrupt (EOI).
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
index f19d3080bf11..c0f44c06d69d 100644
--- a/kernel/irq/Makefile
+++ b/kernel/irq/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o
+obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o kexec.o
 obj-$(CONFIG_IRQ_TIMINGS) += timings.o
 ifeq ($(CONFIG_TEST_IRQ_TIMINGS),y)
 	CFLAGS_timings.o += -DDEBUG
diff --git a/kernel/irq/kexec.c b/kernel/irq/kexec.c
new file mode 100644
index 000000000000..0f9548c1708d
--- /dev/null
+++ b/kernel/irq/kexec.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+#include <linux/irqnr.h>
+
+#include "internals.h"
+
+void machine_kexec_mask_interrupts(void)
+{
+	struct irq_desc *desc;
+	unsigned int i;
+
+	for_each_irq_desc(i, desc) {
+		struct irq_chip *chip;
+		int check_eoi = 1;
+
+		chip = irq_desc_get_chip(desc);
+		if (!chip)
+			continue;
+
+		if (IS_ENABLED(CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD)) {
+			/*
+			 * First try to remove the active state from an interrupt which is forwarded
+			 * to a VM. If the interrupt is not forwarded, try to EOI the interrupt.
+			 */
+			check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
+		}
+
+		if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
+			chip->irq_eoi(&desc->irq_data);
+
+		if (chip->irq_mask)
+			chip->irq_mask(&desc->irq_data);
+
+		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
+			chip->irq_disable(&desc->irq_data);
+	}
+}
-- 
2.40.1



From farbere at amazon.com  Sat Nov 30 12:11:41 2024
From: farbere at amazon.com (Eliav Farber)
Date: Sat, 30 Nov 2024 20:11:41 +0000
Subject: [PATCH v5 0/2] Improve interrupt handling during machine kexec
Message-ID: <20241130201143.48808-1-farbere@amazon.com>

This patch series focuses on improving the machine_kexec_mask_interrupts()
function by consolidating its implementation and optimizing its behavior to
avoid redundant interrupt masking.

Patch Summary:
[PATCH v5 1/2] Move machine_kexec_mask_interrupts() to kernel/irq/kexec.c,
               removing duplicate architecture-specific implementations.
[PATCH v5 2/2] Refine machine_kexec_mask_interrupts() to avoid re-masking
               already-masked interrupts, resolving specific warnings
               triggered in GPIO IRQ flows.

Changes between v4 and v5:
 - The function machine_kexec_mask_interrupts() has been moved
   from kernel/kexec_core.c to a new file kernel/irq/kexec.c.
 - A new configuration option, GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD, has been
   added.
 - The parameters for the machine_kexec_mask_interrupts() function have
   been defined in reverse Christmas Tree style.
 - The comment explaining the call to irq_set_irqchip_state() has been
   improved for clarity.
 - The phrase 'This patch' has been removed from the commit message.
 
Changes between v3 and v4:
 - Add missing <linux/irqdesc.h> and <linux/irq.h> includes.

Eliav Farber (2):
  kexec: Consolidate machine_kexec_mask_interrupts() implementation
  kexec: Prevent redundant IRQ masking by checking state before shutdown

 arch/arm/kernel/machine_kexec.c   | 23 --------------------
 arch/arm64/Kconfig                |  1 +
 arch/arm64/kernel/machine_kexec.c | 31 --------------------------
 arch/powerpc/include/asm/kexec.h  |  1 -
 arch/powerpc/kexec/core.c         | 22 -------------------
 arch/powerpc/kexec/core_32.c      |  1 +
 arch/riscv/kernel/machine_kexec.c | 23 --------------------
 include/linux/irq.h               |  3 +++
 kernel/irq/Kconfig                |  9 ++++++++
 kernel/irq/Makefile               |  2 +-
 kernel/irq/kexec.c                | 36 +++++++++++++++++++++++++++++++
 11 files changed, 51 insertions(+), 101 deletions(-)
 create mode 100644 kernel/irq/kexec.c

-- 
2.40.1



From farbere at amazon.com  Sat Nov 30 12:11:43 2024
From: farbere at amazon.com (Eliav Farber)
Date: Sat, 30 Nov 2024 20:11:43 +0000
Subject: [PATCH v5 2/2] kexec: Prevent redundant IRQ masking by checking state before shutdown
In-Reply-To: <20241130201143.48808-1-farbere@amazon.com>
References: <20241130201143.48808-1-farbere@amazon.com>
Message-ID: <20241130201143.48808-3-farbere@amazon.com>

During machine kexec, the function machine_kexec_mask_interrupts() is
responsible for disabling or masking all interrupts. While the irq_disable
hook ensures that an already-disabled IRQ is not disabled again, the
current implementation unconditionally invokes the irq_mask() function for
every interrupt descriptor, even when the interrupt is already masked.

A specific issue was observed in the crash kernel flow after unbinding a
device (prior to kexec) that used a GPIO as an IRQ source. The warning was
triggered by the gpiochip_disable_irq() function, which attempted to clear
the FLAG_IRQ_IS_ENABLED flag when FLAG_USED_AS_IRQ was not set:

```
void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset)
{
	struct gpio_desc *desc = gpiochip_get_desc(gc, offset);

	if (!IS_ERR(desc) &&
	    !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags)))
		clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
}
```

This issue surfaced after commit a8173820f441 ("gpio: gpiolib: Allow GPIO
IRQs to lazy disable") introduced lazy disablement for GPIO IRQs. It
replaced disable/enable hooks with mask/unmask hooks. Unlike the disable
hook, the mask hook doesn't handle already-masked IRQs.

When a GPIO-IRQ driver is unbound, the IRQ is released, triggering
__irq_disable() and irq_state_set_masked(). A subsequent call to
machine_kexec_mask_interrupts() re-invokes chip->irq_mask(). This results
in a call chain, including gpiochip_irq_mask() and gpiochip_disable_irq().
Since FLAG_USED_AS_IRQ was cleared earlier, a warning occurs.

Replace calls to irq_mask() and irq_disable() hooks with a simplified call
to irq_shutdown(), and check if the interrupt is started (irqd_is_started)
before calling the shutdown.

Signed-off-by: Eliav Farber <farbere at amazon.com>
---
V4 -> V5:
 - The phrase 'This patch' has been removed from the commit message.

 kernel/irq/kexec.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/kernel/irq/kexec.c b/kernel/irq/kexec.c
index 0f9548c1708d..1a3deffe6b5b 100644
--- a/kernel/irq/kexec.c
+++ b/kernel/irq/kexec.c
@@ -17,7 +17,7 @@ void machine_kexec_mask_interrupts(void)
 		int check_eoi = 1;
 
 		chip = irq_desc_get_chip(desc);
-		if (!chip)
+		if (!chip || !irqd_is_started(&desc->irq_data))
 			continue;
 
 		if (IS_ENABLED(CONFIG_GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD)) {
@@ -31,10 +31,6 @@ void machine_kexec_mask_interrupts(void)
 		if (check_eoi && chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
 			chip->irq_eoi(&desc->irq_data);
 
-		if (chip->irq_mask)
-			chip->irq_mask(&desc->irq_data);
-
-		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
-			chip->irq_disable(&desc->irq_data);
+		irq_shutdown(desc);
 	}
 }
-- 
2.40.1



From uwu at coelacanthus.name  Sat Nov 30 13:47:13 2024
From: uwu at coelacanthus.name (Celeste Liu)
Date: Sun, 01 Dec 2024 05:47:13 +0800
Subject: [PATCH] riscv/ptrace: add new regset to get original a0 register
Message-ID: <20241201-riscv-new-regset-v1-1-c83c58abcc7b@coelacanthus.name>

The orig_a0 is missing in struct user_regs_struct of riscv, and there is
no way to add it without breaking UAPI. (See Link tag below)

Like NT_ARM_SYSTEM_CALL do, we add a new regset name NT_RISCV_ORIG_A0 to
access original a0 register from userspace via ptrace API.

Link: https://lore.kernel.org/all/59505464-c84a-403d-972f-d4b2055eeaac at gmail.com/
Signed-off-by: Celeste Liu <uwu at coelacanthus.name>
---
 arch/riscv/kernel/ptrace.c | 33 +++++++++++++++++++++++++++++++++
 include/uapi/linux/elf.h   |  1 +
 2 files changed, 34 insertions(+)

diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index ea67e9fb7a583683b922fe2c017ea61f3bc848db..faa46de9000376eb445a32d43a40210d7b846844 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -31,6 +31,7 @@ enum riscv_regset {
 #ifdef CONFIG_RISCV_ISA_SUPM
 	REGSET_TAGGED_ADDR_CTRL,
 #endif
+	REGSET_ORIG_A0,
 };
 
 static int riscv_gpr_get(struct task_struct *target,
@@ -184,6 +185,30 @@ static int tagged_addr_ctrl_set(struct task_struct *target,
 }
 #endif
 
+static int riscv_orig_a0_get(struct task_struct *target,
+			     const struct user_regset *regset,
+			     struct membuf to)
+{
+	return membuf_store(&to, task_pt_regs(target)->orig_a0);
+}
+
+static int riscv_orig_a0_set(struct task_struct *target,
+			     const struct user_regset *regset,
+			     unsigned int pos, unsigned int count,
+			     const void *kbuf, const void __user *ubuf)
+{
+	int orig_a0 = task_pt_regs(target)->orig_a0;
+	int ret;
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &orig_a0, 0, -1);
+	if (ret)
+		return ret;
+
+	task_pt_regs(target)->orig_a0 = orig_a0;
+	return ret;
+}
+
+
 static const struct user_regset riscv_user_regset[] = {
 	[REGSET_X] = {
 		.core_note_type = NT_PRSTATUS,
@@ -224,6 +249,14 @@ static const struct user_regset riscv_user_regset[] = {
 		.set = tagged_addr_ctrl_set,
 	},
 #endif
+	[REGSET_ORIG_A0] = {
+		.core_note_type = NT_RISCV_ORIG_A0,
+		.n = 1,
+		.size = sizeof(elf_greg_t),
+		.align = sizeof(elf_greg_t),
+		.regset_get = riscv_orig_a0_get,
+		.set = riscv_orig_a0_set,
+	},
 };
 
 static const struct user_regset_view riscv_user_native_view = {
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index b44069d29cecc0f9de90ee66bfffd2137f4275a8..390060229601631da2fb27030d9fa2142e676c14 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -452,6 +452,7 @@ typedef struct elf64_shdr {
 #define NT_RISCV_CSR	0x900		/* RISC-V Control and Status Registers */
 #define NT_RISCV_VECTOR	0x901		/* RISC-V vector registers */
 #define NT_RISCV_TAGGED_ADDR_CTRL 0x902	/* RISC-V tagged address control (prctl()) */
+#define NT_RISCV_ORIG_A0	  0x903	/* RISC-V original a0 register */
 #define NT_LOONGARCH_CPUCFG	0xa00	/* LoongArch CPU config registers */
 #define NT_LOONGARCH_CSR	0xa01	/* LoongArch control and status registers */
 #define NT_LOONGARCH_LSX	0xa02	/* LoongArch Loongson SIMD Extension registers */

---
base-commit: 0e287d31b62bb53ad81d5e59778384a40f8b6f56
change-id: 20241201-riscv-new-regset-d529b952ad0d

Best regards,
-- 
Celeste Liu <uwu at coelacanthus.name>



From uwu at coelacanthus.name  Sat Nov 30 14:39:45 2024
From: uwu at coelacanthus.name (Celeste Liu)
Date: Sun, 1 Dec 2024 06:39:45 +0800
Subject: [PATCH] riscv/entry: get correct syscall number from
 syscall_get_nr()
In-Reply-To: <CAJ+HfNj4d8_Ow1GyA3uX+2f79V8173e9RWfcX6_KjTPfinZCiw@mail.gmail.com>
References: <87ldya4nv0.ffs@tglx>
 <3dc10d89-6c0c-4654-95ed-dd6f19efbad4@gmail.com> <87a5ep4k0n.ffs@tglx>
 <2b1a96b1-dbc5-40ed-b1b6-2c82d3df9eb2@gmail.com> <877c9t43jw.ffs@tglx>
 <81afb4bf-084b-e061-8ce4-90b76da16256@w6rz.net>
 <109afaab-05c0-4228-8ea0-1dc1aabe904f@gmail.com>
 <CAJ+HfNj4d8_Ow1GyA3uX+2f79V8173e9RWfcX6_KjTPfinZCiw@mail.gmail.com>
Message-ID: <bded8cfb-c881-4c78-a8a8-1e0c8abe327f@coelacanthus.name>


On 2024-10-29 03:33, Bj?rn T?pel wrote:
> On Mon, 28 Oct 2024 at 17:26, Celeste Liu <coelacanthushex at gmail.com> wrote:
>>
>>
>> On 2024-10-28 08:17, Ron Economos wrote:
>>> On 10/27/24 2:52 PM, Thomas Gleixner wrote:
>>>> On Mon, Oct 28 2024 at 01:01, Celeste Liu wrote:
>>>>> On 2024-10-27 23:56, Thomas Gleixner wrote:
>>>>>> Equivalently you need to be able to modify orig_a0 for changing arg0,
>>>>>> no?
>>>>> Ok.
>>>>>
>>>>> Greg, could you accept a backport a new API parameter for
>>>>> PTRACE_GETREGSET/PTRACE_SETREGSET to 4.19 LTS branch?
>>>> Fix the problem properly and put a proper Fixes tag on it and worry
>>>> about the backport later.
>>>>
>>>> Thanks,
>>>>
>>>>          tglx
>>>>
>>> I wouldn't worry about backporting to the 4.19 kernel. It's essentially prehistoric for RISC-V. There's no device tree support for any hardware. Also, 4.19 will be going EOL very soon (December 2024).
>>
>> Ok, I will work on preparing a new patch to add a new set in
>> PTRACE_GETREGSET/PTRACE_SETREGSET.
> 
> Thanks for working/finding working on this! Looking forward to the patch!

The patch to add new regset has been sent.
See https://lore.kernel.org/lkml/20241201-riscv-new-regset-v1-1-c83c58abcc7b at coelacanthus.name/T/



From farbere at amazon.com  Thu Nov 28 12:07:57 2024
From: farbere at amazon.com (Farber, Eliav)
Date: Thu, 28 Nov 2024 20:07:57 +0000
Subject: [PATCH v2] arm64: kexec: Check if IRQ is already masked before
 masking
Message-ID: <3a499ecdfa5042f8b6e8834c47cdb2d9@amazon.com>

On 11/28/2024 12:39 PM, Thomas Gleixner wrote:
> This is just wrong. If the interrupt was torn down, then its state is deactivated and it was masked already. So the EOI handling and the mask/disable dance are neither required nor make sense.
>
> So this whole thing should be:
>
>                 chip = irq_desc_get_chip(desc);
> -               if (!chip)
> +               if (!chip || !irqd_is_started(&desc->irq_data))
>                         continue;
ACK. Will be done this way in V3.

> But what's worse is that we have 4 almost identical variants of the same code.
>
> So instead of exposing core functionality and "fixing" up four variants, can we please have a consolidated version of this function in the core
> code:
>                 struct irq_chip *chip;
>                 int check_eoi = 1;
>
>                 chip = irq_desc_get_chip(desc);
>                 if (!chip || !irqd_is_started(&desc->irq_data))
>                         continue;
>
>                 if (IS_ENABLED(CONFIG_.....)) {
>                         /*
>                          * Add a sensible comment which explains this.
>                          */
>                         check_eoi = irq_set_irqchip_state(....);
>                 }
>
>                 if (check_eoi && ....)
>                         chip->irq_eoi(&desc->irq_data);
>
>                 irq_shutdown(desc);
>
> No?
In V3 I will add a preliminary patch that will remove the four variants
and instead add a common implementations to the kexec core.

Thanks, Eliav


From farbere at amazon.com  Sat Nov 30 12:08:44 2024
From: farbere at amazon.com (Farber, Eliav)
Date: Sat, 30 Nov 2024 20:08:44 +0000
Subject: [PATCH v4 1/2] kexec: Consolidate machine_kexec_mask_interrupts()
 implementation
Message-ID: <cd8809e379dc4dd089350ec2d1f8c210@amazon.com>

On 11/29/2024 3:30 PM, Thomas Gleixner wrote:
>> Move the machine_kexec_mask_interrupts function to a common location in
>> kernel/kexec_core.c, removing duplicate implementations from architecture
>> specific files (arch/arm, arch/arm64, arch/powerpc, and arch/riscv).
>
> Can you please move this into kernel/irq/kexec.c?
>
> It's pure interrupt core internal code and there is no point to make
> core internal functions visible to random other code just because.
Done (in v5 series)

>> +void machine_kexec_mask_interrupts(void)
>> +{
>> +     unsigned int i;
>> +     struct irq_desc *desc;
>
>         struct irq_desc *desc;
>         unsigned int i;
>
> please
Done (in v5 series)

>> +     for_each_irq_desc(i, desc) {
>> +             struct irq_chip *chip;
>> +             int check_eoi = 1;
>> +
>> +             chip = irq_desc_get_chip(desc);
>> +             if (!chip)
>> +                     continue;
>> +
>> +             if (IS_ENABLED(CONFIG_ARM64)) {
>
> This should not be CONFIG_ARM64. Add something like:
>
> config GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD
>         bool
>
> and select this from ARM64?
Done (in v5 series)

>> +                     /*
>> +                      * First try to remove the active state. If this fails, try to EOI the
>> +                      * interrupt.
>
> This comment does not really explain what this is about. I know you
> copied it from the ARM64 implementation, but it should explain what this
> actually means. Something like:
>
>          First try to remove the active state from an interrupt which is
>          forwarded to a VM. If the interrupt is not forwarded, try to
>          EOI the interrupt.
>
> or something like that.
Done (in v5 series)

>> +                      */
>> +                     check_eoi = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
>
> Looking deeper. This function actually cannot be called from this
> context. It does:
>
>           irq_get_desc_buslock(irq, &flags, 0);
>
> which means for any interrupt which has an actual buslock implementation
> it will end up in a sleepable function and deadlock in the worst case.
>
> Marc?
I will wait for Marc's response regarding this issue.
Regardless, if any changes are required, I believe it would be better
to address them in a separate patch, as this behavior existed before my
modification.

Thanks, Eliav


From farbere at amazon.com  Sat Nov 30 12:10:59 2024
From: farbere at amazon.com (Farber, Eliav)
Date: Sat, 30 Nov 2024 20:10:59 +0000
Subject: [PATCH v4 2/2] kexec: Prevent redundant IRQ masking by checking
 state before shutdown
Message-ID: <0e467b4c2bc34eb59c8f23f36a9a6956@amazon.com>

On 11/29/2024 3:32 PM, Thomas Gleixner wrote:
>> This patch addresses the issue by:
>
> Again:  git grep 'This patch' Documentation/process/
Done (in v5 series)


