arm64: Expose SVE2 features for userspace
authorDave Martin <Dave.Martin@arm.com>
Thu, 18 Apr 2019 17:41:38 +0000 (18:41 +0100)
committerWill Deacon <will.deacon@arm.com>
Tue, 23 Apr 2019 17:02:00 +0000 (18:02 +0100)
This patch provides support for reporting the presence of SVE2 and
its optional features to userspace.

This will also enable visibility of SVE2 for guests, when KVM
support for SVE-enabled guests is available.

Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Documentation/arm64/cpu-feature-registers.txt
Documentation/arm64/elf_hwcaps.txt
Documentation/arm64/sve.txt
arch/arm64/Kconfig
arch/arm64/include/asm/hwcap.h
arch/arm64/include/asm/sysreg.h
arch/arm64/include/uapi/asm/hwcap.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/cpuinfo.c

index d4b4dd1fe786a16f9cd97d41c13dbf8425bb3321..684a0da3937863980bd84e92f025b6ee0141674a 100644 (file)
@@ -209,6 +209,22 @@ infrastructure:
      | AT                           | [35-32] |    y    |
      x--------------------------------------------------x
 
+  6) ID_AA64ZFR0_EL1 - SVE feature ID register 0
+
+     x--------------------------------------------------x
+     | Name                         |  bits   | visible |
+     |--------------------------------------------------|
+     | SM4                          | [43-40] |    y    |
+     |--------------------------------------------------|
+     | SHA3                         | [35-32] |    y    |
+     |--------------------------------------------------|
+     | BitPerm                      | [19-16] |    y    |
+     |--------------------------------------------------|
+     | AES                          | [7-4]   |    y    |
+     |--------------------------------------------------|
+     | SVEVer                       | [3-0]   |    y    |
+     x--------------------------------------------------x
+
 Appendix I: Example
 ---------------------------
 
index 55431fd2a67a68a18371165e4bdba0f4c5aedac3..b73a2519ecf231d74ab36f68a9fa2cfdee8af6ac 100644 (file)
@@ -163,6 +163,30 @@ HWCAP_SVE
 
     Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001.
 
+HWCAP2_SVE2
+
+    Functionality implied by ID_AA64ZFR0_EL1.SVEVer == 0b0001.
+
+HWCAP2_SVEAES
+
+    Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0001.
+
+HWCAP2_SVEPMULL
+
+    Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0010.
+
+HWCAP2_SVEBITPERM
+
+    Functionality implied by ID_AA64ZFR0_EL1.BitPerm == 0b0001.
+
+HWCAP2_SVESHA3
+
+    Functionality implied by ID_AA64ZFR0_EL1.SHA3 == 0b0001.
+
+HWCAP2_SVESM4
+
+    Functionality implied by ID_AA64ZFR0_EL1.SM4 == 0b0001.
+
 HWCAP_ASIMDFHM
 
    Functionality implied by ID_AA64ISAR0_EL1.FHM == 0b0001.
index 7169a0ec41d86911ad4a9c7fc34488841dc7c1e6..9940e924a47ed4cf378d083c76b4820e1cafd68d 100644 (file)
@@ -34,6 +34,23 @@ model features for SVE is included in Appendix A.
   following sections: software that needs to verify that those interfaces are
   present must check for HWCAP_SVE instead.
 
+* On hardware that supports the SVE2 extensions, HWCAP2_SVE2 will also
+  be reported in the AT_HWCAP2 aux vector entry.  In addition to this,
+  optional extensions to SVE2 may be reported by the presence of:
+
+       HWCAP2_SVE2
+       HWCAP2_SVEAES
+       HWCAP2_SVEPMULL
+       HWCAP2_SVEBITPERM
+       HWCAP2_SVESHA3
+       HWCAP2_SVESM4
+
+  This list may be extended over time as the SVE architecture evolves.
+
+  These extensions are also reported via the CPU ID register ID_AA64ZFR0_EL1,
+  which userspace can read using an MRS instruction.  See elf_hwcaps.txt and
+  cpu-feature-registers.txt for details.
+
 * Debuggers should restrict themselves to interacting with the target via the
   NT_ARM_SVE regset.  The recommended way of detecting support for this regset
   is to connect to a target process first and then attempt a
index 75c1a07abc728095e7609b043c874b90ffb62cc7..4791d485712441ca6a50f589d13c511ff7d27fb0 100644 (file)
@@ -1372,6 +1372,9 @@ config ARM64_SVE
 
          To enable use of this extension on CPUs that implement it, say Y.
 
+         On CPUs that support the SVE2 extensions, this option will enable
+         those too.
+
          Note that for architectural reasons, firmware _must_ implement SVE
          support when running on SVE capable hardware.  The required support
          is present in:
index f78c86c64e6825b2739d6c2ef52679885e83e23a..b4bfb6672168b3f24eb18bd1822e3a6dd7441580 100644 (file)
 
 #define __khwcap2_feature(x)           (const_ilog2(HWCAP2_ ## x) + 32)
 #define KERNEL_HWCAP_DCPODP            __khwcap2_feature(DCPODP)
+#define KERNEL_HWCAP_SVE2              __khwcap2_feature(SVE2)
+#define KERNEL_HWCAP_SVEAES            __khwcap2_feature(SVEAES)
+#define KERNEL_HWCAP_SVEPMULL          __khwcap2_feature(SVEPMULL)
+#define KERNEL_HWCAP_SVEBITPERM                __khwcap2_feature(SVEBITPERM)
+#define KERNEL_HWCAP_SVESHA3           __khwcap2_feature(SVESHA3)
+#define KERNEL_HWCAP_SVESM4            __khwcap2_feature(SVESM4)
 
 /*
  * This yields a mask that user programs can use to figure out what
index 5b267dec6194e9675bb48f710a0d16b58eca3d64..29c6559693204608de508f8ae4cb3b6ad77f237d 100644 (file)
 #define ID_AA64PFR1_SSBS_PSTATE_ONLY   1
 #define ID_AA64PFR1_SSBS_PSTATE_INSNS  2
 
+/* id_aa64zfr0 */
+#define ID_AA64ZFR0_SM4_SHIFT          40
+#define ID_AA64ZFR0_SHA3_SHIFT         32
+#define ID_AA64ZFR0_BITPERM_SHIFT      16
+#define ID_AA64ZFR0_AES_SHIFT          4
+#define ID_AA64ZFR0_SVEVER_SHIFT       0
+
+#define ID_AA64ZFR0_SM4                        0x1
+#define ID_AA64ZFR0_SHA3               0x1
+#define ID_AA64ZFR0_BITPERM            0x1
+#define ID_AA64ZFR0_AES                        0x1
+#define ID_AA64ZFR0_AES_PMULL          0x2
+#define ID_AA64ZFR0_SVEVER_SVE2                0x1
+
 /* id_aa64mmfr0 */
 #define ID_AA64MMFR0_TGRAN4_SHIFT      28
 #define ID_AA64MMFR0_TGRAN64_SHIFT     24
index d64af3913a9e002d31fcfb9f7b2bde33dc7bf404..1a772b162191ad71f2a07620c9d4f31b7ab59d65 100644 (file)
  * HWCAP2 flags - for AT_HWCAP2
  */
 #define HWCAP2_DCPODP          (1 << 0)
+#define HWCAP2_SVE2            (1 << 1)
+#define HWCAP2_SVEAES          (1 << 2)
+#define HWCAP2_SVEPMULL                (1 << 3)
+#define HWCAP2_SVEBITPERM      (1 << 4)
+#define HWCAP2_SVESHA3         (1 << 5)
+#define HWCAP2_SVESM4          (1 << 6)
 
 #endif /* _UAPI__ASM_HWCAP_H */
index 9d18e45311fd45aa2be8396b3334bf3fcde476bd..d856c55445a24bee4565a1393febc99ea8d9bddf 100644 (file)
@@ -184,6 +184,15 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
        ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SM4_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SHA3_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_BITPERM_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_AES_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SVEVER_SHIFT, 4, 0),
+       ARM64_FTR_END,
+};
+
 static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
        S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI),
        S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI),
@@ -392,7 +401,7 @@ static const struct __ftr_reg_entry {
        /* Op1 = 0, CRn = 0, CRm = 4 */
        ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0),
        ARM64_FTR_REG(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1),
-       ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_raz),
+       ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),
 
        /* Op1 = 0, CRn = 0, CRm = 5 */
        ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
@@ -1610,6 +1619,12 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
        HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
 #ifdef CONFIG_ARM64_SVE
        HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
+       HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
 #endif
        HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
 #ifdef CONFIG_ARM64_PTR_AUTH
index 093ca53ce1d1c5af02b9c9691e6bbcfb7ac85a0b..f6f7936be6e7f81b0e39a5db68afdd864edda775 100644 (file)
@@ -86,6 +86,12 @@ static const char *const hwcap_str[] = {
        "paca",
        "pacg",
        "dcpodp",
+       "sve2",
+       "sveaes",
+       "svepmull",
+       "svebitperm",
+       "svesha3",
+       "svesm4",
        NULL
 };