[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH RFC v1 11/13] xen/libxl: allow creating HVM guests without a device model



Intorduce a new device model version (NONE) that can be used to specify that
no device model should be used. Propagate this to Xen by creating a new
XEN_DOMCTL_CDF_noemu flag that disables some of the emulation done inside of
Xen.

Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx>
Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Cc: Ian Campbell <ian.campbell@xxxxxxxxxx>
Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Cc: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Cc: Elena Ufimtseva <elena.ufimtseva@xxxxxxxxxx>
---
IMHO the XEN_DOMCTL_CDF_noemu flag should be expanded into multiple smaller
flags that can be used to disable specific emulated devices, like the
vlapic, vioapic, vhpet...

Also hvm_mmio_handlers should become domain specific in order to populate it
with the usable handlers only.
---
 tools/libxl/libxl.c              |  7 +++----
 tools/libxl/libxl_create.c       | 16 ++++++++++++++++
 tools/libxl/libxl_dom.c          |  6 ++++++
 tools/libxl/libxl_types.idl      |  1 +
 tools/libxl/xl_cmdimpl.c         |  2 ++
 xen/arch/x86/domain.c            |  2 +-
 xen/arch/x86/hvm/hvm.c           | 14 +++++++++-----
 xen/arch/x86/hvm/intercept.c     |  6 ++++++
 xen/common/domctl.c              |  5 ++++-
 xen/include/asm-x86/hvm/domain.h |  1 +
 xen/include/asm-x86/hvm/hvm.h    |  2 +-
 xen/include/public/domctl.h      |  3 +++
 xen/include/xen/sched.h          |  4 ++++
 13 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index d86ea62..7c83486 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -1587,11 +1587,10 @@ void libxl__destroy_domid(libxl__egc *egc, 
libxl__destroy_domid_state *dis)
 
     switch (libxl__domain_type(gc, domid)) {
     case LIBXL_DOMAIN_TYPE_HVM:
-        if (!libxl_get_stubdom_id(CTX, domid))
-            dm_present = 1;
-        else
+        if (libxl_get_stubdom_id(CTX, domid)) {
             dm_present = 0;
-        break;
+            break;
+        }
     case LIBXL_DOMAIN_TYPE_PV:
         pid = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, 
"/local/domain/%d/image/device-model-pid", domid));
         dm_present = (pid != NULL);
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 86384d2..06cf02c 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -164,6 +164,8 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
                 b_info->u.hvm.bios = LIBXL_BIOS_TYPE_ROMBIOS; break;
             case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
                 b_info->u.hvm.bios = LIBXL_BIOS_TYPE_SEABIOS; break;
+            case LIBXL_DEVICE_MODEL_VERSION_NONE:
+                break;
             default:return ERROR_INVAL;
             }
 
@@ -177,6 +179,8 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
             if (b_info->u.hvm.bios == LIBXL_BIOS_TYPE_ROMBIOS)
                 return ERROR_INVAL;
             break;
+        case LIBXL_DEVICE_MODEL_VERSION_NONE:
+            break;
         default:abort();
         }
 
@@ -278,6 +282,9 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
                 break;
             }
             break;
+        case LIBXL_DEVICE_MODEL_VERSION_NONE:
+            b_info->video_memkb = 0;
+            break;
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
         default:
             switch (b_info->u.hvm.vga.kind) {
@@ -535,6 +542,7 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config 
*d_config,
 
     /* convenience aliases */
     libxl_domain_create_info *info = &d_config->c_info;
+    libxl_domain_build_info *b_info = &d_config->b_info;
 
     assert(!libxl_domid_valid_guest(*domid));
 
@@ -549,6 +557,8 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config 
*d_config,
         flags |= XEN_DOMCTL_CDF_hvm_guest;
         flags |= libxl_defbool_val(info->hap) ? XEN_DOMCTL_CDF_hap : 0;
         flags |= libxl_defbool_val(info->oos) ? 0 : XEN_DOMCTL_CDF_oos_off;
+        if (b_info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_NONE)
+            flags |= XEN_DOMCTL_CDF_noemu;
     } else if (libxl_defbool_val(info->pvh)) {
         flags |= XEN_DOMCTL_CDF_pvh_guest;
         if (!libxl_defbool_val(info->hap)) {
@@ -1293,6 +1303,12 @@ static void domcreate_launch_dm(libxl__egc *egc, 
libxl__multidev *multidev,
         libxl__device_console_add(gc, domid, &console, state, &device);
         libxl__device_console_dispose(&console);
 
+        if (d_config->b_info.device_model_version ==
+            LIBXL_DEVICE_MODEL_VERSION_NONE) {
+            domcreate_devmodel_started(egc, &dcs->dmss.dm, 0);
+            return;
+        }
+
         libxl_device_vkb_init(&vkb);
         libxl__device_vkb_add(gc, domid, &vkb);
         libxl_device_vkb_dispose(&vkb);
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 8ee14b9..d948546 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -866,6 +866,12 @@ static int libxl__domain_firmware(libxl__gc *gc,
         case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
             firmware = "hvmloader";
             break;
+        case LIBXL_DEVICE_MODEL_VERSION_NONE:
+            if (info->kernel == NULL) {
+                LOG(ERROR, "no device model requested without a kernel");
+                return ERROR_FAIL;
+            }
+            break;
         default:
             LOG(ERROR, "invalid device model version %d",
                 info->device_model_version);
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 23f27d4..0b75834 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -83,6 +83,7 @@ libxl_device_model_version = 
Enumeration("device_model_version", [
     (0, "UNKNOWN"),
     (1, "QEMU_XEN_TRADITIONAL"), # Historical qemu-xen device model (qemu-dm)
     (2, "QEMU_XEN"),             # Upstream based qemu-xen device model
+    (3, "NONE"),                 # No device model
     ])
 
 libxl_console_type = Enumeration("console_type", [
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index c858068..3d9b3d4 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -2067,6 +2067,8 @@ skip_vfb:
         } else if (!strcmp(buf, "qemu-xen")) {
             b_info->device_model_version
                 = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN;
+        } else if (!strcmp(buf, "none")) {
+            b_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_NONE;
         } else {
             fprintf(stderr,
                     "Unknown device_model_version \"%s\" specified\n", buf);
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 0363650..bad0872 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -610,7 +610,7 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags,
 
     if ( has_hvm_container_domain(d) )
     {
-        if ( (rc = hvm_domain_initialise(d)) != 0 )
+        if ( (rc = hvm_domain_initialise(d, domcr_flags)) != 0 )
         {
             iommu_domain_destroy(d);
             goto fail;
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index d5e5242..7694c9e 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -343,7 +343,7 @@ u64 hvm_get_guest_tsc_adjust(struct vcpu *v)
 void hvm_migrate_timers(struct vcpu *v)
 {
     /* PVH doesn't use rtc and emulated timers, it uses pvclock mechanism. */
-    if ( is_pvh_vcpu(v) )
+    if ( is_pvh_vcpu(v) || v->domain->arch.hvm_domain.no_emu )
         return;
 
     rtc_migrate_timers(v);
@@ -1423,7 +1423,7 @@ static int hvm_set_dm_domain(struct domain *d, domid_t 
domid)
     return rc;
 }
 
-int hvm_domain_initialise(struct domain *d)
+int hvm_domain_initialise(struct domain *d, unsigned int domcr_flags)
 {
     int rc;
 
@@ -1485,9 +1485,10 @@ int hvm_domain_initialise(struct domain *d)
     else
         d->arch.hvm_domain.io_bitmap = hvm_io_bitmap;
 
-    if ( is_pvh_domain(d) )
+    if ( is_pvh_domain(d) || domcr_flags & DOMCRF_noemu )
     {
         register_portio_handler(d, 0, 0x10003, handle_pvh_io);
+        d->arch.hvm_domain.no_emu = TRUE;
         return 0;
     }
 
@@ -1531,7 +1532,7 @@ int hvm_domain_initialise(struct domain *d)
 
 void hvm_domain_relinquish_resources(struct domain *d)
 {
-    if ( is_pvh_domain(d) )
+    if ( is_pvh_domain(d) || d->arch.hvm_domain.no_emu )
         return;
 
     if ( hvm_funcs.nhvm_domain_relinquish_resources )
@@ -1557,7 +1558,7 @@ void hvm_domain_destroy(struct domain *d)
 
     hvm_destroy_cacheattr_region_list(d);
 
-    if ( is_pvh_domain(d) )
+    if ( is_pvh_domain(d) || d->arch.hvm_domain.no_emu )
         return;
 
     hvm_funcs.domain_destroy(d);
@@ -2327,6 +2328,9 @@ int hvm_vcpu_initialise(struct vcpu *v)
         return 0;
     }
 
+    if ( d->arch.hvm_domain.no_emu )
+        return 0;
+
     rc = setup_compat_arg_xlat(v); /* teardown: free_compat_arg_xlat() */
     if ( rc != 0 )
         goto fail4;
diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c
index d52a48c..b7bc3c7 100644
--- a/xen/arch/x86/hvm/intercept.c
+++ b/xen/arch/x86/hvm/intercept.c
@@ -168,6 +168,9 @@ bool_t hvm_mmio_internal(paddr_t gpa)
     struct vcpu *curr = current;
     unsigned int i;
 
+    if ( curr->domain->arch.hvm_domain.no_emu )
+        return 0;
+
     for ( i = 0; i < HVM_MMIO_HANDLER_NR; ++i )
         if ( hvm_mmio_handlers[i]->check_handler(curr, gpa) )
             return 1;
@@ -180,6 +183,9 @@ int hvm_mmio_intercept(ioreq_t *p)
     struct vcpu *v = current;
     int i;
 
+    if ( v->domain->arch.hvm_domain.no_emu )
+        return X86EMUL_UNHANDLEABLE;
+
     for ( i = 0; i < HVM_MMIO_HANDLER_NR; i++ )
     {
         hvm_mmio_check_t check_handler =
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index ce517a7..1ce7ae0 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -550,7 +550,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
                | XEN_DOMCTL_CDF_pvh_guest
                | XEN_DOMCTL_CDF_hap
                | XEN_DOMCTL_CDF_s3_integrity
-               | XEN_DOMCTL_CDF_oos_off)) )
+               | XEN_DOMCTL_CDF_oos_off
+               | XEN_DOMCTL_CDF_noemu)) )
             break;
 
         dom = op->domain;
@@ -592,6 +593,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
u_domctl)
             domcr_flags |= DOMCRF_s3_integrity;
         if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_oos_off )
             domcr_flags |= DOMCRF_oos_off;
+        if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_noemu )
+            domcr_flags |= DOMCRF_noemu;
 
         d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref,
                           &op->u.createdomain.config);
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index ad68fcf..948ced8 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -135,6 +135,7 @@ struct hvm_domain {
     bool_t                 mem_sharing_enabled;
     bool_t                 qemu_mapcache_invalidate;
     bool_t                 is_s3_suspended;
+    bool_t                 no_emu;
 
     /*
      * TSC value that VCPUs use to calculate their tsc_offset value.
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index 77eeac5..68c987a 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -217,7 +217,7 @@ extern s8 hvm_port80_allowed;
 extern const struct hvm_function_table *start_svm(void);
 extern const struct hvm_function_table *start_vmx(void);
 
-int hvm_domain_initialise(struct domain *d);
+int hvm_domain_initialise(struct domain *d, unsigned int domcr_flags);
 void hvm_domain_relinquish_resources(struct domain *d);
 void hvm_domain_destroy(struct domain *d);
 
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index bc45ea5..4e9d7e7 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -63,6 +63,9 @@ struct xen_domctl_createdomain {
  /* Is this a PVH guest (as opposed to an HVM or PV guest)? */
 #define _XEN_DOMCTL_CDF_pvh_guest     4
 #define XEN_DOMCTL_CDF_pvh_guest      (1U<<_XEN_DOMCTL_CDF_pvh_guest)
+ /* Disable emulated devices */
+#define _XEN_DOMCTL_CDF_noemu         5
+#define XEN_DOMCTL_CDF_noemu          (1U<<_XEN_DOMCTL_CDF_noemu)
     uint32_t flags;
     struct xen_arch_domainconfig config;
 };
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 604d047..0aaff1e 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -552,6 +552,10 @@ struct domain *domain_create(domid_t domid, unsigned int 
domcr_flags,
  /* DOMCRF_pvh: Create PV domain in HVM container. */
 #define _DOMCRF_pvh             5
 #define DOMCRF_pvh              (1U<<_DOMCRF_pvh)
+/* DOMCRF_noemu: Create a HVM domain without emulated devices. */
+/* XXX: Should be split into smaller flags that disable specific devices? */
+#define _DOMCRF_noemu           6
+#define DOMCRF_noemu            (1U<<_DOMCRF_noemu)
 
 /*
  * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().
-- 
1.9.5 (Apple Git-50.3)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.