Add SME vector length detect

- cpuinfo_get_max_arm_sme_length() returns svl vector length in bits
- Display length of SME vectors in isa-tool
- Upgrade cmake-linux-riscv64 ubuntu-22.04 runners to ubuntu-24.04

SME may be enabled on cpus that do not have SVE
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 622650a..17483b1 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -94,14 +94,14 @@
         env:
           ANDROID_NDK: ${{ steps.setup-ndk.outputs.ndk-path }}
   cmake-linux-qemu:
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
     timeout-minutes: 40
     strategy:
       matrix:
         build_props:
           - [
               "cmake-linux-riscv64",
-              "riscv64/ubuntu:22.04"
+              "riscv64/ubuntu:24.04"
           ]
 
     name: ${{ matrix.build_props[0] }}
diff --git a/include/cpuinfo.h b/include/cpuinfo.h
index 5f93819..f1d35d4 100644
--- a/include/cpuinfo.h
+++ b/include/cpuinfo.h
@@ -1700,6 +1700,7 @@
 	bool sme_b16b16;
 	bool sme_f16f16;
 	uint32_t svelen;
+	uint32_t smelen;
 #endif
 	bool rdm;
 	bool fp16arith;
@@ -2081,6 +2082,15 @@
 #endif
 }
 
+// Function to get the max SME vector length on ARM CPU's which support SME.
+static inline uint32_t cpuinfo_get_max_arm_sme_length(void) {
+#if CPUINFO_ARCH_ARM64
+	return cpuinfo_isa.smelen * 8; // bytes * 8 = bit length(vector length)
+#else
+	return 0;
+#endif
+}
+
 static inline bool cpuinfo_has_arm_sme(void) {
 #if CPUINFO_ARCH_ARM64
 	return cpuinfo_isa.sme;
diff --git a/src/arm/linux/aarch64-isa.c b/src/arm/linux/aarch64-isa.c
index bc2186f..7a9cebb 100644
--- a/src/arm/linux/aarch64-isa.c
+++ b/src/arm/linux/aarch64-isa.c
@@ -191,4 +191,22 @@
 		// Mask out the SVE vector length bits
 		isa->svelen = ret & PR_SVE_VL_LEN_MASK;
 	}
+
+#ifndef PR_SME_GET_VL
+#define PR_SME_GET_VL 64
+#endif
+
+#ifndef PR_SME_VL_LEN_MASK
+#define PR_SME_VL_LEN_MASK 0xffff
+#endif
+
+	ret = prctl(PR_SME_GET_VL);
+	if (ret < 0) {
+		cpuinfo_log_warning("No SME support on this machine");
+		isa->smelen = 0; // Assume no SME support if the call fails
+	} else {
+		// Mask out the SME vector length bits
+		isa->smelen = ret & PR_SME_VL_LEN_MASK;
+	}
 }
+
diff --git a/tools/isa-info.c b/tools/isa-info.c
index 023b698..740be64 100644
--- a/tools/isa-info.c
+++ b/tools/isa-info.c
@@ -178,6 +178,7 @@
 
 	printf("ARM SVE Capabilities:\n");
 	printf("\tSVE max length: %d\n", cpuinfo_get_max_arm_sve_length());
+	printf("\tSME max length: %d\n", cpuinfo_get_max_arm_sme_length());
 
 	printf("Cryptography extensions:\n");
 	printf("\tAES: %s\n", cpuinfo_has_arm_aes() ? "yes" : "no");