[PATCH v3 5/9] arm64/sysreg: Update ID_AA64SMFR0_EL1 to DDI0601 2024-09

2024-12-03 Thread Mark Brown
DDI0601 2024-09 introduces SME 2.2 as well as a few new optional features,
update sysreg to reflect the changes in ID_AA64SMFR0_EL1 enumerating them.

Signed-off-by: Mark Brown 
---
 arch/arm64/tools/sysreg | 32 +++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 
7e6b204e83270daabd0036c8109b2fdb0e9b700a..0253d3847aeb2294da04b2b0b3f33f81f32c849f
 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1105,6 +1105,7 @@ UnsignedEnum  59:56   SMEver
0b  SME
0b0001  SME2
0b0010  SME2p1
+   0b0011  SME2p2
0b  IMP
 EndEnum
 UnsignedEnum   55:52   I16I64
@@ -1169,7 +1170,36 @@ UnsignedEnum 28  SF8DP2
0b0 NI
0b1 IMP
 EndEnum
-Res0   27:0
+UnsignedEnum   27  SF8MM8
+   0b0 NI
+   0b1 IMP
+EndEnum
+UnsignedEnum   26  SF8MM4
+   0b0 NI
+   0b1 IMP
+EndEnum
+UnsignedEnum   25  SBitPerm
+   0b0 NI
+   0b1 IMP
+EndEnum
+UnsignedEnum   24  AES
+   0b0 NI
+   0b1 IMP
+EndEnum
+UnsignedEnum   23  SFEXPA
+   0b0 NI
+   0b1 IMP
+EndEnum
+Res0   22:17
+UnsignedEnum   16  STMOP
+   0b0 NI
+   0b1 IMP
+EndEnum
+Res0   15:1
+UnsignedEnum   0   SMOP4
+   0b0 NI
+   0b1 IMP
+EndEnum
 EndSysreg
 
 Sysreg ID_AA64FPFR0_EL13   0   0   4   7

-- 
2.39.5




Re: [PATCH v3 2/3] docs: media: document media multi-committers rules and process

2024-12-03 Thread Sakari Ailus
Hi Mauro,

On Tue, Dec 03, 2024 at 09:26:13AM +0100, Mauro Carvalho Chehab wrote:
> > > +is also based on a trust relationship between the rest of the 
> > > committers,  
> > 
> > s/also//
> > s/between the rest of/among/
> > 
> > I wonder if we should add here some expectation on being reachable on
> > #linux-media.
> 
> I'll add it at the note about linuxtv.org:
> 
>   These commit rights are granted with expectation of responsibility:
>   committers are people who care about the Linux Kernel as a whole and
>   about the Linux media subsystem and want to advance its development. It
>   is also based on a trust relationship among other committers, 
> maintainers
>   and the Linux Media community[1].
> 
>   ...
> 
> 
>   [1] The Linux Media Community, also called LinuxTV Community, has its 
> primary
>   site at https://linuxtv.org.
>   
>   Media committers and developers are reachable via the #linux-media
>   IRC channel at OFTC.

Looks good, thanks!

> 
> > > +maintainers and the Linux Media community[1].
> > > +
> > > +As such, a media committer is not just someone who is capable of creating
> > > +code, but someone who has demonstrated their ability to collaborate
> > > +with the team, get the most knowledgeable people to review code,
> > > +contribute high-quality code, and follow through to fix issues (in code
> > > +or tests).
> > > +
> > > +.. Note::
> > > +
> > > +   1. If a patch introduces a regression, then it is the media 
> > > committer's
> > > +  responsibility to correct that as soon as possible. Typically the
> > > +  patch is either reverted, or an additional patch is committed that
> > > +  fixes the regression;  
> > 
> > s/that fixes/to fix/
> 
> Ok.
> 
> > 
> > > +   2. if patches are fixing bugs against already released Kernels, 
> > > including
> > > +  the reverts above mentioned, the media committer shall add the 
> > > needed
> > > +  tags. Please see :ref:`Media development workflow` for more 
> > > details.  
> > 
> > Does this reference work?
> 
> Yes. Tested on Sphinx 6.2.0.
> 
> > > +[1] The Linux Media community, also called LinuxTV community, has its 
> > > primary
> > > +site at https://linuxtv.org.
> > > +
> > > +Becoming a media committer
> > > +--
> > > +
> > > +The most important aspect of volunteering to be a committer is that you 
> > > have
> > > +demonstrated the ability to give good code reviews. So we are looking 
> > > for  
> > 
> > I wonder if we should add some kind of an expectation of demonstrating
> > common sense? :-)
> 
> Could you propose some text for that?

How about:

The most important aspects of volunteering to be a committer are that you
have demonstrated the ability to give good code reviews, interacting with
others in the community as well as common sense. These are what we're
looking for when we're judging whether you'd be a good Media committer.

> 
> > > +whether or not we think you will be good at doing that.
> > > +
> > > +As such, potential committers must earn enough credibility and trust 
> > > from the
> > > +LinuxTV community. To do that, developers shall be familiar with the open
> > > +source model and have been active in the Linux Kernel community for some 
> > > time,
> > > +and, in particular, in the media subsystem.
> > > +
> > > +So, in addition to actually making the code changes, you are basically
> > > +demonstrating your:
> > > +
> > > +- commitment to the project;
> > > +- ability to collaborate with the team and communicate well;
> > > +- understand of how upstream and the LinuxTV community work
> > > +  (policies, processes for testing, code review, ...)
> > > +- reasonable knowledge about:
> > > +
> > > +  - the Kernel development process:
> > > +Documentation/process/index.rst  
> > 
> > :ref:`the Kernel development process `
> 
> No need. a Sphinx converts all *.rst into references automatically.
> 
> Better to use RST files at the text, as makes easier for people
> reading the text file directly.

Ack.

> 
> > > +
> > > +  - the Media development profile:
> > > +Documentation/driver-api/media/maintainer-entry-profile.rst  
> > 
> > Could you add a label to the title and refer to it directly?
> 
> Same as above.
> 
> > > +
> > > +- understanding of the projects' code base and coding style;
> > > +- ability to provide feedback to the patch authors;
> > > +- ability to judge when a patch might be ready for review and to submit;
> > > +- ability to write good code (last but certainly not least).
> > > +
> > > +Developers that intend to become committers are encouraged to 
> > > participate  
> > 
> > s/intend/yearn/
> 
> Heh, I had to go to the dictionary to seek for "yearn" meaning ;-)
> 
> Let's use a simpler language, as most developers are not native-English
> speakers. I did:
> 
>   s/intend/desire/
> 
> which is a synonym.

Works for me.

-- 
Kind regards,

Sakari Ailus



[PATCH v3 3/9] arm64/sysreg: Update ID_AA64FPFR0_EL1 to DDI0601 2024-09

2024-12-03 Thread Mark Brown
DDI0601 2024-09 defines two new feature flags in ID_AA64FPFR0_EL1
describing new FP8 operations, describe them in sysreg.

Signed-off-by: Mark Brown 
---
 arch/arm64/tools/sysreg | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 
c5af604eda6a721cedf5c9c68d6f7038156de651..b44ab511cf5d9d33efd7dca304d0e2f53ce47810
 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1180,7 +1180,15 @@ UnsignedEnum 28  F8DP2
0b0 NI
0b1 IMP
 EndEnum
-Res0   27:2
+UnsignedEnum   27  F8MM8
+   0b0 NI
+   0b1 IMP
+EndEnum
+UnsignedEnum   26  F8MM4
+   0b0 NI
+   0b1 IMP
+EndEnum
+Res0   25:2
 UnsignedEnum   1   F8E4M3
0b0 NI
0b1 IMP

-- 
2.39.5




[PATCH v3 2/9] arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601 2024-09

2024-12-03 Thread Mark Brown
DDI0601 2024-09 defines several new feature flags in ID_AA64ISAR3_EL1,
update our description in sysreg to reflect these.

Signed-off-by: Mark Brown 
---
 arch/arm64/tools/sysreg | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 
911f16c82ebd3ee98ffed965b02a5c6b153bc50c..c5af604eda6a721cedf5c9c68d6f7038156de651
 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1566,7 +1566,23 @@ EndEnum
 EndSysreg
 
 Sysreg ID_AA64ISAR3_EL13   0   0   6   3
-Res0   63:16
+Res0   63:32
+UnsignedEnum   31:28   FPRCVT
+   0b  NI
+   0b0010  IMP
+EndEnum
+UnsignedEnum   27:24   LSUI
+   0b  NI
+   0b0010  IMP
+EndEnum
+UnsignedEnum   23:20   OCCMO
+   0b  NI
+   0b0010  IMP
+EndEnum
+UnsignedEnum   19:16   LSFE
+   0b  NI
+   0b0010  IMP
+EndEnum
 UnsignedEnum   15:12   PACM
0b  NI
0b0001  TRIVIAL_IMP

-- 
2.39.5




[PATCH v3 7/9] arm64/hwcap: Describe 2024 dpISA extensions to userspace

2024-12-03 Thread Mark Brown
The 2024 dpISA introduces a number of architecture features all of which
only add new instructions so only require the addition of hwcaps and ID
register visibility.

Signed-off-by: Mark Brown 
---
 Documentation/arch/arm64/elf_hwcaps.rst | 51 +
 arch/arm64/include/asm/hwcap.h  | 17 +++
 arch/arm64/include/uapi/asm/hwcap.h | 17 +++
 arch/arm64/kernel/cpufeature.c  | 35 ++
 arch/arm64/kernel/cpuinfo.c | 17 +++
 5 files changed, 137 insertions(+)

diff --git a/Documentation/arch/arm64/elf_hwcaps.rst 
b/Documentation/arch/arm64/elf_hwcaps.rst
index 
2ff922a406ad83d0dff8104a6e362ac6b02d0e1f..7c99894ca3e8f5433b1a0db6a4679395e5cd9ecc
 100644
--- a/Documentation/arch/arm64/elf_hwcaps.rst
+++ b/Documentation/arch/arm64/elf_hwcaps.rst
@@ -174,6 +174,57 @@ HWCAP_GCS
 Functionality implied by ID_AA64PFR1_EL1.GCS == 0b1, as
 described by Documentation/arch/arm64/gcs.rst.
 
+HWCAP_CMPBR
+Functionality implied by ID_AA64ISAR2_EL1.CSSC == 0b0010.
+
+HWCAP_FPRCVT
+Functionality implied by ID_AA64ISAR3_EL1.FPRCVT == 0b0001.
+
+HWCAP_F8MM8
+Functionality implied by ID_AA64FPFR0_EL1.F8MM8 == 0b0001.
+
+HWCAP_F8MM4
+Functionality implied by ID_AA64FPFR0_EL1.F8MM4 == 0b0001.
+
+HWCAP_SVE_F16MM
+Functionality implied by ID_AA64ZFR0_EL1.F16MM == 0b0001.
+
+HWCAP_SVE_ELTPERM
+Functionality implied by ID_AA64ZFR0_EL1.ELTPERM == 0b0001.
+
+HWCAP_SVE_AES2
+Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0011.
+
+HWCAP_SVE_BFSCALE
+Functionality implied by ID_AA64ZFR0_EL1.B16B16 == 0b0010.
+
+HWCAP_SVE2P2
+Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0011.
+
+HWCAP_SME2P2
+Functionality implied by ID_AA64SMFR0_EL1.SMEver == 0b0011.
+
+HWCAP_SME_SF8MM8
+Functionality implied by ID_AA64SMFR0_EL1.SF8MM8 == 0b1.
+
+HWCAP_SME_SF8MM4
+Functionality implied by ID_AA64SMFR0_EL1.SF8MM4 == 0b1.
+
+HWCAP_SME_SBITPERM
+Functionality implied by ID_AA64SMFR0_EL1.SBitPerm == 0b1.
+
+HWCAP_SME_AES
+Functionality implied by ID_AA64SMFR0_EL1.AES == 0b1.
+
+HWCAP_SME_SFEXPA
+Functionality implied by ID_AA64SMFR0_EL1.SFEXPA == 0b1.
+
+HWCAP_SME_STMOP
+Functionality implied by ID_AA64SMFR0_EL1.STMOP == 0b1.
+
+HWCAP_SME_SMOP4
+Functionality implied by ID_AA64SMFR0_EL1.SMOP4 == 0b1.
+
 HWCAP2_DCPODP
 Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010.
 
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 
2b6c61c608e2cd107503b09aba5aaeab639b759a..dbec921ee39c8c897f3e1e1c84d522b5b57130bb
 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -93,6 +93,23 @@
 #define KERNEL_HWCAP_PACA  __khwcap_feature(PACA)
 #define KERNEL_HWCAP_PACG  __khwcap_feature(PACG)
 #define KERNEL_HWCAP_GCS   __khwcap_feature(GCS)
+#define KERNEL_HWCAP_CMPBR __khwcap_feature(CMPBR)
+#define KERNEL_HWCAP_FPRCVT__khwcap_feature(FPRCVT)
+#define KERNEL_HWCAP_F8MM8 __khwcap_feature(F8MM8)
+#define KERNEL_HWCAP_F8MM4 __khwcap_feature(F8MM4)
+#define KERNEL_HWCAP_SVE_F16MM __khwcap_feature(SVE_F16MM)
+#define KERNEL_HWCAP_SVE_ELTPERM   __khwcap_feature(SVE_ELTPERM)
+#define KERNEL_HWCAP_SVE_AES2  __khwcap_feature(SVE_AES2)
+#define KERNEL_HWCAP_SVE_BFSCALE   __khwcap_feature(SVE_BFSCALE)
+#define KERNEL_HWCAP_SVE2P2__khwcap_feature(SVE2P2)
+#define KERNEL_HWCAP_SME2P2__khwcap_feature(SME2P2)
+#define KERNEL_HWCAP_SME_SF8MM8__khwcap_feature(SME_SF8MM8)
+#define KERNEL_HWCAP_SME_SF8MM4__khwcap_feature(SME_SF8MM4)
+#define KERNEL_HWCAP_SME_SBITPERM  __khwcap_feature(SME_SBITPERM)
+#define KERNEL_HWCAP_SME_AES   __khwcap_feature(SME_AES)
+#define KERNEL_HWCAP_SME_SFEXPA__khwcap_feature(SME_SFEXPA)
+#define KERNEL_HWCAP_SME_STMOP __khwcap_feature(SME_STMOP)
+#define KERNEL_HWCAP_SME_SMOP4 __khwcap_feature(SME_SMOP4)
 
 #define __khwcap2_feature(x)   (const_ilog2(HWCAP2_ ## x) + 64)
 #define KERNEL_HWCAP_DCPODP__khwcap2_feature(DCPODP)
diff --git a/arch/arm64/include/uapi/asm/hwcap.h 
b/arch/arm64/include/uapi/asm/hwcap.h
index 
48d46b768eaec4c307360cd3bee8b564687f4b88..61fbc88d2bfb81d0bad639ed533ac67440ae2fc4
 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -56,6 +56,23 @@
 #define HWCAP_PACA (1 << 30)
 #define HWCAP_PACG (1UL << 31)
 #define HWCAP_GCS  (1UL << 32)
+#define HWCAP_CMPBR(1UL << 33)
+#define HWCAP_FPRCVT   (1UL << 34)
+#define HWCAP_F8MM8(1UL << 35)
+#define HWCAP_F8MM4(1UL << 36)
+#define HWCAP_SVE_F16MM(1UL << 37)
+#define HWCAP_SVE_ELTPERM  (1UL << 38)
+#define HWCAP_SVE_AES2 (1UL << 39)
+#define HWCAP_SVE_BFSCALE  (1UL << 40)
+#define H

[PATCH v3 1/9] arm64/sysreg: Update ID_AA64PFR2_EL1 to DDI0601 2024-09

2024-12-03 Thread Mark Brown
DDI0601 2024-09 defines a new feature flags in ID_AA64PFR2_EL1
describing support for injecting UNDEF exceptions, update sysreg to
include this.

Signed-off-by: Mark Brown 
---
 arch/arm64/tools/sysreg | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 
b081b54d6d227ed8300a6f129896647316f0b673..911f16c82ebd3ee98ffed965b02a5c6b153bc50c
 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1010,7 +1010,12 @@ UnsignedEnum 35:32   FPMR
0b  NI
0b0001  IMP
 EndEnum
-Res0   31:12
+Res0   31:20
+UnsignedEnum   19:16   UINJ
+   0b  NI
+   0b0001  IMP
+EndEnum
+Res0   15:12
 UnsignedEnum   11:8MTEFAR
0b  NI
0b0001  IMP

-- 
2.39.5




[PATCH v3 6/9] arm64/sysreg: Update ID_AA64ISAR2_EL1 to DDI0601 2024-09

2024-12-03 Thread Mark Brown
DDI0601 2024-09 introduces new features which are enumerated via
ID_AA64ISAR2_EL1, update the sysreg file to reflect these updates.

Signed-off-by: Mark Brown 
---
 arch/arm64/tools/sysreg | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 
0253d3847aeb2294da04b2b0b3f33f81f32c849f..fe55c04624de74a6c1a5e0be45363b9c46ff1340
 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1556,12 +1556,16 @@ EndEnum
 UnsignedEnum   55:52   CSSC
0b  NI
0b0001  IMP
+   0b0010  CMPBR
 EndEnum
 UnsignedEnum   51:48   RPRFM
0b  NI
0b0001  IMP
 EndEnum
-Res0   47:44
+UnsignedEnum   47:44   PCDPHINT
+   0b  NI
+   0b0001  IMP
+EndEnum
 UnsignedEnum   43:40   PRFMSLC
0b  NI
0b0001  IMP

-- 
2.39.5




[PATCH v3 0/9] arm64: Support 2024 dpISA extensions

2024-12-03 Thread Mark Brown
The 2024 architecture release includes a number of data processing
extensions, mostly SVE and SME additions with a few others.  These are
all very straightforward extensions which add instructions but no
architectural state so only need hwcaps and exposing of the ID registers
to KVM guests and userspace.

Signed-off-by: Mark Brown 
---
Changes in v3:
- Commit log update for the hwcap test.
- Link to v2: 
https://lore.kernel.org/r/20241030-arm64-2024-dpisa-v2-0-b6601a15d...@kernel.org

Changes in v2:
- Filter KVM guest visible bitfields in ID_AA64ISAR3_EL1 to only those
  we make writeable.
- Link to v1: 
https://lore.kernel.org/r/20241028-arm64-2024-dpisa-v1-0-a38d08b00...@kernel.org

---
Mark Brown (9):
  arm64/sysreg: Update ID_AA64PFR2_EL1 to DDI0601 2024-09
  arm64/sysreg: Update ID_AA64ISAR3_EL1 to DDI0601 2024-09
  arm64/sysreg: Update ID_AA64FPFR0_EL1 to DDI0601 2024-09
  arm64/sysreg: Update ID_AA64ZFR0_EL1 to DDI0601 2024-09
  arm64/sysreg: Update ID_AA64SMFR0_EL1 to DDI0601 2024-09
  arm64/sysreg: Update ID_AA64ISAR2_EL1 to DDI0601 2024-09
  arm64/hwcap: Describe 2024 dpISA extensions to userspace
  KVM: arm64: Allow control of dpISA extensions in ID_AA64ISAR3_EL1
  kselftest/arm64: Add 2024 dpISA extensions to hwcap test

 Documentation/arch/arm64/elf_hwcaps.rst   |  51 ++
 arch/arm64/include/asm/hwcap.h|  17 ++
 arch/arm64/include/uapi/asm/hwcap.h   |  17 ++
 arch/arm64/kernel/cpufeature.c|  35 
 arch/arm64/kernel/cpuinfo.c   |  17 ++
 arch/arm64/kvm/sys_regs.c |   6 +-
 arch/arm64/tools/sysreg   |  87 +-
 tools/testing/selftests/arm64/abi/hwcap.c | 273 +-
 8 files changed, 493 insertions(+), 10 deletions(-)
---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241008-arm64-2024-dpisa-8091074a7f48

Best regards,
-- 
Mark Brown 




[PATCH v3 4/9] arm64/sysreg: Update ID_AA64ZFR0_EL1 to DDI0601 2024-09

2024-12-03 Thread Mark Brown
DDI0601 2024-09 introduces SVE 2.2 as well as a few new optional features,
update sysreg to reflect the changes in ID_AA64ZFR0_EL1 enumerating them.

Signed-off-by: Mark Brown 
---
 arch/arm64/tools/sysreg | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 
b44ab511cf5d9d33efd7dca304d0e2f53ce47810..7e6b204e83270daabd0036c8109b2fdb0e9b700a
 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -1040,7 +1040,10 @@ UnsignedEnum 55:52   F32MM
0b  NI
0b0001  IMP
 EndEnum
-Res0   51:48
+UnsignedEnum   51:48   F16MM
+   0b  NI
+   0b0001  IMP
+EndEnum
 UnsignedEnum   47:44   I8MM
0b  NI
0b0001  IMP
@@ -1058,6 +1061,7 @@ Res0  31:28
 UnsignedEnum   27:24   B16B16
0b  NI
0b0001  IMP
+   0b0010  BFSCALE
 EndEnum
 UnsignedEnum   23:20   BF16
0b  NI
@@ -1068,16 +1072,22 @@ UnsignedEnum19:16   BitPerm
0b  NI
0b0001  IMP
 EndEnum
-Res0   15:8
+UnsignedEnum   15:12   EltPerm
+   0b  NI
+   0b0001  IMP
+EndEnum
+Res0   11:8
 UnsignedEnum   7:4 AES
0b  NI
0b0001  IMP
0b0010  PMULL128
+   0b0011  AES2
 EndEnum
 UnsignedEnum   3:0 SVEver
0b  IMP
0b0001  SVE2
0b0010  SVE2p1
+   0b0011  SVE2p2
 EndEnum
 EndSysreg
 

-- 
2.39.5




[PATCH v3 9/9] kselftest/arm64: Add 2024 dpISA extensions to hwcap test

2024-12-03 Thread Mark Brown
Add coverage of the hwcaps for the 2024 dpISA extensions to the hwcap
test.

We don't actually test SIGILL generation for CMPBR since the need to
branch makes it a pain to generate and the SIGILL detection would be
unreliable anyway. Since this should be very unusual we provide a stub
function rather than supporting a missing test.

The sigill functions aren't well sorted in the file so the ordering is a
bit random.

Signed-off-by: Mark Brown 
---
 tools/testing/selftests/arm64/abi/hwcap.c | 273 +-
 1 file changed, 271 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/arm64/abi/hwcap.c 
b/tools/testing/selftests/arm64/abi/hwcap.c
index 
0029ed9c5c9aa4451f3d0573ee672eca993fb2f4..2a230cfa4cb4108580a16161e2df03a513710dbc
 100644
--- a/tools/testing/selftests/arm64/abi/hwcap.c
+++ b/tools/testing/selftests/arm64/abi/hwcap.c
@@ -46,6 +46,12 @@ static void atomics_sigill(void)
asm volatile(".inst 0xb82003ff" : : : );
 }
 
+static void cmpbr_sigill(void)
+{
+   /* Not implemented, too complicated and unreliable anyway */
+}
+
+
 static void crc32_sigill(void)
 {
/* CRC32W W0, W0, W1 */
@@ -82,6 +88,18 @@ static void f8fma_sigill(void)
asm volatile(".inst 0xec0fc00");
 }
 
+static void f8mm4_sigill(void)
+{
+   /* FMMLA V0.4SH, V0.16B, V0.16B */
+   asm volatile(".inst 0x6e00ec00");
+}
+
+static void f8mm8_sigill(void)
+{
+   /* FMMLA V0.4S, V0.16B, V0.16B */
+   asm volatile(".inst 0x6e80ec00");
+}
+
 static void faminmax_sigill(void)
 {
/* FAMIN V0.4H, V0.4H, V0.4H */
@@ -98,6 +116,12 @@ static void fpmr_sigill(void)
asm volatile("mrs x0, S3_3_C4_C4_2" : : : "x0");
 }
 
+static void fprcvt_sigill(void)
+{
+   /* FCVTAS S0, H0 */
+   asm volatile(".inst 0x1efa");
+}
+
 static void gcs_sigill(void)
 {
unsigned long *gcspr;
@@ -226,6 +250,42 @@ static void sme2p1_sigill(void)
asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
 }
 
+static void sme2p2_sigill(void)
+{
+   /* SMSTART SM */
+   asm volatile("msr S0_3_C4_C3_3, xzr" : : : );
+
+   /* UXTB Z0.D, P0/Z, Z0.D  */
+   asm volatile(".inst 0x4c1a000" : : : );
+
+   /* SMSTOP */
+   asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void sme_aes_sigill(void)
+{
+   /* SMSTART SM */
+   asm volatile("msr S0_3_C4_C3_3, xzr" : : : );
+
+   /* AESD z0.b, z0.b, z0.b */
+   asm volatile(".inst 0x4522e400" : : : "z0");
+
+   /* SMSTOP */
+   asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void sme_sbitperm_sigill(void)
+{
+   /* SMSTART SM */
+   asm volatile("msr S0_3_C4_C3_3, xzr" : : : );
+
+   /* BDEP Z0.B, Z0.B, Z0.B */
+   asm volatile(".inst 0x4500b400" : : : "z0");
+
+   /* SMSTOP */
+   asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
 static void smei16i32_sigill(void)
 {
/* SMSTART */
@@ -334,13 +394,73 @@ static void smesf8dp4_sigill(void)
asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
 }
 
+static void smesf8mm8_sigill(void)
+{
+   /* SMSTART */
+   asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+   /* FMMLA V0.4S, V0.16B, V0.16B */
+   asm volatile(".inst 0x6e80ec00");
+
+   /* SMSTOP */
+   asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smesf8mm4_sigill(void)
+{
+   /* SMSTART */
+   asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+   /* FMMLA V0.4SH, V0.16B, V0.16B */
+   asm volatile(".inst 0x6e00ec00");
+
+   /* SMSTOP */
+   asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
 static void smesf8fma_sigill(void)
 {
/* SMSTART */
asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
 
-   /* FMLALB V0.8H, V0.16B, V0.16B */
-   asm volatile(".inst 0xec0fc00");
+   /* FMLALB Z0.8H, Z0.B, Z0.B */
+   asm volatile(".inst 0x64205000");
+
+   /* SMSTOP */
+   asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smesfexpa_sigill(void)
+{
+   /* SMSTART */
+   asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+   /* FEXPA Z0.D, Z0.D */
+   asm volatile(".inst 0x04e0b800");
+
+   /* SMSTOP */
+   asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smesmop4_sigill(void)
+{
+   /* SMSTART */
+   asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+   /* SMOP4A ZA0.S, Z0.B, { Z0.B - Z1.B } */
+   asm volatile(".inst 0x80108000");
+
+   /* SMSTOP */
+   asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
+}
+
+static void smestmop_sigill(void)
+{
+   /* SMSTART */
+   asm volatile("msr S0_3_C4_C7_3, xzr" : : : );
+
+   /* STMOPA ZA0.S, { Z0.H - Z1.H }, Z0.H, Z20[0] */
+   asm volatile(".inst 0x80408008");
 
/* SMSTOP */
asm volatile("msr S0_3_C4_C6_3, xzr" : : : );
@@ -364,18 +484,42 @@ static void sve2p1_sigill(void)
asm volatile(".inst 0x6500" : : : "z0");
 }
 
+static void sve2p2_sigill(void)
+{
+   /* NOT Z0.D, P0/Z, Z0.D */
+  

Re: [PATCH v3 2/3] docs: media: document media multi-committers rules and process

2024-12-03 Thread Mauro Carvalho Chehab
Em Mon, 2 Dec 2024 14:13:42 +
Sakari Ailus  escreveu:

> Hi Mauro,
> 
> On Mon, Dec 02, 2024 at 10:26:20AM +0100, Mauro Carvalho Chehab wrote:
> > As the media subsystem will experiment with a multi-committers model,
> > update the Maintainer's entry profile to the new rules, and add a file
> > documenting the process to become a committer and to maintain such
> > rights.
> > 
> > Signed-off-by: Mauro Carvalho Chehab 
> > Signed-off-by: Hans Verkuil 
> > Reviewed-by: Ricardo Ribalda 
> > ---
> >  Documentation/driver-api/media/index.rst  |   1 +
> >  .../media/maintainer-entry-profile.rst|   8 +
> >  .../driver-api/media/media-committer.rst  | 278 ++
> >  .../process/maintainer-pgp-guide.rst  |   2 +
> >  4 files changed, 289 insertions(+)
> >  create mode 100644 Documentation/driver-api/media/media-committer.rst
> > 
> > diff --git a/Documentation/driver-api/media/index.rst 
> > b/Documentation/driver-api/media/index.rst
> > index d5593182a3f9..d0c725fcbc67 100644
> > --- a/Documentation/driver-api/media/index.rst
> > +++ b/Documentation/driver-api/media/index.rst
> > @@ -26,6 +26,7 @@ Documentation/userspace-api/media/index.rst
> >  :numbered:
> >  
> >  maintainer-entry-profile
> > +media-committer
> >  
> >  v4l2-core
> >  dtv-core
> > diff --git a/Documentation/driver-api/media/maintainer-entry-profile.rst 
> > b/Documentation/driver-api/media/maintainer-entry-profile.rst
> > index dc764163cf1c..705209eacf58 100644
> > --- a/Documentation/driver-api/media/maintainer-entry-profile.rst
> > +++ b/Documentation/driver-api/media/maintainer-entry-profile.rst
> > @@ -65,6 +65,9 @@ as described at Documentation/process/index.rst and to 
> > the Kernel
> >  development rules inside the Kernel documentation, including its code of
> >  conduct.
> >  
> > +More details about media commiters' roles and responsibilities can be
> > +found here: Documentation/driver-api/media/media-committer.rst.
> > +
> >  Media development tree
> >  --
> >  
> > @@ -200,6 +203,11 @@ shall be validated by using PGP sign. See: 
> > :ref:`kernel_org_trust_repository`.
> >  
> >  With the pull request workflow, pull requests shall use a PGP-signed tag.
> >  
> > +With the committers' workflow, this is ensured at the time merge request
> > +rights will be granted to the gitlab instance used by media-committers.git
> > +tree, after receiving the e-mail documented at
> > +:ref:`media-committer-agreement`.
> > +
> >  For more details about PGP sign, please read
> >  Documentation/process/maintainer-pgp-guide.rst.
> >  
> > diff --git a/Documentation/driver-api/media/media-committer.rst 
> > b/Documentation/driver-api/media/media-committer.rst
> > new file mode 100644
> > index ..3c2f8f413307
> > --- /dev/null
> > +++ b/Documentation/driver-api/media/media-committer.rst
> > @@ -0,0 +1,278 @@
> > +Media committers
> > +
> > +
> > +What is a media committer?  
> 
> "What" refers to a "thing" but developers generally are humans.
> 
> > +--
> > +
> > +A media committer is a developer who can push patches from other 
> > developers  
> 
> s/can/has been granted commit access to/
> 
> ?
> 
> > +and their own patches to the
> > +`media-committers 
> > `_
> > +tree.
> > +
> > +It is a media committer's duty to ensure that their entries in the 
> > MAINTAINERS
> > +file are kept up-to-date, and that submitted patches for files for which
> > +they are listed as maintainers are timely reviewed on the mailing list,
> > +ideally not waiting in patchwork as ``New`` for more than one Kernel merge
> > +cycle, and, if accepted, applying them at the media committer's tree.
> > +
> > +These commit rights are granted with some expectation of responsibility:  
> 
> s/some //
> 
> > +committers are people who care about the Linux Kernel as a whole and
> > +about the Linux media subsystem and want to help its development. It  
> 
> s/help/advance/
> 
> ?

Ok for all above.
> 
> > +is also based on a trust relationship between the rest of the committers,  
> 
> s/also//
> s/between the rest of/among/
> 
> I wonder if we should add here some expectation on being reachable on
> #linux-media.

I'll add it at the note about linuxtv.org:

These commit rights are granted with expectation of responsibility:
committers are people who care about the Linux Kernel as a whole and
about the Linux media subsystem and want to advance its development. It
is also based on a trust relationship among other committers, 
maintainers
and the Linux Media community[1].

...


[1] The Linux Media Community, also called LinuxTV Community, has its 
primary
site at https://linuxtv.org.

Media committers and developers are reachable via the #linux-media
IRC channel at OFTC.

> > +maintainers and the L

Re: [PATCH v3 0/3] Document the new media-committer's model

2024-12-03 Thread Laurent Pinchart
On Tue, Dec 03, 2024 at 08:19:58AM +0100, Mauro Carvalho Chehab wrote:
> Em Mon, 2 Dec 2024 16:03:45 +0100 Hans Verkuil escreveu:
> > On 02/12/2024 10:26, Mauro Carvalho Chehab wrote:
> > > The media subsystem used to have a multi-commiter's model in the
> > > past, but things didn't go well on that time, and we had to move to
> > > a centralized model.
> > > 
> > > As the community has evolved, and as there are now new policies in
> > > place like CoC, let's experiment with a multi-committers again.
> > > 
> > > The model we're using was inspired by the DRM multi-committers
> > > model. Yet, media subsystem is different on several aspects, so the
> > > model is not exactly the same.
> > > 
> > > The implementation will be in phases. For this phase, the goal is that 
> > > all committers will be people listed at MAINTAINERS.
> > > 
> > > On this series,:
> > > 
> > > patch 1: updates the  media maintainer's entry profile and adds the
> > > workflow that will be used with the new model. While here, it also
> > > adds a missing "P:" tag at the MAINTAINERS file, pointing to it;
> > > 
> > > patch 2: adds a new document focused at the new maintainers
> > > process. Its target is for developers that will be granted with
> > > commit rights at the new media-maintainers.git tree. It also
> > > contains a reference tag addition to kernel.org PGP chain
> > > at process/maintainer-pgp-guide.rst.
> > > 
> > > patch 3: make documents cleared about maintainership duties.  
> > 
> > At least from my perspective, v3 is close to being ready and I hope
> > that v4 will be good enough to be merged.
> > 
> > That said, what is missing in all this is that there is nothing here
> > that explains why you would want to become a media committer. It is all
> > very dry stuff, lots of 'shall's, and 'rights' and 'trust' and obligations,
> > but nothing about the satisfaction you get when you get the responsibility
> > of a part of the kernel and being able to guide the development of that
> > area.
> > 
> > It's good enough to get the multi-committer process off the ground, but
> > it definitely needs more work to make it more inviting to become a media
> > committer. Because right now it is as dry as dust.
> 
> Agreed. We focused on getting a document describing what it is expected
> by committers, in order to start with the model. My view is that it works
> fine for such purpose. I also feel that we're close to the final document.
> 
> I'm sending today a v4 addressing the comments since last review.
> 
> Once we get people that are already interested and ready to be on board,
> and we know that the model and infrastructure works properly, we may implement
> a phase 2 focusing on allowing more committers. For such purpose, we need to 
> document the benefits/satisfaction of becoming a new committer. Depending how
> it goes, either on phase 2 or on phase 3, we can change the model from 
> invitation-only to volunteer-requests.

What's phase 3 ?

-- 
Regards,

Laurent Pinchart



[PATCH v3 8/9] KVM: arm64: Allow control of dpISA extensions in ID_AA64ISAR3_EL1

2024-12-03 Thread Mark Brown
ID_AA64ISAR3_EL1 is currently marked as unallocated in KVM but does have a
number of bitfields defined in it. Expose FPRCVT and FAMINMAX, two simple
instruction only extensions to guests.

Signed-off-by: Mark Brown 
---
 arch/arm64/kvm/sys_regs.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 
83c6b4a07ef56cf0ed9c8751ec80686f45dca6b2..6efbe3f4a579afd1874c4cf844c1c1249ae8b942
 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1604,6 +1604,9 @@ static u64 __kvm_read_sanitised_id_reg(const struct 
kvm_vcpu *vcpu,
if (!cpus_have_final_cap(ARM64_HAS_WFXT))
val &= ~ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_WFxT);
break;
+   case SYS_ID_AA64ISAR3_EL1:
+   val &= ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_FAMINMAX;
+   break;
case SYS_ID_AA64MMFR2_EL1:
val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK;
break;
@@ -2608,7 +2611,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
ID_WRITABLE(ID_AA64ISAR2_EL1, ~(ID_AA64ISAR2_EL1_RES0 |
ID_AA64ISAR2_EL1_APA3 |
ID_AA64ISAR2_EL1_GPA3)),
-   ID_UNALLOCATED(6,3),
+   ID_WRITABLE(ID_AA64ISAR3_EL1, (ID_AA64ISAR3_EL1_FPRCVT |
+  ID_AA64ISAR3_EL1_FAMINMAX)),
ID_UNALLOCATED(6,4),
ID_UNALLOCATED(6,5),
ID_UNALLOCATED(6,6),

-- 
2.39.5




Re: [PATCH v3 0/3] Document the new media-committer's model

2024-12-03 Thread Mauro Carvalho Chehab
Em Tue, 3 Dec 2024 13:22:09 +0200
Laurent Pinchart  escreveu:

> On Tue, Dec 03, 2024 at 08:19:58AM +0100, Mauro Carvalho Chehab wrote:
> > Em Mon, 2 Dec 2024 16:03:45 +0100 Hans Verkuil escreveu:  
> > > On 02/12/2024 10:26, Mauro Carvalho Chehab wrote:  
> > > > The media subsystem used to have a multi-commiter's model in the
> > > > past, but things didn't go well on that time, and we had to move to
> > > > a centralized model.
> > > > 
> > > > As the community has evolved, and as there are now new policies in
> > > > place like CoC, let's experiment with a multi-committers again.
> > > > 
> > > > The model we're using was inspired by the DRM multi-committers
> > > > model. Yet, media subsystem is different on several aspects, so the
> > > > model is not exactly the same.
> > > > 
> > > > The implementation will be in phases. For this phase, the goal is that 
> > > > all committers will be people listed at MAINTAINERS.
> > > > 
> > > > On this series,:
> > > > 
> > > > patch 1: updates the  media maintainer's entry profile and adds the
> > > > workflow that will be used with the new model. While here, it also
> > > > adds a missing "P:" tag at the MAINTAINERS file, pointing to it;
> > > > 
> > > > patch 2: adds a new document focused at the new maintainers
> > > > process. Its target is for developers that will be granted with
> > > > commit rights at the new media-maintainers.git tree. It also
> > > > contains a reference tag addition to kernel.org PGP chain
> > > > at process/maintainer-pgp-guide.rst.
> > > > 
> > > > patch 3: make documents cleared about maintainership duties.
> > > 
> > > At least from my perspective, v3 is close to being ready and I hope
> > > that v4 will be good enough to be merged.
> > > 
> > > That said, what is missing in all this is that there is nothing here
> > > that explains why you would want to become a media committer. It is all
> > > very dry stuff, lots of 'shall's, and 'rights' and 'trust' and 
> > > obligations,
> > > but nothing about the satisfaction you get when you get the responsibility
> > > of a part of the kernel and being able to guide the development of that
> > > area.
> > > 
> > > It's good enough to get the multi-committer process off the ground, but
> > > it definitely needs more work to make it more inviting to become a media
> > > committer. Because right now it is as dry as dust.  
> > 
> > Agreed. We focused on getting a document describing what it is expected
> > by committers, in order to start with the model. My view is that it works
> > fine for such purpose. I also feel that we're close to the final document.
> > 
> > I'm sending today a v4 addressing the comments since last review.
> > 
> > Once we get people that are already interested and ready to be on board,
> > and we know that the model and infrastructure works properly, we may 
> > implement
> > a phase 2 focusing on allowing more committers. For such purpose, we need 
> > to 
> > document the benefits/satisfaction of becoming a new committer. Depending 
> > how
> > it goes, either on phase 2 or on phase 3, we can change the model from 
> > invitation-only to volunteer-requests.  
> 
> What's phase 3 ?

The idea is to gradually open media-committers to more people, as each
phase succeeds, addressing infra, procedures, etc.

My rough idea is to do:

- Phase 0.99: beta testers;
- Phase 1 is to invite people that regularly submit PRs;
- Phase 2 is to invite other active maintainers;
- Phase 3 (or 2?, TBD) to open for non-maintainers.

We shouldn't rush it, as there are a lot to be done before opening it
broadly. So, I would say that:
- phase 0.99 would start in -rc2 (if things go well during this week); 
- phase 1 may still happen on this merge window, but as there will be
  only a few weeks between -rc2 and -rc6, and people usually get
  holidays in Dec/Jan, it is more likely that it will start for
  6.14-rc1, again if we didn't notice big issues on phase 0.99.

  We should wait at least for a couple of releases on phase 1,
  again to cleanup process and fine-tune infra. If things go well, 
  we can move to phase 2.

Thanks,
Mauro



[PATCH v4 0/5]Document the new media-committer's model

2024-12-03 Thread Mauro Carvalho Chehab
The media subsystem used to have a multi-commiter's model in the
past, but things didn't go well on that time, and we had to move to
a centralized model.

As the community has evolved, and as there are now new policies in
place like CoC, let's experiment with a multi-committers again.

The model we're using was inspired by the DRM multi-committers
model. Yet, media subsystem is different on several aspects, so the
model is not exactly the same.

The implementation will be in phases. For this phase, the goal is that 
all committers will be people listed at MAINTAINERS.

On this series:

patch 1 adds a reference for PGP kernel keychain, in preparation for
links to it;

patch 2 fix two issues at the media MAINTAINERS file (S: and P:) tags;

patch 3: updates the  media maintainer's entry profile and adds the
workflow that will be used with the new model;

patch 4: adds a new document focused at the new maintainers
process. Its target is for developers that will be granted with
commit rights at the new media-maintainers.git tree. It also
contains a reference tag addition to kernel.org PGP chain
at process/maintainer-pgp-guide.rst.

patch 5: make documents cleared about maintainership duties.

---
v4:
- patches 1 and 2 were split from other patches;
- minor editorial changes as proposed by Hans, Sakari and Ricardo.

v3:
- added patch 3;
- addressed nits pointed by Ricardo during his review;
- did minor editorial changes to improve Sphinx html output.

v2: I tried to address most of the suggestions where there was an agreement
from Laurent's review and further comments. As there were several changes,
on separate threads, I could have missed something.

Mauro Carvalho Chehab (5):
  docs: maintainer-pgp-guide.rst: add a reference for kernel.org sign
  MAINTAINERS: fix a couple issues at media input infrastructure
  docs: media: update maintainer-entry-profile for multi-committers
  docs: media: document media multi-committers rules and process
  docs: media: profile: make it clearer about maintainership duties

 Documentation/driver-api/media/index.rst  |   1 +
 .../media/maintainer-entry-profile.rst| 252 
 .../driver-api/media/media-committer.rst  | 280 ++
 .../process/maintainer-pgp-guide.rst  |   2 +
 MAINTAINERS   |   3 +-
 5 files changed, 486 insertions(+), 52 deletions(-)
 create mode 100644 Documentation/driver-api/media/media-committer.rst

-- 
2.47.1





[PATCH v4 1/5] docs: maintainer-pgp-guide.rst: add a reference for kernel.org sign

2024-12-03 Thread Mauro Carvalho Chehab
The media profile documentation will point to kernel.org sign.
Add a link to it.

Signed-off-by: Mauro Carvalho Chehab 
---
 Documentation/process/maintainer-pgp-guide.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/process/maintainer-pgp-guide.rst 
b/Documentation/process/maintainer-pgp-guide.rst
index f5277993b195..795ef8d89271 100644
--- a/Documentation/process/maintainer-pgp-guide.rst
+++ b/Documentation/process/maintainer-pgp-guide.rst
@@ -903,6 +903,8 @@ the new default in GnuPG v2). To set it, add (or modify) the
 
 trust-model tofu+pgp
 
+.. _kernel_org_trust_repository:
+
 Using the kernel.org web of trust repository
 
 
-- 
2.47.1




Re: [PATCH 5/5] KVM: arm64: Handle DABT caused by LS64* instructions on unsupported memory

2024-12-03 Thread Marc Zyngier
On Mon, 02 Dec 2024 13:55:04 +,
Yicong Yang  wrote:
> 
> From: Yicong Yang 
> 
> FEAT_LS64* instructions only support to access Device/Uncacheable
> memory, otherwise a data abort for unsupported Exclusive or atomic

Not quite. FEAT_LS64WB explicitly supports Write-Back mappings.

> access (0x35) is generated per spec. It's implementation defined
> whether the target exception level is routed and is possible to
> implemented as route to EL2 on a VHE VM. Per DDI0487K.a Section
> C3.2.12.2 Single-copy atomic 64-byte load/store:
> 
>   The check is performed against the resulting memory type after all
>   enabled stages of translation. In this case the fault is reported
>   at the final enabled stage of translation.
> 
> If it's implemented as generate the DABT to the final enabled stage
> (stage-2), inject a DABT to the guest to handle it.
> 
> Signed-off-by: Yicong Yang 
> ---
>  arch/arm64/kvm/mmu.c | 14 ++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index c9d46ad57e52..b7e6f0a27537 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1787,6 +1787,20 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
>   return 1;
>   }
>  
> + /*
> +  * If instructions of FEAT_{LS64, LS64_V, LS64_ACCDATA} operated on
> +  * unsupported memory regions, a DABT for unsupported Exclusive or
> +  * atomic access is generated. It's implementation defined whether
> +  * the exception will be taken to, a stage-1 DABT or the final enabled
> +  * stage of translation (stage-2 in this case as we hit here). Inject
> +  * a DABT to the guest to handle it if it's implemented as a stage-2
> +  * DABT.
> +  */
> + if (esr_fsc_is_excl_atomic_fault(esr)) {
> + kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
> + return 1;
> + }

This doesn't seem quite right. This is injecting an *External* Data
Abort, which is not what the spec says happens, as you are emulating
the *first* acceptable behaviour:

  "The check is performed at each enabled stage of translation, and
   the fault is reported for the first stage of translation that
   provides an inappropriate memory type. In this case, the value of
   the HCR_EL2.DC bit does not cause accesses generated by the
   instructions to generate a stage 1 Data abort,"

So while the exception is reported at a different EL, the fault should
still be an "unsupported Exclusive or atomic access". But that's also
assuming that S2 has a device mapping, and it is EL1 that did
something wrong. Surely you should check the IPA against its memory
type?

Further questions: what happens when a L2 guest triggers such fault?
I don't think you can't arbitrarily route it back to L2 without
looking at why it faulted.

Thanks,

M.

-- 
Without deviation from the norm, progress is not possible.



Re: [PATCH 2/5] arm64: Add support for FEAT_{LS64, LS64_V, LS64_ACCDATA}

2024-12-03 Thread Marc Zyngier
On Mon, 02 Dec 2024 13:55:01 +,
Yicong Yang  wrote:
> 
> From: Yicong Yang 
> 
> Armv8.7 introduces single-copy atomic 64-byte loads and stores
> instructions and its variants named under FEAT_{LS64, LS64_V,
> LS64_ACCDATA}. These features are identified by ID_AA64ISAR1_EL1.LS64
> and the use of such instructions in userspace (EL0) can be trapped.
> In order to support the use of corresponding instructions in userspace:
> - Make ID_AA64ISAR1_EL1.LS64 visbile to userspace
> - Add identifying and enabling in the cpufeature list
> - Expose these support of these features to userspace through HWCAP
>   and cpuinfo
> 
> Signed-off-by: Yicong Yang 
> ---
>  Documentation/arch/arm64/booting.rst| 28 ++
>  Documentation/arch/arm64/elf_hwcaps.rst |  9 
>  arch/arm64/include/asm/hwcap.h  |  3 ++
>  arch/arm64/include/uapi/asm/hwcap.h |  3 ++
>  arch/arm64/kernel/cpufeature.c  | 70 -
>  arch/arm64/kernel/cpuinfo.c |  3 ++
>  arch/arm64/tools/cpucaps|  3 ++
>  7 files changed, 118 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/arch/arm64/booting.rst 
> b/Documentation/arch/arm64/booting.rst
> index 3278fb4bf219..c35cfe9da501 100644
> --- a/Documentation/arch/arm64/booting.rst
> +++ b/Documentation/arch/arm64/booting.rst
> @@ -449,6 +449,34 @@ Before jumping into the kernel, the following conditions 
> must be met:
>  
>  - HFGWTR_EL2.nGCS_EL0 (bit 52) must be initialised to 0b1.
>  
> +  For CPUs support for 64-byte loads and stores without status (FEAT_LS64):
> +
> +  - If the kernel is entered at EL1 and EL2 is present:
> +
> +- HCRX_EL2.EnALS (bit 1) must be initialised to 0b1.
> +
> +  For CPUs support for 64-byte loads and stores with status (FEAT_LS64_V):
> +
> +  - If the kernel is entered at EL1 and EL2 is present:
> +
> +- HCRX_EL2.EnASR (bit 2) must be initialised to 0b1.
> +
> +  For CPUs support for 64-byte EL0 stores with status (FEAT_LS64_ACCDATA):
> +
> +  - If EL3 is present:
> +
> +- SCR_EL3.EnAS0 (bit 36) must be initialised to 0b1.
> +
> +- SCR_EL3.ADEn (bit 37) must be initialised to 0b1.
> +
> +  - If the kernel is entered at EL1 and EL2 is present:
> +
> +- HCRX_EL2.EnAS0 (bit 0) must be initialised to 0b1.
> +
> +- HFGRTR_EL2.nACCDATA_EL1 (bit 50) must be initialised to 0b1.
> +
> +- HFGWTR_EL2.nACCDATA_EL1 (bit 50) must be initialised to 0b1.
> +
>  The requirements described above for CPU mode, caches, MMUs, architected
>  timers, coherency and system registers apply to all CPUs.  All CPUs must
>  enter the kernel in the same exception level.  Where the values documented
> diff --git a/Documentation/arch/arm64/elf_hwcaps.rst 
> b/Documentation/arch/arm64/elf_hwcaps.rst
> index 2ff922a406ad..6cb2594f0803 100644
> --- a/Documentation/arch/arm64/elf_hwcaps.rst
> +++ b/Documentation/arch/arm64/elf_hwcaps.rst
> @@ -372,6 +372,15 @@ HWCAP2_SME_SF8DP4
>  HWCAP2_POE
>  Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001.
>  
> +HWCAP3_LS64
> +Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0001.
> +
> +HWCAP3_LS64_V
> +Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0010.
> +
> +HWCAP3_LS64_ACCDATA
> +Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0011.
> +

I don't mind the two others, but I seriously question exposing ST64BV0
to userspace. How is ACCDATA_EL1 populated? How is it context-switched?

As it stands, this either does the wrong thing by always having the
low 32bit set to an UNKNOWN value, or actively leaks kernel data.
TBH, I don't see it being usable in practice (the more I read this
part of the architecture, the more broken it looks).

Thanks,

M.

-- 
Without deviation from the norm, progress is not possible.



[PATCH v2 07/13] iommufd/viommu: Add iommufd_viommu_report_irq helper

2024-12-03 Thread Nicolin Chen
Similar to iommu_report_device_fault, this allows IOMMU drivers to report,
from threaded IRQ handlers to user space hypervisors, IRQs or events that
belong to a vIOMMU.

Signed-off-by: Nicolin Chen 
---
 include/linux/iommufd.h|  9 
 drivers/iommu/iommufd/driver.c | 41 ++
 2 files changed, 50 insertions(+)

diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 1f5376476cfa..2ce78edec4e9 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -192,6 +192,8 @@ struct device *iommufd_viommu_find_dev(struct 
iommufd_viommu *viommu,
   unsigned long vdev_id);
 unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
 struct device *dev);
+int iommufd_viommu_report_irq(struct iommufd_viommu *viommu, unsigned int type,
+ void *irq_ptr, size_t irq_len);
 #else /* !CONFIG_IOMMUFD_DRIVER_CORE */
 static inline struct iommufd_object *
 _iommufd_object_alloc(struct iommufd_ctx *ictx, size_t size,
@@ -211,6 +213,13 @@ iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu, 
struct device *dev)
 {
return 0;
 }
+
+static inline int iommufd_viommu_report_irq(struct iommufd_viommu *viommu,
+   unsigned int type, void *irq_ptr,
+   size_t irq_len)
+{
+   return -EOPNOTSUPP;
+}
 #endif /* CONFIG_IOMMUFD_DRIVER_CORE */
 
 /*
diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c
index 817e430a11bc..339baa270d1e 100644
--- a/drivers/iommu/iommufd/driver.c
+++ b/drivers/iommu/iommufd/driver.c
@@ -67,5 +67,46 @@ unsigned long iommufd_viommu_get_vdev_id(struct 
iommufd_viommu *viommu,
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_viommu_get_vdev_id, IOMMUFD);
 
+/* Typically called in driver's threaded IRQ handler */
+int iommufd_viommu_report_irq(struct iommufd_viommu *viommu, unsigned int type,
+ void *irq_ptr, size_t irq_len)
+{
+   struct iommufd_eventq_virq *eventq_virq;
+   struct iommufd_virq *virq;
+   int rc = 0;
+
+   might_sleep();
+
+   if (!viommu)
+   return -ENODEV;
+   if (WARN_ON_ONCE(!irq_len || !irq_ptr))
+   return -EINVAL;
+
+   down_read(&viommu->virqs_rwsem);
+
+   eventq_virq = iommufd_viommu_find_eventq_virq(viommu, type);
+   if (!eventq_virq) {
+   rc = -EOPNOTSUPP;
+   goto out_unlock_vdev_ids;
+   }
+
+   virq = kzalloc(sizeof(*virq) + irq_len, GFP_KERNEL);
+   if (!virq) {
+   rc = -ENOMEM;
+   goto out_unlock_vdev_ids;
+   }
+   virq->irq_data = (void *)virq + sizeof(*virq);
+   memcpy(virq->irq_data, irq_ptr, irq_len);
+
+   virq->eventq_virq = eventq_virq;
+   virq->irq_len = irq_len;
+
+   iommufd_eventq_virq_handler(virq);
+out_unlock_vdev_ids:
+   up_read(&viommu->virqs_rwsem);
+   return rc;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_viommu_report_irq, IOMMUFD);
+
 MODULE_DESCRIPTION("iommufd code shared with builtin modules");
 MODULE_LICENSE("GPL");
-- 
2.43.0




[PATCH v2 09/13] iommufd/selftest: Add IOMMU_TEST_OP_TRIGGER_VIRQ for vIRQ coverage

2024-12-03 Thread Nicolin Chen
The handler will get vDEVICE object from the given mdev and convert it to
its per-vIOMMU virtual ID to mimic a real IOMMU driver.

Signed-off-by: Nicolin Chen 
---
 drivers/iommu/iommufd/iommufd_test.h | 10 ++
 drivers/iommu/iommufd/selftest.c | 30 
 2 files changed, 40 insertions(+)

diff --git a/drivers/iommu/iommufd/iommufd_test.h 
b/drivers/iommu/iommufd/iommufd_test.h
index a6b7a163f636..3037904f2e52 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -24,6 +24,7 @@ enum {
IOMMU_TEST_OP_MD_CHECK_IOTLB,
IOMMU_TEST_OP_TRIGGER_IOPF,
IOMMU_TEST_OP_DEV_CHECK_CACHE,
+   IOMMU_TEST_OP_TRIGGER_VIRQ,
 };
 
 enum {
@@ -145,6 +146,9 @@ struct iommu_test_cmd {
__u32 id;
__u32 cache;
} check_dev_cache;
+   struct {
+   __u32 dev_id;
+   } trigger_virq;
};
__u32 last;
 };
@@ -212,4 +216,10 @@ struct iommu_viommu_invalidate_selftest {
__u32 cache_id;
 };
 
+#define IOMMU_VIRQ_TYPE_SELFTEST 0xbeefbeef
+
+struct iommu_viommu_irq_selftest {
+   __u32 virt_id;
+};
+
 #endif
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index d1438d81e664..0785c9447102 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -1631,6 +1631,34 @@ static int iommufd_test_trigger_iopf(struct iommufd_ucmd 
*ucmd,
return 0;
 }
 
+static int iommufd_test_trigger_virq(struct iommufd_ucmd *ucmd,
+struct iommu_test_cmd *cmd)
+{
+   struct iommu_viommu_irq_selftest test = {};
+   struct iommufd_device *idev;
+   struct mock_dev *mdev;
+   int rc = -ENOENT;
+
+   idev = iommufd_get_device(ucmd, cmd->trigger_virq.dev_id);
+   if (IS_ERR(idev))
+   return PTR_ERR(idev);
+   mdev = to_mock_dev(idev->dev);
+
+   down_read(&mdev->viommu_rwsem);
+   if (!mdev->viommu || !mdev->vdev_id)
+   goto out_unlock;
+
+   test.virt_id = mdev->vdev_id;
+   rc = iommufd_viommu_report_irq(&mdev->viommu->core,
+  IOMMU_VIRQ_TYPE_SELFTEST, &test,
+  sizeof(test));
+out_unlock:
+   up_read(&mdev->viommu_rwsem);
+   iommufd_put_object(ucmd->ictx, &idev->obj);
+
+   return rc;
+}
+
 void iommufd_selftest_destroy(struct iommufd_object *obj)
 {
struct selftest_obj *sobj = to_selftest_obj(obj);
@@ -1712,6 +1740,8 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
  cmd->dirty.flags);
case IOMMU_TEST_OP_TRIGGER_IOPF:
return iommufd_test_trigger_iopf(ucmd, cmd);
+   case IOMMU_TEST_OP_TRIGGER_VIRQ:
+   return iommufd_test_trigger_virq(ucmd, cmd);
default:
return -EOPNOTSUPP;
}
-- 
2.43.0




[PATCH v2 12/13] iommu/arm-smmu-v3: Introduce struct arm_smmu_vmaster

2024-12-03 Thread Nicolin Chen
Use it to store all vSMMU-related data. The vsid (Virtual Stream ID) will
be the first use case. Then, add a rw_semaphore to protect it.

Also add a pair of arm_smmu_attach_prepare/commit_vmaster helpers and put
them in the existing arm_smmu_attach_prepare/commit(). Note that identity
and blocked ops don't call arm_smmu_attach_prepare/commit(), thus simply
call the new helpers at the top.

Signed-off-by: Nicolin Chen 
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   | 23 +
 .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 49 +++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 32 +++-
 3 files changed, 103 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 0107d3f333a1..ec7cff33a0b1 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -789,11 +789,18 @@ struct arm_smmu_stream {
struct rb_node  node;
 };
 
+struct arm_smmu_vmaster {
+   struct arm_vsmmu*vsmmu;
+   unsigned long   vsid;
+};
+
 /* SMMU private data for each master */
 struct arm_smmu_master {
struct arm_smmu_device  *smmu;
struct device   *dev;
struct arm_smmu_stream  *streams;
+   struct arm_smmu_vmaster *vmaster;
+   struct rw_semaphore vmaster_rwsem;
/* Locked by the iommu core using the group mutex */
struct arm_smmu_ctx_desc_cfgcd_table;
unsigned intnum_streams;
@@ -943,6 +950,7 @@ struct arm_smmu_attach_state {
bool disable_ats;
ioasid_t ssid;
/* Resulting state */
+   struct arm_smmu_vmaster *vmaster;
bool ats_enabled;
 };
 
@@ -1026,9 +1034,24 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device 
*dev,
   struct iommu_domain *parent,
   struct iommufd_ctx *ictx,
   unsigned int viommu_type);
+int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+   struct iommu_domain *domain);
+void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state);
 #else
 #define arm_smmu_hw_info NULL
 #define arm_vsmmu_alloc NULL
+
+static inline int
+arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+   struct iommu_domain *domain)
+{
+   return 0; /* NOP */
+}
+
+static inline void
+arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
+{
+}
 #endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
 
 #endif /* _ARM_SMMU_V3_H */
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 6cc14d82399f..3a77eca949e6 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -85,6 +85,55 @@ static void arm_smmu_make_nested_domain_ste(
}
 }
 
+int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
+   struct iommu_domain *domain)
+{
+   struct arm_smmu_nested_domain *nested_domain;
+   struct arm_smmu_vmaster *vmaster;
+   unsigned long vsid;
+   unsigned int cfg;
+
+   iommu_group_mutex_assert(state->master->dev);
+
+   if (domain->type != IOMMU_DOMAIN_NESTED)
+   return 0;
+   nested_domain = to_smmu_nested_domain(domain);
+
+   /* Skip ABORT/BYPASS or invalid vSTE */
+   cfg = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(nested_domain->ste[0]));
+   if (cfg == STRTAB_STE_0_CFG_ABORT || cfg == STRTAB_STE_0_CFG_BYPASS)
+   return 0;
+   if (!(nested_domain->ste[0] & cpu_to_le64(STRTAB_STE_0_V)))
+   return 0;
+
+   vsid = iommufd_viommu_get_vdev_id(&nested_domain->vsmmu->core,
+ state->master->dev);
+   /* Fail the attach if vSID is not correct set by the user space */
+   if (!vsid)
+   return -ENOENT;
+
+   vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
+   if (!vmaster)
+   return -ENOMEM;
+   vmaster->vsmmu = nested_domain->vsmmu;
+   vmaster->vsid = vsid;
+   state->vmaster = vmaster;
+
+   return 0;
+}
+
+void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
+{
+   struct arm_smmu_master *master = state->master;
+
+   down_write(&master->vmaster_rwsem);
+   if (state->vmaster != master->vmaster) {
+   kfree(master->vmaster);
+   master->vmaster = state->vmaster;
+   }
+   up_write(&master->vmaster_rwsem);
+}
+
 static int arm_smmu_attach_dev_nested(struct iommu_domain *domain,
  struct device *dev)
 {
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
b/drivers/iommu

[PATCH v2 02/13] iommufd/fault: Move iommufd_fault_iopf_handler() to header

2024-12-03 Thread Nicolin Chen
The new vIRQ object will need a similar function for drivers to report the
vIOMMU related interrupts. Split the common part out to a smaller helper,
and place it in the header so that CONFIG_IOMMUFD_DRIVER_CORE can include
that in the driver.c file for drivers to use.

Then keep iommufd_fault_iopf_handler() in the header too, since it's quite
simple after all.

Signed-off-by: Nicolin Chen 
---
 drivers/iommu/iommufd/iommufd_private.h | 20 +++-
 drivers/iommu/iommufd/fault.c   | 17 -
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/iommufd/iommufd_private.h 
b/drivers/iommu/iommufd/iommufd_private.h
index b6d706cf2c66..8b378705ee71 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -451,6 +451,17 @@ struct iommufd_fault {
struct wait_queue_head wait_queue;
 };
 
+static inline int iommufd_fault_notify(struct iommufd_fault *fault,
+  struct list_head *new_fault)
+{
+   mutex_lock(&fault->mutex);
+   list_add_tail(new_fault, &fault->deliver);
+   mutex_unlock(&fault->mutex);
+
+   wake_up_interruptible(&fault->wait_queue);
+   return 0;
+}
+
 struct iommufd_attach_handle {
struct iommu_attach_handle handle;
struct iommufd_device *idev;
@@ -469,7 +480,14 @@ iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id)
 
 int iommufd_fault_alloc(struct iommufd_ucmd *ucmd);
 void iommufd_fault_destroy(struct iommufd_object *obj);
-int iommufd_fault_iopf_handler(struct iopf_group *group);
+
+static inline int iommufd_fault_iopf_handler(struct iopf_group *group)
+{
+   struct iommufd_hw_pagetable *hwpt =
+   group->attach_handle->domain->fault_data;
+
+   return iommufd_fault_notify(hwpt->fault, &group->node);
+}
 
 int iommufd_fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,
struct iommufd_device *idev);
diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
index 87c811b9c0d0..5694b04a48bd 100644
--- a/drivers/iommu/iommufd/fault.c
+++ b/drivers/iommu/iommufd/fault.c
@@ -433,20 +433,3 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 
return rc;
 }
-
-int iommufd_fault_iopf_handler(struct iopf_group *group)
-{
-   struct iommufd_hw_pagetable *hwpt;
-   struct iommufd_fault *fault;
-
-   hwpt = group->attach_handle->domain->fault_data;
-   fault = hwpt->fault;
-
-   mutex_lock(&fault->mutex);
-   list_add_tail(&group->node, &fault->deliver);
-   mutex_unlock(&fault->mutex);
-
-   wake_up_interruptible(&fault->wait_queue);
-
-   return 0;
-}
-- 
2.43.0




[PATCH v2 04/13] iommufd: Rename fault.c to eventq.c

2024-12-03 Thread Nicolin Chen
Rename the file, aligning with the new eventq object.

Signed-off-by: Nicolin Chen 
---
 drivers/iommu/iommufd/Makefile  | 2 +-
 drivers/iommu/iommufd/{fault.c => eventq.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/iommu/iommufd/{fault.c => eventq.c} (100%)

diff --git a/drivers/iommu/iommufd/Makefile b/drivers/iommu/iommufd/Makefile
index cb784da6cddc..71d692c9a8f4 100644
--- a/drivers/iommu/iommufd/Makefile
+++ b/drivers/iommu/iommufd/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 iommufd-y := \
device.o \
-   fault.o \
+   eventq.o \
hw_pagetable.o \
io_pagetable.o \
ioas.o \
diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/eventq.c
similarity index 100%
rename from drivers/iommu/iommufd/fault.c
rename to drivers/iommu/iommufd/eventq.c
-- 
2.43.0




[PATCH v2 03/13] iommufd: Rename IOMMUFD_OBJ_FAULT to IOMMUFD_OBJ_EVENTQ_IOPF

2024-12-03 Thread Nicolin Chen
The fault object was designed exclusively for hwpt's IO page faults (PRI).
But its implementation can actually be reused for other purposes too, such
as hardware IRQ and event injections to user space.

Meanwhile, a fault object holds a list of faults. So it's more accurate to
call it a "fault queue". Combining the reusing idea above, a "fault queue"
can further rephrase to an "Event Queue for IOPF".

Rename the struct iommufd_fault to struct iommufd_eventq_iopf that holds a
common Event Queue struct, similar to hwpt_paging holding a common hwpt.

Roll out a minimal level of renamings to all the related functions.

Add a common iommufd_eventq_ops and iommufd_eventq_init to prepare for an
IOMMUFD_OBJ_EVENTQ_VIRQ. Also, add missing xa_destroy and mutex_destroy in
iommufd_fault_destroy().

Signed-off-by: Nicolin Chen 
---
 drivers/iommu/iommufd/iommufd_private.h |  87 ++
 include/linux/iommufd.h |   2 +-
 drivers/iommu/iommufd/fault.c   | 221 ++--
 drivers/iommu/iommufd/hw_pagetable.c|  12 +-
 drivers/iommu/iommufd/main.c|   8 +-
 5 files changed, 195 insertions(+), 135 deletions(-)

diff --git a/drivers/iommu/iommufd/iommufd_private.h 
b/drivers/iommu/iommufd/iommufd_private.h
index 8b378705ee71..1c9a101cc435 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -18,6 +18,8 @@ struct iommu_domain;
 struct iommu_group;
 struct iommu_option;
 struct iommufd_device;
+struct iommufd_eventq;
+struct iommufd_eventq_iopf;
 
 struct iommufd_ctx {
struct file *file;
@@ -275,7 +277,7 @@ int iommufd_check_iova_range(struct io_pagetable *iopt,
 struct iommufd_hw_pagetable {
struct iommufd_object obj;
struct iommu_domain *domain;
-   struct iommufd_fault *fault;
+   struct iommufd_eventq_iopf *fault;
 };
 
 struct iommufd_hwpt_paging {
@@ -433,32 +435,35 @@ void iopt_remove_access(struct io_pagetable *iopt,
u32 iopt_access_list_id);
 void iommufd_access_destroy_object(struct iommufd_object *obj);
 
-/*
- * An iommufd_fault object represents an interface to deliver I/O page faults
- * to the user space. These objects are created/destroyed by the user space and
- * associated with hardware page table objects during page-table allocation.
- */
-struct iommufd_fault {
+struct iommufd_eventq_ops {
+   ssize_t (*read)(struct iommufd_eventq *eventq, char __user *buf,
+   size_t count, loff_t *ppos);
+   ssize_t (*write)(struct iommufd_eventq *eventq, const char __user *buf,
+size_t count, loff_t *ppos);
+};
+
+struct iommufd_eventq {
struct iommufd_object obj;
struct iommufd_ctx *ictx;
struct file *filep;
 
-   /* The lists of outstanding faults protected by below mutex. */
+   const struct iommufd_eventq_ops *ops;
+
+   /* The lists of outstanding events protected by below mutex. */
struct mutex mutex;
struct list_head deliver;
-   struct xarray response;
 
struct wait_queue_head wait_queue;
 };
 
-static inline int iommufd_fault_notify(struct iommufd_fault *fault,
-  struct list_head *new_fault)
+static inline int iommufd_eventq_notify(struct iommufd_eventq *eventq,
+   struct list_head *new_event)
 {
-   mutex_lock(&fault->mutex);
-   list_add_tail(new_fault, &fault->deliver);
-   mutex_unlock(&fault->mutex);
+   mutex_lock(&eventq->mutex);
+   list_add_tail(new_event, &eventq->deliver);
+   mutex_unlock(&eventq->mutex);
 
-   wake_up_interruptible(&fault->wait_queue);
+   wake_up_interruptible(&eventq->wait_queue);
return 0;
 }
 
@@ -470,38 +475,54 @@ struct iommufd_attach_handle {
 /* Convert an iommu attach handle to iommufd handle. */
 #define to_iommufd_handle(hdl) container_of(hdl, struct iommufd_attach_handle, 
handle)
 
-static inline struct iommufd_fault *
-iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id)
+/*
+ * An iommufd_eventq_iopf object represents a queue to deliver I/O page faults
+ * to the user space. These objects are created/destroyed by the user space and
+ * associated with hardware page table objects during page-table allocation.
+ */
+struct iommufd_eventq_iopf {
+   struct iommufd_eventq common;
+   struct xarray response;
+};
+
+static inline struct iommufd_eventq_iopf *
+to_eventq_iopf(struct iommufd_eventq *eventq)
+{
+   return container_of(eventq, struct iommufd_eventq_iopf, common);
+}
+
+static inline struct iommufd_eventq_iopf *
+iommufd_get_eventq_iopf(struct iommufd_ucmd *ucmd, u32 id)
 {
return container_of(iommufd_get_object(ucmd->ictx, id,
-  IOMMUFD_OBJ_FAULT),
-   struct iommufd_fault, obj);
+  IOMMUFD_OBJ_EVENTQ_IOPF),
+   struct iommu

[PATCH v2 13/13] iommu/arm-smmu-v3: Report IRQs that belong to devices attached to vIOMMU

2024-12-03 Thread Nicolin Chen
Aside from the IOPF framework, iommufd provides an additional pathway to
report a hardware event or IRQ, via the vIRQ of vIOMMU infrastructure.

Define an iommu_virq_arm_smmuv3 uAPI structure, and report stage-1 faults
in the threaded IRQ handler.

Signed-off-by: Nicolin Chen 
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  7 +++
 include/uapi/linux/iommufd.h  | 14 +
 .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 16 +
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 62 ++-
 4 files changed, 71 insertions(+), 28 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index ec7cff33a0b1..05915f141eb8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -1037,6 +1037,7 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
 int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
struct iommu_domain *domain);
 void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state);
+int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt);
 #else
 #define arm_smmu_hw_info NULL
 #define arm_vsmmu_alloc NULL
@@ -1052,6 +1053,12 @@ static inline void
 arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state)
 {
 }
+
+static inline int
+arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt)
+{
+   return -EOPNOTSUPP;
+}
 #endif /* CONFIG_ARM_SMMU_V3_IOMMUFD */
 
 #endif /* _ARM_SMMU_V3_H */
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index d9319f5b7c69..164920d7f0ab 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -1016,9 +1016,23 @@ struct iommu_ioas_change_process {
 /**
  * enum iommu_virq_type - Virtual IRQ Type
  * @IOMMU_VIRQ_TYPE_NONE: INVALID type
+ * @IOMMU_VIRQ_TYPE_ARM_SMMUV3: ARM SMMUv3 Virtual Event
  */
 enum iommu_virq_type {
IOMMU_VIRQ_TYPE_NONE = 0,
+   IOMMU_VIRQ_TYPE_ARM_SMMUV3 = 1,
+};
+
+/**
+ * struct iommu_virq_arm_smmuv3 - ARM SMMUv3 Virtual IRQ
+ *(IOMMU_VIRQ_TYPE_ARM_SMMUV3)
+ * @evt: 256-bit ARM SMMUv3 Event record, little-endian.
+ *
+ * StreamID field reports a virtual device ID. To receive a virtual IRQ for a
+ * device, a vDEVICE must be allocated via IOMMU_VDEVICE_ALLOC.
+ */
+struct iommu_virq_arm_smmuv3 {
+   __aligned_le64 evt[4];
 };
 
 /**
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 3a77eca949e6..e3ef77e0bffd 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -447,4 +447,20 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
return &vsmmu->core;
 }
 
+int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt)
+{
+   struct iommu_virq_arm_smmuv3 virq_data =
+   *(struct iommu_virq_arm_smmuv3 *)evt;
+
+   virq_data.evt[0] &= ~EVTQ_0_SID;
+   virq_data.evt[0] |= FIELD_PREP(EVTQ_0_SID, vmaster->vsid);
+
+   virq_data.evt[0] = cpu_to_le64(virq_data.evt[0]);
+   virq_data.evt[1] = cpu_to_le64(virq_data.evt[1]);
+
+   return iommufd_viommu_report_irq(&vmaster->vsmmu->core,
+IOMMU_VIRQ_TYPE_ARM_SMMUV3, &virq_data,
+sizeof(virq_data));
+}
+
 MODULE_IMPORT_NS(IOMMUFD);
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 6a6113b36360..215c2d811eb7 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1779,33 +1779,6 @@ static int arm_smmu_handle_evt(struct arm_smmu_device 
*smmu, u64 *evt)
return -EOPNOTSUPP;
}
 
-   if (!(evt[1] & EVTQ_1_STALL))
-   return -EOPNOTSUPP;
-
-   if (evt[1] & EVTQ_1_RnW)
-   perm |= IOMMU_FAULT_PERM_READ;
-   else
-   perm |= IOMMU_FAULT_PERM_WRITE;
-
-   if (evt[1] & EVTQ_1_InD)
-   perm |= IOMMU_FAULT_PERM_EXEC;
-
-   if (evt[1] & EVTQ_1_PnU)
-   perm |= IOMMU_FAULT_PERM_PRIV;
-
-   flt->type = IOMMU_FAULT_PAGE_REQ;
-   flt->prm = (struct iommu_fault_page_request) {
-   .flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE,
-   .grpid = FIELD_GET(EVTQ_1_STAG, evt[1]),
-   .perm = perm,
-   .addr = FIELD_GET(EVTQ_2_ADDR, evt[2]),
-   };
-
-   if (ssid_valid) {
-   flt->prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
-   flt->prm.pasid = FIELD_GET(EVTQ_0_SSID, evt[0]);
-   }
-
mutex_lock(&smmu->streams_mutex);
master = arm_smmu_find_master(smmu, sid);
if (!master) {
@@ -1813,7 +1786,40 @@ static int arm_smmu_handle_evt(struct arm_smmu_device 
*smmu, u64 *evt)
  

[PATCH v2 05/13] iommufd: Add IOMMUFD_OBJ_EVENTQ_VIRQ and IOMMUFD_CMD_VIRQ_ALLOC

2024-12-03 Thread Nicolin Chen
Allow a vIOMMU object to allocate vIRQ Event Queues, with a condition that
each vIOMMU can only have one single vIRQ event queue per type.

Add iommufd_eventq_virq_alloc with an iommufd_eventq_virq_ops for this new
ioctl.

Signed-off-by: Nicolin Chen 
---
 drivers/iommu/iommufd/iommufd_private.h |  59 ++
 include/linux/iommufd.h |   3 +
 include/uapi/linux/iommufd.h|  31 ++
 drivers/iommu/iommufd/eventq.c  | 138 
 drivers/iommu/iommufd/main.c|   6 ++
 drivers/iommu/iommufd/viommu.c  |   2 +
 6 files changed, 239 insertions(+)

diff --git a/drivers/iommu/iommufd/iommufd_private.h 
b/drivers/iommu/iommufd/iommufd_private.h
index 1c9a101cc435..fd0b87707967 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -548,6 +548,51 @@ static inline int iommufd_hwpt_replace_device(struct 
iommufd_device *idev,
return iommu_group_replace_domain(idev->igroup->group, hwpt->domain);
 }
 
+/*
+ * An iommufd_eventq_virq object represents a queue to deliver vIOMMU 
interrupts
+ * to the user space. These objects are created/destroyed by the user space and
+ * associated with vIOMMU object(s) during the allocations.
+ */
+struct iommufd_eventq_virq {
+   struct iommufd_eventq common;
+   struct iommufd_viommu *viommu;
+   struct workqueue_struct *irq_wq;
+   struct list_head node;
+
+   unsigned int type;
+};
+
+static inline struct iommufd_eventq_virq *
+to_eventq_virq(struct iommufd_eventq *eventq)
+{
+   return container_of(eventq, struct iommufd_eventq_virq, common);
+}
+
+static inline struct iommufd_eventq_virq *
+iommufd_get_eventq_virq(struct iommufd_ucmd *ucmd, u32 id)
+{
+   return container_of(iommufd_get_object(ucmd->ictx, id,
+  IOMMUFD_OBJ_EVENTQ_VIRQ),
+   struct iommufd_eventq_virq, common.obj);
+}
+
+int iommufd_eventq_virq_alloc(struct iommufd_ucmd *ucmd);
+void iommufd_eventq_virq_destroy(struct iommufd_object *obj);
+void iommufd_eventq_virq_abort(struct iommufd_object *obj);
+
+/* An iommufd_virq represents a vIOMMU interrupt in an eventq_virq queue */
+struct iommufd_virq {
+   struct iommufd_eventq_virq *eventq_virq;
+   struct list_head node;
+   ssize_t irq_len;
+   void *irq_data;
+};
+
+static inline int iommufd_eventq_virq_handler(struct iommufd_virq *virq)
+{
+   return iommufd_eventq_notify(&virq->eventq_virq->common, &virq->node);
+}
+
 static inline struct iommufd_viommu *
 iommufd_get_viommu(struct iommufd_ucmd *ucmd, u32 id)
 {
@@ -556,6 +601,20 @@ iommufd_get_viommu(struct iommufd_ucmd *ucmd, u32 id)
struct iommufd_viommu, obj);
 }
 
+static inline struct iommufd_eventq_virq *
+iommufd_viommu_find_eventq_virq(struct iommufd_viommu *viommu, u32 type)
+{
+   struct iommufd_eventq_virq *eventq_virq, *next;
+
+   lockdep_assert_held(&viommu->virqs_rwsem);
+
+   list_for_each_entry_safe(eventq_virq, next, &viommu->virqs, node) {
+   if (eventq_virq->type == type)
+   return eventq_virq;
+   }
+   return NULL;
+}
+
 int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd);
 void iommufd_viommu_destroy(struct iommufd_object *obj);
 int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd);
diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 7ad105ab8090..40cc9bbb1d24 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -32,6 +32,7 @@ enum iommufd_object_type {
IOMMUFD_OBJ_IOAS,
IOMMUFD_OBJ_ACCESS,
IOMMUFD_OBJ_EVENTQ_IOPF,
+   IOMMUFD_OBJ_EVENTQ_VIRQ,
IOMMUFD_OBJ_VIOMMU,
IOMMUFD_OBJ_VDEVICE,
 #ifdef CONFIG_IOMMUFD_TEST
@@ -93,6 +94,8 @@ struct iommufd_viommu {
const struct iommufd_viommu_ops *ops;
 
struct xarray vdevs;
+   struct list_head virqs;
+   struct rw_semaphore virqs_rwsem;
 
unsigned int type;
 };
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index 34810f6ae2b5..d9319f5b7c69 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -55,6 +55,7 @@ enum {
IOMMUFD_CMD_VIOMMU_ALLOC = 0x90,
IOMMUFD_CMD_VDEVICE_ALLOC = 0x91,
IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92,
+   IOMMUFD_CMD_VIRQ_ALLOC = 0x93,
 };
 
 /**
@@ -1012,4 +1013,34 @@ struct iommu_ioas_change_process {
 #define IOMMU_IOAS_CHANGE_PROCESS \
_IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS)
 
+/**
+ * enum iommu_virq_type - Virtual IRQ Type
+ * @IOMMU_VIRQ_TYPE_NONE: INVALID type
+ */
+enum iommu_virq_type {
+   IOMMU_VIRQ_TYPE_NONE = 0,
+};
+
+/**
+ * struct iommu_virq_alloc - ioctl(IOMMU_VIRQ_ALLOC)
+ * @size: sizeof(struct iommu_virq_alloc)
+ * @flags: Must be 0
+ * @viommu: virtual IOMMU ID to associate the virtual IRQ with
+ * @type: Type of the virtual IRQ. Must be defined in enum iommu_virq_

[PATCH v2 06/13] iommufd/viommu: Add iommufd_viommu_get_vdev_id helper

2024-12-03 Thread Nicolin Chen
This is a reverse search v.s. iommufd_viommu_find_dev, as drivers may want
to convert a struct device pointer (physical) to its virtual device ID for
an event injection to the user space VM.

Again, this avoids exposing more core structures to the drivers, than the
iommufd_viommu alone.

Signed-off-by: Nicolin Chen 
---
 include/linux/iommufd.h|  8 
 drivers/iommu/iommufd/driver.c | 18 ++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 40cc9bbb1d24..1f5376476cfa 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -190,6 +190,8 @@ struct iommufd_object *_iommufd_object_alloc(struct 
iommufd_ctx *ictx,
 enum iommufd_object_type type);
 struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
   unsigned long vdev_id);
+unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
+struct device *dev);
 #else /* !CONFIG_IOMMUFD_DRIVER_CORE */
 static inline struct iommufd_object *
 _iommufd_object_alloc(struct iommufd_ctx *ictx, size_t size,
@@ -203,6 +205,12 @@ iommufd_viommu_find_dev(struct iommufd_viommu *viommu, 
unsigned long vdev_id)
 {
return NULL;
 }
+
+static inline unsigned long
+iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu, struct device *dev)
+{
+   return 0;
+}
 #endif /* CONFIG_IOMMUFD_DRIVER_CORE */
 
 /*
diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c
index 7b67fdf44134..817e430a11bc 100644
--- a/drivers/iommu/iommufd/driver.c
+++ b/drivers/iommu/iommufd/driver.c
@@ -49,5 +49,23 @@ struct device *iommufd_viommu_find_dev(struct iommufd_viommu 
*viommu,
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_viommu_find_dev, IOMMUFD);
 
+/* Return 0 if device is not associated to the vIOMMU */
+unsigned long iommufd_viommu_get_vdev_id(struct iommufd_viommu *viommu,
+struct device *dev)
+{
+   struct iommufd_vdevice *vdev;
+   unsigned long vdev_id = 0;
+   unsigned long index;
+
+   xa_lock(&viommu->vdevs);
+   xa_for_each(&viommu->vdevs, index, vdev) {
+   if (vdev && vdev->dev == dev)
+   vdev_id = (unsigned long)vdev->id;
+   }
+   xa_unlock(&viommu->vdevs);
+   return vdev_id;
+}
+EXPORT_SYMBOL_NS_GPL(iommufd_viommu_get_vdev_id, IOMMUFD);
+
 MODULE_DESCRIPTION("iommufd code shared with builtin modules");
 MODULE_LICENSE("GPL");
-- 
2.43.0




[PATCH v2 08/13] iommufd/selftest: Require vdev_id when attaching to a nested domain

2024-12-03 Thread Nicolin Chen
When attaching a device to a vIOMMU-based nested domain, vdev_id must be
present. Add a piece of code hard-requesting it, for vIRQ support in the
following patch. Then, update the TEST_F.

A HWPT-based nested domain will return a NULL new_viommu, thus no such a
vDEVICE requirement.

Signed-off-by: Nicolin Chen 
---
 drivers/iommu/iommufd/selftest.c| 23 +++
 tools/testing/selftests/iommu/iommufd.c |  5 +
 2 files changed, 28 insertions(+)

diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index a0de6d6d4e68..d1438d81e664 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -161,7 +161,10 @@ enum selftest_obj_type {
 
 struct mock_dev {
struct device dev;
+   struct mock_viommu *viommu;
+   struct rw_semaphore viommu_rwsem;
unsigned long flags;
+   unsigned long vdev_id;
int id;
u32 cache[MOCK_DEV_CACHE_NUM];
 };
@@ -193,10 +196,29 @@ static int mock_domain_nop_attach(struct iommu_domain 
*domain,
  struct device *dev)
 {
struct mock_dev *mdev = to_mock_dev(dev);
+   struct mock_viommu *new_viommu = NULL;
+   unsigned long vdev_id = 0;
 
if (domain->dirty_ops && (mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
return -EINVAL;
 
+   iommu_group_mutex_assert(dev);
+   if (domain->type == IOMMU_DOMAIN_NESTED) {
+   new_viommu = to_mock_nested(domain)->mock_viommu;
+   if (new_viommu) {
+   vdev_id = iommufd_viommu_get_vdev_id(&new_viommu->core,
+dev);
+   if (!vdev_id)
+   return -ENOENT;
+   }
+   }
+   if (new_viommu != mdev->viommu) {
+   down_write(&mdev->viommu_rwsem);
+   mdev->viommu = new_viommu;
+   mdev->vdev_id = vdev_id;
+   up_write(&mdev->viommu_rwsem);
+   }
+
return 0;
 }
 
@@ -861,6 +883,7 @@ static struct mock_dev *mock_dev_create(unsigned long 
dev_flags)
if (!mdev)
return ERR_PTR(-ENOMEM);
 
+   init_rwsem(&mdev->viommu_rwsem);
device_initialize(&mdev->dev);
mdev->flags = dev_flags;
mdev->dev.release = mock_dev_release;
diff --git a/tools/testing/selftests/iommu/iommufd.c 
b/tools/testing/selftests/iommu/iommufd.c
index a1b2b657999d..212e5d62e13d 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -2736,6 +2736,7 @@ TEST_F(iommufd_viommu, viommu_alloc_nested_iopf)
uint32_t iopf_hwpt_id;
uint32_t fault_id;
uint32_t fault_fd;
+   uint32_t vdev_id;
 
if (self->device_id) {
test_ioctl_fault_alloc(&fault_id, &fault_fd);
@@ -2752,6 +2753,10 @@ TEST_F(iommufd_viommu, viommu_alloc_nested_iopf)
&iopf_hwpt_id, IOMMU_HWPT_DATA_SELFTEST, &data,
sizeof(data));
 
+   /* Must allocate vdevice before attaching to a nested hwpt */
+   test_err_mock_domain_replace(ENOENT, self->stdev_id,
+iopf_hwpt_id);
+   test_cmd_vdevice_alloc(viommu_id, dev_id, 0x99, &vdev_id);
test_cmd_mock_domain_replace(self->stdev_id, iopf_hwpt_id);
EXPECT_ERRNO(EBUSY,
 _test_ioctl_destroy(self->fd, iopf_hwpt_id));
-- 
2.43.0




[PATCH v2 10/13] iommufd/selftest: Add EVENT_VIRQ test coverage

2024-12-03 Thread Nicolin Chen
Trigger an IRQ giving an idev ID, to test the loopback whether receiving
or not the vdev_id that was set to the idev by the line above.

Signed-off-by: Nicolin Chen 
---
 tools/testing/selftests/iommu/iommufd_utils.h | 63 +++
 tools/testing/selftests/iommu/iommufd.c   | 22 +++
 .../selftests/iommu/iommufd_fail_nth.c|  6 ++
 3 files changed, 91 insertions(+)

diff --git a/tools/testing/selftests/iommu/iommufd_utils.h 
b/tools/testing/selftests/iommu/iommufd_utils.h
index d979f5b0efe8..7e3e07c943cc 100644
--- a/tools/testing/selftests/iommu/iommufd_utils.h
+++ b/tools/testing/selftests/iommu/iommufd_utils.h
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "../kselftest_harness.h"
 #include "../../../../drivers/iommu/iommufd/iommufd_test.h"
@@ -936,3 +937,65 @@ static int _test_cmd_vdevice_alloc(int fd, __u32 
viommu_id, __u32 idev_id,
EXPECT_ERRNO(_errno, \
 _test_cmd_vdevice_alloc(self->fd, viommu_id, idev_id,   \
 virt_id, vdev_id))
+
+static int _test_cmd_virq_alloc(int fd, __u32 viommu_id, __u32 type,
+   __u32 *virq_id, __u32 *virq_fd)
+{
+   struct iommu_virq_alloc cmd = {
+   .size = sizeof(cmd),
+   .type = type,
+   .viommu_id = viommu_id,
+   };
+   int ret;
+
+   ret = ioctl(fd, IOMMU_VIRQ_ALLOC, &cmd);
+   if (ret)
+   return ret;
+   if (virq_id)
+   *virq_id = cmd.out_virq_id;
+   if (virq_fd)
+   *virq_fd = cmd.out_virq_fd;
+   return 0;
+}
+
+#define test_cmd_virq_alloc(viommu_id, type, virq_id, virq_fd)   \
+   ASSERT_EQ(0, _test_cmd_virq_alloc(self->fd, viommu_id, type, \
+   virq_id, virq_fd))
+#define test_err_virq_alloc(_errno, viommu_id, type, virq_id, virq_fd)   \
+   EXPECT_ERRNO(_errno, _test_cmd_virq_alloc(self->fd, viommu_id, type, \
+   virq_id, virq_fd))
+
+static int _test_cmd_trigger_virq(int fd, __u32 dev_id, __u32 event_fd,
+ __u32 virt_id)
+{
+   struct iommu_test_cmd trigger_virq_cmd = {
+   .size = sizeof(trigger_virq_cmd),
+   .op = IOMMU_TEST_OP_TRIGGER_VIRQ,
+   .trigger_virq = {
+   .dev_id = dev_id,
+   },
+   };
+   struct pollfd pollfd = { .fd = event_fd, .events = POLLIN };
+   struct iommu_viommu_irq_selftest irq;
+   ssize_t bytes;
+   int ret;
+
+   ret = ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_TRIGGER_VIRQ),
+   &trigger_virq_cmd);
+   if (ret)
+   return ret;
+
+   ret = poll(&pollfd, 1, 1000);
+   if (ret < 0)
+   return ret;
+
+   bytes = read(event_fd, &irq, sizeof(irq));
+   if (bytes <= 0)
+   return -EIO;
+
+   return irq.virt_id == virt_id ? 0 : -EINVAL;
+}
+
+#define test_cmd_trigger_virq(dev_id, event_fd, vdev_id) \
+   ASSERT_EQ(0, \
+ _test_cmd_trigger_virq(self->fd, dev_id, event_fd, vdev_id))
diff --git a/tools/testing/selftests/iommu/iommufd.c 
b/tools/testing/selftests/iommu/iommufd.c
index 212e5d62e13d..b15ebc963e56 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -2774,15 +2774,37 @@ TEST_F(iommufd_viommu, vdevice_alloc)
uint32_t viommu_id = self->viommu_id;
uint32_t dev_id = self->device_id;
uint32_t vdev_id = 0;
+   uint32_t virq_id;
+   uint32_t virq_fd;
 
if (dev_id) {
+   /* Must allocate vdevice before attaching to a nested hwpt */
+   test_err_mock_domain_replace(ENOENT, self->stdev_id,
+self->nested_hwpt_id);
+
+   test_cmd_virq_alloc(viommu_id, IOMMU_VIRQ_TYPE_SELFTEST,
+   &virq_id, &virq_fd);
+   test_err_virq_alloc(EEXIST, viommu_id, IOMMU_VIRQ_TYPE_SELFTEST,
+   NULL, NULL);
/* Set vdev_id to 0x99, unset it, and set to 0x88 */
test_cmd_vdevice_alloc(viommu_id, dev_id, 0x99, &vdev_id);
+   test_cmd_mock_domain_replace(self->stdev_id,
+self->nested_hwpt_id);
+   test_cmd_trigger_virq(dev_id, virq_fd, 0x99);
test_err_vdevice_alloc(EEXIST, viommu_id, dev_id, 0x99,
   &vdev_id);
+   test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
test_ioctl_destroy(vdev_id);
+
+   /* Try again with 0x88 */
test_cmd_vdevice_alloc(viommu_id, dev_id, 0x88, &vdev_id);
+   test_cmd_mock_domain_replace(self->stdev_id,
+

[PATCH v2 11/13] Documentation: userspace-api: iommufd: Update EVENTQ_IOPF and EVENTQ_VIRQ

2024-12-03 Thread Nicolin Chen
With the introduction of the new objects, update the doc to reflect that.

Signed-off-by: Nicolin Chen 
---
 Documentation/userspace-api/iommufd.rst | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/userspace-api/iommufd.rst 
b/Documentation/userspace-api/iommufd.rst
index 70289d6815d2..798520d9344d 100644
--- a/Documentation/userspace-api/iommufd.rst
+++ b/Documentation/userspace-api/iommufd.rst
@@ -63,6 +63,14 @@ Following IOMMUFD objects are exposed to userspace:
   space usually has mappings from guest-level I/O virtual addresses to guest-
   level physical addresses.
 
+- IOMMUFD_OBJ_EVENTQ_IOPF, representing a software queue for an HWPT_NESTED
+  reporting IO Page Fault using the IOMMU HW's PRI (Page Request Interface).
+  This queue object provides user space an FD to poll the page fault events
+  and also to respond to those events. An EVENTQ_IOPF object must be created
+  first to get a fault_id that could be then used to allocate an HWPT_NESTED
+  via the IOMMU_HWPT_ALLOC command setting IOMMU_HWPT_FAULT_ID_VALID set in
+  its flags field.
+
 - IOMMUFD_OBJ_VIOMMU, representing a slice of the physical IOMMU instance,
   passed to or shared with a VM. It may be some HW-accelerated virtualization
   features and some SW resources used by the VM. For examples:
@@ -109,6 +117,15 @@ Following IOMMUFD objects are exposed to userspace:
   vIOMMU, which is a separate ioctl call from attaching the same device to an
   HWPT_PAGING that the vIOMMU holds.
 
+- IOMMUFD_OBJ_EVENTQ_VIRQ, representing a software queue for IOMMUFD_OBJ_VIOMMU
+  reporting its non-affiliated events, such as translation faults occurred to a
+  nested stage-1 and HW-specific events/irqs e.g. events to invalidation queues
+  that are assigned to VMs via vIOMMUs. This queue object provides user space 
an
+  FD to poll the vIOMMU events. A vIOMMU object must be created first to get 
its
+  viommu_id that could be then used to allocate an EVENTQ_VIRQ. Each vIOMMU can
+  support multiple types of EVENTQ_VIRQs, but is confined to one EVENTQ_VIRQ 
per
+  vIRQ type.
+
 All user-visible objects are destroyed via the IOMMU_DESTROY uAPI.
 
 The diagrams below show relationships between user-visible objects and kernel
@@ -251,8 +268,10 @@ User visible objects are backed by following 
datastructures:
 - iommufd_device for IOMMUFD_OBJ_DEVICE.
 - iommufd_hwpt_paging for IOMMUFD_OBJ_HWPT_PAGING.
 - iommufd_hwpt_nested for IOMMUFD_OBJ_HWPT_NESTED.
+- iommufd_eventq_iopf for IOMMUFD_OBJ_EVENTQ_IOPF.
 - iommufd_viommu for IOMMUFD_OBJ_VIOMMU.
 - iommufd_vdevice for IOMMUFD_OBJ_VDEVICE.
+- iommufd_eventq_virq for IOMMUFD_OBJ_EVENTQ_VIRQ.
 
 Several terminologies when looking at these datastructures:
 
-- 
2.43.0




Re: [PATCH v6 00/15] integrity: Introduce the Integrity Digest Cache

2024-12-03 Thread Eric Snowberg


> On Nov 26, 2024, at 3:41 AM, Roberto Sassu  
> wrote:
> 
> On Tue, 2024-11-26 at 00:13 +, Eric Snowberg wrote:
>> 
>>> On Nov 19, 2024, at 3:49 AM, Roberto Sassu  
>>> wrote:
>>> 
>>> From: Roberto Sassu 
>>> 
>>> The Integrity Digest Cache can also help IMA for appraisal. IMA can simply
>>> lookup the calculated digest of an accessed file in the list of digests
>>> extracted from package headers, after verifying the header signature. It is
>>> sufficient to verify only one signature for all files in the package, as
>>> opposed to verifying a signature for each file.
>> 
>> Is there a way to maintain integrity over time?  Today if a CVE is 
>> discovered 
>> in a signed program, the program hash can be added to the blacklist keyring. 
>> Later if IMA appraisal is used, the signature validation will fail just for 
>> that 
>> program.  With the Integrity Digest Cache, is there a way to do this?  
> 
> As far as I can see, the ima_check_blacklist() call is before
> ima_appraise_measurement(). If it fails, appraisal with the Integrity
> Digest Cache will not be done.


It is good the program hash would be checked beforehand and fail if it is 
contained on the list. 

The .ima keyring may contain many keys.  If one of the keys was later 
revoked and added to the .blacklist, wouldn't this be missed?  It would 
be caught during signature validation when the file is later appraised, but 
now this step isn't taking place.  Correct?

With IMA appraisal, it is easy to maintain authenticity but challenging to 
maintain integrity over time. In user-space there are constantly new CVEs.  
To maintain integrity over time, either keys need to be rotated in the .ima 
keyring or program hashes need to be frequently added to the .blacklist.   
If neither is done, for an end-user on a distro, IMA-appraisal basically 
guarantees authenticity.

While I understand the intent of the series is to increase performance, 
have you considered using this to give the end-user the ability to maintain 
integrity of their system?  What I mean is, instead of trying to import 
anything 
from an RPM, just have the end-user provide this information in some format 
to the Digest Cache.  User-space tools could be built to collect and format 
the data needed by the Digest Cache.  This data  may allow multiple versions 
of the same program.  The data would then be signed by one of the system 
kernel keys (either something in the secondary or machine keyring), to maintain 
a root of trust.  This would give the end-user the ability to have integrity 
however 
they see fit.  This leaves the distro to provide signed programs and the 
end-user 
the ability to decide what level of software they want to run on their system.  
If 
something isn't in the Digest Cache, it gets bumped down to the traditional 
IMA-appraisal.  I think it would simplify the problem you are trying to solve, 
especially around the missing kernel PGP code required for all this to work, 
since it wouldn't be necessary.   With this approach, besides the performance 
gain, the end-user would gain the ability to maintain integrity that is 
enforced by
the kernel.



Re: [PATCH v2 0/3] Make Helped-by tag supported

2024-12-03 Thread Shuah Khan

On 12/2/24 10:11, Matthew Wilcox wrote:

On Mon, Dec 02, 2024 at 04:00:47PM +0100, Dragan Simic wrote:

On 2024-11-09 04:10, Dragan Simic wrote:

On 2024-11-08 20:12, Dan Williams wrote:

Dragan Simic wrote:

I'm fully aware that we may be reluctant to supporting
additional tags,
because we may then end up with a whole bunch of strange tags
that might
be a bit hard to understand and use properly, but I think that adding
Helped-by to the supported tag list may actually be a good thing
to do.
As described above, Helped-by fits very well between the Suggested-by
tag and the Co-developed-by + Signed-off-by pair of tags, and I think
that providing the right level of attribution may be beneficial.


Patch attribution is separate from giving thanks. I would much rather
someone take the time to say "Thanks" in the changelog with some
supporting text rather than boil down all the myriad ways to be
thankful
into a generic tag. "git log --grep=Thanks" often yields valuable
details, beyond just attribution, on how people have helped each other
develop this global project of ours. If the introduction of Helped-by
would replace even one authentic "Thank you" note with a generic tag
then it is a net loss for the community.


I do agree that writing "Thanks John for helping with..." in a patch
description would be nice, but unfortunately I've seen multiple times
that people don't enjoy writing their patch descriptions at all, and
just want to "get them out the door" as quickly as possible.

With that in mind, making Helped-by tags supported would allow such
people to at least quickly mention someone they're thankful to, which
actually wouldn't prevent anyone from saying the same more verbosely
in a patch description.


Just checking, are there any further thoughts on this patch?


I agree with Dan & Jon; we don't need this tag.  And if someone's doing
a poor job of writing commit messages, they need to be helped to write
better ones.



+1 on this. I don't think we need yet another tag.

thanks,
-- Shuah



Re: [PATCH v3 DONOTMERGE] docs: clarify rules wrt tagging other people

2024-12-03 Thread Shuah Khan

On 12/2/24 01:14, Thorsten Leemhuis wrote:

Point out that explicit permission is usually needed to tag other people
in changes, but mention that implicit permission can be sufficient in
certain cases. This fixes slight inconsistencies between Reported-by:
and Suggested-by: and makes the usage more intuitive.

While at it, explicitly mention the dangers of our bugzilla instance, as
it makes it easy to forget that email addresses visible there are only
shown to logged-in users.

The latter is not a theoretical issue, as one maintainer mentioned that
his employer received a EU GDPR (general data protection regulation)


Thank you for taking care of this.

Reviewed-by: Shuah Khan 

thanks,
-- Shuah






[PATCH v2 00/13] iommufd: Add vIOMMU infrastructure (Part-3: vIRQ)

2024-12-03 Thread Nicolin Chen
As the part-3 of the vIOMMU infrastructure, this series introduces a vIRQ
object. The existing FAULT object provides a nice notification pathway to
the user space already, so let vIRQ reuse the infrastructure.

Mimicing the HWPT structure, add a common EVENTQ structure to support its
derivatives: EVENTQ_IOPF (the prior FAULT object) and EVENTQ_VIRQ (new).
IOMMUFD_CMD_VIRQ_ALLOC is introduced to allocate EVENTQ_VIRQ for vIOMMUs.
One vIOMMU can have multiple vIRQs in different types but can not support
multiple vIRQs with the same types.

The forwarding part is fairly simple but might need to replace a physical
device ID with a virtual device ID in a driver-level IRQ data structure.
So, this comes with some helpers for drivers to use.

As usual, this series comes with the selftest coverage for this new vIRQ,
and with a real world use case in the ARM SMMUv3 driver.

This is on Github:
https://github.com/nicolinc/iommufd/commits/iommufd_virq-v2

Testing with RMR patches for MSI:
https://github.com/nicolinc/iommufd/commits/iommufd_virq-v2-with-rmr
Paring QEMU branch for testing:
https://github.com/nicolinc/qemu/commits/wip/for_iommufd_virq-v2

Changelog
v2
 * Rebased on v6.13-rc1
 * Added IOPF and vIRQ in iommufd.rst (userspace-api)
 * Added a proper locking in iommufd_event_virq_destroy
 * Added iommufd_event_virq_abort with a lockdep_assert_held
 * Renamed "EVENT_*" to "EVENTQ_*" to describe the objects better
 * Reorganized flows in iommufd_eventq_virq_alloc for abort() to work
 * Added struct arm_smmu_vmaster to store vSID upon attaching to a nested
   domain, calling a newly added iommufd_viommu_get_vdev_id helper
 * Added an arm_vmaster_report_event helper in arm-smmu-v3-iommufd file
   to simplify the routine in arm_smmu_handle_evt() of the main driver
v1
 https://lore.kernel.org/all/cover.1724777091.git.nicol...@nvidia.com/

Thanks!
Nicolin

Nicolin Chen (13):
  iommufd/fault: Add an iommufd_fault_init() helper
  iommufd/fault: Move iommufd_fault_iopf_handler() to header
  iommufd: Rename IOMMUFD_OBJ_FAULT to IOMMUFD_OBJ_EVENTQ_IOPF
  iommufd: Rename fault.c to eventq.c
  iommufd: Add IOMMUFD_OBJ_EVENTQ_VIRQ and IOMMUFD_CMD_VIRQ_ALLOC
  iommufd/viommu: Add iommufd_viommu_get_vdev_id helper
  iommufd/viommu: Add iommufd_viommu_report_irq helper
  iommufd/selftest: Require vdev_id when attaching to a nested domain
  iommufd/selftest: Add IOMMU_TEST_OP_TRIGGER_VIRQ for vIRQ coverage
  iommufd/selftest: Add EVENT_VIRQ test coverage
  Documentation: userspace-api: iommufd: Update EVENTQ_IOPF and
EVENTQ_VIRQ
  iommu/arm-smmu-v3: Introduce struct arm_smmu_vmaster
  iommu/arm-smmu-v3: Report IRQs that belong to devices attached to
vIOMMU

 drivers/iommu/iommufd/Makefile|   2 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  30 +
 drivers/iommu/iommufd/iommufd_private.h   | 150 -
 drivers/iommu/iommufd/iommufd_test.h  |  10 +
 include/linux/iommufd.h   |  22 +-
 include/uapi/linux/iommufd.h  |  45 ++
 tools/testing/selftests/iommu/iommufd_utils.h |  63 ++
 .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c |  65 ++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  94 ++-
 drivers/iommu/iommufd/driver.c|  59 ++
 drivers/iommu/iommufd/eventq.c| 612 ++
 drivers/iommu/iommufd/fault.c | 444 -
 drivers/iommu/iommufd/hw_pagetable.c  |  12 +-
 drivers/iommu/iommufd/main.c  |  14 +-
 drivers/iommu/iommufd/selftest.c  |  53 ++
 drivers/iommu/iommufd/viommu.c|   2 +
 tools/testing/selftests/iommu/iommufd.c   |  27 +
 .../selftests/iommu/iommufd_fail_nth.c|   6 +
 Documentation/userspace-api/iommufd.rst   |  19 +
 19 files changed, 1218 insertions(+), 511 deletions(-)
 create mode 100644 drivers/iommu/iommufd/eventq.c
 delete mode 100644 drivers/iommu/iommufd/fault.c


base-commit: 2ca704f55e22b7b00cc7025953091af3c82fa5c0
-- 
2.43.0




[PATCH v2 01/13] iommufd/fault: Add an iommufd_fault_init() helper

2024-12-03 Thread Nicolin Chen
A fault object will be renamed and shared with a new vIRQ object in one of
the following changes. Add a helper for the new allocator to call it too.

Reorder the iommufd_ctx_get and refcount_inc to keep them symmetrical with
the iommufd_fault_fops_release().

Since the new vIRQ object doesn't need "response", leave the xa_init_flags
in its original location.

Signed-off-by: Nicolin Chen 
---
 drivers/iommu/iommufd/fault.c | 48 ---
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c
index 1fe804e28a86..87c811b9c0d0 100644
--- a/drivers/iommu/iommufd/fault.c
+++ b/drivers/iommu/iommufd/fault.c
@@ -367,11 +367,35 @@ static const struct file_operations iommufd_fault_fops = {
.release= iommufd_fault_fops_release,
 };
 
+static int iommufd_fault_init(struct iommufd_fault *fault, char *name,
+ struct iommufd_ctx *ictx)
+{
+   struct file *filep;
+   int fdno;
+
+   fault->ictx = ictx;
+   mutex_init(&fault->mutex);
+   INIT_LIST_HEAD(&fault->deliver);
+   init_waitqueue_head(&fault->wait_queue);
+
+   filep = anon_inode_getfile(name, &iommufd_fault_fops, fault, O_RDWR);
+   if (IS_ERR(filep))
+   return PTR_ERR(filep);
+
+   fault->filep = filep;
+   iommufd_ctx_get(fault->ictx);
+   refcount_inc(&fault->obj.users);
+
+   fdno = get_unused_fd_flags(O_CLOEXEC);
+   if (fdno < 0)
+   fput(filep);
+   return fdno;
+}
+
 int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
 {
struct iommu_fault_alloc *cmd = ucmd->cmd;
struct iommufd_fault *fault;
-   struct file *filep;
int fdno;
int rc;
 
@@ -382,27 +406,12 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
if (IS_ERR(fault))
return PTR_ERR(fault);
 
-   fault->ictx = ucmd->ictx;
-   INIT_LIST_HEAD(&fault->deliver);
xa_init_flags(&fault->response, XA_FLAGS_ALLOC1);
-   mutex_init(&fault->mutex);
-   init_waitqueue_head(&fault->wait_queue);
-
-   filep = anon_inode_getfile("[iommufd-pgfault]", &iommufd_fault_fops,
-  fault, O_RDWR);
-   if (IS_ERR(filep)) {
-   rc = PTR_ERR(filep);
-   goto out_abort;
-   }
 
-   refcount_inc(&fault->obj.users);
-   iommufd_ctx_get(fault->ictx);
-   fault->filep = filep;
-
-   fdno = get_unused_fd_flags(O_CLOEXEC);
+   fdno = iommufd_fault_init(fault, "[iommufd-pgfault]", ucmd->ictx);
if (fdno < 0) {
rc = fdno;
-   goto out_fput;
+   goto out_abort;
}
 
cmd->out_fault_id = fault->obj.id;
@@ -418,8 +427,7 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
return 0;
 out_put_fdno:
put_unused_fd(fdno);
-out_fput:
-   fput(filep);
+   fput(fault->filep);
 out_abort:
iommufd_object_abort_and_destroy(ucmd->ictx, &fault->obj);
 
-- 
2.43.0