[libvirt] [PATCH] Implement capabilities for Solaris

john.levon at sun.com john.levon at sun.com
Wed Jan 14 15:20:12 UTC 2009


# HG changeset patch
# User John Levon <john.levon at sun.com>
# 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 at sun.com>

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, &regs, 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 *)&regs.r_ebx, "AuthcAMDenti", 12) == 0) {
+        if (pread(fd, &regs, 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 *)&regs.r_ebx, "GenuntelineI", 12) == 0) {
+        if (pread(fd, &regs, 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 */
 }
 
 




More information about the libvir-list mailing list