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/libvirt_private.syms b/src/libvirt_private.syms index 5918dc0eb2..08dbe730da 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2437,6 +2437,7 @@ virHostCPUGetMicrocodeVersion; virHostCPUGetMSR; virHostCPUGetOnline; virHostCPUGetOnlineBitmap; +virHostCPUGetPhysAddrSize; virHostCPUGetPresentBitmap; virHostCPUGetSignature; virHostCPUGetStats; diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c index 639dd9b51e..3a02e224e8 100644 --- a/src/util/virhostcpu.c +++ b/src/util/virhostcpu.c @@ -570,6 +570,38 @@ 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 (!(str = STRSKIP(line, "address sizes"))) + continue; + + /* 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 +1648,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 +1671,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);