# HG changeset patch # User John Levon <john.levon@xxxxxxx> # Date 1231940906 28800 # Node ID a0d98d39955f4f304d318c7c780742ab929eb351 # Parent ddfcba6b4181ab433dce345d66dc399a81c92a3b Implement capabilities for Solaris Use Solaris interfaces to derive the hypervisor capabilities. Signed-off-by: John Levon <john.levon@xxxxxxx> diff --git a/src/xen_internal.c b/src/xen_internal.c --- a/src/xen_internal.c +++ b/src/xen_internal.c @@ -35,6 +35,10 @@ #ifdef HAVE_XEN_SYS_PRIVCMD_H #include <xen/sys/privcmd.h> #endif +#endif + +#ifdef __sun +#include <sys/systeminfo.h> #endif /* required for shutdown flags */ @@ -662,11 +666,8 @@ typedef struct xen_op_v2_dom xen_op_v2_d #ifdef __linux__ #define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd" #define HYPERVISOR_CAPABILITIES "/sys/hypervisor/properties/capabilities" -#define CPUINFO "/proc/cpuinfo" #elif defined(__sun) #define XEN_HYPERVISOR_SOCKET "/dev/xen/privcmd" -#define HYPERVISOR_CAPABILITIES "" -#define CPUINFO "/dev/cpu/self/cpuid" #else #error "unsupported platform" #endif @@ -2123,7 +2124,7 @@ xenHypervisorBuildCapabilities(virConnec xenHypervisorBuildCapabilities(virConnectPtr conn, const char *hostmachine, int host_pae, - char *hvm_type, + const char *hvm_type, struct guest_arch *guest_archs, int nr_guest_archs) { virCapsPtr caps; @@ -2227,8 +2228,126 @@ xenHypervisorBuildCapabilities(virConnec return NULL; } -/** - * xenHypervisorGetCapabilities: +#ifdef __sun + +static int +get_cpu_flags(virConnectPtr conn, const char **hvm, int *pae, int *longmode) +{ + struct { + uint32_t r_eax, r_ebx, r_ecx, r_edx; + } regs; + + char tmpbuf[20]; + int fd = -1; + int ret = 0; + + /* returns -1, errno 22 if in 32-bit mode */ + *longmode = (sysinfo(SI_ARCHITECTURE_64, tmpbuf, 20) != -1); + + if ((fd = open("/dev/cpu/self/cpuid", O_RDONLY)) == -1 || + pread(fd, ®s, sizeof(regs), 0) != sizeof(regs)) { + virXenError(conn, VIR_ERR_SYSTEM_ERROR, + "couldn't read CPU flags: %s", strerror(errno)); + goto out; + } + + *pae = 0; + *hvm = ""; + + if (strncmp((const char *)®s.r_ebx, "AuthcAMDenti", 12) == 0) { + if (pread(fd, ®s, sizeof (regs), 0x80000001) == sizeof (regs)) { + /* Read secure virtual machine bit (bit 2 of ECX feature ID) */ + if ((regs.r_ecx >> 2) & 1) { + *hvm = "svm"; + } + if ((regs.r_edx >> 6) & 1) + *pae = 1; + } + } else if (strncmp((const char *)®s.r_ebx, "GenuntelineI", 12) == 0) { + if (pread(fd, ®s, sizeof (regs), 0x00000001) == sizeof (regs)) { + /* Read VMXE feature bit (bit 5 of ECX feature ID) */ + if ((regs.r_ecx >> 5) & 1) + *hvm = "vmx"; + if ((regs.r_edx >> 6) & 1) + *pae = 1; + } + } + + ret = 1; + +out: + if (fd != -1) + close(fd); + return ret; +} + +static virCapsPtr +xenHypervisorMakeCapabilitiesSunOS(virConnectPtr conn) +{ + struct guest_arch guest_arches[32]; + int i = 0; + virCapsPtr caps = NULL; + struct utsname utsname; + int pae, longmode; + const char *hvm; + + if (!get_cpu_flags(conn, &hvm, &pae, &longmode)) + return NULL; + + /* Really, this never fails - look at the man-page. */ + uname (&utsname); + + guest_arches[i].model = "i686"; + guest_arches[i].bits = 32; + guest_arches[i].hvm = 0; + guest_arches[i].pae = pae; + guest_arches[i].nonpae = 1; + guest_arches[i].ia64_be = 0; + i++; + + if (longmode) { + guest_arches[i].model = "x86_64"; + guest_arches[i].bits = 64; + guest_arches[i].hvm = 0; + guest_arches[i].pae = 0; + guest_arches[i].nonpae = 1; + guest_arches[i].ia64_be = 0; + i++; + } + + if (hvm[0] != '\0') { + guest_arches[i].model = "i686"; + guest_arches[i].bits = 32; + guest_arches[i].hvm = 1; + guest_arches[i].pae = pae; + guest_arches[i].nonpae = 1; + guest_arches[i].ia64_be = 0; + i++; + + if (longmode) { + guest_arches[i].model = "x86_64"; + guest_arches[i].bits = 64; + guest_arches[i].hvm = 1; + guest_arches[i].pae = 0; + guest_arches[i].nonpae = 1; + guest_arches[i].ia64_be = 0; + i++; + } + } + + if ((caps = xenHypervisorBuildCapabilities(conn, + utsname.machine, + pae, hvm, + guest_arches, i)) == NULL) + virXenError(NULL, VIR_ERR_NO_MEMORY, NULL); + + return caps; +} + +#endif /* __sun */ + +/** + * xenHypervisorMakeCapabilitiesInternal: * @conn: pointer to the connection block * @cpuinfo: file handle containing /proc/cpuinfo data, or NULL * @capabilities: file handle containing /sys/hypervisor/properties/capabilities data, or NULL @@ -2394,6 +2513,9 @@ virCapsPtr virCapsPtr xenHypervisorMakeCapabilities(virConnectPtr conn) { +#ifdef __sun + return xenHypervisorMakeCapabilitiesSunOS(conn); +#else virCapsPtr caps; FILE *cpuinfo, *capabilities; struct utsname utsname; @@ -2432,6 +2554,7 @@ xenHypervisorMakeCapabilities(virConnect fclose(capabilities); return caps; +#endif /* __sun */ } -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list