mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-05 13:30:02 -05:00
spa: add cpu method to get the VM type
Make a method to query the VM we are running on.
This commit is contained in:
parent
07c9dbbffa
commit
ce828af9e1
2 changed files with 95 additions and 1 deletions
|
|
@ -80,13 +80,31 @@ struct spa_cpu { struct spa_interface iface; };
|
||||||
#define SPA_CPU_FLAG_ARMV8 (1 << 6)
|
#define SPA_CPU_FLAG_ARMV8 (1 << 6)
|
||||||
|
|
||||||
#define SPA_CPU_FORCE_AUTODETECT ((uint32_t)-1)
|
#define SPA_CPU_FORCE_AUTODETECT ((uint32_t)-1)
|
||||||
|
|
||||||
|
#define SPA_CPU_VM_NONE (0)
|
||||||
|
#define SPA_CPU_VM_OTHER (1 << 0)
|
||||||
|
#define SPA_CPU_VM_KVM (1 << 1)
|
||||||
|
#define SPA_CPU_VM_QEMU (1 << 2)
|
||||||
|
#define SPA_CPU_VM_BOCHS (1 << 3)
|
||||||
|
#define SPA_CPU_VM_XEN (1 << 4)
|
||||||
|
#define SPA_CPU_VM_UML (1 << 5)
|
||||||
|
#define SPA_CPU_VM_VMWARE (1 << 6)
|
||||||
|
#define SPA_CPU_VM_ORACLE (1 << 7)
|
||||||
|
#define SPA_CPU_VM_MICROSOFT (1 << 8)
|
||||||
|
#define SPA_CPU_VM_ZVM (1 << 9)
|
||||||
|
#define SPA_CPU_VM_PARALLELS (1 << 10)
|
||||||
|
#define SPA_CPU_VM_BHYVE (1 << 11)
|
||||||
|
#define SPA_CPU_VM_QNX (1 << 12)
|
||||||
|
#define SPA_CPU_VM_ACRN (1 << 13)
|
||||||
|
#define SPA_CPU_VM_POWERVM (1 << 14)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* methods
|
* methods
|
||||||
*/
|
*/
|
||||||
struct spa_cpu_methods {
|
struct spa_cpu_methods {
|
||||||
/** the version of the methods. This can be used to expand this
|
/** the version of the methods. This can be used to expand this
|
||||||
structure in the future */
|
structure in the future */
|
||||||
#define SPA_VERSION_CPU_METHODS 0
|
#define SPA_VERSION_CPU_METHODS 1
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
||||||
/** get CPU flags */
|
/** get CPU flags */
|
||||||
|
|
@ -100,6 +118,9 @@ struct spa_cpu_methods {
|
||||||
|
|
||||||
/** get maximum required alignment of data */
|
/** get maximum required alignment of data */
|
||||||
uint32_t (*get_max_align) (void *object);
|
uint32_t (*get_max_align) (void *object);
|
||||||
|
|
||||||
|
/* check if running in a VM. Since:1 */
|
||||||
|
uint32_t (*get_vm_type) (void *object);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define spa_cpu_method(o,method,version,...) \
|
#define spa_cpu_method(o,method,version,...) \
|
||||||
|
|
@ -115,6 +136,7 @@ struct spa_cpu_methods {
|
||||||
#define spa_cpu_force_flags(c,f) spa_cpu_method(c, force_flags, 0, f)
|
#define spa_cpu_force_flags(c,f) spa_cpu_method(c, force_flags, 0, f)
|
||||||
#define spa_cpu_get_count(c) spa_cpu_method(c, get_count, 0)
|
#define spa_cpu_get_count(c) spa_cpu_method(c, get_count, 0)
|
||||||
#define spa_cpu_get_max_align(c) spa_cpu_method(c, get_max_align, 0)
|
#define spa_cpu_get_max_align(c) spa_cpu_method(c, get_max_align, 0)
|
||||||
|
#define spa_cpu_get_vm_type(c) spa_cpu_method(c, get_vm_type, 1)
|
||||||
|
|
||||||
/** keys can be given when initializing the cpu handle */
|
/** keys can be given when initializing the cpu handle */
|
||||||
#define SPA_KEY_CPU_FORCE "cpu.force" /**< force cpu flags */
|
#define SPA_KEY_CPU_FORCE "cpu.force" /**< force cpu flags */
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|
@ -52,8 +53,25 @@ struct impl {
|
||||||
uint32_t force;
|
uint32_t force;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
uint32_t max_align;
|
uint32_t max_align;
|
||||||
|
uint32_t vm_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *read_file(const char *name, char *buffer, size_t len)
|
||||||
|
{
|
||||||
|
int n, fd;
|
||||||
|
|
||||||
|
if ((fd = open(name, O_RDONLY | O_CLOEXEC, 0)) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((n = read(fd, buffer, len)) < 0) {
|
||||||
|
close(fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
buffer[n] = 0;
|
||||||
|
close(fd);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
# if defined (__i386__) || defined (__x86_64__)
|
# if defined (__i386__) || defined (__x86_64__)
|
||||||
#include "cpu-x86.c"
|
#include "cpu-x86.c"
|
||||||
#define init(t) x86_init(t)
|
#define init(t) x86_init(t)
|
||||||
|
|
@ -116,12 +134,66 @@ impl_cpu_get_max_align(void *object)
|
||||||
return impl->max_align;
|
return impl->max_align;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
impl_cpu_get_vm_type(void *object)
|
||||||
|
{
|
||||||
|
struct impl *impl = object;
|
||||||
|
|
||||||
|
if (impl->vm_type != 0)
|
||||||
|
return impl->vm_type;
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
|
||||||
|
static const char *const dmi_vendors[] = {
|
||||||
|
"/sys/class/dmi/id/product_name", /* Test this before sys_vendor to detect KVM over QEMU */
|
||||||
|
"/sys/class/dmi/id/sys_vendor",
|
||||||
|
"/sys/class/dmi/id/board_vendor",
|
||||||
|
"/sys/class/dmi/id/bios_vendor"
|
||||||
|
};
|
||||||
|
static const struct {
|
||||||
|
const char *vendor;
|
||||||
|
int id;
|
||||||
|
} dmi_vendor_table[] = {
|
||||||
|
{ "KVM", SPA_CPU_VM_KVM },
|
||||||
|
{ "QEMU", SPA_CPU_VM_QEMU },
|
||||||
|
{ "VMware", SPA_CPU_VM_VMWARE }, /* https://kb.vmware.com/s/article/1009458 */
|
||||||
|
{ "VMW", SPA_CPU_VM_VMWARE },
|
||||||
|
{ "innotek GmbH", SPA_CPU_VM_ORACLE },
|
||||||
|
{ "Oracle Corporation", SPA_CPU_VM_ORACLE },
|
||||||
|
{ "Xen", SPA_CPU_VM_XEN },
|
||||||
|
{ "Bochs", SPA_CPU_VM_BOCHS },
|
||||||
|
{ "Parallels", SPA_CPU_VM_PARALLELS },
|
||||||
|
/* https://wiki.freebsd.org/bhyve */
|
||||||
|
{ "BHYVE", SPA_CPU_VM_BHYVE },
|
||||||
|
};
|
||||||
|
uint32_t i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < SPA_N_ELEMENTS(dmi_vendors); i++) {
|
||||||
|
char buffer[256], *s;
|
||||||
|
|
||||||
|
if ((s = read_file(dmi_vendors[i], buffer, sizeof(buffer))) == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (j = 0; j < SPA_N_ELEMENTS(dmi_vendor_table); j++) {
|
||||||
|
if (strstr(s, dmi_vendor_table[j].vendor) == s) {
|
||||||
|
spa_log_debug(impl->log, "Virtualization %s found in DMI (%s)",
|
||||||
|
s, dmi_vendors[i]);
|
||||||
|
impl->vm_type = dmi_vendor_table[j].id;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
#endif
|
||||||
|
return impl->vm_type;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct spa_cpu_methods impl_cpu = {
|
static const struct spa_cpu_methods impl_cpu = {
|
||||||
SPA_VERSION_CPU_METHODS,
|
SPA_VERSION_CPU_METHODS,
|
||||||
.get_flags = impl_cpu_get_flags,
|
.get_flags = impl_cpu_get_flags,
|
||||||
.force_flags = impl_cpu_force_flags,
|
.force_flags = impl_cpu_force_flags,
|
||||||
.get_count = impl_cpu_get_count,
|
.get_count = impl_cpu_get_count,
|
||||||
.get_max_align = impl_cpu_get_max_align,
|
.get_max_align = impl_cpu_get_max_align,
|
||||||
|
.get_vm_type = impl_cpu_get_vm_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
|
static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue