All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/7] xen: Hardware domain support
@ 2014-03-27 11:52 Daniel De Graaf
  2014-03-27 11:52 ` [PATCH 1/7] xen: use domid check in is_hardware_domain Daniel De Graaf
                   ` (7 more replies)
  0 siblings, 8 replies; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 11:52 UTC (permalink / raw)
  To: xen-devel; +Cc: dgdegra

This adds support to the hypervisor for the creation of a hardware
domain distinct from domain 0, allowing further disaggregation of the
duties of domain 0.  The commit message for patch 1 contains a more
complete description of the distinction between the hardware domain and
control domain(s).  Making the hardware domain distinct from domain 0
allows it to be further de-privileged using an XSM policy: the hardware
domain does not need to be permitted access to create or modify other
domains in order to act as a device backend for them.

Changes since v2:
 - Rename and move CONFIG_LATE_HWDOM declaration to asm-x86/config.h
 - Move alloc_dom0_vcpu0 prototype change from patch 5 to 4
 - Also rename nmi_{dom0 => hwdom}_report
 - Add help/documentation for xl destroy -f

Changes since v1:
 - More complete conversion to is_hardware_domain (convert "== dom0")
 - Rename "dom0" global variable and associated functions
 - Avoid locating the hardware_domid variable in x86-only code
 - Require using "xl destroy -f 0" to destroy domain 0 to retain the
   existing guard against accidental attempts to destroy domain 0 that
   will still cause disruption of the platform.
 - Add an XSM permission check so that the security label of the
   hardware domain can be limited by the policy.
 - Rebase against updated xen/staging

[PATCH 1/7] xen: use domid check in is_hardware_domain
[PATCH 2/7] xen/iommu: Move dom0 setup to __hwdom_init
[PATCH 3/7] xen: prevent 0 from being used as a dynamic domid
[PATCH 4/7] xen: rename dom0 to hardware_domain
[PATCH 5/7] xen: rename various functions referencing dom0
[PATCH 6/7] xen: Allow hardare domain != dom0
[PATCH 7/7] tools/libxl: Allow dom0 to be destroyed

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/7] xen: use domid check in is_hardware_domain
  2014-03-27 11:52 [PATCH v3 0/7] xen: Hardware domain support Daniel De Graaf
@ 2014-03-27 11:52 ` Daniel De Graaf
  2014-03-27 15:31   ` Ian Campbell
  2014-03-27 11:52 ` [PATCH 2/7] xen/iommu: Move dom0 setup code to __hwdom_init Daniel De Graaf
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 11:52 UTC (permalink / raw)
  To: xen-devel
  Cc: Keir Fraser, Ian Campbell, Tim Deegan, Stefano Stabellini,
	Suravee Suthikulpanit, dgdegra, Xiantao Zhang

Instead of checking is_privileged to determine if a domain should
control the hardware, check that the domain_id is equal to zero (which
is currently the only domain for which is_privileged is true).  This
allows other places where domain_id is checked for zero to be replaced
with is_hardware_domain.

The distinction between is_hardware_domain, is_control_domain, and
domain 0 is based on the following disaggregation model:

Domain 0 bootstraps the system.  It may remain to perform requested
builds of domains that need a minimal trust chain (i.e. vTPM domains).
Other than being built by the hypervisor, nothing is special about this
domain - although it may be useful to have is_control_domain() return
true depending on the toolstack it uses to build other domains.

The hardware domain manages devices for PCI pass-through to driver
domains or can act as a driver domain itself, depending on the desired
degree of disaggregation.  It is also the domain managing devices that
do not support pass-through: PCI configuration space access, parsing the
hardware ACPI tables and system power or machine check events.  This is
the only domain where is_hardware_domain() is true.  The return of
is_control_domain() may be false for this domain.

The control domain manages other domains, controls guest launch and
shutdown, and manages resource constraints; is_control_domain() returns
true.  The functionality guarded by is_control_domain may in the future
be adapted to use explicit hypercalls, eliminating the special treatment
of this domain.  It may be reasonable to have multiple control domains
on a multi-tenant system.

Guest domains and other service or driver domains are all treated
identically by the hypervisor; the security policy may further constrain
administrative actions on or communication between these domains.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Tim Deegan <tim@xen.org>
Cc: Xiantao Zhang <xiantao.zhang@intel.com>

---
 xen/arch/arm/domain.c                       |  6 +++---
 xen/arch/arm/gic.c                          |  4 ++--
 xen/arch/arm/vgic.c                         |  2 +-
 xen/arch/arm/vtimer.c                       |  5 +++--
 xen/arch/arm/vuart.c                        |  2 +-
 xen/arch/x86/cpu/mcheck/vmce.c              |  2 +-
 xen/arch/x86/domain.c                       |  3 ++-
 xen/arch/x86/hvm/i8254.c                    |  2 +-
 xen/arch/x86/mm.c                           |  2 +-
 xen/arch/x86/time.c                         |  4 ++--
 xen/arch/x86/traps.c                        | 21 +++++++++++----------
 xen/common/domain.c                         |  6 +++---
 xen/common/kernel.c                         |  2 +-
 xen/common/xenoprof.c                       |  8 +++++++-
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  2 +-
 xen/drivers/passthrough/iommu.c             |  2 +-
 xen/drivers/passthrough/vtd/iommu.c         | 11 ++++++-----
 xen/drivers/passthrough/vtd/x86/vtd.c       |  2 +-
 xen/include/xen/sched.h                     |  4 ++--
 19 files changed, 50 insertions(+), 40 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 46ee486..2c76a8f 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -540,10 +540,10 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
 
     /*
      * Virtual UART is only used by linux early printk and decompress code.
-     * Only use it for dom0 because the linux kernel may not support
-     * multi-platform.
+     * Only use it for the hardware domain because the linux kernel may not
+     * support multi-platform.
      */
-    if ( (d->domain_id == 0) && (rc = domain_vuart_init(d)) )
+    if ( is_hardware_domain(d) && (rc = domain_vuart_init(d)) )
         goto fail;
 
     return 0;
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 0095b97..8168b7b 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -865,10 +865,10 @@ int gicv_setup(struct domain *d)
     int ret;
 
     /*
-     * Domain 0 gets the hardware address.
+     * The hardware domain gets the hardware address.
      * Guests get the virtual platform layout.
      */
-    if ( d->domain_id == 0 )
+    if ( is_hardware_domain(d) )
     {
         d->arch.vgic.dbase = gic.dbase;
         d->arch.vgic.cbase = gic.cbase;
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 9fc9586..4a7f8c0 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -82,7 +82,7 @@ int domain_vgic_init(struct domain *d)
     /* Currently nr_lines in vgic and gic doesn't have the same meanings
      * Here nr_lines = number of SPIs
      */
-    if ( d->domain_id == 0 )
+    if ( is_hardware_domain(d) )
         d->arch.vgic.nr_lines = gic_number_lines() - 32;
     else
         d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index 3d6a721..cb690bb 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -54,10 +54,11 @@ int vcpu_domain_init(struct domain *d)
 int vcpu_vtimer_init(struct vcpu *v)
 {
     struct vtimer *t = &v->arch.phys_timer;
-    bool_t d0 = (v->domain == dom0);
+    bool_t d0 = is_hardware_domain(v->domain);
 
     /*
-     * Domain 0 uses the hardware interrupts, guests get the virtual platform.
+     * Hardware domain uses the hardware interrupts, guests get the virtual
+     * platform.
      */
 
     init_timer(&t->timer, phys_timer_expired, t, v->processor);
diff --git a/xen/arch/arm/vuart.c b/xen/arch/arm/vuart.c
index b9d3ced..c02a8a9 100644
--- a/xen/arch/arm/vuart.c
+++ b/xen/arch/arm/vuart.c
@@ -46,7 +46,7 @@
 
 int domain_vuart_init(struct domain *d)
 {
-    ASSERT( !d->domain_id );
+    ASSERT( is_hardware_domain(d) );
 
     d->arch.vuart.info = serial_vuart_info(SERHND_DTUART);
     if ( !d->arch.vuart.info )
diff --git a/xen/arch/x86/cpu/mcheck/vmce.c b/xen/arch/x86/cpu/mcheck/vmce.c
index ed00f7c..c83375e 100644
--- a/xen/arch/x86/cpu/mcheck/vmce.c
+++ b/xen/arch/x86/cpu/mcheck/vmce.c
@@ -430,7 +430,7 @@ int unmmap_broken_page(struct domain *d, mfn_t mfn, unsigned long gfn)
     int rc;
 
     /* Always trust dom0's MCE handler will prevent future access */
-    if ( d == dom0 )
+    if ( is_hardware_domain(d) )
         return 0;
 
     if (!mfn_valid(mfn_x(mfn)))
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 796b775..66acc90 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1529,7 +1529,8 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
         }
 
         set_cpuid_faulting(is_pv_vcpu(next) &&
-                           (next->domain->domain_id != 0));
+                           !is_control_domain(next->domain) &&
+                           !is_hardware_domain(next->domain));
     }
 
     if (is_hvm_vcpu(next) && (prev != next) )
diff --git a/xen/arch/x86/hvm/i8254.c b/xen/arch/x86/hvm/i8254.c
index f7493b8..6a91f76 100644
--- a/xen/arch/x86/hvm/i8254.c
+++ b/xen/arch/x86/hvm/i8254.c
@@ -540,7 +540,7 @@ int pv_pit_handler(int port, int data, int write)
         .data = data
     };
 
-    if ( (current->domain->domain_id == 0) && dom0_pit_access(&ioreq) )
+    if ( is_hardware_domain(current->domain) && dom0_pit_access(&ioreq) )
     {
         /* nothing to do */;
     }
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index fdc5ed3..ad48acc 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4787,7 +4787,7 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg)
             .max_mfn = MACH2PHYS_NR_ENTRIES - 1
         };
 
-        if ( !mem_hotplug && current->domain == dom0 )
+        if ( !mem_hotplug && is_hardware_domain(current->domain) )
             mapping.max_mfn = max_page - 1;
         if ( copy_to_guest(arg, &mapping, 1) )
             return -EFAULT;
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index f904af2..89308bd 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -1839,7 +1839,7 @@ void tsc_set_info(struct domain *d,
                   uint32_t tsc_mode, uint64_t elapsed_nsec,
                   uint32_t gtsc_khz, uint32_t incarnation)
 {
-    if ( is_idle_domain(d) || (d->domain_id == 0) )
+    if ( is_idle_domain(d) || is_hardware_domain(d) )
     {
         d->arch.vtsc = 0;
         return;
@@ -1943,7 +1943,7 @@ static void dump_softtsc(unsigned char key)
                "warp=%lu (count=%lu)\n", tsc_max_warp, tsc_check_count);
     for_each_domain ( d )
     {
-        if ( d->domain_id == 0 && d->arch.tsc_mode == TSC_MODE_DEFAULT )
+        if ( is_hardware_domain(d) && d->arch.tsc_mode == TSC_MODE_DEFAULT )
             continue;
         printk("dom%u%s: mode=%d",d->domain_id,
                 is_hvm_domain(d) ? "(hvm)" : "", d->arch.tsc_mode);
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index ed4ae2d..21c8b63 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -732,18 +732,19 @@ int cpuid_hypervisor_leaves( uint32_t idx, uint32_t sub_idx,
 void pv_cpuid(struct cpu_user_regs *regs)
 {
     uint32_t a, b, c, d;
+    struct vcpu *curr = current;
 
     a = regs->eax;
     b = regs->ebx;
     c = regs->ecx;
     d = regs->edx;
 
-    if ( current->domain->domain_id != 0 )
+    if ( !is_control_domain(curr->domain) && !is_hardware_domain(curr->domain) )
     {
         unsigned int cpuid_leaf = a, sub_leaf = c;
 
         if ( !cpuid_hypervisor_leaves(a, c, &a, &b, &c, &d) )
-            domain_cpuid(current->domain, a, c, &a, &b, &c, &d);
+            domain_cpuid(curr->domain, a, c, &a, &b, &c, &d);
 
         switch ( cpuid_leaf )
         {
@@ -751,15 +752,15 @@ void pv_cpuid(struct cpu_user_regs *regs)
         {
             unsigned int _eax, _ebx, _ecx, _edx;
             /* EBX value of main leaf 0 depends on enabled xsave features */
-            if ( sub_leaf == 0 && current->arch.xcr0 )
+            if ( sub_leaf == 0 && curr->arch.xcr0 )
             {
                 /* reset EBX to default value first */
                 b = XSTATE_AREA_MIN_SIZE;
                 for ( sub_leaf = 2; sub_leaf < 63; sub_leaf++ )
                 {
-                    if ( !(current->arch.xcr0 & (1ULL << sub_leaf)) )
+                    if ( !(curr->arch.xcr0 & (1ULL << sub_leaf)) )
                         continue;
-                    domain_cpuid(current->domain, cpuid_leaf, sub_leaf,
+                    domain_cpuid(curr->domain, cpuid_leaf, sub_leaf,
                                  &_eax, &_ebx, &_ecx, &_edx);
                     if ( (_eax + _ebx) > b )
                         b = _eax + _ebx;
@@ -796,7 +797,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
         __clear_bit(X86_FEATURE_DS, &d);
         __clear_bit(X86_FEATURE_ACC, &d);
         __clear_bit(X86_FEATURE_PBE, &d);
-        if ( is_pvh_vcpu(current) )
+        if ( is_pvh_vcpu(curr) )
             __clear_bit(X86_FEATURE_MTRR, &d);
 
         __clear_bit(X86_FEATURE_DTES64 % 32, &c);
@@ -805,7 +806,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
         __clear_bit(X86_FEATURE_VMXE % 32, &c);
         __clear_bit(X86_FEATURE_SMXE % 32, &c);
         __clear_bit(X86_FEATURE_TM2 % 32, &c);
-        if ( is_pv_32bit_vcpu(current) )
+        if ( is_pv_32bit_vcpu(curr) )
             __clear_bit(X86_FEATURE_CX16 % 32, &c);
         __clear_bit(X86_FEATURE_XTPR % 32, &c);
         __clear_bit(X86_FEATURE_PDCM % 32, &c);
@@ -844,12 +845,12 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
     case 0x80000001:
         /* Modify Feature Information. */
-        if ( is_pv_32bit_vcpu(current) )
+        if ( is_pv_32bit_vcpu(curr) )
         {
             __clear_bit(X86_FEATURE_LM % 32, &d);
             __clear_bit(X86_FEATURE_LAHF_LM % 32, &c);
         }
-        if ( is_pv_32on64_vcpu(current) &&
+        if ( is_pv_32on64_vcpu(curr) &&
              boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
             __clear_bit(X86_FEATURE_SYSCALL % 32, &d);
         __clear_bit(X86_FEATURE_PAGE1GB % 32, &d);
@@ -1860,7 +1861,7 @@ static inline uint64_t guest_misc_enable(uint64_t val)
 static int is_cpufreq_controller(struct domain *d)
 {
     return ((cpufreq_controller == FREQCTL_dom0_kernel) &&
-            (d->domain_id == 0));
+            is_hardware_domain(d));
 }
 
 #include "x86_64/mmconfig.h"
diff --git a/xen/common/domain.c b/xen/common/domain.c
index ad8a1b6..b5868a5 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -237,7 +237,7 @@ struct domain *domain_create(
     else if ( domcr_flags & DOMCRF_pvh )
         d->guest_type = guest_type_pvh;
 
-    if ( domid == 0 )
+    if ( is_hardware_domain(d) )
     {
         d->is_pinned = opt_dom0_vcpus_pin;
         d->disable_migrate = 1;
@@ -262,7 +262,7 @@ struct domain *domain_create(
         d->is_paused_by_controller = 1;
         atomic_inc(&d->pause_count);
 
-        if ( domid )
+        if ( !is_hardware_domain(d) )
             d->nr_pirqs = nr_static_irqs + extra_domU_irqs;
         else
             d->nr_pirqs = nr_static_irqs + extra_dom0_irqs;
@@ -594,7 +594,7 @@ void domain_shutdown(struct domain *d, u8 reason)
         d->shutdown_code = reason;
     reason = d->shutdown_code;
 
-    if ( d->domain_id == 0 )
+    if ( is_hardware_domain(d) )
         dom0_shutdown(reason);
 
     if ( d->is_shutting_down )
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index b371f8f..7e83353 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -303,7 +303,7 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
                     (1U << XENFEAT_auto_translated_physmap);
             if ( supervisor_mode_kernel )
                 fi.submap |= 1U << XENFEAT_supervisor_mode_kernel;
-            if ( current->domain == dom0 )
+            if ( is_hardware_domain(current->domain) )
                 fi.submap |= 1U << XENFEAT_dom0;
 #ifdef CONFIG_X86
             switch ( d->guest_type )
diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c
index 52ab00d..3c30c3e 100644
--- a/xen/common/xenoprof.c
+++ b/xen/common/xenoprof.c
@@ -601,9 +601,15 @@ static int xenoprof_op_init(XEN_GUEST_HANDLE_PARAM(void) arg)
                                    xenoprof_init.cpu_type)) )
         return ret;
 
+    /* Only the hardware domain may become the primary profiler here because
+     * there is currently no cleanup of xenoprof_primary_profiler or associated
+     * profiling state when the primary profiling domain is shut down or
+     * crashes.  Once a better cleanup method is present, it will be possible to
+     * allow another domain to be the primary profiler.
+     */
     xenoprof_init.is_primary = 
         ((xenoprof_primary_profiler == d) ||
-         ((xenoprof_primary_profiler == NULL) && (d->domain_id == 0)));
+         ((xenoprof_primary_profiler == NULL) && is_hardware_domain(d)));
     if ( xenoprof_init.is_primary )
         xenoprof_primary_profiler = current->domain;
 
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index c26aabc..cf67494 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -122,7 +122,7 @@ static void amd_iommu_setup_domain_device(
 
     BUG_ON( !hd->root_table || !hd->paging_mode || !iommu->dev_table.buffer );
 
-    if ( iommu_passthrough && (domain->domain_id == 0) )
+    if ( iommu_passthrough && is_hardware_domain(domain) )
         valid = 0;
 
     if ( ats_enabled )
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 0cf0748..54d891f 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -817,7 +817,7 @@ static void iommu_dump_p2m_table(unsigned char key)
     ops = iommu_get_ops();
     for_each_domain(d)
     {
-        if ( !d->domain_id )
+        if ( is_hardware_domain(d) )
             continue;
 
         if ( iommu_use_hap_pt(d) )
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index beb3723..9c8e4a3 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1327,7 +1327,7 @@ int domain_context_mapping_one(
         return res;
     }
 
-    if ( iommu_passthrough && (domain->domain_id == 0) )
+    if ( iommu_passthrough && is_hardware_domain(domain) )
     {
         context_set_translation_type(*context, CONTEXT_TT_PASS_THRU);
         agaw = level_to_agaw(iommu->nr_pt_levels);
@@ -1723,7 +1723,7 @@ static int intel_iommu_map_page(
         return 0;
 
     /* do nothing if dom0 and iommu supports pass thru */
-    if ( iommu_passthrough && (d->domain_id == 0) )
+    if ( iommu_passthrough && is_hardware_domain(d) )
         return 0;
 
     spin_lock(&hd->mapping_lock);
@@ -1767,7 +1767,7 @@ static int intel_iommu_map_page(
 static int intel_iommu_unmap_page(struct domain *d, unsigned long gfn)
 {
     /* Do nothing if dom0 and iommu supports pass thru. */
-    if ( iommu_passthrough && (d->domain_id == 0) )
+    if ( iommu_passthrough && is_hardware_domain(d) )
         return 0;
 
     dma_pte_clear_one(d, (paddr_t)gfn << PAGE_SHIFT_4K);
@@ -1950,8 +1950,9 @@ static int intel_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
             continue;
 
         /*
-         * If the device belongs to dom0, and it has RMRR, don't remove
-         * it from dom0, because BIOS may use RMRR at booting time.
+         * If the device belongs to the hardware domain, and it has RMRR, don't
+         * remove it from the hardware domain, because BIOS may use RMRR at
+         * booting time.
          */
         if ( is_hardware_domain(pdev->domain) )
             return 0;
diff --git a/xen/drivers/passthrough/vtd/x86/vtd.c b/xen/drivers/passthrough/vtd/x86/vtd.c
index ca17cb1..f271a42 100644
--- a/xen/drivers/passthrough/vtd/x86/vtd.c
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c
@@ -111,7 +111,7 @@ void __init iommu_set_dom0_mapping(struct domain *d)
 {
     unsigned long i, j, tmp, top;
 
-    BUG_ON(d->domain_id != 0);
+    BUG_ON(!is_hardware_domain(d));
 
     top = max(max_pdx, pfn_to_pdx(0xffffffffUL >> PAGE_SHIFT) + 1);
 
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index b9ba379..1f45f71 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -791,10 +791,10 @@ void watchdog_domain_destroy(struct domain *d);
 /* 
  * Use this check when the following are both true:
  *  - Using this feature or interface requires full access to the hardware
- *    (that is, this is would not be suitable for a driver domain)
+ *    (that is, this would not be suitable for a driver domain)
  *  - There is never a reason to deny dom0 access to this
  */
-#define is_hardware_domain(_d) ((_d)->is_privileged)
+#define is_hardware_domain(_d) ((_d)->domain_id == 0)
 
 /* This check is for functionality specific to a control domain */
 #define is_control_domain(_d) ((_d)->is_privileged)
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 2/7] xen/iommu: Move dom0 setup code to __hwdom_init
  2014-03-27 11:52 [PATCH v3 0/7] xen: Hardware domain support Daniel De Graaf
  2014-03-27 11:52 ` [PATCH 1/7] xen: use domid check in is_hardware_domain Daniel De Graaf
@ 2014-03-27 11:52 ` Daniel De Graaf
  2014-03-27 11:52 ` [PATCH 3/7] xen: prevent 0 from being used as a dynamic domid Daniel De Graaf
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 11:52 UTC (permalink / raw)
  To: xen-devel
  Cc: dgdegra, Xiantao Zhang, Keir Fraser, Suravee Suthikulpanit, Jan Beulich

When the hardware domain is split from domain 0, the initialization code
for the hardware domain cannot be in the __init section, since the
actual domain creation happens after these sections have been discarded.
Create a __hwdom_init section designator to annotate these functions,
and control it using the XSM configuration option for now (since XSM is
required to take advantage of the security benefits of disaggregation).

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Cc: Keir Fraser <keir@xen.org>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Xiantao Zhang <xiantao.zhang@intel.com>
---
 xen/arch/x86/setup.c                        | 4 ++--
 xen/drivers/passthrough/amd/pci_amd_iommu.c | 5 +++--
 xen/drivers/passthrough/iommu.c             | 6 +++---
 xen/drivers/passthrough/pci.c               | 4 ++--
 xen/drivers/passthrough/vtd/iommu.c         | 6 +++---
 xen/drivers/passthrough/vtd/quirks.c        | 2 +-
 xen/drivers/passthrough/vtd/x86/vtd.c       | 4 ++--
 xen/include/asm-x86/config.h                | 4 ++++
 xen/include/xen/init.h                      | 8 ++++++++
 9 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 4dbf2b7..13a148c 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1438,7 +1438,7 @@ void arch_get_xen_caps(xen_capabilities_info_t *info)
     }
 }
 
-int __init xen_in_range(unsigned long mfn)
+int __hwdom_init xen_in_range(unsigned long mfn)
 {
     paddr_t start, end;
     int i;
@@ -1446,7 +1446,7 @@ int __init xen_in_range(unsigned long mfn)
     enum { region_s3, region_text, region_bss, nr_regions };
     static struct {
         paddr_t s, e;
-    } xen_regions[nr_regions] __initdata;
+    } xen_regions[nr_regions] __hwdom_initdata;
 
     /* initialize first time */
     if ( !xen_regions[0].s )
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index cf67494..ff5f06e 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -169,7 +169,8 @@ static void amd_iommu_setup_domain_device(
     }
 }
 
-static int __init amd_iommu_setup_dom0_device(u8 devfn, struct pci_dev *pdev)
+static int __hwdom_init amd_iommu_setup_dom0_device(
+    u8 devfn, struct pci_dev *pdev)
 {
     int bdf = PCI_BDF2(pdev->bus, pdev->devfn);
     struct amd_iommu *iommu = find_iommu_for_device(pdev->seg, bdf);
@@ -280,7 +281,7 @@ static int amd_iommu_domain_init(struct domain *d)
     return 0;
 }
 
-static void __init amd_iommu_dom0_init(struct domain *d)
+static void __hwdom_init amd_iommu_dom0_init(struct domain *d)
 {
     unsigned long i; 
 
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 54d891f..3e5635c 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -45,7 +45,7 @@ custom_param("iommu", parse_iommu_param);
 bool_t __initdata iommu_enable = 1;
 bool_t __read_mostly iommu_enabled;
 bool_t __read_mostly force_iommu;
-bool_t __initdata iommu_dom0_strict;
+bool_t __hwdom_initdata iommu_dom0_strict;
 bool_t __read_mostly iommu_verbose;
 bool_t __read_mostly iommu_workaround_bios_bug;
 bool_t __read_mostly iommu_passthrough;
@@ -130,7 +130,7 @@ int iommu_domain_init(struct domain *d)
     return hd->platform_ops->init(d);
 }
 
-static __init void check_dom0_pvh_reqs(struct domain *d)
+static void __hwdom_init check_dom0_pvh_reqs(struct domain *d)
 {
     if ( !iommu_enabled )
         panic("Presently, iommu must be enabled for pvh dom0\n");
@@ -141,7 +141,7 @@ static __init void check_dom0_pvh_reqs(struct domain *d)
     iommu_dom0_strict = 1;
 }
 
-void __init iommu_dom0_init(struct domain *d)
+void __hwdom_init iommu_dom0_init(struct domain *d)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(d);
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index ff78142..dfa195a 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -893,7 +893,7 @@ static void setup_one_dom0_device(const struct setup_dom0 *ctxt,
               PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn) );
 }
 
-static int __init _setup_dom0_pci_devices(struct pci_seg *pseg, void *arg)
+static int __hwdom_init _setup_dom0_pci_devices(struct pci_seg *pseg, void *arg)
 {
     struct setup_dom0 *ctxt = arg;
     int bus, devfn;
@@ -943,7 +943,7 @@ static int __init _setup_dom0_pci_devices(struct pci_seg *pseg, void *arg)
     return 0;
 }
 
-void __init setup_dom0_pci_devices(
+void __hwdom_init setup_dom0_pci_devices(
     struct domain *d, int (*handler)(u8 devfn, struct pci_dev *))
 {
     struct setup_dom0 ctxt = { .d = d, .handler = handler };
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 9c8e4a3..d22d518 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1242,7 +1242,7 @@ static int intel_iommu_domain_init(struct domain *d)
     return 0;
 }
 
-static void __init intel_iommu_dom0_init(struct domain *d)
+static void __hwdom_init intel_iommu_dom0_init(struct domain *d)
 {
     struct acpi_drhd_unit *drhd;
 
@@ -1992,7 +1992,7 @@ static int intel_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
     return domain_context_unmap(pdev->domain, devfn, pdev);
 }
 
-static int __init setup_dom0_device(u8 devfn, struct pci_dev *pdev)
+static int __hwdom_init setup_dom0_device(u8 devfn, struct pci_dev *pdev)
 {
     int err;
 
@@ -2140,7 +2140,7 @@ static int init_vtd_hw(void)
     return 0;
 }
 
-static void __init setup_dom0_rmrr(struct domain *d)
+static void __hwdom_init setup_dom0_rmrr(struct domain *d)
 {
     struct acpi_rmrr_unit *rmrr;
     u16 bdf;
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index 7f6c3a7..fbba23b 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -384,7 +384,7 @@ void me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map)
  *   - This can cause system failure upon non-fatal VT-d faults
  *   - Potential security issue if malicious guest trigger VT-d faults
  */
-void __init pci_vtd_quirk(struct pci_dev *pdev)
+void __hwdom_init pci_vtd_quirk(struct pci_dev *pdev)
 {
     int seg = pdev->seg;
     int bus = pdev->bus;
diff --git a/xen/drivers/passthrough/vtd/x86/vtd.c b/xen/drivers/passthrough/vtd/x86/vtd.c
index f271a42..00131b3 100644
--- a/xen/drivers/passthrough/vtd/x86/vtd.c
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c
@@ -36,7 +36,7 @@
  * iommu_inclusive_mapping: when set, all memory below 4GB is included in dom0
  * 1:1 iommu mappings except xen and unusable regions.
  */
-static bool_t __initdata iommu_inclusive_mapping = 1;
+static bool_t __hwdom_initdata iommu_inclusive_mapping = 1;
 boolean_param("iommu_inclusive_mapping", iommu_inclusive_mapping);
 
 void *map_vtd_domain_page(u64 maddr)
@@ -107,7 +107,7 @@ void hvm_dpci_isairq_eoi(struct domain *d, unsigned int isairq)
     spin_unlock(&d->event_lock);
 }
 
-void __init iommu_set_dom0_mapping(struct domain *d)
+void __hwdom_init iommu_set_dom0_mapping(struct domain *d)
 {
     unsigned long i, j, tmp, top;
 
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index 99d0e2c..56b93cd 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -52,6 +52,10 @@
 #define CONFIG_KEXEC 1
 #define CONFIG_WATCHDOG 1
 
+#ifdef XSM_ENABLE
+#define CONFIG_LATE_HWDOM 1
+#endif
+
 #define HZ 100
 
 #define OPT_CONSOLE_STR "vga"
diff --git a/xen/include/xen/init.h b/xen/include/xen/init.h
index 9d481b3..b3bced3 100644
--- a/xen/include/xen/init.h
+++ b/xen/include/xen/init.h
@@ -129,4 +129,12 @@ extern struct kernel_param __setup_start, __setup_end;
 #define __devexitdata __exitdata
 #endif
 
+#ifdef CONFIG_LATE_HWDOM
+#define __hwdom_init
+#define __hwdom_initdata  __read_mostly
+#else
+#define __hwdom_init      __init
+#define __hwdom_initdata  __initdata
+#endif
+
 #endif /* _LINUX_INIT_H */
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 3/7] xen: prevent 0 from being used as a dynamic domid
  2014-03-27 11:52 [PATCH v3 0/7] xen: Hardware domain support Daniel De Graaf
  2014-03-27 11:52 ` [PATCH 1/7] xen: use domid check in is_hardware_domain Daniel De Graaf
  2014-03-27 11:52 ` [PATCH 2/7] xen/iommu: Move dom0 setup code to __hwdom_init Daniel De Graaf
@ 2014-03-27 11:52 ` Daniel De Graaf
  2014-03-27 11:52 ` [PATCH 4/7] xen: rename dom0 to hardware_domain Daniel De Graaf
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 11:52 UTC (permalink / raw)
  To: xen-devel; +Cc: dgdegra, Keir Fraser

When the hardware domain is made distinct from dom0, it becomes possible
to shut down and destroy domain 0 while leaving the hypervisor running.
If this happens, prevent this domain ID from being considered for
allocation to a new guest.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Cc: Keir Fraser <keir@xen.org>
---
 xen/common/domctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 7cf610a..eebeee7 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -436,7 +436,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             for ( dom = rover + 1; dom != rover; dom++ )
             {
                 if ( dom == DOMID_FIRST_RESERVED )
-                    dom = 0;
+                    dom = 1;
                 if ( is_free_domid(dom) )
                     break;
             }
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 4/7] xen: rename dom0 to hardware_domain
  2014-03-27 11:52 [PATCH v3 0/7] xen: Hardware domain support Daniel De Graaf
                   ` (2 preceding siblings ...)
  2014-03-27 11:52 ` [PATCH 3/7] xen: prevent 0 from being used as a dynamic domid Daniel De Graaf
@ 2014-03-27 11:52 ` Daniel De Graaf
  2014-03-27 12:20   ` Egger, Christoph
  2014-03-27 15:33   ` Ian Campbell
  2014-03-27 11:52 ` [PATCH 5/7] xen: rename various functions referencing dom0 Daniel De Graaf
                   ` (3 subsequent siblings)
  7 siblings, 2 replies; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 11:52 UTC (permalink / raw)
  To: xen-devel
  Cc: Liu Jinsong, Ian Campbell, Christoph Egger, Tim Deegan,
	Stefano Stabellini, Suravee Suthikulpanit, dgdegra,
	Xiantao Zhang

This should not change any functionality other than renaming the global
variable.  In a few cases (primarily the domain building code), a local
variable or argument named dom0 was created and used instead of the
global hardware_domain to clarify that the domain being used in this
case is actually domain 0.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
Cc: Tim Deegan <tim@xen.org>
Cc: Liu Jinsong <jinsong.liu@intel.com>
Cc: Christoph Egger <chegger@amazon.de>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Xiantao Zhang <xiantao.zhang@intel.com>
---
 xen/arch/arm/domain_build.c                 |  2 +-
 xen/arch/arm/setup.c                        |  5 ++--
 xen/arch/x86/acpi/cpu_idle.c                |  2 +-
 xen/arch/x86/cpu/mcheck/vmce.h              |  5 ++--
 xen/arch/x86/crash.c                        |  2 +-
 xen/arch/x86/domain_build.c                 | 37 +++++++++++++++--------------
 xen/arch/x86/io_apic.c                      |  8 +++----
 xen/arch/x86/irq.c                          |  8 +++----
 xen/arch/x86/mm.c                           |  2 +-
 xen/arch/x86/nmi.c                          |  2 +-
 xen/arch/x86/setup.c                        |  5 ++--
 xen/arch/x86/traps.c                        |  2 +-
 xen/arch/x86/x86_64/mm.c                    |  6 ++---
 xen/common/domain.c                         |  2 +-
 xen/common/event_channel.c                  |  2 +-
 xen/common/kexec.c                          |  2 +-
 xen/common/keyhandler.c                     |  4 ++--
 xen/common/xenoprof.c                       |  2 +-
 xen/drivers/char/ns16550.c                  |  4 +++-
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  2 +-
 xen/drivers/passthrough/iommu.c             | 10 ++++----
 xen/drivers/passthrough/pci.c               |  4 ++--
 xen/drivers/passthrough/vtd/iommu.c         |  4 ++--
 xen/include/asm-arm/domain.h                |  2 +-
 xen/include/xen/domain.h                    |  2 +-
 xen/include/xen/sched.h                     |  4 ++--
 26 files changed, 68 insertions(+), 62 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index c9dda0e..3226792 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -50,7 +50,7 @@ custom_param("dom0_mem", parse_dom0_mem);
  */
 #define DOM0_FDT_EXTRA_SIZE (128 + sizeof(struct fdt_reserve_entry))
 
-struct vcpu *__init alloc_dom0_vcpu0(void)
+struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0)
 {
     if ( opt_dom0_max_vcpus == 0 )
         opt_dom0_max_vcpus = num_online_cpus();
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 215ec24..2d562c6 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -664,6 +664,7 @@ void __init start_xen(unsigned long boot_phys_offset,
     size_t fdt_size;
     int cpus, i;
     const char *cmdline;
+    struct domain *dom0;
 
     setup_cache();
 
@@ -760,8 +761,8 @@ void __init start_xen(unsigned long boot_phys_offset,
     do_initcalls();
 
     /* Create initial domain 0. */
-    dom0 = domain_create(0, 0, 0);
-    if ( IS_ERR(dom0) || (alloc_dom0_vcpu0() == NULL) )
+    hardware_domain = dom0 = domain_create(0, 0, 0);
+    if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
             panic("Error creating domain 0");
 
     dom0->is_privileged = 1;
diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
index d2119e2..b05fb39 100644
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -972,7 +972,7 @@ static void set_cx(
             cx->entry_method = ACPI_CSTATE_EM_HALT;
         break;
     case ACPI_ADR_SPACE_SYSTEM_IO:
-        if ( ioports_deny_access(dom0, cx->address, cx->address) )
+        if ( ioports_deny_access(hardware_domain, cx->address, cx->address) )
             printk(XENLOG_WARNING "Could not deny access to port %04x\n",
                    cx->address);
         cx->entry_method = ACPI_CSTATE_EM_SYSIO;
diff --git a/xen/arch/x86/cpu/mcheck/vmce.h b/xen/arch/x86/cpu/mcheck/vmce.h
index 6b2c95a..163ce3c 100644
--- a/xen/arch/x86/cpu/mcheck/vmce.h
+++ b/xen/arch/x86/cpu/mcheck/vmce.h
@@ -5,8 +5,9 @@
 
 int vmce_init(struct cpuinfo_x86 *c);
 
-#define dom0_vmce_enabled() (dom0 && dom0->max_vcpus && dom0->vcpu[0] \
-        && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA))
+#define dom0_vmce_enabled() (hardware_domain && hardware_domain->max_vcpus \
+        && hardware_domain->vcpu[0] \
+        && guest_enabled_event(hardware_domain->vcpu[0], VIRQ_MCA))
 
 int unmmap_broken_page(struct domain *d, mfn_t mfn, unsigned long gfn);
 
diff --git a/xen/arch/x86/crash.c b/xen/arch/x86/crash.c
index ec586bd..aed3b3e 100644
--- a/xen/arch/x86/crash.c
+++ b/xen/arch/x86/crash.c
@@ -205,7 +205,7 @@ void machine_crash_shutdown(void)
     info = kexec_crash_save_info();
     info->xen_phys_start = xen_phys_start;
     info->dom0_pfn_to_mfn_frame_list_list =
-        arch_get_pfn_to_mfn_frame_list_list(dom0);
+        arch_get_pfn_to_mfn_frame_list_list(hardware_domain);
 }
 
 /*
diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index 84ce392..b2411b0 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -100,7 +100,7 @@ static void __init parse_dom0_max_vcpus(const char *s)
 }
 custom_param("dom0_max_vcpus", parse_dom0_max_vcpus);
 
-struct vcpu *__init alloc_dom0_vcpu0(void)
+struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0)
 {
     unsigned max_vcpus;
 
@@ -302,7 +302,7 @@ static void __init process_dom0_ioports_disable(void)
         printk("Disabling dom0 access to ioport range %04lx-%04lx\n",
             io_from, io_to);
 
-        if ( ioports_deny_access(dom0, io_from, io_to) != 0 )
+        if ( ioports_deny_access(hardware_domain, io_from, io_to) != 0 )
             BUG();
     }
 }
@@ -1082,27 +1082,28 @@ int __init construct_dom0(
 
     rc = 0;
 
-    /* DOM0 is permitted full I/O capabilities. */
-    rc |= ioports_permit_access(dom0, 0, 0xFFFF);
-    rc |= iomem_permit_access(dom0, 0UL, ~0UL);
-    rc |= irqs_permit_access(dom0, 1, nr_irqs_gsi - 1);
+    /* The hardware domain is initially permitted full I/O capabilities. */
+    rc |= ioports_permit_access(hardware_domain, 0, 0xFFFF);
+    rc |= iomem_permit_access(hardware_domain, 0UL, ~0UL);
+    rc |= irqs_permit_access(hardware_domain, 1, nr_irqs_gsi - 1);
 
     /*
      * Modify I/O port access permissions.
      */
     /* Master Interrupt Controller (PIC). */
-    rc |= ioports_deny_access(dom0, 0x20, 0x21);
+    rc |= ioports_deny_access(hardware_domain, 0x20, 0x21);
     /* Slave Interrupt Controller (PIC). */
-    rc |= ioports_deny_access(dom0, 0xA0, 0xA1);
+    rc |= ioports_deny_access(hardware_domain, 0xA0, 0xA1);
     /* Interval Timer (PIT). */
-    rc |= ioports_deny_access(dom0, 0x40, 0x43);
+    rc |= ioports_deny_access(hardware_domain, 0x40, 0x43);
     /* PIT Channel 2 / PC Speaker Control. */
-    rc |= ioports_deny_access(dom0, 0x61, 0x61);
+    rc |= ioports_deny_access(hardware_domain, 0x61, 0x61);
     /* ACPI PM Timer. */
     if ( pmtmr_ioport )
-        rc |= ioports_deny_access(dom0, pmtmr_ioport, pmtmr_ioport + 3);
+        rc |= ioports_deny_access(hardware_domain, pmtmr_ioport,
+		                          pmtmr_ioport + 3);
     /* PCI configuration space (NB. 0xcf8 has special treatment). */
-    rc |= ioports_deny_access(dom0, 0xcfc, 0xcff);
+    rc |= ioports_deny_access(hardware_domain, 0xcfc, 0xcff);
     /* Command-line I/O ranges. */
     process_dom0_ioports_disable();
 
@@ -1113,22 +1114,22 @@ int __init construct_dom0(
     if ( mp_lapic_addr != 0 )
     {
         mfn = paddr_to_pfn(mp_lapic_addr);
-        rc |= iomem_deny_access(dom0, mfn, mfn);
+        rc |= iomem_deny_access(hardware_domain, mfn, mfn);
     }
     /* I/O APICs. */
     for ( i = 0; i < nr_ioapics; i++ )
     {
         mfn = paddr_to_pfn(mp_ioapics[i].mpc_apicaddr);
         if ( !rangeset_contains_singleton(mmio_ro_ranges, mfn) )
-            rc |= iomem_deny_access(dom0, mfn, mfn);
+            rc |= iomem_deny_access(hardware_domain, mfn, mfn);
     }
     /* MSI range. */
-    rc |= iomem_deny_access(dom0, paddr_to_pfn(MSI_ADDR_BASE_LO),
+    rc |= iomem_deny_access(hardware_domain, paddr_to_pfn(MSI_ADDR_BASE_LO),
                             paddr_to_pfn(MSI_ADDR_BASE_LO +
                                          MSI_ADDR_DEST_ID_MASK));
     /* HyperTransport range. */
     if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
-        rc |= iomem_deny_access(dom0, paddr_to_pfn(0xfdULL << 32),
+        rc |= iomem_deny_access(hardware_domain, paddr_to_pfn(0xfdULL << 32),
                                 paddr_to_pfn((1ULL << 40) - 1));
 
     /* Remove access to E820_UNUSABLE I/O regions above 1MB. */
@@ -1140,7 +1141,7 @@ int __init construct_dom0(
         if ( (e820.map[i].type == E820_UNUSABLE) &&
              (e820.map[i].size != 0) &&
              (sfn <= efn) )
-            rc |= iomem_deny_access(dom0, sfn, efn);
+            rc |= iomem_deny_access(hardware_domain, sfn, efn);
     }
 
     BUG_ON(rc != 0);
@@ -1149,7 +1150,7 @@ int __init construct_dom0(
         printk(" Xen warning: dom0 kernel broken ELF: %s\n",
                elf_check_broken(&elf));
 
-    iommu_dom0_init(dom0);
+    iommu_dom0_init(hardware_domain);
     return 0;
 
 out:
diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index bddc588..4e6fe2b 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -2363,7 +2363,7 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
      * that dom0 pirq == irq.
      */
     pirq = (irq >= 256) ? irq : rte.vector;
-    if ( (pirq < 0) || (pirq >= dom0->nr_pirqs) )
+    if ( (pirq < 0) || (pirq >= hardware_domain->nr_pirqs) )
         return -EINVAL;
     
     if ( desc->action )
@@ -2399,10 +2399,10 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
 
         printk(XENLOG_INFO "allocated vector %02x for irq %d\n", ret, irq);
     }
-    spin_lock(&dom0->event_lock);
-    ret = map_domain_pirq(dom0, pirq, irq,
+    spin_lock(&hardware_domain->event_lock);
+    ret = map_domain_pirq(hardware_domain, pirq, irq,
             MAP_PIRQ_TYPE_GSI, NULL);
-    spin_unlock(&dom0->event_lock);
+    spin_unlock(&hardware_domain->event_lock);
     if ( ret < 0 )
         return ret;
 
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 88444be..ca68f92 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -185,9 +185,9 @@ int create_irq(int node)
         desc->arch.used = IRQ_UNUSED;
         irq = ret;
     }
-    else if ( dom0 )
+    else if ( hardware_domain )
     {
-        ret = irq_permit_access(dom0, irq);
+        ret = irq_permit_access(hardware_domain, irq);
         if ( ret )
             printk(XENLOG_G_ERR
                    "Could not grant Dom0 access to IRQ%d (error %d)\n",
@@ -205,9 +205,9 @@ void destroy_irq(unsigned int irq)
 
     BUG_ON(!MSI_IRQ(irq));
 
-    if ( dom0 )
+    if ( hardware_domain )
     {
-        int err = irq_deny_access(dom0, irq);
+        int err = irq_deny_access(hardware_domain, irq);
 
         if ( err )
             printk(XENLOG_G_ERR
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index ad48acc..b9a54a5 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -5222,7 +5222,7 @@ void *alloc_xen_pagetable(void)
     {
         void *ptr = alloc_xenheap_page();
 
-        BUG_ON(!dom0 && !ptr);
+        BUG_ON(!hardware_domain && !ptr);
         return ptr;
     }
 
diff --git a/xen/arch/x86/nmi.c b/xen/arch/x86/nmi.c
index c67a9c3..526020b 100644
--- a/xen/arch/x86/nmi.c
+++ b/xen/arch/x86/nmi.c
@@ -519,7 +519,7 @@ static void do_nmi_stats(unsigned char key)
     for_each_online_cpu ( i )
         printk("%3d\t%3d\n", i, nmi_count(i));
 
-    if ( ((d = dom0) == NULL) || (d->vcpu == NULL) ||
+    if ( ((d = hardware_domain) == NULL) || (d->vcpu == NULL) ||
          ((v = d->vcpu[0]) == NULL) )
         return;
 
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 13a148c..75cf212 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -547,6 +547,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     unsigned long nr_pages, raw_max_page, modules_headroom, *module_map;
     int i, j, e820_warn = 0, bytes = 0;
     bool_t acpi_boot_table_init_done = 0;
+    struct domain *dom0;
     struct ns16550_defaults ns16550 = {
         .data_bits = 8,
         .parity    = 'n',
@@ -1338,8 +1339,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         panic("Could not protect TXT memory regions");
 
     /* Create initial domain 0. */
-    dom0 = domain_create(0, DOMCRF_s3_integrity, 0);
-    if ( IS_ERR(dom0) || (alloc_dom0_vcpu0() == NULL) )
+    hardware_domain = dom0 = domain_create(0, DOMCRF_s3_integrity, 0);
+    if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
         panic("Error creating domain 0");
 
     dom0->is_privileged = 1;
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 21c8b63..e5c1269 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -3152,7 +3152,7 @@ void async_exception_cleanup(struct vcpu *curr)
 
 static void nmi_dom0_report(unsigned int reason_idx)
 {
-    struct domain *d = dom0;
+    struct domain *d = hardware_domain;
 
     if ( (d == NULL) || (d->vcpu == NULL) || (d->vcpu[0] == NULL) )
         return;
diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c
index f6ea012..71ae519 100644
--- a/xen/arch/x86/x86_64/mm.c
+++ b/xen/arch/x86/x86_64/mm.c
@@ -1447,15 +1447,15 @@ int memory_add(unsigned long spfn, unsigned long epfn, unsigned int pxm)
     if ( ret )
         goto destroy_m2p;
 
-    if ( !need_iommu(dom0) )
+    if ( !need_iommu(hardware_domain) )
     {
         for ( i = spfn; i < epfn; i++ )
-            if ( iommu_map_page(dom0, i, i, IOMMUF_readable|IOMMUF_writable) )
+            if ( iommu_map_page(hardware_domain, i, i, IOMMUF_readable|IOMMUF_writable) )
                 break;
         if ( i != epfn )
         {
             while (i-- > old_max)
-                iommu_unmap_page(dom0, i);
+                iommu_unmap_page(hardware_domain, i);
             goto destroy_m2p;
         }
     }
diff --git a/xen/common/domain.c b/xen/common/domain.c
index b5868a5..f8ef439 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -59,7 +59,7 @@ DEFINE_RCU_READ_LOCK(domlist_read_lock);
 static struct domain *domain_hash[DOMAIN_HASH_SIZE];
 struct domain *domain_list;
 
-struct domain *dom0;
+struct domain *hardware_domain __read_mostly;
 
 struct vcpu *idle_vcpu[NR_CPUS] __read_mostly;
 
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index db952af..51fd63d 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -743,7 +743,7 @@ void send_global_virq(uint32_t virq)
     ASSERT(virq < NR_VIRQS);
     ASSERT(virq_is_global(virq));
 
-    send_guest_global_virq(global_virq_handlers[virq] ?: dom0, virq);
+    send_guest_global_virq(global_virq_handlers[virq] ?: hardware_domain, virq);
 }
 
 int set_global_virq_handler(struct domain *d, uint32_t virq)
diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index 23d964e..2239ee8 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -872,7 +872,7 @@ static int kexec_load_slot(struct kexec_image *kimage)
 static uint16_t kexec_load_v1_arch(void)
 {
 #ifdef CONFIG_X86
-    return is_pv_32on64_domain(dom0) ? EM_386 : EM_X86_64;
+    return is_pv_32on64_domain(hardware_domain) ? EM_386 : EM_X86_64;
 #else
     return EM_NONE;
 #endif
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
index 5a974b1..627ef99 100644
--- a/xen/common/keyhandler.c
+++ b/xen/common/keyhandler.c
@@ -172,12 +172,12 @@ static void dump_dom0_registers(unsigned char key)
 {
     struct vcpu *v;
 
-    if ( dom0 == NULL )
+    if ( hardware_domain == NULL )
         return;
 
     printk("'%c' pressed -> dumping Dom0's registers\n", key);
 
-    for_each_vcpu ( dom0, v )
+    for_each_vcpu ( hardware_domain, v )
     {
         if ( alt_key_handling && softirq_pending(smp_processor_id()) )
         {
diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c
index 3c30c3e..3de20b8 100644
--- a/xen/common/xenoprof.c
+++ b/xen/common/xenoprof.c
@@ -219,7 +219,7 @@ static int alloc_xenoprof_struct(
     bufsize = sizeof(struct xenoprof_buf);
     i = sizeof(struct event_log);
 #ifdef CONFIG_COMPAT
-    d->xenoprof->is_compat = is_pv_32on64_domain(is_passive ? dom0 : d);
+    d->xenoprof->is_compat = is_pv_32on64_domain(is_passive ? hardware_domain : d);
     if ( XENOPROF_COMPAT(d->xenoprof) )
     {
         bufsize = sizeof(struct compat_oprof_buf);
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 429d786..d437bbf 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -703,10 +703,12 @@ static void __init ns16550_endboot(struct serial_port *port)
 {
 #ifdef HAS_IOPORTS
     struct ns16550 *uart = port->uart;
+    int rv;
 
     if ( uart->remapped_io_base )
         return;
-    if ( ioports_deny_access(dom0, uart->io_base, uart->io_base + 7) != 0 )
+    rv = ioports_deny_access(hardware_domain, uart->io_base, uart->io_base + 7);
+    if ( rv != 0 )
         BUG();
 #endif
 }
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index ff5f06e..031480f 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -403,7 +403,7 @@ static int amd_iommu_assign_device(struct domain *d, u8 devfn,
             ivrs_mappings[req_id].read_permission);
     }
 
-    return reassign_device(dom0, d, devfn, pdev);
+    return reassign_device(hardware_domain, d, devfn, pdev);
 }
 
 static void deallocate_next_page_table(struct page_info *pg, int level)
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 3e5635c..25d9af9 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -265,7 +265,7 @@ static void iommu_teardown(struct domain *d)
 }
 
 /*
- * If the device isn't owned by dom0, it means it already
+ * If the device isn't owned by the hardware domain, it means it already
  * has been assigned to other domain, or it doesn't exist.
  */
 static int device_assigned(u16 seg, u8 bus, u8 devfn)
@@ -273,7 +273,7 @@ static int device_assigned(u16 seg, u8 bus, u8 devfn)
     struct pci_dev *pdev;
 
     spin_lock(&pcidevs_lock);
-    pdev = pci_get_pdev_by_domain(dom0, seg, bus, devfn);
+    pdev = pci_get_pdev_by_domain(hardware_domain, seg, bus, devfn);
     spin_unlock(&pcidevs_lock);
 
     return pdev ? 0 : -EBUSY;
@@ -312,7 +312,7 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
         d->need_iommu = 1;
     }
 
-    pdev = pci_get_pdev_by_domain(dom0, seg, bus, devfn);
+    pdev = pci_get_pdev_by_domain(hardware_domain, seg, bus, devfn);
     if ( !pdev )
     {
         rc = pci_get_pdev(seg, bus, devfn) ? -EBUSY : -ENODEV;
@@ -507,7 +507,7 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
         devfn += pdev->phantom_stride;
         if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
             break;
-        ret = hd->platform_ops->reassign_device(d, dom0, devfn, pdev);
+        ret = hd->platform_ops->reassign_device(d, hardware_domain, devfn, pdev);
         if ( !ret )
             continue;
 
@@ -517,7 +517,7 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
     }
 
     devfn = pdev->devfn;
-    ret = hd->platform_ops->reassign_device(d, dom0, devfn, pdev);
+    ret = hd->platform_ops->reassign_device(d, hardware_domain, devfn, pdev);
     if ( ret )
     {
         dprintk(XENLOG_G_ERR,
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index dfa195a..fbc777c 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -569,7 +569,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct pci_dev_info *info)
     ret = 0;
     if ( !pdev->domain )
     {
-        pdev->domain = dom0;
+        pdev->domain = hardware_domain;
         ret = iommu_add_device(pdev);
         if ( ret )
         {
@@ -577,7 +577,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct pci_dev_info *info)
             goto out;
         }
 
-        list_add(&pdev->domain_list, &dom0->arch.pdev_list);
+        list_add(&pdev->domain_list, &hardware_domain->arch.pdev_list);
     }
     else
         iommu_enable_device(pdev);
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index d22d518..263448d 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1667,7 +1667,7 @@ static int reassign_device_ownership(
      * can attempt to send arbitrary LAPIC/MSI messages. We are unprotected
      * by the root complex unless interrupt remapping is enabled.
      */
-    if ( (target != dom0) && !iommu_intremap )
+    if ( (target != hardware_domain) && !iommu_intremap )
         untrusted_msi = 1;
 
     ret = domain_context_unmap(source, devfn, pdev);
@@ -2270,7 +2270,7 @@ static int intel_iommu_assign_device(
     if ( list_empty(&acpi_drhd_units) )
         return -ENODEV;
 
-    ret = reassign_device_ownership(dom0, d, devfn, pdev);
+    ret = reassign_device_ownership(hardware_domain, d, devfn, pdev);
     if ( ret )
         goto done;
 
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 28c359a..ec66a4e 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -87,7 +87,7 @@ enum domain_type {
 #endif
 
 extern int dom0_11_mapping;
-#define is_domain_direct_mapped(d) ((d) == dom0 && dom0_11_mapping)
+#define is_domain_direct_mapped(d) ((d) == hardware_domain && dom0_11_mapping)
 
 struct vtimer {
         struct vcpu *v;
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index a057069..bb1c398 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -12,7 +12,7 @@ typedef union {
 
 struct vcpu *alloc_vcpu(
     struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
-struct vcpu *alloc_dom0_vcpu0(void);
+struct vcpu *alloc_dom0_vcpu0(struct domain *dom0);
 int vcpu_reset(struct vcpu *);
 
 struct xen_domctl_getdomaininfo;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 1f45f71..91adc8c 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -43,8 +43,8 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
 
 #define SCHED_STAT_CRANK(_X)                (perfc_incr(_X))
 
-/* A global pointer to the initial domain (DOM0). */
-extern struct domain *dom0;
+/* A global pointer to the hardware domain (usually DOM0). */
+extern struct domain *hardware_domain;
 
 #ifndef CONFIG_COMPAT
 #define BITS_PER_EVTCHN_WORD(d) BITS_PER_XEN_ULONG
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 5/7] xen: rename various functions referencing dom0
  2014-03-27 11:52 [PATCH v3 0/7] xen: Hardware domain support Daniel De Graaf
                   ` (3 preceding siblings ...)
  2014-03-27 11:52 ` [PATCH 4/7] xen: rename dom0 to hardware_domain Daniel De Graaf
@ 2014-03-27 11:52 ` Daniel De Graaf
  2014-03-27 15:34   ` Ian Campbell
  2014-03-27 11:52 ` [PATCH 6/7] xen: Allow hardare domain != dom0 Daniel De Graaf
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 11:52 UTC (permalink / raw)
  To: xen-devel
  Cc: Suravee Suthikulpanit, dgdegra, Xiantao Zhang, Ian Campbell, Jan Beulich

Most of these functions actually act on the hardware domain, so change
their names to reflect this.

Command line parameters and variables based on those parameters are
excluded since those changes would be user-visible, as are any public
headers.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Xiantao Zhang <xiantao.zhang@intel.com>
---
 xen/arch/x86/domain_build.c                 |  2 +-
 xen/arch/x86/hvm/i8254.c                    |  2 +-
 xen/arch/x86/time.c                         |  2 +-
 xen/arch/x86/traps.c                        |  8 ++++----
 xen/common/domain.c                         |  2 +-
 xen/common/keyhandler.c                     | 22 +++++++++++-----------
 xen/common/shutdown.c                       |  2 +-
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  8 ++++----
 xen/drivers/passthrough/iommu.c             |  8 ++++----
 xen/drivers/passthrough/pci.c               | 18 +++++++++---------
 xen/drivers/passthrough/vtd/iommu.c         | 18 +++++++++---------
 xen/drivers/passthrough/vtd/x86/vtd.c       |  2 +-
 xen/include/asm-x86/time.h                  |  2 +-
 xen/include/xen/iommu.h                     |  6 +++---
 xen/include/xen/pci.h                       |  2 +-
 xen/include/xen/shutdown.h                  |  2 +-
 16 files changed, 53 insertions(+), 53 deletions(-)

diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index b2411b0..f75f6e7 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -1150,7 +1150,7 @@ int __init construct_dom0(
         printk(" Xen warning: dom0 kernel broken ELF: %s\n",
                elf_check_broken(&elf));
 
-    iommu_dom0_init(hardware_domain);
+    iommu_hwdom_init(hardware_domain);
     return 0;
 
 out:
diff --git a/xen/arch/x86/hvm/i8254.c b/xen/arch/x86/hvm/i8254.c
index 6a91f76..8907721 100644
--- a/xen/arch/x86/hvm/i8254.c
+++ b/xen/arch/x86/hvm/i8254.c
@@ -540,7 +540,7 @@ int pv_pit_handler(int port, int data, int write)
         .data = data
     };
 
-    if ( is_hardware_domain(current->domain) && dom0_pit_access(&ioreq) )
+    if ( is_hardware_domain(current->domain) && hwdom_pit_access(&ioreq) )
     {
         /* nothing to do */;
     }
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index 89308bd..07bceda 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -1602,7 +1602,7 @@ int time_resume(void)
     return 0;
 }
 
-int dom0_pit_access(struct ioreq *ioreq)
+int hwdom_pit_access(struct ioreq *ioreq)
 {
     /* Is Xen using Channel 2? Then disallow direct dom0 access. */
     if ( using_pit )
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index e5c1269..b7303d7 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -3150,7 +3150,7 @@ void async_exception_cleanup(struct vcpu *curr)
     curr->async_exception_mask = curr->async_exception_state(trap).old_mask;
 }
 
-static void nmi_dom0_report(unsigned int reason_idx)
+static void nmi_hwdom_report(unsigned int reason_idx)
 {
     struct domain *d = hardware_domain;
 
@@ -3169,7 +3169,7 @@ static void pci_serr_error(struct cpu_user_regs *regs)
     switch ( opt_nmi[0] )
     {
     case 'd': /* 'dom0' */
-        nmi_dom0_report(_XEN_NMIREASON_pci_serr);
+        nmi_hwdom_report(_XEN_NMIREASON_pci_serr);
     case 'i': /* 'ignore' */
         /* Would like to print a diagnostic here but can't call printk()
            from NMI context -- raise a softirq instead. */
@@ -3187,7 +3187,7 @@ static void io_check_error(struct cpu_user_regs *regs)
     switch ( opt_nmi[0] )
     {
     case 'd': /* 'dom0' */
-        nmi_dom0_report(_XEN_NMIREASON_io_error);
+        nmi_hwdom_report(_XEN_NMIREASON_io_error);
     case 'i': /* 'ignore' */
         break;
     default:  /* 'fatal' */
@@ -3206,7 +3206,7 @@ static void unknown_nmi_error(struct cpu_user_regs *regs, unsigned char reason)
     switch ( opt_nmi[0] )
     {
     case 'd': /* 'dom0' */
-        nmi_dom0_report(_XEN_NMIREASON_unknown);
+        nmi_hwdom_report(_XEN_NMIREASON_unknown);
     case 'i': /* 'ignore' */
         break;
     default:  /* 'fatal' */
diff --git a/xen/common/domain.c b/xen/common/domain.c
index f8ef439..6a282a2 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -595,7 +595,7 @@ void domain_shutdown(struct domain *d, u8 reason)
     reason = d->shutdown_code;
 
     if ( is_hardware_domain(d) )
-        dom0_shutdown(reason);
+        hwdom_shutdown(reason);
 
     if ( d->is_shutting_down )
     {
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
index 627ef99..5afcfef 100644
--- a/xen/common/keyhandler.c
+++ b/xen/common/keyhandler.c
@@ -148,9 +148,9 @@ static struct keyhandler dump_registers_keyhandler = {
     .desc = "dump registers"
 };
 
-static DECLARE_TASKLET(dump_dom0_tasklet, NULL, 0);
+static DECLARE_TASKLET(dump_hwdom_tasklet, NULL, 0);
 
-static void dump_dom0_action(unsigned long arg)
+static void dump_hwdom_action(unsigned long arg)
 {
     struct vcpu *v = (void *)arg;
 
@@ -161,14 +161,14 @@ static void dump_dom0_action(unsigned long arg)
             break;
         if ( softirq_pending(smp_processor_id()) )
         {
-            dump_dom0_tasklet.data = (unsigned long)v;
-            tasklet_schedule_on_cpu(&dump_dom0_tasklet, v->processor);
+            dump_hwdom_tasklet.data = (unsigned long)v;
+            tasklet_schedule_on_cpu(&dump_hwdom_tasklet, v->processor);
             break;
         }
     }
 }
 
-static void dump_dom0_registers(unsigned char key)
+static void dump_hwdom_registers(unsigned char key)
 {
     struct vcpu *v;
 
@@ -181,19 +181,19 @@ static void dump_dom0_registers(unsigned char key)
     {
         if ( alt_key_handling && softirq_pending(smp_processor_id()) )
         {
-            tasklet_kill(&dump_dom0_tasklet);
-            tasklet_init(&dump_dom0_tasklet, dump_dom0_action,
+            tasklet_kill(&dump_hwdom_tasklet);
+            tasklet_init(&dump_hwdom_tasklet, dump_hwdom_action,
                          (unsigned long)v);
-            tasklet_schedule_on_cpu(&dump_dom0_tasklet, v->processor);
+            tasklet_schedule_on_cpu(&dump_hwdom_tasklet, v->processor);
             return;
         }
         vcpu_show_execution_state(v);
     }
 }
 
-static struct keyhandler dump_dom0_registers_keyhandler = {
+static struct keyhandler dump_hwdom_registers_keyhandler = {
     .diagnostic = 1,
-    .u.fn = dump_dom0_registers,
+    .u.fn = dump_hwdom_registers,
     .desc = "dump Dom0 registers"
 };
 
@@ -543,7 +543,7 @@ void __init initialize_keytable(void)
     register_keyhandler('r', &dump_runq_keyhandler);
     register_keyhandler('R', &reboot_machine_keyhandler);
     register_keyhandler('t', &read_clocks_keyhandler);
-    register_keyhandler('0', &dump_dom0_registers_keyhandler);
+    register_keyhandler('0', &dump_hwdom_registers_keyhandler);
     register_keyhandler('%', &do_debug_key_keyhandler);
     register_keyhandler('*', &run_all_keyhandlers_keyhandler);
 
diff --git a/xen/common/shutdown.c b/xen/common/shutdown.c
index fadb69b..94d4c53 100644
--- a/xen/common/shutdown.c
+++ b/xen/common/shutdown.c
@@ -32,7 +32,7 @@ static void noreturn maybe_reboot(void)
     }
 }
 
-void dom0_shutdown(u8 reason)
+void hwdom_shutdown(u8 reason)
 {
     switch ( reason )
     {
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index 031480f..366c750 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -169,7 +169,7 @@ static void amd_iommu_setup_domain_device(
     }
 }
 
-static int __hwdom_init amd_iommu_setup_dom0_device(
+static int __hwdom_init amd_iommu_setup_hwdom_device(
     u8 devfn, struct pci_dev *pdev)
 {
     int bdf = PCI_BDF2(pdev->bus, pdev->devfn);
@@ -281,7 +281,7 @@ static int amd_iommu_domain_init(struct domain *d)
     return 0;
 }
 
-static void __hwdom_init amd_iommu_dom0_init(struct domain *d)
+static void __hwdom_init amd_iommu_hwdom_init(struct domain *d)
 {
     unsigned long i; 
 
@@ -305,7 +305,7 @@ static void __hwdom_init amd_iommu_dom0_init(struct domain *d)
         }
     }
 
-    setup_dom0_pci_devices(d, amd_iommu_setup_dom0_device);
+    setup_hwdom_pci_devices(d, amd_iommu_setup_hwdom_device);
 }
 
 void amd_iommu_disable_domain_device(struct domain *domain,
@@ -603,7 +603,7 @@ static void amd_dump_p2m_table(struct domain *d)
 
 const struct iommu_ops amd_iommu_ops = {
     .init = amd_iommu_domain_init,
-    .dom0_init = amd_iommu_dom0_init,
+    .hwdom_init = amd_iommu_hwdom_init,
     .add_device = amd_iommu_add_device,
     .remove_device = amd_iommu_remove_device,
     .assign_device  = amd_iommu_assign_device,
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 25d9af9..96a79ce 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -130,7 +130,7 @@ int iommu_domain_init(struct domain *d)
     return hd->platform_ops->init(d);
 }
 
-static void __hwdom_init check_dom0_pvh_reqs(struct domain *d)
+static void __hwdom_init check_hwdom_pvh_reqs(struct domain *d)
 {
     if ( !iommu_enabled )
         panic("Presently, iommu must be enabled for pvh dom0\n");
@@ -141,12 +141,12 @@ static void __hwdom_init check_dom0_pvh_reqs(struct domain *d)
     iommu_dom0_strict = 1;
 }
 
-void __hwdom_init iommu_dom0_init(struct domain *d)
+void __hwdom_init iommu_hwdom_init(struct domain *d)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(d);
 
     if ( is_pvh_domain(d) )
-        check_dom0_pvh_reqs(d);
+        check_hwdom_pvh_reqs(d);
 
     if ( !iommu_enabled )
         return;
@@ -173,7 +173,7 @@ void __hwdom_init iommu_dom0_init(struct domain *d)
         }
     }
 
-    return hd->platform_ops->dom0_init(d);
+    return hd->platform_ops->hwdom_init(d);
 }
 
 int iommu_add_device(struct pci_dev *pdev)
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index fbc777c..0794eaf 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -867,12 +867,12 @@ int __init scan_pci_devices(void)
     return ret;
 }
 
-struct setup_dom0 {
+struct setup_hwdom {
     struct domain *d;
     int (*handler)(u8 devfn, struct pci_dev *);
 };
 
-static void setup_one_dom0_device(const struct setup_dom0 *ctxt,
+static void setup_one_hwdom_device(const struct setup_hwdom *ctxt,
                                   struct pci_dev *pdev)
 {
     u8 devfn = pdev->devfn;
@@ -893,9 +893,9 @@ static void setup_one_dom0_device(const struct setup_dom0 *ctxt,
               PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn) );
 }
 
-static int __hwdom_init _setup_dom0_pci_devices(struct pci_seg *pseg, void *arg)
+static int __hwdom_init _setup_hwdom_pci_devices(struct pci_seg *pseg, void *arg)
 {
-    struct setup_dom0 *ctxt = arg;
+    struct setup_hwdom *ctxt = arg;
     int bus, devfn;
 
     for ( bus = 0; bus < 256; bus++ )
@@ -911,12 +911,12 @@ static int __hwdom_init _setup_dom0_pci_devices(struct pci_seg *pseg, void *arg)
             {
                 pdev->domain = ctxt->d;
                 list_add(&pdev->domain_list, &ctxt->d->arch.pdev_list);
-                setup_one_dom0_device(ctxt, pdev);
+                setup_one_hwdom_device(ctxt, pdev);
             }
             else if ( pdev->domain == dom_xen )
             {
                 pdev->domain = ctxt->d;
-                setup_one_dom0_device(ctxt, pdev);
+                setup_one_hwdom_device(ctxt, pdev);
                 pdev->domain = dom_xen;
             }
             else if ( pdev->domain != ctxt->d )
@@ -943,13 +943,13 @@ static int __hwdom_init _setup_dom0_pci_devices(struct pci_seg *pseg, void *arg)
     return 0;
 }
 
-void __hwdom_init setup_dom0_pci_devices(
+void __hwdom_init setup_hwdom_pci_devices(
     struct domain *d, int (*handler)(u8 devfn, struct pci_dev *))
 {
-    struct setup_dom0 ctxt = { .d = d, .handler = handler };
+    struct setup_hwdom ctxt = { .d = d, .handler = handler };
 
     spin_lock(&pcidevs_lock);
-    pci_segments_iterate(_setup_dom0_pci_devices, &ctxt);
+    pci_segments_iterate(_setup_hwdom_pci_devices, &ctxt);
     spin_unlock(&pcidevs_lock);
 }
 
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 263448d..abaa8c9 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -55,8 +55,8 @@ int nr_iommus;
 
 static struct tasklet vtd_fault_tasklet;
 
-static int setup_dom0_device(u8 devfn, struct pci_dev *);
-static void setup_dom0_rmrr(struct domain *d);
+static int setup_hwdom_device(u8 devfn, struct pci_dev *);
+static void setup_hwdom_rmrr(struct domain *d);
 
 static int domain_iommu_domid(struct domain *d,
                               struct iommu *iommu)
@@ -1242,18 +1242,18 @@ static int intel_iommu_domain_init(struct domain *d)
     return 0;
 }
 
-static void __hwdom_init intel_iommu_dom0_init(struct domain *d)
+static void __hwdom_init intel_iommu_hwdom_init(struct domain *d)
 {
     struct acpi_drhd_unit *drhd;
 
     if ( !iommu_passthrough && !need_iommu(d) )
     {
         /* Set up 1:1 page table for dom0 */
-        iommu_set_dom0_mapping(d);
+        iommu_set_hwdom_mapping(d);
     }
 
-    setup_dom0_pci_devices(d, setup_dom0_device);
-    setup_dom0_rmrr(d);
+    setup_hwdom_pci_devices(d, setup_hwdom_device);
+    setup_hwdom_rmrr(d);
 
     iommu_flush_all();
 
@@ -1992,7 +1992,7 @@ static int intel_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
     return domain_context_unmap(pdev->domain, devfn, pdev);
 }
 
-static int __hwdom_init setup_dom0_device(u8 devfn, struct pci_dev *pdev)
+static int __hwdom_init setup_hwdom_device(u8 devfn, struct pci_dev *pdev)
 {
     int err;
 
@@ -2140,7 +2140,7 @@ static int init_vtd_hw(void)
     return 0;
 }
 
-static void __hwdom_init setup_dom0_rmrr(struct domain *d)
+static void __hwdom_init setup_hwdom_rmrr(struct domain *d)
 {
     struct acpi_rmrr_unit *rmrr;
     u16 bdf;
@@ -2464,7 +2464,7 @@ static void vtd_dump_p2m_table(struct domain *d)
 
 const struct iommu_ops intel_iommu_ops = {
     .init = intel_iommu_domain_init,
-    .dom0_init = intel_iommu_dom0_init,
+    .hwdom_init = intel_iommu_hwdom_init,
     .add_device = intel_iommu_add_device,
     .enable_device = intel_iommu_enable_device,
     .remove_device = intel_iommu_remove_device,
diff --git a/xen/drivers/passthrough/vtd/x86/vtd.c b/xen/drivers/passthrough/vtd/x86/vtd.c
index 00131b3..218e223 100644
--- a/xen/drivers/passthrough/vtd/x86/vtd.c
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c
@@ -107,7 +107,7 @@ void hvm_dpci_isairq_eoi(struct domain *d, unsigned int isairq)
     spin_unlock(&d->event_lock);
 }
 
-void __hwdom_init iommu_set_dom0_mapping(struct domain *d)
+void __hwdom_init iommu_set_hwdom_mapping(struct domain *d)
 {
     unsigned long i, j, tmp, top;
 
diff --git a/xen/include/asm-x86/time.h b/xen/include/asm-x86/time.h
index c01b0a2..0631baa 100644
--- a/xen/include/asm-x86/time.h
+++ b/xen/include/asm-x86/time.h
@@ -44,7 +44,7 @@ int time_resume(void);
 void init_percpu_time(void);
 
 struct ioreq;
-int dom0_pit_access(struct ioreq *ioreq);
+int hwdom_pit_access(struct ioreq *ioreq);
 
 int cpu_frequency_change(u64 freq);
 
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index 4f534ed..f8da9f2 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -55,7 +55,7 @@ int iommu_add_device(struct pci_dev *pdev);
 int iommu_enable_device(struct pci_dev *pdev);
 int iommu_remove_device(struct pci_dev *pdev);
 int iommu_domain_init(struct domain *d);
-void iommu_dom0_init(struct domain *d);
+void iommu_hwdom_init(struct domain *d);
 void iommu_domain_destroy(struct domain *d);
 int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn);
 
@@ -90,7 +90,7 @@ struct page_info;
 
 struct iommu_ops {
     int (*init)(struct domain *d);
-    void (*dom0_init)(struct domain *d);
+    void (*hwdom_init)(struct domain *d);
     int (*add_device)(u8 devfn, struct pci_dev *);
     int (*enable_device)(struct pci_dev *pdev);
     int (*remove_device)(u8 devfn, struct pci_dev *);
@@ -127,7 +127,7 @@ void iommu_suspend(void);
 void iommu_resume(void);
 void iommu_crash_shutdown(void);
 
-void iommu_set_dom0_mapping(struct domain *d);
+void iommu_set_hwdom_mapping(struct domain *d);
 void iommu_share_p2m_table(struct domain *d);
 
 int iommu_do_domctl(struct xen_domctl *, struct domain *d,
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index cadb525..edafa20 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -97,7 +97,7 @@ struct pci_dev *pci_lock_pdev(int seg, int bus, int devfn);
 struct pci_dev *pci_lock_domain_pdev(
     struct domain *, int seg, int bus, int devfn);
 
-void setup_dom0_pci_devices(struct domain *,
+void setup_hwdom_pci_devices(struct domain *,
                             int (*)(u8 devfn, struct pci_dev *));
 void pci_release_devices(struct domain *d);
 int pci_add_segment(u16 seg);
diff --git a/xen/include/xen/shutdown.h b/xen/include/xen/shutdown.h
index a00bfef..b3f7e30 100644
--- a/xen/include/xen/shutdown.h
+++ b/xen/include/xen/shutdown.h
@@ -6,7 +6,7 @@
 /* opt_noreboot: If true, machine will need manual reset on error. */
 extern bool_t opt_noreboot;
 
-void noreturn dom0_shutdown(u8 reason);
+void noreturn hwdom_shutdown(u8 reason);
 
 void noreturn machine_restart(unsigned int delay_millisecs);
 void noreturn machine_halt(void);
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 6/7] xen: Allow hardare domain != dom0
  2014-03-27 11:52 [PATCH v3 0/7] xen: Hardware domain support Daniel De Graaf
                   ` (4 preceding siblings ...)
  2014-03-27 11:52 ` [PATCH 5/7] xen: rename various functions referencing dom0 Daniel De Graaf
@ 2014-03-27 11:52 ` Daniel De Graaf
  2014-04-11  9:13   ` Jan Beulich
  2014-03-27 11:52 ` [PATCH 7/7] tools/libxl: Allow dom0 to be destroyed Daniel De Graaf
  2014-04-10 15:58 ` [PATCH v3 0/7] xen: Hardware domain support Keir Fraser
  7 siblings, 1 reply; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 11:52 UTC (permalink / raw)
  To: xen-devel; +Cc: dgdegra, Keir Fraser

This adds a hypervisor command line option "hardware_dom=" which takes a
domain ID.  When the domain with this ID is created, it will be used
as the hardware domain.

This is intended to be used when domain 0 is a dedicated stub domain for
domain building, allowing the hardware domain to be de-privileged and
act only as a driver domain.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
---
 xen/arch/x86/domain_build.c         |  4 +++-
 xen/arch/x86/setup.c                |  2 ++
 xen/common/domain.c                 |  1 +
 xen/common/domctl.c                 | 41 +++++++++++++++++++++++++++++++++++++
 xen/common/rangeset.c               | 40 ++++++++++++++++++++++++++++++++++++
 xen/include/xen/rangeset.h          |  3 +++
 xen/include/xen/sched.h             |  3 ++-
 xen/include/xsm/dummy.h             |  6 ++++++
 xen/include/xsm/xsm.h               |  6 ++++++
 xen/xsm/dummy.c                     |  2 ++
 xen/xsm/flask/hooks.c               |  6 ++++++
 xen/xsm/flask/policy/access_vectors |  2 ++
 12 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index f75f6e7..a554d3b 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -1150,7 +1150,9 @@ int __init construct_dom0(
         printk(" Xen warning: dom0 kernel broken ELF: %s\n",
                elf_check_broken(&elf));
 
-    iommu_hwdom_init(hardware_domain);
+    if ( is_hardware_domain(d) )
+        iommu_hwdom_init(d);
+
     return 0;
 
 out:
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 75cf212..f246ac3 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -84,6 +84,8 @@ unsigned long __initdata highmem_start;
 size_param("highmem-start", highmem_start);
 #endif
 
+integer_param("hardware_dom", hardware_domid);
+
 cpumask_t __read_mostly cpu_present_map;
 
 unsigned long __read_mostly xen_phys_start;
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 6a282a2..a77f8af 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -60,6 +60,7 @@ static struct domain *domain_hash[DOMAIN_HASH_SIZE];
 struct domain *domain_list;
 
 struct domain *hardware_domain __read_mostly;
+domid_t hardware_domid __read_mostly;
 
 struct vcpu *idle_vcpu[NR_CPUS] __read_mostly;
 
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index eebeee7..57bb026 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -472,6 +472,47 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             break;
         }
 
+#ifdef CONFIG_LATE_HWDOM
+        if ( is_hardware_domain(d) )
+        {
+            struct domain *dom0 = hardware_domain;
+            ASSERT(dom0->domain_id == 0);
+
+            ret = xsm_init_hardware_domain(XSM_HOOK, d);
+            if ( ret )
+            {
+                domain_kill(d);
+                d = NULL;
+                break;
+            }
+
+            printk("Initialising hardware domain %d\n", hardware_domid);
+            hardware_domain = d;
+
+            /*
+             * Hardware resource ranges for domain 0 have been set up from
+             * various sources intended to restrict the hardware domain's
+             * access.  Apply these ranges to the actual hardware domain.
+             *
+             * Because the lists are being swapped, a side effect of this
+             * operation is that Domain 0's rangesets are cleared.  Since
+             * domain 0 should not be accessing the hardware when it constructs
+             * a hardware domain, this should not be a problem.  Both lists
+             * may be modified after this hypercall returns if a more complex
+             * device model is desired.
+             *
+             * Since late hardware domain initialization is only supported on
+             * x86, the reference to arch.ioport_caps does not need its own
+             * preprocessor conditional.
+             */
+            rangeset_swap(d->irq_caps, dom0->irq_caps);
+            rangeset_swap(d->iomem_caps, dom0->iomem_caps);
+            rangeset_swap(d->arch.ioport_caps, dom0->arch.ioport_caps);
+
+            iommu_hwdom_init(d);
+        }
+#endif
+
         ret = 0;
 
         memcpy(d->handle, op->u.createdomain.handle,
diff --git a/xen/common/rangeset.c b/xen/common/rangeset.c
index f09c0c4..52fae1f 100644
--- a/xen/common/rangeset.c
+++ b/xen/common/rangeset.c
@@ -438,3 +438,43 @@ void rangeset_domain_printk(
 
     spin_unlock(&d->rangesets_lock);
 }
+
+void rangeset_swap(struct rangeset *a, struct rangeset *b)
+{
+    struct list_head tmp;
+    if (&a < &b)
+    {
+        spin_lock(&a->lock);
+        spin_lock(&b->lock);
+    }
+    else
+    {
+        spin_lock(&b->lock);
+        spin_lock(&a->lock);
+    }
+    memcpy(&tmp, &a->range_list, sizeof(tmp));
+    memcpy(&a->range_list, &b->range_list, sizeof(tmp));
+    memcpy(&b->range_list, &tmp, sizeof(tmp));
+    if ( a->range_list.next == &b->range_list )
+    {
+        a->range_list.next = &a->range_list;
+        a->range_list.prev = &a->range_list;
+    }
+    else
+    {
+        a->range_list.next->prev = &a->range_list;
+        a->range_list.prev->next = &a->range_list;
+    }
+    if ( b->range_list.next == &a->range_list )
+    {
+        b->range_list.next = &b->range_list;
+        b->range_list.prev = &b->range_list;
+    }
+    else
+    {
+        b->range_list.next->prev = &b->range_list;
+        b->range_list.prev->next = &b->range_list;
+    }
+    spin_unlock(&a->lock);
+    spin_unlock(&b->lock);
+}
diff --git a/xen/include/xen/rangeset.h b/xen/include/xen/rangeset.h
index 1e16a6b..805ebde 100644
--- a/xen/include/xen/rangeset.h
+++ b/xen/include/xen/rangeset.h
@@ -73,4 +73,7 @@ void rangeset_printk(
 void rangeset_domain_printk(
     struct domain *d);
 
+/* swap contents */
+void rangeset_swap(struct rangeset *a, struct rangeset *b);
+
 #endif /* __XEN_RANGESET_H__ */
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 91adc8c..8b28f79 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -45,6 +45,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
 
 /* A global pointer to the hardware domain (usually DOM0). */
 extern struct domain *hardware_domain;
+extern domid_t hardware_domid;
 
 #ifndef CONFIG_COMPAT
 #define BITS_PER_EVTCHN_WORD(d) BITS_PER_XEN_ULONG
@@ -794,7 +795,7 @@ void watchdog_domain_destroy(struct domain *d);
  *    (that is, this would not be suitable for a driver domain)
  *  - There is never a reason to deny dom0 access to this
  */
-#define is_hardware_domain(_d) ((_d)->domain_id == 0)
+#define is_hardware_domain(d)  ((d)->domain_id == hardware_domid)
 
 /* This check is for functionality specific to a control domain */
 #define is_control_domain(_d) ((_d)->is_privileged)
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index e722155..8ca1117 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -299,6 +299,12 @@ static XSM_INLINE char *xsm_show_security_evtchn(struct domain *d, const struct
     return NULL;
 }
 
+static XSM_INLINE int xsm_init_hardware_domain(XSM_DEFAULT_ARG struct domain *d)
+{
+    XSM_ASSERT_ACTION(XSM_HOOK);
+    return xsm_default_action(action, current->domain, d);
+}
+
 static XSM_INLINE int xsm_get_pod_target(XSM_DEFAULT_ARG struct domain *d)
 {
     XSM_ASSERT_ACTION(XSM_PRIV);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 15acb3b..bff0574 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -82,6 +82,7 @@ struct xsm_operations {
     int (*alloc_security_evtchn) (struct evtchn *chn);
     void (*free_security_evtchn) (struct evtchn *chn);
     char *(*show_security_evtchn) (struct domain *d, const struct evtchn *chn);
+    int (*init_hardware_domain) (struct domain *d);
 
     int (*get_pod_target) (struct domain *d);
     int (*set_pod_target) (struct domain *d);
@@ -311,6 +312,11 @@ static inline char *xsm_show_security_evtchn (struct domain *d, const struct evt
     return xsm_ops->show_security_evtchn(d, chn);
 }
 
+static inline int xsm_init_hardware_domain (xsm_default_t def, struct domain *d)
+{
+    return xsm_ops->init_hardware_domain(d);
+}
+
 static inline int xsm_get_pod_target (xsm_default_t def, struct domain *d)
 {
     return xsm_ops->get_pod_target(d);
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index b79e10f..c2804f2 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -58,6 +58,8 @@ void xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, alloc_security_evtchn);
     set_to_dummy_if_null(ops, free_security_evtchn);
     set_to_dummy_if_null(ops, show_security_evtchn);
+    set_to_dummy_if_null(ops, init_hardware_domain);
+
     set_to_dummy_if_null(ops, get_pod_target);
     set_to_dummy_if_null(ops, set_pod_target);
 
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 4ce31c9..f1a4a2d 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -327,6 +327,11 @@ static char *flask_show_security_evtchn(struct domain *d, const struct evtchn *c
     return ctx;
 }
 
+static int flask_init_hardware_domain(struct domain *d)
+{
+    return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__CREATE_HARDWARE_DOMAIN);
+}
+
 static int flask_grant_mapref(struct domain *d1, struct domain *d2, 
                               uint32_t flags)
 {
@@ -1500,6 +1505,7 @@ static struct xsm_operations flask_ops = {
     .alloc_security_evtchn = flask_alloc_security_evtchn,
     .free_security_evtchn = flask_free_security_evtchn,
     .show_security_evtchn = flask_show_security_evtchn,
+    .init_hardware_domain = flask_init_hardware_domain,
 
     .get_pod_target = flask_get_pod_target,
     .set_pod_target = flask_set_pod_target,
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index a0ed13d..32371a9 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -198,6 +198,8 @@ class domain2
     set_max_evtchn
 # XEN_DOMCTL_cacheflush
     cacheflush
+# Creation of the hardware domain when it is not dom0
+    create_hardware_domain
 }
 
 # Similar to class domain, but primarily contains domctls related to HVM domains
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 7/7] tools/libxl: Allow dom0 to be destroyed
  2014-03-27 11:52 [PATCH v3 0/7] xen: Hardware domain support Daniel De Graaf
                   ` (5 preceding siblings ...)
  2014-03-27 11:52 ` [PATCH 6/7] xen: Allow hardare domain != dom0 Daniel De Graaf
@ 2014-03-27 11:52 ` Daniel De Graaf
  2014-03-27 15:35   ` Ian Campbell
  2014-04-10 15:58 ` [PATCH v3 0/7] xen: Hardware domain support Keir Fraser
  7 siblings, 1 reply; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 11:52 UTC (permalink / raw)
  To: xen-devel; +Cc: dgdegra, Ian Jackson, Ian Campbell, Stefano Stabellini

When dom0 is not the hardware domain, it can be destroyed in the same
way as any other service domain.  To avoid accidental use when a domain
is not resolved, destroying domain 0 requires passing -f to xl destroy.
Since the hypervisor already prevents a domain from destroying itself,
this patch is only useful in a disaggregated environment.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
---
 docs/man/xl.pod.1         | 14 +++++++++++++-
 tools/libxl/xl_cmdimpl.c  | 17 +++++++++++------
 tools/libxl/xl_cmdtable.c |  5 ++++-
 3 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1
index f7ceaa8..fd35d32 100644
--- a/docs/man/xl.pod.1
+++ b/docs/man/xl.pod.1
@@ -218,13 +218,25 @@ Connect to console number I<NUM>. Console numbers start from 0.
 
 =back
 
-=item B<destroy> I<domain-id>
+=item B<destroy> [I<OPTIONS>] I<domain-id>
 
 Immediately terminate the domain I<domain-id>.  This doesn't give the
 domain OS any chance to react, and is the equivalent of ripping the
 power cord out on a physical machine.  In most cases you will want to
 use the B<shutdown> command instead.
 
+B<OPTIONS>
+
+=over 4
+
+=item I<-f>
+
+Allow domain 0 to be destroyed.  Because domain cannot destroy itself, this is
+only possible when using a disaggregated toolstack, and is most useful when
+using a hardware domain separated from domain 0.
+
+=back
+
 =item B<domid> I<domain-name>
 
 Converts a domain name to a domain id.
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 8389468..0b38b32 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -3053,12 +3053,14 @@ static void unpause_domain(uint32_t domid)
     libxl_domain_unpause(ctx, domid);
 }
 
-static void destroy_domain(uint32_t domid)
+static void destroy_domain(uint32_t domid, int force)
 {
     int rc;
 
-    if (domid == 0) {
-        fprintf(stderr, "Cannot destroy privileged domain 0.\n\n");
+    if (domid == 0 && !force) {
+        fprintf(stderr, "Not destroying domain 0; use -f to force.\n"
+                        "This can only be done when using a disaggregated "
+                        "hardware domain and toolstack.\n\n");
         exit(-1);
     }
     rc = libxl_domain_destroy(ctx, domid, 0);
@@ -4157,12 +4159,15 @@ int main_unpause(int argc, char **argv)
 int main_destroy(int argc, char **argv)
 {
     int opt;
+    int force = 0;
 
-    SWITCH_FOREACH_OPT(opt, "", NULL, "destroy", 1) {
-        /* No options */
+    SWITCH_FOREACH_OPT(opt, "f", NULL, "destroy", 1) {
+    case 'f':
+        force = 1;
+        break;
     }
 
-    destroy_domain(find_domain(argv[optind]));
+    destroy_domain(find_domain(argv[optind]), force);
     return 0;
 }
 
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
index e8ab93a..4279b9f 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -56,7 +56,10 @@ struct cmd_spec cmd_table[] = {
     { "destroy",
       &main_destroy, 0, 1,
       "Terminate a domain immediately",
-      "<Domain>",
+      "[options] <Domain>\n",
+      "-f                      Permit destroying domain 0, which will only succeed\n"
+      "                        when run from disaggregated toolstack domain with a\n"
+      "                        hardware domain distinct from domain 0."
     },
     { "shutdown",
       &main_shutdown, 0, 1,
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/7] xen: rename dom0 to hardware_domain
  2014-03-27 11:52 ` [PATCH 4/7] xen: rename dom0 to hardware_domain Daniel De Graaf
@ 2014-03-27 12:20   ` Egger, Christoph
  2014-03-27 12:48     ` Daniel De Graaf
  2014-03-27 15:33   ` Ian Campbell
  1 sibling, 1 reply; 26+ messages in thread
From: Egger, Christoph @ 2014-03-27 12:20 UTC (permalink / raw)
  To: Daniel De Graaf, xen-devel
  Cc: Liu Jinsong, Ian Campbell, Tim Deegan, Stefano Stabellini,
	Suravee Suthikulpanit, Xiantao Zhang

On 27.03.14 12:52, Daniel De Graaf wrote:
> This should not change any functionality other than renaming the global
> variable.  In a few cases (primarily the domain building code), a local
> variable or argument named dom0 was created and used instead of the
> global hardware_domain to clarify that the domain being used in this
> case is actually domain 0.
> 
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Liu Jinsong <jinsong.liu@intel.com>
> Cc: Christoph Egger <chegger@amazon.de>
> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> Cc: Xiantao Zhang <xiantao.zhang@intel.com>

These changes are pretty mechanical.
I suppose you have code (or at least a plan) on top of
this patch? Is this a cleanup patch splitted out of it?

Christoph

> ---
>  xen/arch/arm/domain_build.c                 |  2 +-
>  xen/arch/arm/setup.c                        |  5 ++--
>  xen/arch/x86/acpi/cpu_idle.c                |  2 +-
>  xen/arch/x86/cpu/mcheck/vmce.h              |  5 ++--
>  xen/arch/x86/crash.c                        |  2 +-
>  xen/arch/x86/domain_build.c                 | 37 +++++++++++++++--------------
>  xen/arch/x86/io_apic.c                      |  8 +++----
>  xen/arch/x86/irq.c                          |  8 +++----
>  xen/arch/x86/mm.c                           |  2 +-
>  xen/arch/x86/nmi.c                          |  2 +-
>  xen/arch/x86/setup.c                        |  5 ++--
>  xen/arch/x86/traps.c                        |  2 +-
>  xen/arch/x86/x86_64/mm.c                    |  6 ++---
>  xen/common/domain.c                         |  2 +-
>  xen/common/event_channel.c                  |  2 +-
>  xen/common/kexec.c                          |  2 +-
>  xen/common/keyhandler.c                     |  4 ++--
>  xen/common/xenoprof.c                       |  2 +-
>  xen/drivers/char/ns16550.c                  |  4 +++-
>  xen/drivers/passthrough/amd/pci_amd_iommu.c |  2 +-
>  xen/drivers/passthrough/iommu.c             | 10 ++++----
>  xen/drivers/passthrough/pci.c               |  4 ++--
>  xen/drivers/passthrough/vtd/iommu.c         |  4 ++--
>  xen/include/asm-arm/domain.h                |  2 +-
>  xen/include/xen/domain.h                    |  2 +-
>  xen/include/xen/sched.h                     |  4 ++--
>  26 files changed, 68 insertions(+), 62 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index c9dda0e..3226792 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -50,7 +50,7 @@ custom_param("dom0_mem", parse_dom0_mem);
>   */
>  #define DOM0_FDT_EXTRA_SIZE (128 + sizeof(struct fdt_reserve_entry))
>  
> -struct vcpu *__init alloc_dom0_vcpu0(void)
> +struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0)
>  {
>      if ( opt_dom0_max_vcpus == 0 )
>          opt_dom0_max_vcpus = num_online_cpus();
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index 215ec24..2d562c6 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -664,6 +664,7 @@ void __init start_xen(unsigned long boot_phys_offset,
>      size_t fdt_size;
>      int cpus, i;
>      const char *cmdline;
> +    struct domain *dom0;
>  
>      setup_cache();
>  
> @@ -760,8 +761,8 @@ void __init start_xen(unsigned long boot_phys_offset,
>      do_initcalls();
>  
>      /* Create initial domain 0. */
> -    dom0 = domain_create(0, 0, 0);
> -    if ( IS_ERR(dom0) || (alloc_dom0_vcpu0() == NULL) )
> +    hardware_domain = dom0 = domain_create(0, 0, 0);
> +    if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
>              panic("Error creating domain 0");
>  
>      dom0->is_privileged = 1;
> diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c
> index d2119e2..b05fb39 100644
> --- a/xen/arch/x86/acpi/cpu_idle.c
> +++ b/xen/arch/x86/acpi/cpu_idle.c
> @@ -972,7 +972,7 @@ static void set_cx(
>              cx->entry_method = ACPI_CSTATE_EM_HALT;
>          break;
>      case ACPI_ADR_SPACE_SYSTEM_IO:
> -        if ( ioports_deny_access(dom0, cx->address, cx->address) )
> +        if ( ioports_deny_access(hardware_domain, cx->address, cx->address) )
>              printk(XENLOG_WARNING "Could not deny access to port %04x\n",
>                     cx->address);
>          cx->entry_method = ACPI_CSTATE_EM_SYSIO;
> diff --git a/xen/arch/x86/cpu/mcheck/vmce.h b/xen/arch/x86/cpu/mcheck/vmce.h
> index 6b2c95a..163ce3c 100644
> --- a/xen/arch/x86/cpu/mcheck/vmce.h
> +++ b/xen/arch/x86/cpu/mcheck/vmce.h
> @@ -5,8 +5,9 @@
>  
>  int vmce_init(struct cpuinfo_x86 *c);
>  
> -#define dom0_vmce_enabled() (dom0 && dom0->max_vcpus && dom0->vcpu[0] \
> -        && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA))
> +#define dom0_vmce_enabled() (hardware_domain && hardware_domain->max_vcpus \
> +        && hardware_domain->vcpu[0] \
> +        && guest_enabled_event(hardware_domain->vcpu[0], VIRQ_MCA))
>  
>  int unmmap_broken_page(struct domain *d, mfn_t mfn, unsigned long gfn);
>  
> diff --git a/xen/arch/x86/crash.c b/xen/arch/x86/crash.c
> index ec586bd..aed3b3e 100644
> --- a/xen/arch/x86/crash.c
> +++ b/xen/arch/x86/crash.c
> @@ -205,7 +205,7 @@ void machine_crash_shutdown(void)
>      info = kexec_crash_save_info();
>      info->xen_phys_start = xen_phys_start;
>      info->dom0_pfn_to_mfn_frame_list_list =
> -        arch_get_pfn_to_mfn_frame_list_list(dom0);
> +        arch_get_pfn_to_mfn_frame_list_list(hardware_domain);
>  }
>  
>  /*
> diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
> index 84ce392..b2411b0 100644
> --- a/xen/arch/x86/domain_build.c
> +++ b/xen/arch/x86/domain_build.c
> @@ -100,7 +100,7 @@ static void __init parse_dom0_max_vcpus(const char *s)
>  }
>  custom_param("dom0_max_vcpus", parse_dom0_max_vcpus);
>  
> -struct vcpu *__init alloc_dom0_vcpu0(void)
> +struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0)
>  {
>      unsigned max_vcpus;
>  
> @@ -302,7 +302,7 @@ static void __init process_dom0_ioports_disable(void)
>          printk("Disabling dom0 access to ioport range %04lx-%04lx\n",
>              io_from, io_to);
>  
> -        if ( ioports_deny_access(dom0, io_from, io_to) != 0 )
> +        if ( ioports_deny_access(hardware_domain, io_from, io_to) != 0 )
>              BUG();
>      }
>  }
> @@ -1082,27 +1082,28 @@ int __init construct_dom0(
>  
>      rc = 0;
>  
> -    /* DOM0 is permitted full I/O capabilities. */
> -    rc |= ioports_permit_access(dom0, 0, 0xFFFF);
> -    rc |= iomem_permit_access(dom0, 0UL, ~0UL);
> -    rc |= irqs_permit_access(dom0, 1, nr_irqs_gsi - 1);
> +    /* The hardware domain is initially permitted full I/O capabilities. */
> +    rc |= ioports_permit_access(hardware_domain, 0, 0xFFFF);
> +    rc |= iomem_permit_access(hardware_domain, 0UL, ~0UL);
> +    rc |= irqs_permit_access(hardware_domain, 1, nr_irqs_gsi - 1);
>  
>      /*
>       * Modify I/O port access permissions.
>       */
>      /* Master Interrupt Controller (PIC). */
> -    rc |= ioports_deny_access(dom0, 0x20, 0x21);
> +    rc |= ioports_deny_access(hardware_domain, 0x20, 0x21);
>      /* Slave Interrupt Controller (PIC). */
> -    rc |= ioports_deny_access(dom0, 0xA0, 0xA1);
> +    rc |= ioports_deny_access(hardware_domain, 0xA0, 0xA1);
>      /* Interval Timer (PIT). */
> -    rc |= ioports_deny_access(dom0, 0x40, 0x43);
> +    rc |= ioports_deny_access(hardware_domain, 0x40, 0x43);
>      /* PIT Channel 2 / PC Speaker Control. */
> -    rc |= ioports_deny_access(dom0, 0x61, 0x61);
> +    rc |= ioports_deny_access(hardware_domain, 0x61, 0x61);
>      /* ACPI PM Timer. */
>      if ( pmtmr_ioport )
> -        rc |= ioports_deny_access(dom0, pmtmr_ioport, pmtmr_ioport + 3);
> +        rc |= ioports_deny_access(hardware_domain, pmtmr_ioport,
> +		                          pmtmr_ioport + 3);
>      /* PCI configuration space (NB. 0xcf8 has special treatment). */
> -    rc |= ioports_deny_access(dom0, 0xcfc, 0xcff);
> +    rc |= ioports_deny_access(hardware_domain, 0xcfc, 0xcff);
>      /* Command-line I/O ranges. */
>      process_dom0_ioports_disable();
>  
> @@ -1113,22 +1114,22 @@ int __init construct_dom0(
>      if ( mp_lapic_addr != 0 )
>      {
>          mfn = paddr_to_pfn(mp_lapic_addr);
> -        rc |= iomem_deny_access(dom0, mfn, mfn);
> +        rc |= iomem_deny_access(hardware_domain, mfn, mfn);
>      }
>      /* I/O APICs. */
>      for ( i = 0; i < nr_ioapics; i++ )
>      {
>          mfn = paddr_to_pfn(mp_ioapics[i].mpc_apicaddr);
>          if ( !rangeset_contains_singleton(mmio_ro_ranges, mfn) )
> -            rc |= iomem_deny_access(dom0, mfn, mfn);
> +            rc |= iomem_deny_access(hardware_domain, mfn, mfn);
>      }
>      /* MSI range. */
> -    rc |= iomem_deny_access(dom0, paddr_to_pfn(MSI_ADDR_BASE_LO),
> +    rc |= iomem_deny_access(hardware_domain, paddr_to_pfn(MSI_ADDR_BASE_LO),
>                              paddr_to_pfn(MSI_ADDR_BASE_LO +
>                                           MSI_ADDR_DEST_ID_MASK));
>      /* HyperTransport range. */
>      if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
> -        rc |= iomem_deny_access(dom0, paddr_to_pfn(0xfdULL << 32),
> +        rc |= iomem_deny_access(hardware_domain, paddr_to_pfn(0xfdULL << 32),
>                                  paddr_to_pfn((1ULL << 40) - 1));
>  
>      /* Remove access to E820_UNUSABLE I/O regions above 1MB. */
> @@ -1140,7 +1141,7 @@ int __init construct_dom0(
>          if ( (e820.map[i].type == E820_UNUSABLE) &&
>               (e820.map[i].size != 0) &&
>               (sfn <= efn) )
> -            rc |= iomem_deny_access(dom0, sfn, efn);
> +            rc |= iomem_deny_access(hardware_domain, sfn, efn);
>      }
>  
>      BUG_ON(rc != 0);
> @@ -1149,7 +1150,7 @@ int __init construct_dom0(
>          printk(" Xen warning: dom0 kernel broken ELF: %s\n",
>                 elf_check_broken(&elf));
>  
> -    iommu_dom0_init(dom0);
> +    iommu_dom0_init(hardware_domain);
>      return 0;
>  
>  out:
> diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
> index bddc588..4e6fe2b 100644
> --- a/xen/arch/x86/io_apic.c
> +++ b/xen/arch/x86/io_apic.c
> @@ -2363,7 +2363,7 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
>       * that dom0 pirq == irq.
>       */
>      pirq = (irq >= 256) ? irq : rte.vector;
> -    if ( (pirq < 0) || (pirq >= dom0->nr_pirqs) )
> +    if ( (pirq < 0) || (pirq >= hardware_domain->nr_pirqs) )
>          return -EINVAL;
>      
>      if ( desc->action )
> @@ -2399,10 +2399,10 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
>  
>          printk(XENLOG_INFO "allocated vector %02x for irq %d\n", ret, irq);
>      }
> -    spin_lock(&dom0->event_lock);
> -    ret = map_domain_pirq(dom0, pirq, irq,
> +    spin_lock(&hardware_domain->event_lock);
> +    ret = map_domain_pirq(hardware_domain, pirq, irq,
>              MAP_PIRQ_TYPE_GSI, NULL);
> -    spin_unlock(&dom0->event_lock);
> +    spin_unlock(&hardware_domain->event_lock);
>      if ( ret < 0 )
>          return ret;
>  
> diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
> index 88444be..ca68f92 100644
> --- a/xen/arch/x86/irq.c
> +++ b/xen/arch/x86/irq.c
> @@ -185,9 +185,9 @@ int create_irq(int node)
>          desc->arch.used = IRQ_UNUSED;
>          irq = ret;
>      }
> -    else if ( dom0 )
> +    else if ( hardware_domain )
>      {
> -        ret = irq_permit_access(dom0, irq);
> +        ret = irq_permit_access(hardware_domain, irq);
>          if ( ret )
>              printk(XENLOG_G_ERR
>                     "Could not grant Dom0 access to IRQ%d (error %d)\n",
> @@ -205,9 +205,9 @@ void destroy_irq(unsigned int irq)
>  
>      BUG_ON(!MSI_IRQ(irq));
>  
> -    if ( dom0 )
> +    if ( hardware_domain )
>      {
> -        int err = irq_deny_access(dom0, irq);
> +        int err = irq_deny_access(hardware_domain, irq);
>  
>          if ( err )
>              printk(XENLOG_G_ERR
> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index ad48acc..b9a54a5 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -5222,7 +5222,7 @@ void *alloc_xen_pagetable(void)
>      {
>          void *ptr = alloc_xenheap_page();
>  
> -        BUG_ON(!dom0 && !ptr);
> +        BUG_ON(!hardware_domain && !ptr);
>          return ptr;
>      }
>  
> diff --git a/xen/arch/x86/nmi.c b/xen/arch/x86/nmi.c
> index c67a9c3..526020b 100644
> --- a/xen/arch/x86/nmi.c
> +++ b/xen/arch/x86/nmi.c
> @@ -519,7 +519,7 @@ static void do_nmi_stats(unsigned char key)
>      for_each_online_cpu ( i )
>          printk("%3d\t%3d\n", i, nmi_count(i));
>  
> -    if ( ((d = dom0) == NULL) || (d->vcpu == NULL) ||
> +    if ( ((d = hardware_domain) == NULL) || (d->vcpu == NULL) ||
>           ((v = d->vcpu[0]) == NULL) )
>          return;
>  
> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index 13a148c..75cf212 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -547,6 +547,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      unsigned long nr_pages, raw_max_page, modules_headroom, *module_map;
>      int i, j, e820_warn = 0, bytes = 0;
>      bool_t acpi_boot_table_init_done = 0;
> +    struct domain *dom0;
>      struct ns16550_defaults ns16550 = {
>          .data_bits = 8,
>          .parity    = 'n',
> @@ -1338,8 +1339,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          panic("Could not protect TXT memory regions");
>  
>      /* Create initial domain 0. */
> -    dom0 = domain_create(0, DOMCRF_s3_integrity, 0);
> -    if ( IS_ERR(dom0) || (alloc_dom0_vcpu0() == NULL) )
> +    hardware_domain = dom0 = domain_create(0, DOMCRF_s3_integrity, 0);
> +    if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
>          panic("Error creating domain 0");
>  
>      dom0->is_privileged = 1;
> diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
> index 21c8b63..e5c1269 100644
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -3152,7 +3152,7 @@ void async_exception_cleanup(struct vcpu *curr)
>  
>  static void nmi_dom0_report(unsigned int reason_idx)
>  {
> -    struct domain *d = dom0;
> +    struct domain *d = hardware_domain;
>  
>      if ( (d == NULL) || (d->vcpu == NULL) || (d->vcpu[0] == NULL) )
>          return;
> diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c
> index f6ea012..71ae519 100644
> --- a/xen/arch/x86/x86_64/mm.c
> +++ b/xen/arch/x86/x86_64/mm.c
> @@ -1447,15 +1447,15 @@ int memory_add(unsigned long spfn, unsigned long epfn, unsigned int pxm)
>      if ( ret )
>          goto destroy_m2p;
>  
> -    if ( !need_iommu(dom0) )
> +    if ( !need_iommu(hardware_domain) )
>      {
>          for ( i = spfn; i < epfn; i++ )
> -            if ( iommu_map_page(dom0, i, i, IOMMUF_readable|IOMMUF_writable) )
> +            if ( iommu_map_page(hardware_domain, i, i, IOMMUF_readable|IOMMUF_writable) )
>                  break;
>          if ( i != epfn )
>          {
>              while (i-- > old_max)
> -                iommu_unmap_page(dom0, i);
> +                iommu_unmap_page(hardware_domain, i);
>              goto destroy_m2p;
>          }
>      }
> diff --git a/xen/common/domain.c b/xen/common/domain.c
> index b5868a5..f8ef439 100644
> --- a/xen/common/domain.c
> +++ b/xen/common/domain.c
> @@ -59,7 +59,7 @@ DEFINE_RCU_READ_LOCK(domlist_read_lock);
>  static struct domain *domain_hash[DOMAIN_HASH_SIZE];
>  struct domain *domain_list;
>  
> -struct domain *dom0;
> +struct domain *hardware_domain __read_mostly;
>  
>  struct vcpu *idle_vcpu[NR_CPUS] __read_mostly;
>  
> diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
> index db952af..51fd63d 100644
> --- a/xen/common/event_channel.c
> +++ b/xen/common/event_channel.c
> @@ -743,7 +743,7 @@ void send_global_virq(uint32_t virq)
>      ASSERT(virq < NR_VIRQS);
>      ASSERT(virq_is_global(virq));
>  
> -    send_guest_global_virq(global_virq_handlers[virq] ?: dom0, virq);
> +    send_guest_global_virq(global_virq_handlers[virq] ?: hardware_domain, virq);
>  }
>  
>  int set_global_virq_handler(struct domain *d, uint32_t virq)
> diff --git a/xen/common/kexec.c b/xen/common/kexec.c
> index 23d964e..2239ee8 100644
> --- a/xen/common/kexec.c
> +++ b/xen/common/kexec.c
> @@ -872,7 +872,7 @@ static int kexec_load_slot(struct kexec_image *kimage)
>  static uint16_t kexec_load_v1_arch(void)
>  {
>  #ifdef CONFIG_X86
> -    return is_pv_32on64_domain(dom0) ? EM_386 : EM_X86_64;
> +    return is_pv_32on64_domain(hardware_domain) ? EM_386 : EM_X86_64;
>  #else
>      return EM_NONE;
>  #endif
> diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
> index 5a974b1..627ef99 100644
> --- a/xen/common/keyhandler.c
> +++ b/xen/common/keyhandler.c
> @@ -172,12 +172,12 @@ static void dump_dom0_registers(unsigned char key)
>  {
>      struct vcpu *v;
>  
> -    if ( dom0 == NULL )
> +    if ( hardware_domain == NULL )
>          return;
>  
>      printk("'%c' pressed -> dumping Dom0's registers\n", key);
>  
> -    for_each_vcpu ( dom0, v )
> +    for_each_vcpu ( hardware_domain, v )
>      {
>          if ( alt_key_handling && softirq_pending(smp_processor_id()) )
>          {
> diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c
> index 3c30c3e..3de20b8 100644
> --- a/xen/common/xenoprof.c
> +++ b/xen/common/xenoprof.c
> @@ -219,7 +219,7 @@ static int alloc_xenoprof_struct(
>      bufsize = sizeof(struct xenoprof_buf);
>      i = sizeof(struct event_log);
>  #ifdef CONFIG_COMPAT
> -    d->xenoprof->is_compat = is_pv_32on64_domain(is_passive ? dom0 : d);
> +    d->xenoprof->is_compat = is_pv_32on64_domain(is_passive ? hardware_domain : d);
>      if ( XENOPROF_COMPAT(d->xenoprof) )
>      {
>          bufsize = sizeof(struct compat_oprof_buf);
> diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
> index 429d786..d437bbf 100644
> --- a/xen/drivers/char/ns16550.c
> +++ b/xen/drivers/char/ns16550.c
> @@ -703,10 +703,12 @@ static void __init ns16550_endboot(struct serial_port *port)
>  {
>  #ifdef HAS_IOPORTS
>      struct ns16550 *uart = port->uart;
> +    int rv;
>  
>      if ( uart->remapped_io_base )
>          return;
> -    if ( ioports_deny_access(dom0, uart->io_base, uart->io_base + 7) != 0 )
> +    rv = ioports_deny_access(hardware_domain, uart->io_base, uart->io_base + 7);
> +    if ( rv != 0 )
>          BUG();
>  #endif
>  }
> diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
> index ff5f06e..031480f 100644
> --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
> +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
> @@ -403,7 +403,7 @@ static int amd_iommu_assign_device(struct domain *d, u8 devfn,
>              ivrs_mappings[req_id].read_permission);
>      }
>  
> -    return reassign_device(dom0, d, devfn, pdev);
> +    return reassign_device(hardware_domain, d, devfn, pdev);
>  }
>  
>  static void deallocate_next_page_table(struct page_info *pg, int level)
> diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
> index 3e5635c..25d9af9 100644
> --- a/xen/drivers/passthrough/iommu.c
> +++ b/xen/drivers/passthrough/iommu.c
> @@ -265,7 +265,7 @@ static void iommu_teardown(struct domain *d)
>  }
>  
>  /*
> - * If the device isn't owned by dom0, it means it already
> + * If the device isn't owned by the hardware domain, it means it already
>   * has been assigned to other domain, or it doesn't exist.
>   */
>  static int device_assigned(u16 seg, u8 bus, u8 devfn)
> @@ -273,7 +273,7 @@ static int device_assigned(u16 seg, u8 bus, u8 devfn)
>      struct pci_dev *pdev;
>  
>      spin_lock(&pcidevs_lock);
> -    pdev = pci_get_pdev_by_domain(dom0, seg, bus, devfn);
> +    pdev = pci_get_pdev_by_domain(hardware_domain, seg, bus, devfn);
>      spin_unlock(&pcidevs_lock);
>  
>      return pdev ? 0 : -EBUSY;
> @@ -312,7 +312,7 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
>          d->need_iommu = 1;
>      }
>  
> -    pdev = pci_get_pdev_by_domain(dom0, seg, bus, devfn);
> +    pdev = pci_get_pdev_by_domain(hardware_domain, seg, bus, devfn);
>      if ( !pdev )
>      {
>          rc = pci_get_pdev(seg, bus, devfn) ? -EBUSY : -ENODEV;
> @@ -507,7 +507,7 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
>          devfn += pdev->phantom_stride;
>          if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
>              break;
> -        ret = hd->platform_ops->reassign_device(d, dom0, devfn, pdev);
> +        ret = hd->platform_ops->reassign_device(d, hardware_domain, devfn, pdev);
>          if ( !ret )
>              continue;
>  
> @@ -517,7 +517,7 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
>      }
>  
>      devfn = pdev->devfn;
> -    ret = hd->platform_ops->reassign_device(d, dom0, devfn, pdev);
> +    ret = hd->platform_ops->reassign_device(d, hardware_domain, devfn, pdev);
>      if ( ret )
>      {
>          dprintk(XENLOG_G_ERR,
> diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
> index dfa195a..fbc777c 100644
> --- a/xen/drivers/passthrough/pci.c
> +++ b/xen/drivers/passthrough/pci.c
> @@ -569,7 +569,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct pci_dev_info *info)
>      ret = 0;
>      if ( !pdev->domain )
>      {
> -        pdev->domain = dom0;
> +        pdev->domain = hardware_domain;
>          ret = iommu_add_device(pdev);
>          if ( ret )
>          {
> @@ -577,7 +577,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct pci_dev_info *info)
>              goto out;
>          }
>  
> -        list_add(&pdev->domain_list, &dom0->arch.pdev_list);
> +        list_add(&pdev->domain_list, &hardware_domain->arch.pdev_list);
>      }
>      else
>          iommu_enable_device(pdev);
> diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
> index d22d518..263448d 100644
> --- a/xen/drivers/passthrough/vtd/iommu.c
> +++ b/xen/drivers/passthrough/vtd/iommu.c
> @@ -1667,7 +1667,7 @@ static int reassign_device_ownership(
>       * can attempt to send arbitrary LAPIC/MSI messages. We are unprotected
>       * by the root complex unless interrupt remapping is enabled.
>       */
> -    if ( (target != dom0) && !iommu_intremap )
> +    if ( (target != hardware_domain) && !iommu_intremap )
>          untrusted_msi = 1;
>  
>      ret = domain_context_unmap(source, devfn, pdev);
> @@ -2270,7 +2270,7 @@ static int intel_iommu_assign_device(
>      if ( list_empty(&acpi_drhd_units) )
>          return -ENODEV;
>  
> -    ret = reassign_device_ownership(dom0, d, devfn, pdev);
> +    ret = reassign_device_ownership(hardware_domain, d, devfn, pdev);
>      if ( ret )
>          goto done;
>  
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 28c359a..ec66a4e 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -87,7 +87,7 @@ enum domain_type {
>  #endif
>  
>  extern int dom0_11_mapping;
> -#define is_domain_direct_mapped(d) ((d) == dom0 && dom0_11_mapping)
> +#define is_domain_direct_mapped(d) ((d) == hardware_domain && dom0_11_mapping)
>  
>  struct vtimer {
>          struct vcpu *v;
> diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
> index a057069..bb1c398 100644
> --- a/xen/include/xen/domain.h
> +++ b/xen/include/xen/domain.h
> @@ -12,7 +12,7 @@ typedef union {
>  
>  struct vcpu *alloc_vcpu(
>      struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
> -struct vcpu *alloc_dom0_vcpu0(void);
> +struct vcpu *alloc_dom0_vcpu0(struct domain *dom0);
>  int vcpu_reset(struct vcpu *);
>  
>  struct xen_domctl_getdomaininfo;
> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
> index 1f45f71..91adc8c 100644
> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -43,8 +43,8 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
>  
>  #define SCHED_STAT_CRANK(_X)                (perfc_incr(_X))
>  
> -/* A global pointer to the initial domain (DOM0). */
> -extern struct domain *dom0;
> +/* A global pointer to the hardware domain (usually DOM0). */
> +extern struct domain *hardware_domain;
>  
>  #ifndef CONFIG_COMPAT
>  #define BITS_PER_EVTCHN_WORD(d) BITS_PER_XEN_ULONG
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/7] xen: rename dom0 to hardware_domain
  2014-03-27 12:20   ` Egger, Christoph
@ 2014-03-27 12:48     ` Daniel De Graaf
  2014-03-27 15:46       ` Egger, Christoph
  0 siblings, 1 reply; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 12:48 UTC (permalink / raw)
  To: Egger, Christoph, xen-devel
  Cc: Liu Jinsong, Ian Campbell, Tim Deegan, Stefano Stabellini,
	Suravee Suthikulpanit, Xiantao Zhang

On 03/27/2014 08:20 AM, Egger, Christoph wrote:
> On 27.03.14 12:52, Daniel De Graaf wrote:
>> This should not change any functionality other than renaming the global
>> variable.  In a few cases (primarily the domain building code), a local
>> variable or argument named dom0 was created and used instead of the
>> global hardware_domain to clarify that the domain being used in this
>> case is actually domain 0.
>>
>> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>> Reviewed-by: Jan Beulich <jbeulich@suse.com>
>> Cc: Ian Campbell <ian.campbell@citrix.com>
>> Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
>> Cc: Tim Deegan <tim@xen.org>
>> Cc: Liu Jinsong <jinsong.liu@intel.com>
>> Cc: Christoph Egger <chegger@amazon.de>
>> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
>> Cc: Xiantao Zhang <xiantao.zhang@intel.com>
>
> These changes are pretty mechanical.
> I suppose you have code (or at least a plan) on top of
> this patch? Is this a cleanup patch splitted out of it?
>
> Christoph

This is a part of a patch series that allows the hardware domain to be
distinct from the domain with ID 0.  As part of this series, the "dom0"
global variable now refers to the hardware domain, and as such, should
not be named dom0.

You were CC'd on this patch because of the MAINTAINERS entry for mcheck.
Actually, it looks like patch 1 of this series should also have cc'd
you; I neglected to rerun get_maintainer.pl after expanding it.

-- 
Daniel De Graaf
National Security Agency

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/7] xen: use domid check in is_hardware_domain
  2014-03-27 11:52 ` [PATCH 1/7] xen: use domid check in is_hardware_domain Daniel De Graaf
@ 2014-03-27 15:31   ` Ian Campbell
  0 siblings, 0 replies; 26+ messages in thread
From: Ian Campbell @ 2014-03-27 15:31 UTC (permalink / raw)
  To: Daniel De Graaf
  Cc: Keir Fraser, Tim Deegan, xen-devel, Stefano Stabellini,
	Suravee Suthikulpanit, Xiantao Zhang

On Thu, 2014-03-27 at 07:52 -0400, Daniel De Graaf wrote:
> Instead of checking is_privileged to determine if a domain should
> control the hardware, check that the domain_id is equal to zero (which
> is currently the only domain for which is_privileged is true).  This
> allows other places where domain_id is checked for zero to be replaced
> with is_hardware_domain.
> 
> The distinction between is_hardware_domain, is_control_domain, and
> domain 0 is based on the following disaggregation model:
> 
> Domain 0 bootstraps the system.  It may remain to perform requested
> builds of domains that need a minimal trust chain (i.e. vTPM domains).
> Other than being built by the hypervisor, nothing is special about this
> domain - although it may be useful to have is_control_domain() return
> true depending on the toolstack it uses to build other domains.
> 
> The hardware domain manages devices for PCI pass-through to driver
> domains or can act as a driver domain itself, depending on the desired
> degree of disaggregation.  It is also the domain managing devices that
> do not support pass-through: PCI configuration space access, parsing the
> hardware ACPI tables and system power or machine check events.  This is
> the only domain where is_hardware_domain() is true.  The return of
> is_control_domain() may be false for this domain.
> 
> The control domain manages other domains, controls guest launch and
> shutdown, and manages resource constraints; is_control_domain() returns
> true.  The functionality guarded by is_control_domain may in the future
> be adapted to use explicit hypercalls, eliminating the special treatment
> of this domain.  It may be reasonable to have multiple control domains
> on a multi-tenant system.
> 
> Guest domains and other service or driver domains are all treated
> identically by the hypervisor; the security policy may further constrain
> administrative actions on or communication between these domains.
> 
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Reviewed-by: Jan Beulich <jbeulich@suse.com>

For the arm bits:
Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/7] xen: rename dom0 to hardware_domain
  2014-03-27 11:52 ` [PATCH 4/7] xen: rename dom0 to hardware_domain Daniel De Graaf
  2014-03-27 12:20   ` Egger, Christoph
@ 2014-03-27 15:33   ` Ian Campbell
  1 sibling, 0 replies; 26+ messages in thread
From: Ian Campbell @ 2014-03-27 15:33 UTC (permalink / raw)
  To: Daniel De Graaf
  Cc: Liu Jinsong, Christoph Egger, Tim Deegan, xen-devel,
	Stefano Stabellini, Suravee Suthikulpanit, Xiantao Zhang

On Thu, 2014-03-27 at 07:52 -0400, Daniel De Graaf wrote:
> This should not change any functionality other than renaming the global
> variable.  In a few cases (primarily the domain building code), a local
> variable or argument named dom0 was created and used instead of the
> global hardware_domain to clarify that the domain being used in this
> case is actually domain 0.
> 
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Reviewed-by: Jan Beulich <jbeulich@suse.com>

For the ARM bits:
Acked-by: Ian Campbell <ian.campbell@citrix.com>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 5/7] xen: rename various functions referencing dom0
  2014-03-27 11:52 ` [PATCH 5/7] xen: rename various functions referencing dom0 Daniel De Graaf
@ 2014-03-27 15:34   ` Ian Campbell
  2014-03-27 15:47     ` Daniel De Graaf
  0 siblings, 1 reply; 26+ messages in thread
From: Ian Campbell @ 2014-03-27 15:34 UTC (permalink / raw)
  To: Daniel De Graaf
  Cc: Xiantao Zhang, Suravee Suthikulpanit, Jan Beulich, xen-devel

On Thu, 2014-03-27 at 07:52 -0400, Daniel De Graaf wrote:
> Most of these functions actually act on the hardware domain, so change
> their names to reflect this.
> 
> Command line parameters and variables based on those parameters are
> excluded since those changes would be user-visible, as are any public
> headers.
> 
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Cc: Ian Campbell <ian.campbell@citrix.com>

Did there used to be some ARM bits which have now moved? Otherwise I've
forgotten which bit of the below I'm supposed to be maintainer of ;-)

> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> Cc: Xiantao Zhang <xiantao.zhang@intel.com>
> ---
>  xen/arch/x86/domain_build.c                 |  2 +-
>  xen/arch/x86/hvm/i8254.c                    |  2 +-
>  xen/arch/x86/time.c                         |  2 +-
>  xen/arch/x86/traps.c                        |  8 ++++----
>  xen/common/domain.c                         |  2 +-
>  xen/common/keyhandler.c                     | 22 +++++++++++-----------
>  xen/common/shutdown.c                       |  2 +-
>  xen/drivers/passthrough/amd/pci_amd_iommu.c |  8 ++++----
>  xen/drivers/passthrough/iommu.c             |  8 ++++----
>  xen/drivers/passthrough/pci.c               | 18 +++++++++---------
>  xen/drivers/passthrough/vtd/iommu.c         | 18 +++++++++---------
>  xen/drivers/passthrough/vtd/x86/vtd.c       |  2 +-
>  xen/include/asm-x86/time.h                  |  2 +-
>  xen/include/xen/iommu.h                     |  6 +++---
>  xen/include/xen/pci.h                       |  2 +-
>  xen/include/xen/shutdown.h                  |  2 +-
>  16 files changed, 53 insertions(+), 53 deletions(-)

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] tools/libxl: Allow dom0 to be destroyed
  2014-03-27 11:52 ` [PATCH 7/7] tools/libxl: Allow dom0 to be destroyed Daniel De Graaf
@ 2014-03-27 15:35   ` Ian Campbell
  2014-04-02 15:08     ` Ian Jackson
  0 siblings, 1 reply; 26+ messages in thread
From: Ian Campbell @ 2014-03-27 15:35 UTC (permalink / raw)
  To: Daniel De Graaf, Jan Beulich, Keir Fraser
  Cc: Stefano Stabellini, Ian Jackson, xen-devel

On Thu, 2014-03-27 at 07:52 -0400, Daniel De Graaf wrote:
> When dom0 is not the hardware domain, it can be destroyed in the same
> way as any other service domain.  To avoid accidental use when a domain
> is not resolved, destroying domain 0 requires passing -f to xl destroy.
> Since the hypervisor already prevents a domain from destroying itself,
> this patch is only useful in a disaggregated environment.
> 
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Acked-by: Ian Campbell <ian.campbell@citrix.com>

It looks like Jan or Keir will be committing the majority of this patch,
so I will assume that this will go in at the same time.

Cheers,
Ian.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/7] xen: rename dom0 to hardware_domain
  2014-03-27 12:48     ` Daniel De Graaf
@ 2014-03-27 15:46       ` Egger, Christoph
  0 siblings, 0 replies; 26+ messages in thread
From: Egger, Christoph @ 2014-03-27 15:46 UTC (permalink / raw)
  To: Daniel De Graaf, xen-devel
  Cc: Liu Jinsong, Ian Campbell, Tim Deegan, Stefano Stabellini,
	Suravee Suthikulpanit, Xiantao Zhang

On 27.03.14 13:48, Daniel De Graaf wrote:
> On 03/27/2014 08:20 AM, Egger, Christoph wrote:
>> On 27.03.14 12:52, Daniel De Graaf wrote:
>>> This should not change any functionality other than renaming the global
>>> variable.  In a few cases (primarily the domain building code), a local
>>> variable or argument named dom0 was created and used instead of the
>>> global hardware_domain to clarify that the domain being used in this
>>> case is actually domain 0.
>>>
>>> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>>> Reviewed-by: Jan Beulich <jbeulich@suse.com>
>>> Cc: Ian Campbell <ian.campbell@citrix.com>
>>> Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
>>> Cc: Tim Deegan <tim@xen.org>
>>> Cc: Liu Jinsong <jinsong.liu@intel.com>
>>> Cc: Christoph Egger <chegger@amazon.de>
>>> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
>>> Cc: Xiantao Zhang <xiantao.zhang@intel.com>
>>
>> These changes are pretty mechanical.
>> I suppose you have code (or at least a plan) on top of
>> this patch? Is this a cleanup patch splitted out of it?
>>
>> Christoph
> 
> This is a part of a patch series that allows the hardware domain to be
> distinct from the domain with ID 0.  As part of this series, the "dom0"
> global variable now refers to the hardware domain, and as such, should
> not be named dom0.
> 
> You were CC'd on this patch because of the MAINTAINERS entry for mcheck.
> Actually, it looks like patch 1 of this series should also have cc'd
> you; I neglected to rerun get_maintainer.pl after expanding it.
> 

Ok. For the mcheck bits:
Acked-by: Christoph Egger <chegger@amazon.de>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 5/7] xen: rename various functions referencing dom0
  2014-03-27 15:34   ` Ian Campbell
@ 2014-03-27 15:47     ` Daniel De Graaf
  0 siblings, 0 replies; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-27 15:47 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Xiantao Zhang, Suravee Suthikulpanit, Jan Beulich, xen-devel

On 03/27/2014 11:34 AM, Ian Campbell wrote:
> On Thu, 2014-03-27 at 07:52 -0400, Daniel De Graaf wrote:
>> Most of these functions actually act on the hardware domain, so change
>> their names to reflect this.
>>
>> Command line parameters and variables based on those parameters are
>> excluded since those changes would be user-visible, as are any public
>> headers.
>>
>> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>> Cc: Ian Campbell <ian.campbell@citrix.com>
>
> Did there used to be some ARM bits which have now moved? Otherwise I've
> forgotten which bit of the below I'm supposed to be maintainer of ;-)

Yes, there used to be ARM bits here, but they were moved to #4.  While
I mentioned that in the header, I neglected to adjust the Cc list here.

-- 
Daniel De Graaf
National Security Agency

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 7/7] tools/libxl: Allow dom0 to be destroyed
  2014-03-27 15:35   ` Ian Campbell
@ 2014-04-02 15:08     ` Ian Jackson
  0 siblings, 0 replies; 26+ messages in thread
From: Ian Jackson @ 2014-04-02 15:08 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Daniel De Graaf, Stefano Stabellini, Keir Fraser, Jan Beulich, xen-devel

Ian Campbell writes ("Re: [PATCH 7/7] tools/libxl: Allow dom0 to be destroyed"):
> On Thu, 2014-03-27 at 07:52 -0400, Daniel De Graaf wrote:
> > When dom0 is not the hardware domain, it can be destroyed in the same
> > way as any other service domain.  To avoid accidental use when a domain
> > is not resolved, destroying domain 0 requires passing -f to xl destroy.
> > Since the hypervisor already prevents a domain from destroying itself,
> > this patch is only useful in a disaggregated environment.
> > 
> > Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> > Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> > Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> 
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
> 
> It looks like Jan or Keir will be committing the majority of this patch,
> so I will assume that this will go in at the same time.

FWIW

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

Thanks,
Ian.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v3 0/7] xen: Hardware domain support
  2014-03-27 11:52 [PATCH v3 0/7] xen: Hardware domain support Daniel De Graaf
                   ` (6 preceding siblings ...)
  2014-03-27 11:52 ` [PATCH 7/7] tools/libxl: Allow dom0 to be destroyed Daniel De Graaf
@ 2014-04-10 15:58 ` Keir Fraser
  7 siblings, 0 replies; 26+ messages in thread
From: Keir Fraser @ 2014-04-10 15:58 UTC (permalink / raw)
  To: Daniel De Graaf; +Cc: xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 1994 bytes --]



> Daniel De Graaf <mailto:dgdegra@tycho.nsa.gov>
> 27 March 2014 11:52
> This adds support to the hypervisor for the creation of a hardware
> domain distinct from domain 0, allowing further disaggregation of the
> duties of domain 0. The commit message for patch 1 contains a more
> complete description of the distinction between the hardware domain and
> control domain(s). Making the hardware domain distinct from domain 0
> allows it to be further de-privileged using an XSM policy: the hardware
> domain does not need to be permitted access to create or modify other
> domains in order to act as a device backend for them.
>
> Changes since v2:
> - Rename and move CONFIG_LATE_HWDOM declaration to asm-x86/config.h
> - Move alloc_dom0_vcpu0 prototype change from patch 5 to 4
> - Also rename nmi_{dom0 => hwdom}_report
> - Add help/documentation for xl destroy -f
>
> Changes since v1:
> - More complete conversion to is_hardware_domain (convert "== dom0")
> - Rename "dom0" global variable and associated functions
> - Avoid locating the hardware_domid variable in x86-only code
> - Require using "xl destroy -f 0" to destroy domain 0 to retain the
> existing guard against accidental attempts to destroy domain 0 that
> will still cause disruption of the platform.
> - Add an XSM permission check so that the security label of the
> hardware domain can be limited by the policy.
> - Rebase against updated xen/staging
>
> [PATCH 1/7] xen: use domid check in is_hardware_domain
> [PATCH 2/7] xen/iommu: Move dom0 setup to __hwdom_init
> [PATCH 3/7] xen: prevent 0 from being used as a dynamic domid
> [PATCH 4/7] xen: rename dom0 to hardware_domain
> [PATCH 5/7] xen: rename various functions referencing dom0
> [PATCH 6/7] xen: Allow hardare domain != dom0
> [PATCH 7/7] tools/libxl: Allow dom0 to be destroyed

Acked-by: Keir Fraser <keir@xen.org>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

[-- Attachment #1.2.1: Type: text/html, Size: 3825 bytes --]

[-- Attachment #1.2.2: compose-unknown-contact.jpg --]
[-- Type: image/jpeg, Size: 770 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/7] xen: Allow hardare domain != dom0
  2014-03-27 11:52 ` [PATCH 6/7] xen: Allow hardare domain != dom0 Daniel De Graaf
@ 2014-04-11  9:13   ` Jan Beulich
  2014-04-11 15:07     ` Daniel De Graaf
  0 siblings, 1 reply; 26+ messages in thread
From: Jan Beulich @ 2014-04-11  9:13 UTC (permalink / raw)
  To: dgdegra; +Cc: Keir Fraser, xen-devel

>>> On 27.03.14 at 12:52, <dgdegra@tycho.nsa.gov> wrote:

I was about to commit this, but further changes are needed (along
with fixing the typo in the title):

> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -84,6 +84,8 @@ unsigned long __initdata highmem_start;
>  size_param("highmem-start", highmem_start);
>  #endif
>  
> +integer_param("hardware_dom", hardware_domid);

This should be moved alongside the definition of the symbol in
common code, and be enclosed in "#ifdef CONFIG_LATE_HWDOM".

And docs/misc/xen-command-line.markdown wants an entry for it.

> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -45,6 +45,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
>  
>  /* A global pointer to the hardware domain (usually DOM0). */
>  extern struct domain *hardware_domain;
> +extern domid_t hardware_domid;
>  
>  #ifndef CONFIG_COMPAT
>  #define BITS_PER_EVTCHN_WORD(d) BITS_PER_XEN_ULONG
> @@ -794,7 +795,7 @@ void watchdog_domain_destroy(struct domain *d);
>   *    (that is, this would not be suitable for a driver domain)
>   *  - There is never a reason to deny dom0 access to this
>   */
> -#define is_hardware_domain(_d) ((_d)->domain_id == 0)
> +#define is_hardware_domain(d)  ((d)->domain_id == hardware_domid)

This macro should imo evaluate to true for Dom0 until the hardware
domain go created, i.e. you should compare _d with hardware_domain
rather than their IDs. With that the definition of hardware_domid can
then also be moved inside the #ifdef requested above.

Jan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/7] xen: Allow hardare domain != dom0
  2014-04-11  9:13   ` Jan Beulich
@ 2014-04-11 15:07     ` Daniel De Graaf
  2014-04-11 15:20       ` Jan Beulich
  0 siblings, 1 reply; 26+ messages in thread
From: Daniel De Graaf @ 2014-04-11 15:07 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Keir Fraser, xen-devel

On 04/11/2014 05:13 AM, Jan Beulich wrote:
>>>> On 27.03.14 at 12:52, <dgdegra@tycho.nsa.gov> wrote:
>
> I was about to commit this, but further changes are needed (along
> with fixing the typo in the title):

I noticed the typo soon after posting v3, but didn't want to post
v4 with that and some other whitespace.  It looks like v4 will have
useful changes now, however.

>> --- a/xen/arch/x86/setup.c
>> +++ b/xen/arch/x86/setup.c
>> @@ -84,6 +84,8 @@ unsigned long __initdata highmem_start;
>>   size_param("highmem-start", highmem_start);
>>   #endif
>>
>> +integer_param("hardware_dom", hardware_domid);
>
> This should be moved alongside the definition of the symbol in
> common code, and be enclosed in "#ifdef CONFIG_LATE_HWDOM".
>
> And docs/misc/xen-command-line.markdown wants an entry for it.

OK.

>> --- a/xen/include/xen/sched.h
>> +++ b/xen/include/xen/sched.h
>> @@ -45,6 +45,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
>>
>>   /* A global pointer to the hardware domain (usually DOM0). */
>>   extern struct domain *hardware_domain;
>> +extern domid_t hardware_domid;
>>
>>   #ifndef CONFIG_COMPAT
>>   #define BITS_PER_EVTCHN_WORD(d) BITS_PER_XEN_ULONG
>> @@ -794,7 +795,7 @@ void watchdog_domain_destroy(struct domain *d);
>>    *    (that is, this would not be suitable for a driver domain)
>>    *  - There is never a reason to deny dom0 access to this
>>    */
>> -#define is_hardware_domain(_d) ((_d)->domain_id == 0)
>> +#define is_hardware_domain(d)  ((d)->domain_id == hardware_domid)
>
> This macro should imo evaluate to true for Dom0 until the hardware
> domain go created, i.e. you should compare _d with hardware_domain
> rather than their IDs. With that the definition of hardware_domid can
> then also be moved inside the #ifdef requested above.

This isn't quite as simple as changing the function since there are
some places where is_hardware_domain needs to return false for domain 0
when a hardware domain is used.  Also, the hardware_domain variable is
not set until domain_create returns, so there are a few places where the
domain ID still needs to be checked explicitly.  It should be possible
to create an is_hardware_domid function for those cases, if comparing to
hardware_domain is preferred for most cases; I think that would belong in
a new patch 5.5/7 (i.e. 6/8 in v4).

Otherwise, I think the is_hardware_domain definition should be:

#ifdef CONFIG_LATE_HWDOM
#define is_hardware_domain(_d) ((_d)->domain_id == hardware_domid)
#else
#define is_hardware_domain(_d) ((_d)->domain_id == 0)
#endif

This also allows hardware_domid to be declared inside the #ifdef.

-- 
Daniel De Graaf
National Security Agency

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/7] xen: Allow hardare domain != dom0
  2014-04-11 15:07     ` Daniel De Graaf
@ 2014-04-11 15:20       ` Jan Beulich
  2014-04-11 18:22         ` Daniel De Graaf
  0 siblings, 1 reply; 26+ messages in thread
From: Jan Beulich @ 2014-04-11 15:20 UTC (permalink / raw)
  To: Daniel De Graaf; +Cc: Keir Fraser, xen-devel

>>> On 11.04.14 at 17:07, <dgdegra@tycho.nsa.gov> wrote:
> On 04/11/2014 05:13 AM, Jan Beulich wrote:
>>>>> On 27.03.14 at 12:52, <dgdegra@tycho.nsa.gov> wrote:
>>> @@ -794,7 +795,7 @@ void watchdog_domain_destroy(struct domain *d);
>>>    *    (that is, this would not be suitable for a driver domain)
>>>    *  - There is never a reason to deny dom0 access to this
>>>    */
>>> -#define is_hardware_domain(_d) ((_d)->domain_id == 0)
>>> +#define is_hardware_domain(d)  ((d)->domain_id == hardware_domid)
>>
>> This macro should imo evaluate to true for Dom0 until the hardware
>> domain go created, i.e. you should compare _d with hardware_domain
>> rather than their IDs. With that the definition of hardware_domid can
>> then also be moved inside the #ifdef requested above.
> 
> This isn't quite as simple as changing the function since there are
> some places where is_hardware_domain needs to return false for domain 0
> when a hardware domain is used.  Also, the hardware_domain variable is
> not set until domain_create returns, so there are a few places where the
> domain ID still needs to be checked explicitly.  It should be possible
> to create an is_hardware_domid function for those cases, if comparing to
> hardware_domain is preferred for most cases; I think that would belong in
> a new patch 5.5/7 (i.e. 6/8 in v4).
> 
> Otherwise, I think the is_hardware_domain definition should be:
> 
> #ifdef CONFIG_LATE_HWDOM
> #define is_hardware_domain(_d) ((_d)->domain_id == hardware_domid)
> #else
> #define is_hardware_domain(_d) ((_d)->domain_id == 0)
> #endif
> 
> This also allows hardware_domid to be declared inside the #ifdef.

But that still wouldn't necessarily do the correct thing for any use of
the macro before that new special case code in domain_create() got
run. Maybe my thinking of this is wrong, but as I tried to state above,
I would expect Dom0 to be the hardware domain up to the point
where the intended hardware domain gets created, at which point all
state Dom0 obtained because of having been the de-facto hardware
domain get transferred to hardware_domain.

And btw, the above could be simplified by just having

#define hardware_domid 0

alongside the extern declaration of it (in a respective conditional).
That way all eventual future uses of the variable don't need to also
be enclosed in conditionals.

Jan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/7] xen: Allow hardare domain != dom0
  2014-04-11 15:20       ` Jan Beulich
@ 2014-04-11 18:22         ` Daniel De Graaf
  2014-04-14  7:56           ` Jan Beulich
  0 siblings, 1 reply; 26+ messages in thread
From: Daniel De Graaf @ 2014-04-11 18:22 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Keir Fraser, xen-devel

[-- Attachment #1: Type: text/plain, Size: 7703 bytes --]

On 04/11/2014 11:20 AM, Jan Beulich wrote:
>>>> On 11.04.14 at 17:07, <dgdegra@tycho.nsa.gov> wrote:
>> On 04/11/2014 05:13 AM, Jan Beulich wrote:
>>>>>> On 27.03.14 at 12:52, <dgdegra@tycho.nsa.gov> wrote:
>>>> @@ -794,7 +795,7 @@ void watchdog_domain_destroy(struct domain *d);
>>>>     *    (that is, this would not be suitable for a driver domain)
>>>>     *  - There is never a reason to deny dom0 access to this
>>>>     */
>>>> -#define is_hardware_domain(_d) ((_d)->domain_id == 0)
>>>> +#define is_hardware_domain(d)  ((d)->domain_id == hardware_domid)
>>>
>>> This macro should imo evaluate to true for Dom0 until the hardware
>>> domain go created, i.e. you should compare _d with hardware_domain
>>> rather than their IDs. With that the definition of hardware_domid can
>>> then also be moved inside the #ifdef requested above.
>>
>> This isn't quite as simple as changing the function since there are
>> some places where is_hardware_domain needs to return false for domain 0
>> when a hardware domain is used.  Also, the hardware_domain variable is
>> not set until domain_create returns, so there are a few places where the
>> domain ID still needs to be checked explicitly.  It should be possible
>> to create an is_hardware_domid function for those cases, if comparing to
>> hardware_domain is preferred for most cases; I think that would belong in
>> a new patch 5.5/7 (i.e. 6/8 in v4).
>>
>> Otherwise, I think the is_hardware_domain definition should be:
>>
>> #ifdef CONFIG_LATE_HWDOM
>> #define is_hardware_domain(_d) ((_d)->domain_id == hardware_domid)
>> #else
>> #define is_hardware_domain(_d) ((_d)->domain_id == 0)
>> #endif
>>
>> This also allows hardware_domid to be declared inside the #ifdef.
>
> But that still wouldn't necessarily do the correct thing for any use of
> the macro before that new special case code in domain_create() got
> run. Maybe my thinking of this is wrong, but as I tried to state above,
> I would expect Dom0 to be the hardware domain up to the point
> where the intended hardware domain gets created, at which point all
> state Dom0 obtained because of having been the de-facto hardware
> domain get transferred to hardware_domain.

I agree with this in most cases, and I think the few places where that
is not true should be changed to make them more explicit.  This must
include all checks in domain_create and those in functions called from
domain_create, because (d == hardware_domain) is always false inside
domain_create.  An initial version of this patch is below, but unless
there are objections I plan to integrate it into patch 1 to avoid doing
(d->domain_id == 0) => is_hardware_domain => is_hardware_domain_by_id
for the ARM code.

------------------------------>8------------------------

Subject: [PATCH RFC 6/8] xen: introduce is_hardware_domain_by_id

In order to better handle the period when domain 0 is running but has
not yet built a late hardware domain, change is_hardware_domain to do
what its name implies: check that the passed domain is the hardware
domain.  To address some cases where this variable is not set (in
particular, during the creation of domain 0 this variable will still be
NULL), the old check is retained with the name is_hardware_domain_by_id.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
  xen/arch/arm/domain.c   | 2 +-
  xen/arch/arm/gic.c      | 2 +-
  xen/arch/arm/vgic.c     | 2 +-
  xen/arch/arm/vtimer.c   | 2 +-
  xen/arch/arm/vuart.c    | 2 +-
  xen/common/domain.c     | 4 ++--
  xen/include/xen/sched.h | 9 ++++++++-
  7 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index ccccb77..4f235e4 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -528,7 +528,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
       * Only use it for the hardware domain because the linux kernel may not
       * support multi-platform.
       */
-    if ( is_hardware_domain(d) && (rc = domain_vuart_init(d)) )
+    if ( is_hardware_domain_by_id(d) && (rc = domain_vuart_init(d)) )
          goto fail;
  
      return 0;
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 8168b7b..5c16aba 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -868,7 +868,7 @@ int gicv_setup(struct domain *d)
       * The hardware domain gets the hardware address.
       * Guests get the virtual platform layout.
       */
-    if ( is_hardware_domain(d) )
+    if ( is_hardware_domain_by_id(d) )
      {
          d->arch.vgic.dbase = gic.dbase;
          d->arch.vgic.cbase = gic.cbase;
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 4a7f8c0..cc795e0 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -82,7 +82,7 @@ int domain_vgic_init(struct domain *d)
      /* Currently nr_lines in vgic and gic doesn't have the same meanings
       * Here nr_lines = number of SPIs
       */
-    if ( is_hardware_domain(d) )
+    if ( is_hardware_domain_by_id(d) )
          d->arch.vgic.nr_lines = gic_number_lines() - 32;
      else
          d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index cb690bb..4dcb80d 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -54,7 +54,7 @@ int vcpu_domain_init(struct domain *d)
  int vcpu_vtimer_init(struct vcpu *v)
  {
      struct vtimer *t = &v->arch.phys_timer;
-    bool_t d0 = is_hardware_domain(v->domain);
+    bool_t d0 = is_hardware_domain_by_id(v->domain);
  
      /*
       * Hardware domain uses the hardware interrupts, guests get the virtual
diff --git a/xen/arch/arm/vuart.c b/xen/arch/arm/vuart.c
index c02a8a9..cf9745c 100644
--- a/xen/arch/arm/vuart.c
+++ b/xen/arch/arm/vuart.c
@@ -46,7 +46,7 @@
  
  int domain_vuart_init(struct domain *d)
  {
-    ASSERT( is_hardware_domain(d) );
+    ASSERT( is_hardware_domain_by_id(d) );
  
      d->arch.vuart.info = serial_vuart_info(SERHND_DTUART);
      if ( !d->arch.vuart.info )
diff --git a/xen/common/domain.c b/xen/common/domain.c
index c4720a9..4036e69 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -237,7 +237,7 @@ struct domain *domain_create(
      else if ( domcr_flags & DOMCRF_pvh )
          d->guest_type = guest_type_pvh;
  
-    if ( is_hardware_domain(d) )
+    if ( is_hardware_domain_by_id(d) )
      {
          d->is_pinned = opt_dom0_vcpus_pin;
          d->disable_migrate = 1;
@@ -262,7 +262,7 @@ struct domain *domain_create(
          d->is_paused_by_controller = 1;
          atomic_inc(&d->pause_count);
  
-        if ( !is_hardware_domain(d) )
+        if ( !is_hardware_domain_by_id(d) )
              d->nr_pirqs = nr_static_irqs + extra_domU_irqs;
          else
              d->nr_pirqs = nr_static_irqs + extra_dom0_irqs;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index cbbe8a4..34447f1 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -797,7 +797,14 @@ void watchdog_domain_destroy(struct domain *d);
   *    (that is, this would not be suitable for a driver domain)
   *  - There is never a reason to deny dom0 access to this
   */
-#define is_hardware_domain(_d) ((_d)->domain_id == 0)
+#define is_hardware_domain(_d) ((_d) == hardware_domain)
+
+/*
+ * Check for the hardware domain based on domain ID, not using the global
+ * hardware_domain variable.  This is necessary inside domain_create where
+ * hardware_domain is NULL and for some checks implementing CONFIG_LATE_HWDOM.
+ */
+#define is_hardware_domain_by_id(_d) ((_d)->domain_id == 0)
  
  /* This check is for functionality specific to a control domain */
  #define is_control_domain(_d) ((_d)->is_privileged)
-- 
1.9.0



[-- Attachment #2: 0006-xen-introduce-is_hardware_domain_by_id.patch --]
[-- Type: text/x-patch, Size: 5043 bytes --]

>From 8271965e73890ce25b86f31045b2c1784bd04273 Mon Sep 17 00:00:00 2001
From: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Date: Fri, 11 Apr 2014 13:46:24 -0400
Subject: [PATCH RFC 6/8] xen: introduce is_hardware_domain_by_id

In order to better handle the period when domain 0 is running but has
not yet built a late hardware domain, change is_hardware_domain to do
what its name implies: check that the passed domain is the hardware
domain.  To address some cases where this variable is not set (in
particular, during the creation of domain 0 this variable will still be
NULL), the old check is retained with the name is_hardware_domain_by_id.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
 xen/arch/arm/domain.c   | 2 +-
 xen/arch/arm/gic.c      | 2 +-
 xen/arch/arm/vgic.c     | 2 +-
 xen/arch/arm/vtimer.c   | 2 +-
 xen/arch/arm/vuart.c    | 2 +-
 xen/common/domain.c     | 4 ++--
 xen/include/xen/sched.h | 9 ++++++++-
 7 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index ccccb77..4f235e4 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -528,7 +528,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
      * Only use it for the hardware domain because the linux kernel may not
      * support multi-platform.
      */
-    if ( is_hardware_domain(d) && (rc = domain_vuart_init(d)) )
+    if ( is_hardware_domain_by_id(d) && (rc = domain_vuart_init(d)) )
         goto fail;
 
     return 0;
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 8168b7b..5c16aba 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -868,7 +868,7 @@ int gicv_setup(struct domain *d)
      * The hardware domain gets the hardware address.
      * Guests get the virtual platform layout.
      */
-    if ( is_hardware_domain(d) )
+    if ( is_hardware_domain_by_id(d) )
     {
         d->arch.vgic.dbase = gic.dbase;
         d->arch.vgic.cbase = gic.cbase;
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 4a7f8c0..cc795e0 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -82,7 +82,7 @@ int domain_vgic_init(struct domain *d)
     /* Currently nr_lines in vgic and gic doesn't have the same meanings
      * Here nr_lines = number of SPIs
      */
-    if ( is_hardware_domain(d) )
+    if ( is_hardware_domain_by_id(d) )
         d->arch.vgic.nr_lines = gic_number_lines() - 32;
     else
         d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
index cb690bb..4dcb80d 100644
--- a/xen/arch/arm/vtimer.c
+++ b/xen/arch/arm/vtimer.c
@@ -54,7 +54,7 @@ int vcpu_domain_init(struct domain *d)
 int vcpu_vtimer_init(struct vcpu *v)
 {
     struct vtimer *t = &v->arch.phys_timer;
-    bool_t d0 = is_hardware_domain(v->domain);
+    bool_t d0 = is_hardware_domain_by_id(v->domain);
 
     /*
      * Hardware domain uses the hardware interrupts, guests get the virtual
diff --git a/xen/arch/arm/vuart.c b/xen/arch/arm/vuart.c
index c02a8a9..cf9745c 100644
--- a/xen/arch/arm/vuart.c
+++ b/xen/arch/arm/vuart.c
@@ -46,7 +46,7 @@
 
 int domain_vuart_init(struct domain *d)
 {
-    ASSERT( is_hardware_domain(d) );
+    ASSERT( is_hardware_domain_by_id(d) );
 
     d->arch.vuart.info = serial_vuart_info(SERHND_DTUART);
     if ( !d->arch.vuart.info )
diff --git a/xen/common/domain.c b/xen/common/domain.c
index c4720a9..4036e69 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -237,7 +237,7 @@ struct domain *domain_create(
     else if ( domcr_flags & DOMCRF_pvh )
         d->guest_type = guest_type_pvh;
 
-    if ( is_hardware_domain(d) )
+    if ( is_hardware_domain_by_id(d) )
     {
         d->is_pinned = opt_dom0_vcpus_pin;
         d->disable_migrate = 1;
@@ -262,7 +262,7 @@ struct domain *domain_create(
         d->is_paused_by_controller = 1;
         atomic_inc(&d->pause_count);
 
-        if ( !is_hardware_domain(d) )
+        if ( !is_hardware_domain_by_id(d) )
             d->nr_pirqs = nr_static_irqs + extra_domU_irqs;
         else
             d->nr_pirqs = nr_static_irqs + extra_dom0_irqs;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index cbbe8a4..34447f1 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -797,7 +797,14 @@ void watchdog_domain_destroy(struct domain *d);
  *    (that is, this would not be suitable for a driver domain)
  *  - There is never a reason to deny dom0 access to this
  */
-#define is_hardware_domain(_d) ((_d)->domain_id == 0)
+#define is_hardware_domain(_d) ((_d) == hardware_domain)
+
+/*
+ * Check for the hardware domain based on domain ID, not using the global
+ * hardware_domain variable.  This is necessary inside domain_create where
+ * hardware_domain is NULL and for some checks implementing CONFIG_LATE_HWDOM.
+ */
+#define is_hardware_domain_by_id(_d) ((_d)->domain_id == 0)
 
 /* This check is for functionality specific to a control domain */
 #define is_control_domain(_d) ((_d)->is_privileged)
-- 
1.9.0


[-- Attachment #3: 0007-xen-Allow-hardware-domain-dom0.patch --]
[-- Type: text/x-patch, Size: 11513 bytes --]

>From 1cb71b69284ce002c299ea3a3dfa061cad78e7f7 Mon Sep 17 00:00:00 2001
From: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Date: Fri, 6 May 2011 15:13:22 -0400
Subject: [PATCH RFC 7/8] xen: Allow hardware domain != dom0

This adds a hypervisor command line option "hardware_dom=" which takes a
domain ID.  When the domain with this ID is created, it will be used
as the hardware domain.

This is intended to be used when domain 0 is a dedicated stub domain for
domain building, allowing the hardware domain to be de-privileged and
act only as a driver domain.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Acked-by: Keir Fraser <keir@xen.org>
Cc: Jan Beulich <jbeulich@suse.com>
---
 docs/misc/xen-command-line.markdown | 10 +++++++++
 xen/arch/x86/domain_build.c         |  4 +++-
 xen/common/domain.c                 |  5 +++++
 xen/common/domctl.c                 | 41 +++++++++++++++++++++++++++++++++++++
 xen/common/rangeset.c               | 40 ++++++++++++++++++++++++++++++++++++
 xen/include/xen/rangeset.h          |  3 +++
 xen/include/xen/sched.h             | 10 +++++++--
 xen/include/xsm/dummy.h             |  6 ++++++
 xen/include/xsm/xsm.h               |  6 ++++++
 xen/xsm/dummy.c                     |  2 ++
 xen/xsm/flask/hooks.c               |  6 ++++++
 xen/xsm/flask/policy/access_vectors |  2 ++
 12 files changed, 132 insertions(+), 3 deletions(-)

diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 87de2dc..6f5064f 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -590,6 +590,16 @@ Paging (HAP).
 Flag to enable 2 MB host page table support for Hardware Assisted
 Paging (HAP).
 
+### hardware\_dom
+> `= <domid>`
+
+> Default: `0`
+
+Enable late hardware domain creation using the specified domain ID.  This is
+intended to be used when domain 0 is a stub domain which builds a disaggregated
+system including a hardware domain with the specified domain ID.  This option is
+supported only when compiled with CONFIG\_XSM on x86.
+
 ### hpetbroadcast
 > `= <boolean>`
 
diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index 08c40f8..1b61687 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -1150,7 +1150,9 @@ int __init construct_dom0(
         printk(" Xen warning: dom0 kernel broken ELF: %s\n",
                elf_check_broken(&elf));
 
-    iommu_hwdom_init(hardware_domain);
+    if ( is_hardware_domain_by_id(d) )
+        iommu_hwdom_init(d);
+
     return 0;
 
 out:
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 4036e69..2561236 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -61,6 +61,11 @@ struct domain *domain_list;
 
 struct domain *hardware_domain __read_mostly;
 
+#ifdef CONFIG_LATE_HWDOM
+domid_t hardware_domid __read_mostly;
+integer_param("hardware_dom", hardware_domid);
+#endif
+
 struct vcpu *idle_vcpu[NR_CPUS] __read_mostly;
 
 vcpu_info_t dummy_vcpu_info;
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index af3614b..c77fe99 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -472,6 +472,47 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             break;
         }
 
+#ifdef CONFIG_LATE_HWDOM
+        if ( is_hardware_domain_by_id(d) )
+        {
+            struct domain *dom0 = hardware_domain;
+            ASSERT(dom0->domain_id == 0);
+
+            ret = xsm_init_hardware_domain(XSM_HOOK, d);
+            if ( ret )
+            {
+                domain_kill(d);
+                d = NULL;
+                break;
+            }
+
+            printk("Initialising hardware domain %d\n", hardware_domid);
+            hardware_domain = d;
+
+            /*
+             * Hardware resource ranges for domain 0 have been set up from
+             * various sources intended to restrict the hardware domain's
+             * access.  Apply these ranges to the actual hardware domain.
+             *
+             * Because the lists are being swapped, a side effect of this
+             * operation is that Domain 0's rangesets are cleared.  Since
+             * domain 0 should not be accessing the hardware when it constructs
+             * a hardware domain, this should not be a problem.  Both lists
+             * may be modified after this hypercall returns if a more complex
+             * device model is desired.
+             *
+             * Since late hardware domain initialization is only supported on
+             * x86, the reference to arch.ioport_caps does not need its own
+             * preprocessor conditional.
+             */
+            rangeset_swap(d->irq_caps, dom0->irq_caps);
+            rangeset_swap(d->iomem_caps, dom0->iomem_caps);
+            rangeset_swap(d->arch.ioport_caps, dom0->arch.ioport_caps);
+
+            iommu_hwdom_init(d);
+        }
+#endif
+
         ret = 0;
 
         memcpy(d->handle, op->u.createdomain.handle,
diff --git a/xen/common/rangeset.c b/xen/common/rangeset.c
index f09c0c4..52fae1f 100644
--- a/xen/common/rangeset.c
+++ b/xen/common/rangeset.c
@@ -438,3 +438,43 @@ void rangeset_domain_printk(
 
     spin_unlock(&d->rangesets_lock);
 }
+
+void rangeset_swap(struct rangeset *a, struct rangeset *b)
+{
+    struct list_head tmp;
+    if (&a < &b)
+    {
+        spin_lock(&a->lock);
+        spin_lock(&b->lock);
+    }
+    else
+    {
+        spin_lock(&b->lock);
+        spin_lock(&a->lock);
+    }
+    memcpy(&tmp, &a->range_list, sizeof(tmp));
+    memcpy(&a->range_list, &b->range_list, sizeof(tmp));
+    memcpy(&b->range_list, &tmp, sizeof(tmp));
+    if ( a->range_list.next == &b->range_list )
+    {
+        a->range_list.next = &a->range_list;
+        a->range_list.prev = &a->range_list;
+    }
+    else
+    {
+        a->range_list.next->prev = &a->range_list;
+        a->range_list.prev->next = &a->range_list;
+    }
+    if ( b->range_list.next == &a->range_list )
+    {
+        b->range_list.next = &b->range_list;
+        b->range_list.prev = &b->range_list;
+    }
+    else
+    {
+        b->range_list.next->prev = &b->range_list;
+        b->range_list.prev->next = &b->range_list;
+    }
+    spin_unlock(&a->lock);
+    spin_unlock(&b->lock);
+}
diff --git a/xen/include/xen/rangeset.h b/xen/include/xen/rangeset.h
index 1e16a6b..805ebde 100644
--- a/xen/include/xen/rangeset.h
+++ b/xen/include/xen/rangeset.h
@@ -73,4 +73,7 @@ void rangeset_printk(
 void rangeset_domain_printk(
     struct domain *d);
 
+/* swap contents */
+void rangeset_swap(struct rangeset *a, struct rangeset *b);
+
 #endif /* __XEN_RANGESET_H__ */
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 34447f1..50937db 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -46,6 +46,12 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
 /* A global pointer to the hardware domain (usually DOM0). */
 extern struct domain *hardware_domain;
 
+#ifdef CONFIG_LATE_HWDOM
+extern domid_t hardware_domid;
+#else
+#define hardware_domid 0
+#endif
+
 #ifndef CONFIG_COMPAT
 #define BITS_PER_EVTCHN_WORD(d) BITS_PER_XEN_ULONG
 #else
@@ -795,7 +801,7 @@ void watchdog_domain_destroy(struct domain *d);
  * Use this check when the following are both true:
  *  - Using this feature or interface requires full access to the hardware
  *    (that is, this would not be suitable for a driver domain)
- *  - There is never a reason to deny dom0 access to this
+ *  - There is never a reason to deny the hardware domain access to this
  */
 #define is_hardware_domain(_d) ((_d) == hardware_domain)
 
@@ -804,7 +810,7 @@ void watchdog_domain_destroy(struct domain *d);
  * hardware_domain variable.  This is necessary inside domain_create where
  * hardware_domain is NULL and for some checks implementing CONFIG_LATE_HWDOM.
  */
-#define is_hardware_domain_by_id(_d) ((_d)->domain_id == 0)
+#define is_hardware_domain_by_id(_d) ((_d)->domain_id == hardware_domid)
 
 /* This check is for functionality specific to a control domain */
 #define is_control_domain(_d) ((_d)->is_privileged)
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index e722155..8ca1117 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -299,6 +299,12 @@ static XSM_INLINE char *xsm_show_security_evtchn(struct domain *d, const struct
     return NULL;
 }
 
+static XSM_INLINE int xsm_init_hardware_domain(XSM_DEFAULT_ARG struct domain *d)
+{
+    XSM_ASSERT_ACTION(XSM_HOOK);
+    return xsm_default_action(action, current->domain, d);
+}
+
 static XSM_INLINE int xsm_get_pod_target(XSM_DEFAULT_ARG struct domain *d)
 {
     XSM_ASSERT_ACTION(XSM_PRIV);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 2cd3a3b..ef1c584 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -82,6 +82,7 @@ struct xsm_operations {
     int (*alloc_security_evtchn) (struct evtchn *chn);
     void (*free_security_evtchn) (struct evtchn *chn);
     char *(*show_security_evtchn) (struct domain *d, const struct evtchn *chn);
+    int (*init_hardware_domain) (struct domain *d);
 
     int (*get_pod_target) (struct domain *d);
     int (*set_pod_target) (struct domain *d);
@@ -311,6 +312,11 @@ static inline char *xsm_show_security_evtchn (struct domain *d, const struct evt
     return xsm_ops->show_security_evtchn(d, chn);
 }
 
+static inline int xsm_init_hardware_domain (xsm_default_t def, struct domain *d)
+{
+    return xsm_ops->init_hardware_domain(d);
+}
+
 static inline int xsm_get_pod_target (xsm_default_t def, struct domain *d)
 {
     return xsm_ops->get_pod_target(d);
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index b79e10f..c2804f2 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -58,6 +58,8 @@ void xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, alloc_security_evtchn);
     set_to_dummy_if_null(ops, free_security_evtchn);
     set_to_dummy_if_null(ops, show_security_evtchn);
+    set_to_dummy_if_null(ops, init_hardware_domain);
+
     set_to_dummy_if_null(ops, get_pod_target);
     set_to_dummy_if_null(ops, set_pod_target);
 
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 4ce31c9..f1a4a2d 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -327,6 +327,11 @@ static char *flask_show_security_evtchn(struct domain *d, const struct evtchn *c
     return ctx;
 }
 
+static int flask_init_hardware_domain(struct domain *d)
+{
+    return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__CREATE_HARDWARE_DOMAIN);
+}
+
 static int flask_grant_mapref(struct domain *d1, struct domain *d2, 
                               uint32_t flags)
 {
@@ -1500,6 +1505,7 @@ static struct xsm_operations flask_ops = {
     .alloc_security_evtchn = flask_alloc_security_evtchn,
     .free_security_evtchn = flask_free_security_evtchn,
     .show_security_evtchn = flask_show_security_evtchn,
+    .init_hardware_domain = flask_init_hardware_domain,
 
     .get_pod_target = flask_get_pod_target,
     .set_pod_target = flask_set_pod_target,
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index a0ed13d..32371a9 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -198,6 +198,8 @@ class domain2
     set_max_evtchn
 # XEN_DOMCTL_cacheflush
     cacheflush
+# Creation of the hardware domain when it is not dom0
+    create_hardware_domain
 }
 
 # Similar to class domain, but primarily contains domctls related to HVM domains
-- 
1.9.0


[-- Attachment #4: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/7] xen: Allow hardare domain != dom0
  2014-04-11 18:22         ` Daniel De Graaf
@ 2014-04-14  7:56           ` Jan Beulich
  2014-04-14 20:12             ` Daniel De Graaf
  0 siblings, 1 reply; 26+ messages in thread
From: Jan Beulich @ 2014-04-14  7:56 UTC (permalink / raw)
  To: Daniel De Graaf; +Cc: Keir Fraser, xen-devel

>>> On 11.04.14 at 20:22, <dgdegra@tycho.nsa.gov> wrote:
> On 04/11/2014 11:20 AM, Jan Beulich wrote:
>>>>> On 11.04.14 at 17:07, <dgdegra@tycho.nsa.gov> wrote:
>>> On 04/11/2014 05:13 AM, Jan Beulich wrote:
>>> Otherwise, I think the is_hardware_domain definition should be:
>>>
>>> #ifdef CONFIG_LATE_HWDOM
>>> #define is_hardware_domain(_d) ((_d)->domain_id == hardware_domid)
>>> #else
>>> #define is_hardware_domain(_d) ((_d)->domain_id == 0)
>>> #endif
>>>
>>> This also allows hardware_domid to be declared inside the #ifdef.
>>
>> But that still wouldn't necessarily do the correct thing for any use of
>> the macro before that new special case code in domain_create() got
>> run. Maybe my thinking of this is wrong, but as I tried to state above,
>> I would expect Dom0 to be the hardware domain up to the point
>> where the intended hardware domain gets created, at which point all
>> state Dom0 obtained because of having been the de-facto hardware
>> domain get transferred to hardware_domain.
> 
> I agree with this in most cases, and I think the few places where that
> is not true should be changed to make them more explicit.  This must
> include all checks in domain_create and those in functions called from
> domain_create, because (d == hardware_domain) is always false inside
> domain_create.  An initial version of this patch is below, but unless
> there are objections I plan to integrate it into patch 1 to avoid doing
> (d->domain_id == 0) => is_hardware_domain => is_hardware_domain_by_id
> for the ARM code.

Integration into any earlier patch would work only if we reverted
what was already applied.

> ------------------------------>8------------------------
> 
> Subject: [PATCH RFC 6/8] xen: introduce is_hardware_domain_by_id

Certainly not very nice a name, and also not very nice to then have
two ways to check, which likely people will not always distinguish
properly. I think this needs some better idea, albeit I can't immediately
offer one.

Jan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/7] xen: Allow hardare domain != dom0
  2014-04-14  7:56           ` Jan Beulich
@ 2014-04-14 20:12             ` Daniel De Graaf
  0 siblings, 0 replies; 26+ messages in thread
From: Daniel De Graaf @ 2014-04-14 20:12 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Keir Fraser, xen-devel

On 04/14/2014 03:56 AM, Jan Beulich wrote:
>>>> On 11.04.14 at 20:22, <dgdegra@tycho.nsa.gov> wrote:
>> On 04/11/2014 11:20 AM, Jan Beulich wrote:
>>>>>> On 11.04.14 at 17:07, <dgdegra@tycho.nsa.gov> wrote:
>>>> On 04/11/2014 05:13 AM, Jan Beulich wrote:
>>>> Otherwise, I think the is_hardware_domain definition should be:
>>>>
>>>> #ifdef CONFIG_LATE_HWDOM
>>>> #define is_hardware_domain(_d) ((_d)->domain_id == hardware_domid)
>>>> #else
>>>> #define is_hardware_domain(_d) ((_d)->domain_id == 0)
>>>> #endif
>>>>
>>>> This also allows hardware_domid to be declared inside the #ifdef.
>>>
>>> But that still wouldn't necessarily do the correct thing for any use of
>>> the macro before that new special case code in domain_create() got
>>> run. Maybe my thinking of this is wrong, but as I tried to state above,
>>> I would expect Dom0 to be the hardware domain up to the point
>>> where the intended hardware domain gets created, at which point all
>>> state Dom0 obtained because of having been the de-facto hardware
>>> domain get transferred to hardware_domain.
>>
>> I agree with this in most cases, and I think the few places where that
>> is not true should be changed to make them more explicit.  This must
>> include all checks in domain_create and those in functions called from
>> domain_create, because (d == hardware_domain) is always false inside
>> domain_create.  An initial version of this patch is below, but unless
>> there are objections I plan to integrate it into patch 1 to avoid doing
>> (d->domain_id == 0) => is_hardware_domain => is_hardware_domain_by_id
>> for the ARM code.
>
> Integration into any earlier patch would work only if we reverted
> what was already applied.

Ah, I didn't see that part of the series was applied.  Anyway, I didn't
really like how far the full version (larger than the RFC below) ended up
having to propagate the _by_id version, so a different solution would be
better.

>> ------------------------------>8------------------------
>>
>> Subject: [PATCH RFC 6/8] xen: introduce is_hardware_domain_by_id
>
> Certainly not very nice a name, and also not very nice to then have
> two ways to check, which likely people will not always distinguish
> properly. I think this needs some better idea, albeit I can't immediately
> offer one.
>
> Jan

If the assignment to hardware_domain is moved into domain_create, this
makes the (d == hardware_domain) version of is_hardware_domain work as
expected, and removes the need for is_hardware_domain_by_id.  This also
makes the initialization look a bit cleaner; the patch will be posted
momentarily.

-- 
Daniel De Graaf
National Security Agency

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/7] xen: Allow hardare domain != dom0
  2014-03-18 21:34 ` [PATCH 6/7] xen: Allow hardare domain != dom0 Daniel De Graaf
@ 2014-03-19  9:15   ` Jan Beulich
  0 siblings, 0 replies; 26+ messages in thread
From: Jan Beulich @ 2014-03-19  9:15 UTC (permalink / raw)
  To: Daniel De Graaf; +Cc: Keir Fraser, xen-devel

>>> On 18.03.14 at 22:34, Daniel De Graaf <dgdegra@tycho.nsa.gov> wrote:
> This adds a hypervisor command line option "hardware_dom=" which takes a
> domain ID.  When the domain with this ID is created, it will be used
> as the hardware domain.
> 
> This is intended to be used when domain 0 is a dedicated stub domain for
> domain building, allowing the hardware domain to be de-privileged and
> act only as a driver domain.
> 
> Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Cc: Keir Fraser <keir@xen.org>

Reviewed-by: Jan Beulich <jbeulich@suse.com>

(assuming the LATE_HWDOM_ENABLE -> CONFIG_LATE_HWDOM
will get done)

> ---
>  xen/arch/x86/domain_build.c         |  4 +++-
>  xen/arch/x86/setup.c                |  2 ++
>  xen/common/domain.c                 |  3 ++-
>  xen/common/domctl.c                 | 40 +++++++++++++++++++++++++++++++++++++
>  xen/common/rangeset.c               | 40 +++++++++++++++++++++++++++++++++++++
>  xen/include/xen/rangeset.h          |  3 +++
>  xen/include/xen/sched.h             |  3 ++-
>  xen/include/xsm/dummy.h             |  6 ++++++
>  xen/include/xsm/xsm.h               |  6 ++++++
>  xen/xsm/dummy.c                     |  2 ++
>  xen/xsm/flask/hooks.c               |  6 ++++++
>  xen/xsm/flask/policy/access_vectors |  2 ++
>  12 files changed, 114 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
> index f75f6e7..a554d3b 100644
> --- a/xen/arch/x86/domain_build.c
> +++ b/xen/arch/x86/domain_build.c
> @@ -1150,7 +1150,9 @@ int __init construct_dom0(
>          printk(" Xen warning: dom0 kernel broken ELF: %s\n",
>                 elf_check_broken(&elf));
>  
> -    iommu_hwdom_init(hardware_domain);
> +    if ( is_hardware_domain(d) )
> +        iommu_hwdom_init(d);
> +
>      return 0;
>  
>  out:
> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index 75cf212..f246ac3 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -84,6 +84,8 @@ unsigned long __initdata highmem_start;
>  size_param("highmem-start", highmem_start);
>  #endif
>  
> +integer_param("hardware_dom", hardware_domid);
> +
>  cpumask_t __read_mostly cpu_present_map;
>  
>  unsigned long __read_mostly xen_phys_start;
> diff --git a/xen/common/domain.c b/xen/common/domain.c
> index c8414ed..a77f8af 100644
> --- a/xen/common/domain.c
> +++ b/xen/common/domain.c
> @@ -59,7 +59,8 @@ DEFINE_RCU_READ_LOCK(domlist_read_lock);
>  static struct domain *domain_hash[DOMAIN_HASH_SIZE];
>  struct domain *domain_list;
>  
> -struct domain *hardware_domain;
> +struct domain *hardware_domain __read_mostly;
> +domid_t hardware_domid __read_mostly;
>  
>  struct vcpu *idle_vcpu[NR_CPUS] __read_mostly;
>  
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index eebeee7..9af24bf 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -472,6 +472,46 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) 
> u_domctl)
>              break;
>          }
>  
> +        /*
> +         * Late initialization of the hardware domain is only supported on 
> x86,
> +         * so only check for it there.
> +         */
> +#ifdef LATE_HWDOM_ENABLE
> +        if ( is_hardware_domain(d) )
> +        {
> +            struct domain *dom0 = hardware_domain;
> +            ASSERT(dom0->domain_id == 0);
> +
> +            ret = xsm_init_hardware_domain(XSM_HOOK, d);
> +            if ( ret )
> +            {
> +                domain_kill(d);
> +                d = NULL;
> +                break;
> +            }
> +
> +            printk("Initialising hardware domain %d\n", hardware_domid);
> +            hardware_domain = d;
> +
> +            /* Hardware resource ranges for domain 0 have been set up from
> +             * various sources intended to restrict the hardware domain's
> +             * access. Apply these ranges to the actual hardware domain.
> +             *
> +             * Because the lists are being swapped, a side effect of this
> +             * operation is that Domain 0's rangesets are cleared. Since 
> domain
> +             * 0 should not be accessing the hardware when it constructs a
> +             * hardware domain, this should not be a problem. Both lists 
> should
> +             * be modified after this hypercall returns if a more complex
> +             * device model is desired.
> +             */
> +            rangeset_swap(d->irq_caps, dom0->irq_caps);
> +            rangeset_swap(d->iomem_caps, dom0->iomem_caps);
> +            rangeset_swap(d->arch.ioport_caps, dom0->arch.ioport_caps);
> +
> +            iommu_hwdom_init(d);
> +        }
> +#endif
> +
>          ret = 0;
>  
>          memcpy(d->handle, op->u.createdomain.handle,
> diff --git a/xen/common/rangeset.c b/xen/common/rangeset.c
> index f09c0c4..52fae1f 100644
> --- a/xen/common/rangeset.c
> +++ b/xen/common/rangeset.c
> @@ -438,3 +438,43 @@ void rangeset_domain_printk(
>  
>      spin_unlock(&d->rangesets_lock);
>  }
> +
> +void rangeset_swap(struct rangeset *a, struct rangeset *b)
> +{
> +    struct list_head tmp;
> +    if ( &a < &b )
> +    {
> +        spin_lock(&a->lock);
> +        spin_lock(&b->lock);
> +    }
> +    else
> +    {
> +        spin_lock(&b->lock);
> +        spin_lock(&a->lock);
> +    }
> +    memcpy(&tmp, &a->range_list, sizeof(tmp));
> +    memcpy(&a->range_list, &b->range_list, sizeof(tmp));
> +    memcpy(&b->range_list, &tmp, sizeof(tmp));
> +    if ( a->range_list.next == &b->range_list )
> +    {
> +        a->range_list.next = &a->range_list;
> +        a->range_list.prev = &a->range_list;
> +    }
> +    else
> +    {
> +        a->range_list.next->prev = &a->range_list;
> +        a->range_list.prev->next = &a->range_list;
> +    }
> +    if ( b->range_list.next == &a->range_list )
> +    {
> +        b->range_list.next = &b->range_list;
> +        b->range_list.prev = &b->range_list;
> +    }
> +    else
> +    {
> +        b->range_list.next->prev = &b->range_list;
> +        b->range_list.prev->next = &b->range_list;
> +    }
> +    spin_unlock(&a->lock);
> +    spin_unlock(&b->lock);
> +}
> diff --git a/xen/include/xen/rangeset.h b/xen/include/xen/rangeset.h
> index 1e16a6b..805ebde 100644
> --- a/xen/include/xen/rangeset.h
> +++ b/xen/include/xen/rangeset.h
> @@ -73,4 +73,7 @@ void rangeset_printk(
>  void rangeset_domain_printk(
>      struct domain *d);
>  
> +/* swap contents */
> +void rangeset_swap(struct rangeset *a, struct rangeset *b);
> +
>  #endif /* __XEN_RANGESET_H__ */
> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
> index 146514d..ce37c77 100644
> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -45,6 +45,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
>  
>  /* A global pointer to the hardware domain (usually DOM0). */
>  extern struct domain *hardware_domain;
> +extern domid_t hardware_domid;
>  
>  #ifndef CONFIG_COMPAT
>  #define BITS_PER_EVTCHN_WORD(d) BITS_PER_XEN_ULONG
> @@ -778,7 +779,7 @@ void watchdog_domain_destroy(struct domain *d);
>   *    (that is, this would not be suitable for a driver domain)
>   *  - There is never a reason to deny dom0 access to this
>   */
> -#define is_hardware_domain(_d) ((_d)->domain_id == 0)
> +#define is_hardware_domain(d)  ((d)->domain_id == hardware_domid)
>  
>  /* This check is for functionality specific to a control domain */
>  #define is_control_domain(_d) ((_d)->is_privileged)
> diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
> index 3bcd941..180cc88 100644
> --- a/xen/include/xsm/dummy.h
> +++ b/xen/include/xsm/dummy.h
> @@ -305,6 +305,12 @@ static XSM_INLINE char *xsm_show_security_evtchn(struct 
> domain *d, const struct
>      return NULL;
>  }
>  
> +static XSM_INLINE int xsm_init_hardware_domain(XSM_DEFAULT_ARG struct 
> domain *d)
> +{
> +    XSM_ASSERT_ACTION(XSM_HOOK);
> +    return xsm_default_action(action, current->domain, d);
> +}
> +
>  static XSM_INLINE int xsm_get_pod_target(XSM_DEFAULT_ARG struct domain *d)
>  {
>      XSM_ASSERT_ACTION(XSM_PRIV);
> diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
> index de9cf86..6ab9ed1 100644
> --- a/xen/include/xsm/xsm.h
> +++ b/xen/include/xsm/xsm.h
> @@ -83,6 +83,7 @@ struct xsm_operations {
>      int (*alloc_security_evtchn) (struct evtchn *chn);
>      void (*free_security_evtchn) (struct evtchn *chn);
>      char *(*show_security_evtchn) (struct domain *d, const struct evtchn 
> *chn);
> +    int (*init_hardware_domain) (struct domain *d);
>  
>      int (*get_pod_target) (struct domain *d);
>      int (*set_pod_target) (struct domain *d);
> @@ -314,6 +315,11 @@ static inline char *xsm_show_security_evtchn (struct 
> domain *d, const struct evt
>      return xsm_ops->show_security_evtchn(d, chn);
>  }
>  
> +static inline int xsm_init_hardware_domain (xsm_default_t def, struct 
> domain *d)
> +{
> +    return xsm_ops->init_hardware_domain(d);
> +}
> +
>  static inline int xsm_get_pod_target (xsm_default_t def, struct domain *d)
>  {
>      return xsm_ops->get_pod_target(d);
> diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
> index 3fe4c59..689af3d 100644
> --- a/xen/xsm/dummy.c
> +++ b/xen/xsm/dummy.c
> @@ -59,6 +59,8 @@ void xsm_fixup_ops (struct xsm_operations *ops)
>      set_to_dummy_if_null(ops, alloc_security_evtchn);
>      set_to_dummy_if_null(ops, free_security_evtchn);
>      set_to_dummy_if_null(ops, show_security_evtchn);
> +    set_to_dummy_if_null(ops, init_hardware_domain);
> +
>      set_to_dummy_if_null(ops, get_pod_target);
>      set_to_dummy_if_null(ops, set_pod_target);
>  
> diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
> index 96276ac..5b906d6 100644
> --- a/xen/xsm/flask/hooks.c
> +++ b/xen/xsm/flask/hooks.c
> @@ -344,6 +344,11 @@ static char *flask_show_security_evtchn(struct domain 
> *d, const struct evtchn *c
>      return ctx;
>  }
>  
> +static int flask_init_hardware_domain(struct domain *d)
> +{
> +    return current_has_perm(d, SECCLASS_DOMAIN2, 
> DOMAIN2__CREATE_HARDWARE_DOMAIN);
> +}
> +
>  static int flask_grant_mapref(struct domain *d1, struct domain *d2, 
>                                uint32_t flags)
>  {
> @@ -1491,6 +1496,7 @@ static struct xsm_operations flask_ops = {
>      .alloc_security_evtchn = flask_alloc_security_evtchn,
>      .free_security_evtchn = flask_free_security_evtchn,
>      .show_security_evtchn = flask_show_security_evtchn,
> +    .init_hardware_domain = flask_init_hardware_domain,
>  
>      .get_pod_target = flask_get_pod_target,
>      .set_pod_target = flask_set_pod_target,
> diff --git a/xen/xsm/flask/policy/access_vectors 
> b/xen/xsm/flask/policy/access_vectors
> index a0ed13d..32371a9 100644
> --- a/xen/xsm/flask/policy/access_vectors
> +++ b/xen/xsm/flask/policy/access_vectors
> @@ -198,6 +198,8 @@ class domain2
>      set_max_evtchn
>  # XEN_DOMCTL_cacheflush
>      cacheflush
> +# Creation of the hardware domain when it is not dom0
> +    create_hardware_domain
>  }
>  
>  # Similar to class domain, but primarily contains domctls related to HVM 
> domains
> -- 
> 1.8.5.3

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 6/7] xen: Allow hardare domain != dom0
  2014-03-18 21:34 [PATCH v2 " Daniel De Graaf
@ 2014-03-18 21:34 ` Daniel De Graaf
  2014-03-19  9:15   ` Jan Beulich
  0 siblings, 1 reply; 26+ messages in thread
From: Daniel De Graaf @ 2014-03-18 21:34 UTC (permalink / raw)
  To: xen-devel; +Cc: Daniel De Graaf, Keir Fraser, Jan Beulich

This adds a hypervisor command line option "hardware_dom=" which takes a
domain ID.  When the domain with this ID is created, it will be used
as the hardware domain.

This is intended to be used when domain 0 is a dedicated stub domain for
domain building, allowing the hardware domain to be de-privileged and
act only as a driver domain.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Cc: Keir Fraser <keir@xen.org>
Cc: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/domain_build.c         |  4 +++-
 xen/arch/x86/setup.c                |  2 ++
 xen/common/domain.c                 |  3 ++-
 xen/common/domctl.c                 | 40 +++++++++++++++++++++++++++++++++++++
 xen/common/rangeset.c               | 40 +++++++++++++++++++++++++++++++++++++
 xen/include/xen/rangeset.h          |  3 +++
 xen/include/xen/sched.h             |  3 ++-
 xen/include/xsm/dummy.h             |  6 ++++++
 xen/include/xsm/xsm.h               |  6 ++++++
 xen/xsm/dummy.c                     |  2 ++
 xen/xsm/flask/hooks.c               |  6 ++++++
 xen/xsm/flask/policy/access_vectors |  2 ++
 12 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index f75f6e7..a554d3b 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -1150,7 +1150,9 @@ int __init construct_dom0(
         printk(" Xen warning: dom0 kernel broken ELF: %s\n",
                elf_check_broken(&elf));
 
-    iommu_hwdom_init(hardware_domain);
+    if ( is_hardware_domain(d) )
+        iommu_hwdom_init(d);
+
     return 0;
 
 out:
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 75cf212..f246ac3 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -84,6 +84,8 @@ unsigned long __initdata highmem_start;
 size_param("highmem-start", highmem_start);
 #endif
 
+integer_param("hardware_dom", hardware_domid);
+
 cpumask_t __read_mostly cpu_present_map;
 
 unsigned long __read_mostly xen_phys_start;
diff --git a/xen/common/domain.c b/xen/common/domain.c
index c8414ed..a77f8af 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -59,7 +59,8 @@ DEFINE_RCU_READ_LOCK(domlist_read_lock);
 static struct domain *domain_hash[DOMAIN_HASH_SIZE];
 struct domain *domain_list;
 
-struct domain *hardware_domain;
+struct domain *hardware_domain __read_mostly;
+domid_t hardware_domid __read_mostly;
 
 struct vcpu *idle_vcpu[NR_CPUS] __read_mostly;
 
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index eebeee7..9af24bf 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -472,6 +472,46 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             break;
         }
 
+        /*
+         * Late initialization of the hardware domain is only supported on x86,
+         * so only check for it there.
+         */
+#ifdef LATE_HWDOM_ENABLE
+        if ( is_hardware_domain(d) )
+        {
+            struct domain *dom0 = hardware_domain;
+            ASSERT(dom0->domain_id == 0);
+
+            ret = xsm_init_hardware_domain(XSM_HOOK, d);
+            if ( ret )
+            {
+                domain_kill(d);
+                d = NULL;
+                break;
+            }
+
+            printk("Initialising hardware domain %d\n", hardware_domid);
+            hardware_domain = d;
+
+            /* Hardware resource ranges for domain 0 have been set up from
+             * various sources intended to restrict the hardware domain's
+             * access. Apply these ranges to the actual hardware domain.
+             *
+             * Because the lists are being swapped, a side effect of this
+             * operation is that Domain 0's rangesets are cleared. Since domain
+             * 0 should not be accessing the hardware when it constructs a
+             * hardware domain, this should not be a problem. Both lists should
+             * be modified after this hypercall returns if a more complex
+             * device model is desired.
+             */
+            rangeset_swap(d->irq_caps, dom0->irq_caps);
+            rangeset_swap(d->iomem_caps, dom0->iomem_caps);
+            rangeset_swap(d->arch.ioport_caps, dom0->arch.ioport_caps);
+
+            iommu_hwdom_init(d);
+        }
+#endif
+
         ret = 0;
 
         memcpy(d->handle, op->u.createdomain.handle,
diff --git a/xen/common/rangeset.c b/xen/common/rangeset.c
index f09c0c4..52fae1f 100644
--- a/xen/common/rangeset.c
+++ b/xen/common/rangeset.c
@@ -438,3 +438,43 @@ void rangeset_domain_printk(
 
     spin_unlock(&d->rangesets_lock);
 }
+
+void rangeset_swap(struct rangeset *a, struct rangeset *b)
+{
+    struct list_head tmp;
+    if ( &a < &b )
+    {
+        spin_lock(&a->lock);
+        spin_lock(&b->lock);
+    }
+    else
+    {
+        spin_lock(&b->lock);
+        spin_lock(&a->lock);
+    }
+    memcpy(&tmp, &a->range_list, sizeof(tmp));
+    memcpy(&a->range_list, &b->range_list, sizeof(tmp));
+    memcpy(&b->range_list, &tmp, sizeof(tmp));
+    if ( a->range_list.next == &b->range_list )
+    {
+        a->range_list.next = &a->range_list;
+        a->range_list.prev = &a->range_list;
+    }
+    else
+    {
+        a->range_list.next->prev = &a->range_list;
+        a->range_list.prev->next = &a->range_list;
+    }
+    if ( b->range_list.next == &a->range_list )
+    {
+        b->range_list.next = &b->range_list;
+        b->range_list.prev = &b->range_list;
+    }
+    else
+    {
+        b->range_list.next->prev = &b->range_list;
+        b->range_list.prev->next = &b->range_list;
+    }
+    spin_unlock(&a->lock);
+    spin_unlock(&b->lock);
+}
diff --git a/xen/include/xen/rangeset.h b/xen/include/xen/rangeset.h
index 1e16a6b..805ebde 100644
--- a/xen/include/xen/rangeset.h
+++ b/xen/include/xen/rangeset.h
@@ -73,4 +73,7 @@ void rangeset_printk(
 void rangeset_domain_printk(
     struct domain *d);
 
+/* swap contents */
+void rangeset_swap(struct rangeset *a, struct rangeset *b);
+
 #endif /* __XEN_RANGESET_H__ */
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 146514d..ce37c77 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -45,6 +45,7 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
 
 /* A global pointer to the hardware domain (usually DOM0). */
 extern struct domain *hardware_domain;
+extern domid_t hardware_domid;
 
 #ifndef CONFIG_COMPAT
 #define BITS_PER_EVTCHN_WORD(d) BITS_PER_XEN_ULONG
@@ -778,7 +779,7 @@ void watchdog_domain_destroy(struct domain *d);
  *    (that is, this would not be suitable for a driver domain)
  *  - There is never a reason to deny dom0 access to this
  */
-#define is_hardware_domain(_d) ((_d)->domain_id == 0)
+#define is_hardware_domain(d)  ((d)->domain_id == hardware_domid)
 
 /* This check is for functionality specific to a control domain */
 #define is_control_domain(_d) ((_d)->is_privileged)
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 3bcd941..180cc88 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -305,6 +305,12 @@ static XSM_INLINE char *xsm_show_security_evtchn(struct domain *d, const struct
     return NULL;
 }
 
+static XSM_INLINE int xsm_init_hardware_domain(XSM_DEFAULT_ARG struct domain *d)
+{
+    XSM_ASSERT_ACTION(XSM_HOOK);
+    return xsm_default_action(action, current->domain, d);
+}
+
 static XSM_INLINE int xsm_get_pod_target(XSM_DEFAULT_ARG struct domain *d)
 {
     XSM_ASSERT_ACTION(XSM_PRIV);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index de9cf86..6ab9ed1 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -83,6 +83,7 @@ struct xsm_operations {
     int (*alloc_security_evtchn) (struct evtchn *chn);
     void (*free_security_evtchn) (struct evtchn *chn);
     char *(*show_security_evtchn) (struct domain *d, const struct evtchn *chn);
+    int (*init_hardware_domain) (struct domain *d);
 
     int (*get_pod_target) (struct domain *d);
     int (*set_pod_target) (struct domain *d);
@@ -314,6 +315,11 @@ static inline char *xsm_show_security_evtchn (struct domain *d, const struct evt
     return xsm_ops->show_security_evtchn(d, chn);
 }
 
+static inline int xsm_init_hardware_domain (xsm_default_t def, struct domain *d)
+{
+    return xsm_ops->init_hardware_domain(d);
+}
+
 static inline int xsm_get_pod_target (xsm_default_t def, struct domain *d)
 {
     return xsm_ops->get_pod_target(d);
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 3fe4c59..689af3d 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -59,6 +59,8 @@ void xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, alloc_security_evtchn);
     set_to_dummy_if_null(ops, free_security_evtchn);
     set_to_dummy_if_null(ops, show_security_evtchn);
+    set_to_dummy_if_null(ops, init_hardware_domain);
+
     set_to_dummy_if_null(ops, get_pod_target);
     set_to_dummy_if_null(ops, set_pod_target);
 
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 96276ac..5b906d6 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -344,6 +344,11 @@ static char *flask_show_security_evtchn(struct domain *d, const struct evtchn *c
     return ctx;
 }
 
+static int flask_init_hardware_domain(struct domain *d)
+{
+    return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__CREATE_HARDWARE_DOMAIN);
+}
+
 static int flask_grant_mapref(struct domain *d1, struct domain *d2, 
                               uint32_t flags)
 {
@@ -1491,6 +1496,7 @@ static struct xsm_operations flask_ops = {
     .alloc_security_evtchn = flask_alloc_security_evtchn,
     .free_security_evtchn = flask_free_security_evtchn,
     .show_security_evtchn = flask_show_security_evtchn,
+    .init_hardware_domain = flask_init_hardware_domain,
 
     .get_pod_target = flask_get_pod_target,
     .set_pod_target = flask_set_pod_target,
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index a0ed13d..32371a9 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -198,6 +198,8 @@ class domain2
     set_max_evtchn
 # XEN_DOMCTL_cacheflush
     cacheflush
+# Creation of the hardware domain when it is not dom0
+    create_hardware_domain
 }
 
 # Similar to class domain, but primarily contains domctls related to HVM domains
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2014-04-14 20:12 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-27 11:52 [PATCH v3 0/7] xen: Hardware domain support Daniel De Graaf
2014-03-27 11:52 ` [PATCH 1/7] xen: use domid check in is_hardware_domain Daniel De Graaf
2014-03-27 15:31   ` Ian Campbell
2014-03-27 11:52 ` [PATCH 2/7] xen/iommu: Move dom0 setup code to __hwdom_init Daniel De Graaf
2014-03-27 11:52 ` [PATCH 3/7] xen: prevent 0 from being used as a dynamic domid Daniel De Graaf
2014-03-27 11:52 ` [PATCH 4/7] xen: rename dom0 to hardware_domain Daniel De Graaf
2014-03-27 12:20   ` Egger, Christoph
2014-03-27 12:48     ` Daniel De Graaf
2014-03-27 15:46       ` Egger, Christoph
2014-03-27 15:33   ` Ian Campbell
2014-03-27 11:52 ` [PATCH 5/7] xen: rename various functions referencing dom0 Daniel De Graaf
2014-03-27 15:34   ` Ian Campbell
2014-03-27 15:47     ` Daniel De Graaf
2014-03-27 11:52 ` [PATCH 6/7] xen: Allow hardare domain != dom0 Daniel De Graaf
2014-04-11  9:13   ` Jan Beulich
2014-04-11 15:07     ` Daniel De Graaf
2014-04-11 15:20       ` Jan Beulich
2014-04-11 18:22         ` Daniel De Graaf
2014-04-14  7:56           ` Jan Beulich
2014-04-14 20:12             ` Daniel De Graaf
2014-03-27 11:52 ` [PATCH 7/7] tools/libxl: Allow dom0 to be destroyed Daniel De Graaf
2014-03-27 15:35   ` Ian Campbell
2014-04-02 15:08     ` Ian Jackson
2014-04-10 15:58 ` [PATCH v3 0/7] xen: Hardware domain support Keir Fraser
  -- strict thread matches above, loose matches on Subject: below --
2014-03-18 21:34 [PATCH v2 " Daniel De Graaf
2014-03-18 21:34 ` [PATCH 6/7] xen: Allow hardare domain != dom0 Daniel De Graaf
2014-03-19  9:15   ` Jan Beulich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.