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

[Xen-devel] [PATCH v7 12/32] xen/x86: add bitmap of enabled emulated devices



Introduce a bitmap in x86 xen_arch_domainconfig that allows enabling or
disabling specific devices emulated inside of Xen for HVM guests.

Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx>
Acked-by: Wei Liu <wei.liu2@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: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
---
Changes since v6:
 - Define XEN_X86_EMU_ALL to contain all the possible emulated devices.
 - Remove full stops form the printks added to arch_domain_create.
 - Add Wei Liu Acked-by.
 - Added a check to x86 arch_domain_create in order to make sure a non-null
   config is always provided.
 - Check that emulation_flags is always 0 for PV guests.
 - Fix x86 callers of domain_create in order to make sure a non-null arch
   config is always provided.
 - Removed XEN_X86_EMU_PMU.
 - Removed Andrew Cooper's Reviewed-by, since the hypervisor side code has
   changed substantially.

Changes since v4:
 - Add a check to make sure the emulation bitmap is sane (undefined bits are
   all 0s).
 - Add Andrew Cooper Reviewed-by.

Changes since v3:
 - Return EOPNOTSUPP instead of ENOPERM if an invalid emulation mask is
   used.
 - Fix error messages (prefix them with d%d and use %#x instead of 0x%x).
 - Clearly state in the public header that emulation_flags should only be
   used with HVM guests.
 - Add a XEN_X86 prefix to the emulation flags defines.
 - Properly parenthese the has_* marcos.
---
 tools/libxl/libxl_x86.c           |  5 ++++-
 xen/arch/x86/domain.c             | 19 +++++++++++++++++++
 xen/arch/x86/mm.c                 |  7 ++++---
 xen/arch/x86/setup.c              |  3 ++-
 xen/common/schedule.c             |  8 +++++++-
 xen/include/asm-x86/domain.h      | 12 ++++++++++++
 xen/include/public/arch-x86/xen.h | 23 ++++++++++++++++++++++-
 7 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
index 9276126..e71f80e 100644
--- a/tools/libxl/libxl_x86.c
+++ b/tools/libxl/libxl_x86.c
@@ -7,7 +7,10 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
                                       libxl_domain_config *d_config,
                                       xc_domain_configuration_t *xc_config)
 {
-    /* No specific configuration right now */
+    if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM)
+        xc_config->emulation_flags = XEN_X86_EMU_ALL;
+    else
+        xc_config->emulation_flags = 0;
 
     return 0;
 }
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index dc3bb08..79182a4 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -496,6 +496,9 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags,
     int i, paging_initialised = 0;
     int rc = -ENOMEM;
 
+    if ( config == NULL )
+        return -EINVAL;
+
     d->arch.s3_integrity = !!(domcr_flags & DOMCRF_s3_integrity);
 
     INIT_LIST_HEAD(&d->arch.pdev_list);
@@ -517,6 +520,22 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags,
                d->domain_id);
     }
 
+    if ( (config->emulation_flags & ~XEN_X86_EMU_ALL) != 0 )
+    {
+        printk(XENLOG_G_ERR "d%d: Invalid emulation bitmap: %#x\n",
+               d->domain_id, config->emulation_flags);
+        return -EINVAL;
+    }
+    if ( (is_hvm_domain(d) && config->emulation_flags != XEN_X86_EMU_ALL) ||
+         (is_pv_domain(d) && config->emulation_flags != 0) )
+    {
+        printk(XENLOG_G_ERR "d%d: Xen does not allow %s domain creation with "
+               "the current selection of emulators: %#x\n", d->domain_id,
+               is_hvm_domain(d) ? "HVM" : "PV", config->emulation_flags);
+        return -EOPNOTSUPP;
+    }
+    d->arch.emulation_flags = config->emulation_flags;
+
     if ( has_hvm_container_domain(d) )
     {
         d->arch.hvm_domain.hap_enabled =
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 327b837..b0873f6 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -255,6 +255,7 @@ static l4_pgentry_t __read_mostly split_l4e;
 void __init arch_init_memory(void)
 {
     unsigned long i, pfn, rstart_pfn, rend_pfn, iostart_pfn, ioend_pfn;
+    struct xen_arch_domainconfig config = { .emulation_flags = 0 };
 
     /* Basic guest-accessible flags: PRESENT, R/W, USER, A/D, AVAIL[0,1,2] */
     base_disallow_mask = ~(_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|
@@ -272,7 +273,7 @@ void __init arch_init_memory(void)
      * Hidden PCI devices will also be associated with this domain
      * (but be [partly] controlled by Dom0 nevertheless).
      */
-    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0, NULL);
+    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0, &config);
     BUG_ON(IS_ERR(dom_xen));
     INIT_LIST_HEAD(&dom_xen->arch.pdev_list);
 
@@ -281,14 +282,14 @@ void __init arch_init_memory(void)
      * This domain owns I/O pages that are within the range of the page_info
      * array. Mappings occur at the priv of the caller.
      */
-    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0, NULL);
+    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0, &config);
     BUG_ON(IS_ERR(dom_io));
     
     /*
      * Initialise our COW domain.
      * This domain owns sharable pages.
      */
-    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0, NULL);
+    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0, &config);
     BUG_ON(IS_ERR(dom_cow));
 
     /* First 1MB of RAM is historically marked as I/O. */
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 3f4868e..7efcb9d 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -582,6 +582,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         .parity    = 'n',
         .stop_bits = 1
     };
+    struct xen_arch_domainconfig config = { .emulation_flags = 0 };
 
     /* Critical region without IDT or TSS.  Any fault is deadly! */
 
@@ -1394,7 +1395,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
      * x86 doesn't support arch-configuration. So it's fine to pass
      * NULL.
      */
-    dom0 = domain_create(0, domcr_flags, 0, NULL);
+    dom0 = domain_create(0, domcr_flags, 0, &config);
     if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
         panic("Error creating domain 0");
 
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 5ffa1a1..aeb911e 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -1428,6 +1428,9 @@ static struct notifier_block cpu_schedule_nfb = {
 /* Initialise the data structures. */
 void __init scheduler_init(void)
 {
+#ifdef CONFIG_X86
+    struct xen_arch_domainconfig config = { .emulation_flags = 0 };
+#endif
     struct domain *idle_domain;
     int i;
 
@@ -1474,8 +1477,11 @@ void __init scheduler_init(void)
         sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
     }
 
-    /* There is no need of arch-specific configuration for an idle domain */
+#ifdef CONFIG_X86
+    idle_domain = domain_create(DOMID_IDLE, 0, 0, &config);
+#else
     idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
+#endif
     BUG_ON(IS_ERR(idle_domain));
     idle_domain->vcpu = idle_vcpu;
     idle_domain->max_vcpus = nr_cpu_ids;
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index f1d7ed6..84ae4c1 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -387,8 +387,20 @@ struct arch_domain
     /* Mem_access emulation control */
     bool_t mem_access_emulate_enabled;
     bool_t mem_access_emulate_each_rep;
+
+    /* Emulated devices enabled bitmap. */
+    uint32_t emulation_flags;
 } __cacheline_aligned;
 
+#define has_vlapic(d)       ((d)->arch.emulation_flags & XEN_X86_EMU_LAPIC)
+#define has_vhpet(d)        ((d)->arch.emulation_flags & XEN_X86_EMU_HPET)
+#define has_vpmtimer(d)     ((d)->arch.emulation_flags & XEN_X86_EMU_PMTIMER)
+#define has_vrtc(d)         ((d)->arch.emulation_flags & XEN_X86_EMU_RTC)
+#define has_vioapic(d)      ((d)->arch.emulation_flags & XEN_X86_EMU_IOAPIC)
+#define has_vpic(d)         ((d)->arch.emulation_flags & XEN_X86_EMU_PIC)
+#define has_vvga(d)         ((d)->arch.emulation_flags & XEN_X86_EMU_VGA)
+#define has_viommu(d)       ((d)->arch.emulation_flags & XEN_X86_EMU_IOMMU)
+
 #define has_arch_pdevs(d)    (!list_empty(&(d)->arch.pdev_list))
 
 #define gdt_ldt_pt_idx(v) \
diff --git a/xen/include/public/arch-x86/xen.h 
b/xen/include/public/arch-x86/xen.h
index 2ecc9c9..c97a9b4 100644
--- a/xen/include/public/arch-x86/xen.h
+++ b/xen/include/public/arch-x86/xen.h
@@ -268,7 +268,28 @@ typedef struct arch_shared_info arch_shared_info_t;
  * XEN_DOMCTL_INTERFACE_VERSION.
  */
 struct xen_arch_domainconfig {
-    char dummy;
+#define _XEN_X86_EMU_LAPIC          0
+#define XEN_X86_EMU_LAPIC           (1U<<_XEN_X86_EMU_LAPIC)
+#define _XEN_X86_EMU_HPET           1
+#define XEN_X86_EMU_HPET            (1U<<_XEN_X86_EMU_HPET)
+#define _XEN_X86_EMU_PMTIMER        2
+#define XEN_X86_EMU_PMTIMER         (1U<<_XEN_X86_EMU_PMTIMER)
+#define _XEN_X86_EMU_RTC            3
+#define XEN_X86_EMU_RTC             (1U<<_XEN_X86_EMU_RTC)
+#define _XEN_X86_EMU_IOAPIC         4
+#define XEN_X86_EMU_IOAPIC          (1U<<_XEN_X86_EMU_IOAPIC)
+#define _XEN_X86_EMU_PIC            5
+#define XEN_X86_EMU_PIC             (1U<<_XEN_X86_EMU_PIC)
+#define _XEN_X86_EMU_VGA            6
+#define XEN_X86_EMU_VGA             (1U<<_XEN_X86_EMU_VGA)
+#define _XEN_X86_EMU_IOMMU          7
+#define XEN_X86_EMU_IOMMU           (1U<<_XEN_X86_EMU_IOMMU)
+
+#define XEN_X86_EMU_ALL             (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET |  \
+                                     XEN_X86_EMU_PMTIMER | XEN_X86_EMU_RTC | \
+                                     XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC |  \
+                                     XEN_X86_EMU_VGA | XEN_X86_EMU_IOMMU)
+    uint32_t emulation_flags;
 };
 #endif
 
-- 
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®.