]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: add lscpu_read_architecture()
authorKarel Zak <kzak@redhat.com>
Thu, 7 May 2020 12:19:39 +0000 (14:19 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 13 Nov 2020 08:19:02 +0000 (09:19 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/lscpu-api.h
sys-utils/lscpu-cputype.c

index bb9d381bfd50deef72cd58d09f3d9ef1b43f5af1..ca4550c924148a6ee7e714209f49feaa68c099ef 100644 (file)
@@ -65,8 +65,6 @@ struct lscpu_cputype {
        int     threads;
        int     ndrawers;
 
-       unsigned int    bit32:1,
-                       bit64:1;
 };
 
 struct lscpu_cpu {
@@ -80,6 +78,13 @@ struct lscpu_cpu {
        char    *static_mhz;
 };
 
+struct lscpu_arch {
+       char    *name;          /* uname() .machine */
+
+       unsigned int    bit32:1,
+                       bit64:1;
+};
+
 struct lscpu_cxt {
        const char *prefix;      /* path to /sys and /proc snapshot or NULL */
 
@@ -92,6 +97,9 @@ struct lscpu_cxt {
        size_t ncpus;
        struct lscpu_cpu **cpus;
 
+       struct lscpu_arch *arch;
+
+       unsigned int noalive;
 };
 
 struct lscpu_cputype *lscpu_new_cputype(void);
@@ -99,7 +107,9 @@ void lscpu_ref_cputype(struct lscpu_cputype *ct);
 void lscpu_unref_cputype(struct lscpu_cputype *ct);
 struct lscpu_cputype *lscpu_add_cputype(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);
 struct lscpu_cputype *lscpu_cputype_get_default(struct lscpu_cxt *cxt);
+
 int lscpu_read_cpuinfo(struct lscpu_cxt *cxt);
+int lscpu_read_architecture(struct lscpu_cxt *cxt);
 
 struct lscpu_cpu *lscpu_new_cpu(void);
 void lscpu_ref_cpu(struct lscpu_cpu *cpu);
index 46c1d3fe612e34399ca07f53843df2dcd5286229..a4b1d811c5c32c506fb3aed01fa00c00ee73a5c7 100644 (file)
@@ -1,4 +1,7 @@
 
+#include <sys/utsname.h>
+#include <sys/personality.h>
+
 #include "lscpu-api.h"
 
 UL_DEBUG_DEFINE_MASK(lscpu);
@@ -364,6 +367,75 @@ int lscpu_read_cpuinfo(struct lscpu_cxt *cxt)
        return 0;
 }
 
+int lscpu_read_architecture(struct lscpu_cxt *cxt)
+{
+       struct utsname utsbuf;
+       struct lscpu_arch *ar;
+       struct lscpu_cputype *ct;
+
+       assert(cxt);
+       assert(!cxt->arch);
+
+       DBG(GATHER, ul_debugobj(cxt, "reading architecture"));
+
+       if (uname(&utsbuf) == -1)
+               err(EXIT_FAILURE, _("error: uname failed"));
+
+       ar = cxt->arch = xcalloc(1, sizeof(*cxt->arch));
+       ar->name = xstrdup(utsbuf.machine);
+
+       if (cxt->noalive)
+               /* reading info from any /{sys,proc} dump, don't mix it with
+                * information about our real CPU */
+               ;
+       else {
+#if defined(__alpha__) || defined(__ia64__)
+               ar->bit64 = 1;  /* 64bit platforms only */
+#endif
+               /* platforms with 64bit flag in /proc/cpuinfo, define
+                * 32bit default here */
+#if defined(__i386__) || defined(__x86_64__) || \
+    defined(__s390x__) || defined(__s390__) || defined(__sparc_v9__)
+               ar->bit32 = 1;
+#endif
+
+#if defined(__aarch64__)
+               {
+                       /* personality() is the most reliable way (since 4.7)
+                        * to determine aarch32 support */
+                       int pers = personality(PER_LINUX32);
+                       if (pers != -1) {
+                               personality(pers);
+                               ar->bit32 = 1;
+                       }
+                       ar->bit64 = 1;
+               }
+#endif
+       }
+
+       ct = lscpu_cputype_get_default(cxt);
+       if (ct && ct->flags) {
+               char buf[BUFSIZ];
+
+               snprintf(buf, sizeof(buf), " %s ", ct->flags);
+               if (strstr(buf, " lm "))
+                       ar->bit32 = 1, ar->bit64 = 1;                   /* x86_64 */
+               if (strstr(buf, " zarch "))
+                       ar->bit32 = 1, ar->bit64 = 1;                   /* s390x */
+               if (strstr(buf, " sun4v ") || strstr(buf, " sun4u "))
+                       ar->bit32 = 1, ar->bit64 = 1;                   /* sparc64 */
+       }
+
+       if (ar->name && !cxt->noalive) {
+               if (strcmp(ar->name, "ppc64") == 0)
+                       ar->bit32 = 1, ar->bit64 = 1;
+               else if (strcmp(ar->name, "ppc") == 0)
+                       ar->bit32 = 1;
+       }
+
+       return 0;
+}
+
 #ifdef TEST_PROGRAM_CPUTYPE
 /* TODO: move to lscpu.c */
 struct lscpu_cxt *lscpu_new_context(void)
@@ -403,13 +475,16 @@ int main(int argc, char **argv)
 
        cxt = lscpu_new_context();
 
-       if (argc == 3 && strcmp(argv[1], "--prefix") == 0)
+       if (argc == 3 && strcmp(argv[1], "--prefix") == 0) {
                cxt->prefix = argv[2];
+               cxt->noalive = 1;
+       }
 
        lscpu_init_debug();
        context_init_paths(cxt);
 
        lscpu_read_cpuinfo(cxt);
+       lscpu_read_architecture(cxt);
 
        lscpu_free_context(cxt);
        return EXIT_SUCCESS;