[PATCH V2 2/4] capabilities: Report number of host CPU physical address bits

Jim Fehlig posted 4 patches 3 years, 6 months ago
[PATCH V2 2/4] capabilities: Report number of host CPU physical address bits
Posted by Jim Fehlig 3 years, 6 months ago
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
---
 src/cpu/cpu_x86.c     |  8 +++++++
 src/util/virhostcpu.c | 55 +++++++++++++++++++++++++++++++++++++++++++
 src/util/virhostcpu.h |  3 +++
 3 files changed, 66 insertions(+)

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 4bb2ea4bae..9fcd6b8add 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2738,6 +2738,7 @@ virCPUx86GetHost(virCPUDef *cpu,
                  virDomainCapsCPUModels *models)
 {
     g_autoptr(virCPUData) cpuData = NULL;
+    unsigned int addrsz;
     int ret;
 
     if (virCPUx86DriverInitialize() < 0)
@@ -2784,6 +2785,13 @@ virCPUx86GetHost(virCPUDef *cpu,
         VIR_DEBUG("Host CPU does not support invariant TSC");
     }
 
+    if (virHostCPUGetPhysAddrSize(&addrsz) == 0) {
+        virCPUMaxPhysAddrDef *addr = g_new0(virCPUMaxPhysAddrDef, 1);
+
+        addr->bits = addrsz;
+        cpu->addr = addr;
+    }
+
     return ret;
 }
 #endif
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 639dd9b51e..668e468f2a 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -570,6 +570,41 @@ virHostCPUParseFrequency(FILE *cpuinfo,
 }
 
 
+static int
+virHostCPUParsePhysAddrSize(FILE *cpuinfo, unsigned int *addrsz)
+{
+    char line[1024];
+
+    while (fgets(line, sizeof(line), cpuinfo) != NULL) {
+        char *str;
+        char *endptr;
+
+        if (!STRPREFIX(line, "address sizes"))
+            continue;
+
+        str = line;
+        str += strlen("address sizes");
+
+        /* Skip the colon. */
+        if ((str = strstr(str, ":")) == NULL)
+            goto error;
+        str++;
+
+        /* Parse the number of physical address bits */
+        if (virStrToLong_ui(str, &endptr, 10, addrsz) < 0)
+            goto error;
+
+        return 0;
+    }
+
+ error:
+    virReportError(VIR_ERR_INTERNAL_ERROR,
+                   _("Missing or invalid CPU address size in %s"),
+                   CPUINFO_PATH);
+    return -1;
+}
+
+
 int
 virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
                                virArch arch,
@@ -1616,6 +1651,20 @@ virHostCPUGetSignature(char **signature)
     return virHostCPUReadSignature(virArchFromHost(), cpuinfo, signature);
 }
 
+int
+virHostCPUGetPhysAddrSize(unsigned int *size)
+{
+    g_autoptr(FILE) cpuinfo = NULL;
+
+    if (!(cpuinfo = fopen(CPUINFO_PATH, "r"))) {
+        virReportSystemError(errno, _("Failed to open cpuinfo file '%s'"),
+                             CPUINFO_PATH);
+        return -1;
+    }
+
+    return virHostCPUParsePhysAddrSize(cpuinfo, size);
+}
+
 #else
 
 int
@@ -1625,6 +1674,12 @@ virHostCPUGetSignature(char **signature)
     return 0;
 }
 
+int
+virHostCPUGetPhysAddrSize(unsigned int *size)
+{
+    return 0;
+}
+
 #endif /* __linux__ */
 
 int
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
index b8ea7aafad..5232fee36d 100644
--- a/src/util/virhostcpu.h
+++ b/src/util/virhostcpu.h
@@ -58,6 +58,7 @@ int virHostCPUGetInfo(virArch hostarch,
                       unsigned int *cores,
                       unsigned int *threads);
 
+
 int virHostCPUGetKVMMaxVCPUs(void) G_NO_INLINE;
 
 int virHostCPUStatsAssign(virNodeCPUStatsPtr param,
@@ -86,6 +87,8 @@ virHostCPUTscInfo *virHostCPUGetTscInfo(void);
 
 int virHostCPUGetSignature(char **signature);
 
+int virHostCPUGetPhysAddrSize(unsigned int *size);
+
 int virHostCPUGetHaltPollTime(pid_t pid,
                               unsigned long long *haltPollSuccess,
                               unsigned long long *haltPollFail);
-- 
2.36.1
Re: [PATCH V2 2/4] capabilities: Report number of host CPU physical address bits
Posted by Michal Prívozník 3 years, 6 months ago
On 7/29/22 21:34, Jim Fehlig wrote:
> Signed-off-by: Jim Fehlig <jfehlig@suse.com>
> ---
>  src/cpu/cpu_x86.c     |  8 +++++++
>  src/util/virhostcpu.c | 55 +++++++++++++++++++++++++++++++++++++++++++
>  src/util/virhostcpu.h |  3 +++
>  3 files changed, 66 insertions(+)
> 
> diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
> index 4bb2ea4bae..9fcd6b8add 100644
> --- a/src/cpu/cpu_x86.c
> +++ b/src/cpu/cpu_x86.c
> @@ -2738,6 +2738,7 @@ virCPUx86GetHost(virCPUDef *cpu,
>                   virDomainCapsCPUModels *models)
>  {
>      g_autoptr(virCPUData) cpuData = NULL;
> +    unsigned int addrsz;
>      int ret;
>  
>      if (virCPUx86DriverInitialize() < 0)
> @@ -2784,6 +2785,13 @@ virCPUx86GetHost(virCPUDef *cpu,
>          VIR_DEBUG("Host CPU does not support invariant TSC");
>      }
>  
> +    if (virHostCPUGetPhysAddrSize(&addrsz) == 0) {
> +        virCPUMaxPhysAddrDef *addr = g_new0(virCPUMaxPhysAddrDef, 1);
> +
> +        addr->bits = addrsz;
> +        cpu->addr = addr;
> +    }
> +
>      return ret;
>  }
>  #endif
> diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
> index 639dd9b51e..668e468f2a 100644
> --- a/src/util/virhostcpu.c
> +++ b/src/util/virhostcpu.c
> @@ -570,6 +570,41 @@ virHostCPUParseFrequency(FILE *cpuinfo,
>  }
>  
>  
> +static int
> +virHostCPUParsePhysAddrSize(FILE *cpuinfo, unsigned int *addrsz)
> +{
> +    char line[1024];
> +
> +    while (fgets(line, sizeof(line), cpuinfo) != NULL) {
> +        char *str;
> +        char *endptr;
> +

Starting from here ...

> +        if (!STRPREFIX(line, "address sizes"))
> +            continue;
> +
> +        str = line;
> +        str += strlen("address sizes");

... until here: this is exactly what STRSKIP() does.

> +
> +        /* Skip the colon. */
> +        if ((str = strstr(str, ":")) == NULL)
> +            goto error;
> +        str++;
> +
> +        /* Parse the number of physical address bits */
> +        if (virStrToLong_ui(str, &endptr, 10, addrsz) < 0)
> +            goto error;
> +
> +        return 0;
> +    }
> +
> + error:
> +    virReportError(VIR_ERR_INTERNAL_ERROR,
> +                   _("Missing or invalid CPU address size in %s"),
> +                   CPUINFO_PATH);
> +    return -1;
> +}
> +
> +
>  int
>  virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
>                                 virArch arch,
> @@ -1616,6 +1651,20 @@ virHostCPUGetSignature(char **signature)
>      return virHostCPUReadSignature(virArchFromHost(), cpuinfo, signature);
>  }
>  
> +int
> +virHostCPUGetPhysAddrSize(unsigned int *size)

This function should be listed in the private syms file, so that it can
be used by other modules.

I suggest squashing this in:

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6db04eff88..7f5c973b2b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2435,6 +2435,7 @@ virHostCPUGetMicrocodeVersion;
 virHostCPUGetMSR;
 virHostCPUGetOnline;
 virHostCPUGetOnlineBitmap;
+virHostCPUGetPhysAddrSize;
 virHostCPUGetPresentBitmap;
 virHostCPUGetSignature;
 virHostCPUGetStats;
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 668e468f2a..3a02e224e8 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -579,12 +579,9 @@ virHostCPUParsePhysAddrSize(FILE *cpuinfo, unsigned int *addrsz)
         char *str;
         char *endptr;
 
-        if (!STRPREFIX(line, "address sizes"))
+        if (!(str = STRSKIP(line, "address sizes")))
             continue;
 
-        str = line;
-        str += strlen("address sizes");
-
         /* Skip the colon. */
         if ((str = strstr(str, ":")) == NULL)
             goto error;


Michal