libxl: Add AHCI support for upstream qemu
authorFabio Fantoni <fabio.fantoni@m2r.biz>
Wed, 8 Jul 2015 14:31:05 +0000 (16:31 +0200)
committerIan Campbell <ian.campbell@citrix.com>
Thu, 9 Jul 2015 11:15:16 +0000 (12:15 +0100)
Usage:
hdtype=ide|ahci (default=ide)

If hdtype=ahci adds ich9 disk controller in ahci mode and uses it with
upstream qemu to emulate disks instead of ide.
It doesn't support cdroms which still using ide (cdroms will use
"-device ide-cd" as new qemu parameter)
Ahci requires new qemu parameter but for now other emulated disks cases
remains with old ones (I did it in other patch, not needed by this one)
I did it as libxl parameter disabled by default to avoid possible
problems:
- with save/restore/migration (restoring with ahci a domU that was with
ide instead)
- windows < 8 without pv drivers (a registry key change is needed for
AHCI<->IDE change FWIK to avoid possible blue screen)
- windows XP or older that many not support ahci by default.
Setting AHCI with libxl parameter and default to disabled seems the best
solution.
AHCI increase hvm domUs boot performance. On linux hvm domU I saw up to
only 20% of the previous total boot time, whereas boot time decrease a
lot on W7 domUs for most of boots I have done. Small difference in boot
time compared to ide mode on W8 and newer (probably other xen
improvements or fixes are needed not ahci related)

Signed-off-by: Fabio Fantoni <fabio.fantoni@m2r.biz>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
[ ijc -- adjust name of LIBXL_HAVE #define as discussed on list,
         fixup pod syntax in xl.cfg.pod.5 ]

docs/man/xl.cfg.pod.5
docs/misc/vbd-interface.txt
tools/libxl/libxl.h
tools/libxl/libxl_create.c
tools/libxl/libxl_dm.c
tools/libxl/libxl_types.idl
tools/libxl/xl_cmdimpl.c

index 27e76439249d9900a7d3b513d12b7090d06353ba..38c977c184d62ff03a53d71d50aba1d9be5474fe 100644 (file)
@@ -882,6 +882,20 @@ default is B<cd>.
 
 =back
 
+=head3 Emulated disk controller type
+
+=over 4
+
+=item B<hdtype="STRING">
+
+Select the hd disk type (ide|ahci).
+If hdtype=ahci adds ich9 disk controller in AHCI mode and uses it with
+upstream qemu to emulate disks instead of IDE. It decreases boot time
+but may not be supported by default in Windows xp and older Windows.
+The default is ide.
+
+=back
+
 =head3 Paging
 
 The following options control the mechanisms used to virtualise guest
index f873db0f709213babecf0025d07f2633977723e1..1c996bf64d55874f4549f2880654a54405b375b2 100644 (file)
@@ -3,18 +3,20 @@ Xen guest interface
 
 A Xen guest can be provided with block devices.  These are always
 provided as Xen VBDs; for HVM guests they may also be provided as
-emulated IDE or SCSI disks.
+emulated IDE, AHCI or SCSI disks.
 
 The abstract interface involves specifying, for each block device:
 
  * Nominal disk type: Xen virtual disk (aka xvd*, the default); SCSI
-   (sd*); IDE (hd*).
+   (sd*); IDE or AHCI (hd*).
 
    For HVM guests, each whole-disk hd* and and sd* device is made
    available _both_ via emulated IDE resp. SCSI controller, _and_ as a
    Xen VBD.  The HVM guest is entitled to assume that the IDE or SCSI
    disks available via the emulated IDE controller target the same
    underlying devices as the corresponding Xen VBD (ie, multipath).
+   In hd* case with hdtype=ahci, disk will be AHCI via emulated
+   ich9 disk controller.
 
    For PV guests every device is made available to the guest only as a
    Xen VBD.  For these domains the type is advisory, for use by the
index a6bd509f40793bb314ad7787087802f4140ef6f3..942cbf147dd46db1d7d55ddb699e1aac1b6d560e 100644 (file)
@@ -595,6 +595,14 @@ typedef struct libxl__ctx libxl_ctx;
  */
 #define LIBXL_HAVE_SPICE_STREAMINGVIDEO 1
 
+/*
+ * LIBXL_HAVE_HVM_HDTYPE
+ *
+ * If defined, then the u.hvm structure will contain a enum type
+ * hdtype.
+ */
+#define LIBXL_HAVE_HVM_HDTYPE 1
+
 /*
  * LIBXL_HAVE_DOMAIN_CREATE_RESTORE_PARAMS 1
  *
index 5f73f616926ef1ef5e777967401294e0c062f5d9..69bfa335fd637d5fc8702e31a2b6490757fcf186 100644 (file)
@@ -195,6 +195,9 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
         if (!b_info->u.hvm.vga.kind)
             b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_CIRRUS;
 
+        if (!b_info->u.hvm.hdtype)
+            b_info->u.hvm.hdtype = LIBXL_HDTYPE_IDE;
+
         switch (b_info->device_model_version) {
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
             switch (b_info->u.hvm.vga.kind) {
index 317a8ebfcf646cdf884478c2d2635ed22cdeea91..ad434f05ef83837ab0c087b079d731ddac8482e5 100644 (file)
@@ -818,6 +818,8 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
     flexarray_append(dm_args, libxl__sprintf(gc, "%"PRId64, ram_size));
 
     if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) {
+        if (b_info->u.hvm.hdtype == LIBXL_HDTYPE_AHCI)
+            flexarray_append_pair(dm_args, "-device", "ahci,id=ahci0");
         for (i = 0; i < num_disks; i++) {
             int disk, part;
             int dev_number =
@@ -872,7 +874,14 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
                     drive = libxl__sprintf
                         (gc, "file=%s,if=scsi,bus=0,unit=%d,format=%s,cache=writeback",
                          pdev_path, disk, format);
-                else if (disk < 4)
+                else if (disk < 6 && b_info->u.hvm.hdtype == LIBXL_HDTYPE_AHCI) {
+                    flexarray_vappend(dm_args, "-drive",
+                        GCSPRINTF("file=%s,if=none,id=ahcidisk-%d,format=%s,cache=writeback",
+                        pdev_path, disk, format),
+                        "-device", GCSPRINTF("ide-hd,bus=ahci0.%d,unit=0,drive=ahcidisk-%d",
+                        disk, disk), NULL);
+                    continue;
+                } else if (disk < 4)
                     drive = libxl__sprintf
                         (gc, "file=%s,if=ide,index=%d,media=disk,format=%s,cache=writeback",
                          pdev_path, disk, format);
index 2afaa38f2c626aec6164838f762f09ed85b51432..ec4cee5cf17f17cf841fce9c672c2203f40f8894 100644 (file)
@@ -202,6 +202,11 @@ libxl_viridian_enlightenment = Enumeration("viridian_enlightenment", [
     (3, "reference_tsc"),
     ])
 
+libxl_hdtype = Enumeration("hdtype", [
+    (1, "IDE"),
+    (2, "AHCI"),
+    ], init_val = "LIBXL_HDTYPE_IDE")
+
 #
 # Complex libxl types
 #
@@ -448,6 +453,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ("nested_hvm",       libxl_defbool),
                                        ("smbios_firmware",  string),
                                        ("acpi_firmware",    string),
+                                       ("hdtype",           libxl_hdtype),
                                        ("nographic",        libxl_defbool),
                                        ("vga",              libxl_vga_interface_info),
                                        ("vnc",              libxl_vnc_info),
index eeb3b9021d5b00c33657ef749fef52f89bd16e58..14527c577f1d55d6e90df269b75138b5af9121b3 100644 (file)
@@ -2154,6 +2154,13 @@ skip_vfb:
             b_info->u.hvm.vga.kind = l ? LIBXL_VGA_INTERFACE_TYPE_STD :
                                          LIBXL_VGA_INTERFACE_TYPE_CIRRUS;
 
+        if (!xlu_cfg_get_string(config, "hdtype", &buf, 0) &&
+            libxl_hdtype_from_string(buf, &b_info->u.hvm.hdtype)) {
+                fprintf(stderr, "ERROR: invalid value \"%s\" for \"hdtype\"\n",
+                    buf);
+                exit (1);
+        }
+
         xlu_cfg_replace_string (config, "keymap", &b_info->u.hvm.keymap, 0);
         xlu_cfg_get_defbool (config, "spice", &b_info->u.hvm.spice.enable, 0);
         if (!xlu_cfg_get_long (config, "spiceport", &l, 0))