All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough
@ 2015-01-13 14:25 Julien Grall
  2015-01-13 14:25 ` [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration Julien Grall
                   ` (25 more replies)
  0 siblings, 26 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.campbell, manish.jaggi, Julien Grall, tim,
	stefano.stabellini, suravee.suthikulpanit, andrii.tseglytskyi

Hello all,

This is the third version of this patch series to add support for platform
device passthrough on ARM.

Compare to the previous version [1], the automatic mapping of MMIO/IRQ and
the generation of the device tree has been dropped.

Instead the user will have to:
    - Map manually MMIO/IRQ
    - Describe the device in the newly partial device tree support
    - Specify the list of device protected by an IOMMU to assign to the
    guest.

While this solution is primitive, this is allow us to support more complex
device in Xen with an little additionnal work for the user. Attempting to
do it automatically is more difficult because we may not know the dependencies
between devices (for instance a Network card and a phy).

To avoid adding code in DOM0 to manage platform device deassignment, the
user has to add the property "xen,passthrough" to the device tree node
describing the device. This can be easily done via U-Boot. For instance,
if we want to passthrough the second network card of a Midway server to the
guest. The user will have to add the following line the u-boot script:

    fdt set /soc/ethernet@fff51000 xen,passthrough

This series has been tested on Midway by assigning the secondary network card
to a guest (see instruction below). I plan to do futher testing on other
boards.

There is some TODO, mostly related to XSM in different patches (see commit
message or /* TODO: ... */ in the files).

This series is based on my series "Find automatically a PPI for DOM0 event
channel IRQ" [2] and "xen/arm: Resync the SMMU driver with the Linux one" [3].
A working tree can be found here:
    git://xenbits.xen.org/julieng/xen-unstable.git branch passthrough-v3

Major changes in v3:
    - Rework the approach to passthrough a device (xen,passthrough +
      partial device tree).
    - Extend the existing hypercalls to assign/deassign device rather than
    adding new one.
    - Merge series [4] and [5] in this serie.

Major changes in v2:
     - Drop the patch #1 of the previous version
     - Virtual IRQ are not anymore equal to the physical interrupt
     - Move the hypercall to get DT informations for privcmd to domctl
     - Split the domain creation in 2 two parts to allow per guest
     VGIC configuration (such as the number of SPIs).
     - Bunch of typoes, commit improvement, function renaming.

For all changes see in each patch.

I believe, it's better to have a basic support in Xen rather than nothing.
This could be improved later.

Sincerely yours,

[1] http://lists.xen.org/archives/html/xen-devel/2014-07/msg04090.html
[2] http://lists.xenproject.org/archives/html/xen-devel/2014-12/msg01386.html
[3] http://lists.xenproject.org/archives/html/xen-devel/2014-12/msg01612.html
[4] http://lists.xen.org/archives/html/xen-devel/2014-11/msg01672.html
[5] http://lists.xenproject.org/archives/html/xen-devel/2014-07/msg02098.html

=========================================================================

Instructions to passthrough a non-PCI device

The example will use the secondary network card for the midway server.

1) Mark the device to let Xen knowns the device will be used for passthrough.
This is done in the device tree node describing the device by adding the
property "xen,passthrough". The command to do it in U-Boot is:

    fdt set /soc/ethernet@fff51000 xen,passthrough

2) Create the partial device tree describing the device. The IRQ are mapped
1:1 to the guest (i.e VIRQ == IRQ). For MMIO will have to find hole in the
guest memory layout (see xen/include/public/arch-arm.h, noted the layout
is not stable and can change between 2 releases version of Xen).

/dts-v1/;

/ {
    #address-cells = <2>;
    #size-cells = <2>;

    aliases {
        net = &mac0;
    };

    passthrough {
        compatible = "simple-bus";
        ranges;
        #address-cells = <2>;
        #size-cells = <2>;
    	mac0: ethernet@10000000 {
	    	compatible = "calxeda,hb-xgmac";
            reg = <0 0x10000000 0 0x1000>;
    		interrupts = <0 80 4  0 81 4  0 82 4>;
            /* dma-coherent can't be set because it requires platform
             * specific code for highbank
             */
/*	    	dma-coherent; */
    	};

        foo {
            my = <&mac0>;
        };
    };
};

3) Compile the partial guest device with dtc (Device Tree Compiler).
For our purpose, the compiled file will be called guest-midway.dtb and
placed in /root in DOM0.

3) Add the following options in the guest configuration file:

device_tree = "/root/guest-midway.dtb"
dtdev = [ "/soc/ethernet@fff51000" ]
irqs = [ 112, 113, 114 ]
iomem = [ "0xfff51,1@0x10000" ]

Cc: manish.jaggi@caviumnetworks.com
Cc: suravee.suthikulpanit@amd.com
Cc: andrii.tseglytskyi@globallogic.com

Julien Grall (24):
  xen: Extend DOMCTL createdomain to support arch configuration
  xen/arm: Divide GIC initialization in 2 parts
  xen/dts: Allow only IRQ translation that are mapped to main GIC
  xen: guestcopy: Provide an helper to safely copy string from guest
  xen/arm: vgic: Introduce a function to initialize pending_irq
  xen/arm: Map disabled device in DOM0
  xen/arm: Introduce xen,passthrough property
  xen/arm: Allow virq != irq
  xen/arm: route_irq_to_guest: Check validity of the IRQ
  xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  xen/arm: Let the toolstack configure the number of SPIs
  xen/arm: Release IRQ routed to a domain when it's destroying
  xen/arm: Implement hypercall PHYSDEVOP_{,un}map_pirq
  xen/dts: Use unsigned int for MMIO and IRQ index
  xen/dts: Provide an helper to get a DT node from a path provided by a
    guest
  xen/passthrough: Introduce iommu_construct
  xen/passthrough: arm: release earlier the DT devices assigned to a
    guest
  xen/passthrough: iommu_deassign_device_dt: By default reassign device
    to nobody
  xen/iommu: arm: Wire iommu DOMCTL for ARM
  xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  tools/(lib)xl: Add partial device tree support for ARM
  tools/libxl: arm: Use an higher value for the GIC phandle
  libxl: Add support for non-PCI passthrough
  xl: Add new option dtdev

 docs/man/xl.cfg.pod.5                        |  12 ++
 docs/misc/arm/device-tree/passthrough.txt    |   7 +
 tools/flask/policy/policy/modules/xen/xen.if |   2 +-
 tools/libxc/include/xenctrl.h                |  24 ++-
 tools/libxc/xc_domain.c                      | 142 ++++++++++--
 tools/libxl/Makefile                         |   2 +-
 tools/libxl/libxl_arch.h                     |   6 +
 tools/libxl/libxl_arm.c                      | 309 +++++++++++++++++++++++++--
 tools/libxl/libxl_create.c                   |  31 ++-
 tools/libxl/libxl_dm.c                       |   3 +-
 tools/libxl/libxl_dom.c                      |   2 +-
 tools/libxl/libxl_dtdev.c                    |  34 +++
 tools/libxl/libxl_internal.h                 |  12 +-
 tools/libxl/libxl_types.idl                  |   6 +
 tools/libxl/libxl_x86.c                      |  10 +
 tools/libxl/xl_cmdimpl.c                     |  22 +-
 xen/arch/arm/device.c                        |   2 +-
 xen/arch/arm/domain.c                        |  39 +++-
 xen/arch/arm/domain_build.c                  | 119 +++++++----
 xen/arch/arm/domctl.c                        |  37 +---
 xen/arch/arm/gic-v2.c                        |  70 +++---
 xen/arch/arm/gic-v3.c                        |  75 +++----
 xen/arch/arm/gic.c                           |  97 ++++++++-
 xen/arch/arm/irq.c                           | 163 ++++++++++++--
 xen/arch/arm/mm.c                            |   6 +-
 xen/arch/arm/physdev.c                       | 136 +++++++++++-
 xen/arch/arm/platforms/omap5.c               |  12 --
 xen/arch/arm/platforms/xgene-storm.c         |   2 +-
 xen/arch/arm/setup.c                         |  10 +-
 xen/arch/arm/vgic.c                          |  65 +++---
 xen/arch/x86/domain.c                        |   3 +-
 xen/arch/x86/mm.c                            |   6 +-
 xen/arch/x86/setup.c                         |   8 +-
 xen/common/Makefile                          |   1 +
 xen/common/device_tree.c                     |  44 +++-
 xen/common/domain.c                          |   7 +-
 xen/common/domctl.c                          |   3 +-
 xen/common/guestcopy.c                       |  30 +++
 xen/common/schedule.c                        |   3 +-
 xen/drivers/passthrough/arm/iommu.c          |   7 +-
 xen/drivers/passthrough/arm/smmu.c           |   8 +-
 xen/drivers/passthrough/device_tree.c        | 115 +++++++++-
 xen/drivers/passthrough/iommu.c              |  26 +++
 xen/drivers/passthrough/pci.c                |  58 +++--
 xen/include/asm-arm/domain.h                 |   2 +
 xen/include/asm-arm/gic.h                    |  18 +-
 xen/include/asm-arm/irq.h                    |   8 +-
 xen/include/asm-arm/setup.h                  |   1 +
 xen/include/asm-arm/vgic.h                   |   8 +-
 xen/include/public/arch-arm.h                |  10 +
 xen/include/public/arch-x86/xen.h            |   4 +
 xen/include/public/domctl.h                  |  33 ++-
 xen/include/xen/device_tree.h                |  35 ++-
 xen/include/xen/domain.h                     |   3 +-
 xen/include/xen/guest_access.h               |   5 +
 xen/include/xen/iommu.h                      |   7 +-
 xen/include/xen/sched.h                      |   9 +-
 xen/xsm/flask/flask_op.c                     |  43 +---
 xen/xsm/flask/hooks.c                        |   3 -
 xen/xsm/flask/policy/access_vectors          |   2 -
 60 files changed, 1570 insertions(+), 397 deletions(-)
 create mode 100644 docs/misc/arm/device-tree/passthrough.txt
 create mode 100644 tools/libxl/libxl_dtdev.c
 create mode 100644 xen/common/guestcopy.c

-- 
2.1.4

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

* [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-13 15:08   ` Daniel De Graaf
                     ` (3 more replies)
  2015-01-13 14:25 ` [PATCH v3 02/24] xen/arm: Divide GIC initialization in 2 parts Julien Grall
                   ` (24 subsequent siblings)
  25 siblings, 4 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, ian.campbell, George Dunlap, tim, Julien Grall,
	Ian Jackson, stefano.stabellini, Jan Beulich, Andrew Cooper,
	Keir Fraser, Daniel De Graaf

On ARM the virtual GIC may differ between each guest (emulated GIC version,
number of SPIs...). Those informations are already known at the domain creation
and can never change.

For now only the gic_version is set. In long run, there will be more parameters
such as the number of SPIs. All will be required to be set at the same time.

A new arch-specific structure arch_domainconfig has been created, the x86
one doesn't have any specific configuration, a dummy structure
(C-spec compliant) has been created to factorize the code on the toolstack.

Some external tools (qemu, xenstore) may require to create a domain. Rather
than asking them to take care of the arch-specific domain configuration, let
the current function (xc_domain_create) to chose a default configuration and
introduce a new one (xc_domain_create_config).

This patch also drop the previously DOMCTL arm_configure_domain introduced
in Xen 4.5, as it has been made useless.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <george.dunlap@eu.citrix.com>

---
    This is a follow-up of http://lists.xen.org/archives/html/xen-devel/2014-11/msg00522.html

    TODO: What about migration? For now the configuration lives in internal
    libxl structure. We need a way to pass the domain configuration to the
    other end.

    I'm not sure if we should care of this right now as migration doesn't
    yet exists on ARM.

    For the xc_domain_create, Stefano S. was looking to drop PV domain
    creation support in QEMU. So maybe I could simply extend xc_domain_create
    and drop the xc_domain_create_config.

    Changes in v3:
        - Patch was previously sent in a separate series [1]
        - Rename arch_domainconfig to xen_arch_domainconfig
        - Drop the typedef
        - Pass NULL for DOM0 config on x86
        - Drop spurious changes
        - Update comment in start_xen in arch/arm/setup.c

        [1] https://patches.linaro.org/41083/
---
 tools/flask/policy/policy/modules/xen/xen.if |  2 +-
 tools/libxc/include/xenctrl.h                | 14 +++++----
 tools/libxc/xc_domain.c                      | 46 ++++++++++++++++------------
 tools/libxl/libxl_arch.h                     |  6 ++++
 tools/libxl/libxl_arm.c                      | 28 ++++++++++-------
 tools/libxl/libxl_create.c                   | 21 ++++++++++---
 tools/libxl/libxl_dm.c                       |  3 +-
 tools/libxl/libxl_dom.c                      |  2 +-
 tools/libxl/libxl_internal.h                 |  7 +++--
 tools/libxl/libxl_x86.c                      | 10 ++++++
 xen/arch/arm/domain.c                        | 28 ++++++++++++++++-
 xen/arch/arm/domctl.c                        | 34 --------------------
 xen/arch/arm/mm.c                            |  6 ++--
 xen/arch/arm/setup.c                         |  6 +++-
 xen/arch/x86/domain.c                        |  3 +-
 xen/arch/x86/mm.c                            |  6 ++--
 xen/arch/x86/setup.c                         |  8 +++--
 xen/common/domain.c                          |  7 +++--
 xen/common/domctl.c                          |  3 +-
 xen/common/schedule.c                        |  3 +-
 xen/include/public/arch-arm.h                |  8 +++++
 xen/include/public/arch-x86/xen.h            |  4 +++
 xen/include/public/domctl.h                  | 18 +----------
 xen/include/xen/domain.h                     |  3 +-
 xen/include/xen/sched.h                      |  9 ++++--
 xen/xsm/flask/hooks.c                        |  3 --
 xen/xsm/flask/policy/access_vectors          |  2 --
 27 files changed, 170 insertions(+), 120 deletions(-)

diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if
index 2d32e1c..620d151 100644
--- a/tools/flask/policy/policy/modules/xen/xen.if
+++ b/tools/flask/policy/policy/modules/xen/xen.if
@@ -51,7 +51,7 @@ define(`create_domain_common', `
 			getaffinity setaffinity setvcpuextstate };
 	allow $1 $2:domain2 { set_cpuid settsc setscheduler setclaim
 			set_max_evtchn set_vnumainfo get_vnumainfo cacheflush
-			psr_cmt_op configure_domain };
+			psr_cmt_op };
 	allow $1 $2:security check_context;
 	allow $1 $2:shadow enable;
 	allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op updatemp };
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 0ad8b8d..d66571f 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -477,18 +477,20 @@ typedef union
 } start_info_any_t;
 #endif
 
+
+typedef struct xen_arch_domainconfig xc_domain_configuration_t;
+int xc_domain_create_config(xc_interface *xch,
+                            uint32_t ssidref,
+                            xen_domain_handle_t handle,
+                            uint32_t flags,
+                            uint32_t *pdomid,
+                            xc_domain_configuration_t *config);
 int xc_domain_create(xc_interface *xch,
                      uint32_t ssidref,
                      xen_domain_handle_t handle,
                      uint32_t flags,
                      uint32_t *pdomid);
 
-#if defined(__arm__) || defined(__aarch64__)
-typedef xen_domctl_arm_configuredomain_t xc_domain_configuration_t;
-
-int xc_domain_configure(xc_interface *xch, uint32_t domid,
-                        xc_domain_configuration_t *config);
-#endif
 
 /* Functions to produce a dump of a given domain
  *  xc_domain_dumpcore - produces a dump to a specified file
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index b864872..eebc121 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -27,11 +27,12 @@
 #include <xen/memory.h>
 #include <xen/hvm/hvm_op.h>
 
-int xc_domain_create(xc_interface *xch,
-                     uint32_t ssidref,
-                     xen_domain_handle_t handle,
-                     uint32_t flags,
-                     uint32_t *pdomid)
+int xc_domain_create_config(xc_interface *xch,
+                            uint32_t ssidref,
+                            xen_domain_handle_t handle,
+                            uint32_t flags,
+                            uint32_t *pdomid,
+                            xc_domain_configuration_t *config)
 {
     int err;
     DECLARE_DOMCTL;
@@ -41,32 +42,39 @@ int xc_domain_create(xc_interface *xch,
     domctl.u.createdomain.ssidref = ssidref;
     domctl.u.createdomain.flags   = flags;
     memcpy(domctl.u.createdomain.handle, handle, sizeof(xen_domain_handle_t));
+    /* xc_domain_configure_t is an alias of arch_domainconfig_t */
+    memcpy(&domctl.u.createdomain.config, config, sizeof(*config));
     if ( (err = do_domctl(xch, &domctl)) != 0 )
         return err;
 
     *pdomid = (uint16_t)domctl.domain;
+    memcpy(config, &domctl.u.createdomain.config, sizeof(*config));
+
     return 0;
 }
 
-#if defined(__arm__) || defined(__aarch64__)
-int xc_domain_configure(xc_interface *xch, uint32_t domid,
-                        xc_domain_configuration_t *config)
+int xc_domain_create(xc_interface *xch,
+                     uint32_t ssidref,
+                     xen_domain_handle_t handle,
+                     uint32_t flags,
+                     uint32_t *pdomid)
 {
-    int rc;
-    DECLARE_DOMCTL;
+    xc_domain_configuration_t config;
 
-    domctl.cmd = XEN_DOMCTL_arm_configure_domain;
-    domctl.domain = (domid_t)domid;
-    /* xc_domain_configure_t is an alias of xen_domctl_arm_configuredomain */
-    memcpy(&domctl.u.configuredomain, config, sizeof(*config));
+    memset(&config, 0, sizeof(config));
 
-    rc = do_domctl(xch, &domctl);
-    if ( !rc )
-        memcpy(config, &domctl.u.configuredomain, sizeof(*config));
+#if defined (__i386) || defined(__x86_64__)
+    /* No arch-specific configuration for now */
+#elif defined (__arm__) || defined(__aarch64__)
+    config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
+#else
+    errno = ENOSYS;
+    return -1;
+#endif
 
-    return rc;
+    return xc_domain_create_config(xch, ssidref, handle,
+                                   flags, pdomid, &config);
 }
-#endif
 
 int xc_domain_cacheflush(xc_interface *xch, uint32_t domid,
                          xen_pfn_t start_pfn, xen_pfn_t nr_pfns)
diff --git a/tools/libxl/libxl_arch.h b/tools/libxl/libxl_arch.h
index d3bc136..f806ed1 100644
--- a/tools/libxl/libxl_arch.h
+++ b/tools/libxl/libxl_arch.h
@@ -15,6 +15,11 @@
 #ifndef LIBXL_ARCH_H
 #define LIBXL_ARCH_H
 
+/* fill the arch specific configuration for the domain */
+int libxl__arch_domain_prepare_config(libxl__gc *gc,
+                                      libxl_domain_config *d_config,
+                                      xc_domain_configuration_t *xc_config);
+
 /* arch specific internal domain creation function */
 int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
                uint32_t domid);
@@ -22,6 +27,7 @@ int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
 /* setup arch specific hardware description, i.e. DTB on ARM */
 int libxl__arch_domain_init_hw_description(libxl__gc *gc,
                                            libxl_domain_build_info *info,
+                                           libxl__domain_build_state *state,
                                            struct xc_dom_image *dom);
 /* finalize arch specific hardware description. */
 int libxl__arch_domain_finalise_hw_description(libxl__gc *gc,
diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index 65a762b..cddce6e 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -35,6 +35,15 @@ static const char *gicv_to_string(uint8_t gic_version)
     }
 }
 
+int libxl__arch_domain_prepare_config(libxl__gc *gc,
+                                      libxl_domain_config *d_config,
+                                      xc_domain_configuration_t *xc_config)
+{
+    xc_config->gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
+
+    return 0;
+}
+
 int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
                               uint32_t domid)
 {
@@ -516,9 +525,9 @@ out:
 
 int libxl__arch_domain_init_hw_description(libxl__gc *gc,
                                            libxl_domain_build_info *info,
+                                           libxl__domain_build_state *state,
                                            struct xc_dom_image *dom)
 {
-    xc_domain_configuration_t config;
     void *fdt = NULL;
     int rc, res;
     size_t fdt_size = 0;
@@ -526,6 +535,9 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
     const libxl_version_info *vers;
     const struct arch_info *ainfo;
 
+    /* convenience aliases */
+    xc_domain_configuration_t *xc_config = &state->config;
+
     assert(info->type == LIBXL_DOMAIN_TYPE_PV);
 
     vers = libxl_get_version_info(CTX);
@@ -534,16 +546,9 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
     ainfo = get_arch_info(gc, dom);
     if (ainfo == NULL) return ERROR_FAIL;
 
-    LOG(DEBUG, "configure the domain");
-    config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
-    if (xc_domain_configure(CTX->xch, dom->guest_domid, &config) != 0) {
-        LOG(ERROR, "couldn't configure the domain");
-        return ERROR_FAIL;
-    }
-
     LOG(DEBUG, "constructing DTB for Xen version %d.%d guest",
         vers->xen_version_major, vers->xen_version_minor);
-    LOG(DEBUG, "  - vGIC version: %s", gicv_to_string(config.gic_version));
+    LOG(DEBUG, " - vGIC version: %s\n", gicv_to_string(xc_config->gic_version));
 
 /*
  * Call "call" handling FDT_ERR_*. Will either:
@@ -592,7 +597,7 @@ next_resize:
 
         FDT( make_memory_nodes(gc, fdt, dom) );
 
-        switch (config.gic_version) {
+        switch (xc_config->gic_version) {
         case XEN_DOMCTL_CONFIG_GIC_V2:
             FDT( make_gicv2_node(gc, fdt,
                                  GUEST_GICD_BASE, GUEST_GICD_SIZE,
@@ -602,7 +607,8 @@ next_resize:
             FDT( make_gicv3_node(gc, fdt) );
             break;
         default:
-            LOG(ERROR, "Unknown GIC version %d", config.gic_version);
+            LOG(ERROR, "Unknown GIC version %s",
+                gicv_to_string(xc_config->gic_version));
             rc = ERROR_FAIL;
             goto out;
         }
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 6f87d1c..029d2e2 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -489,8 +489,8 @@ out:
     return ret;
 }
 
-int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
-                       uint32_t *domid)
+int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config,
+                       uint32_t *domid, xc_domain_configuration_t *xc_config)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     int flags, ret, rc, nb_vm;
@@ -503,6 +503,8 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
     xen_domain_handle_t handle;
     libxl_vminfo *vm_list;
 
+    /* convenience aliases */
+    libxl_domain_create_info *info = &d_config->c_info;
 
     assert(!libxl_domid_valid_guest(*domid));
 
@@ -531,7 +533,16 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
     /* Ultimately, handle is an array of 16 uint8_t, same as uuid */
     libxl_uuid_copy(ctx, (libxl_uuid *)handle, &info->uuid);
 
-    ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
+    ret = libxl__arch_domain_prepare_config(gc, d_config, xc_config);
+    if (ret < 0) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "fail to get domain config");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    ret = xc_domain_create_config(ctx->xch, info->ssidref,
+                                  handle, flags, domid,
+                                  xc_config);
     if (ret < 0) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "domain creation fail");
         rc = ERROR_FAIL;
@@ -764,9 +775,11 @@ static void initiate_domain_create(libxl__egc *egc,
 
     /* convenience aliases */
     libxl_domain_config *const d_config = dcs->guest_config;
+    libxl__domain_build_state *const state = &dcs->build_state;
     const int restore_fd = dcs->restore_fd;
     memset(&dcs->build_state, 0, sizeof(dcs->build_state));
 
+
     domid = 0;
 
     if (d_config->c_info.ssid_label) {
@@ -848,7 +861,7 @@ static void initiate_domain_create(libxl__egc *egc,
     ret = libxl__domain_create_info_setdefault(gc, &d_config->c_info);
     if (ret) goto error_out;
 
-    ret = libxl__domain_make(gc, &d_config->c_info, &domid);
+    ret = libxl__domain_make(gc, d_config, &domid, &state->config);
     if (ret) {
         LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot make domain: %d", ret);
         dcs->guest_domid = domid;
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index c2b0487..f5f9e6d 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1063,7 +1063,8 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
     stubdom_state->pv_ramdisk.path = "";
 
     /* fixme: this function can leak the stubdom if it fails */
-    ret = libxl__domain_make(gc, &dm_config->c_info, &sdss->pvqemu.guest_domid);
+    ret = libxl__domain_make(gc, dm_config, &sdss->pvqemu.guest_domid,
+                             &stubdom_state->config);
     if (ret)
         goto out;
     uint32_t dm_domid = sdss->pvqemu.guest_domid;
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 48d661a..1bea260 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -586,7 +586,7 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
         LOGE(ERROR, "xc_dom_parse_image failed");
         goto out;
     }
-    if ( (ret = libxl__arch_domain_init_hw_description(gc, info, dom)) != 0 ) {
+    if ( (ret = libxl__arch_domain_init_hw_description(gc, info, state, dom)) != 0 ) {
         LOGE(ERROR, "libxl__arch_domain_init_hw_description failed");
         goto out;
     }
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 934465a..be5ed82 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -973,6 +973,8 @@ typedef struct {
     libxl__file_reference pv_ramdisk;
     const char * pv_cmdline;
     bool pvh_enabled;
+
+    xc_domain_configuration_t config;
 } libxl__domain_build_state;
 
 _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid,
@@ -1462,8 +1464,9 @@ _hidden  void libxl__exec(libxl__gc *gc, int stdinfd, int stdoutfd,
  /* on entry, libxl_domid_valid_guest(domid) must be false;
   * on exit (even error exit), domid may be valid and refer to a domain */
 _hidden int libxl__domain_make(libxl__gc *gc,
-                               libxl_domain_create_info *info,
-                               uint32_t *domid);
+                               libxl_domain_config *d_config,
+                               uint32_t *domid,
+                               xc_domain_configuration_t *xc_config);
 
 _hidden int libxl__domain_build(libxl__gc *gc,
                                 libxl_domain_config *d_config,
diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
index 9ceb373..b054d9d 100644
--- a/tools/libxl/libxl_x86.c
+++ b/tools/libxl/libxl_x86.c
@@ -1,6 +1,15 @@
 #include "libxl_internal.h"
 #include "libxl_arch.h"
 
+int libxl__arch_domain_prepare_config(libxl__gc *gc,
+                                      libxl_domain_config *d_config,
+                                      xc_domain_configuration_t *xc_config)
+{
+    /* No specific configuration right now */
+
+    return 0;
+}
+
 static const char *e820_names(int type)
 {
     switch (type) {
@@ -313,6 +322,7 @@ int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
 
 int libxl__arch_domain_init_hw_description(libxl__gc *gc,
                                            libxl_domain_build_info *info,
+                                           libxl__domain_build_state *state,
                                            struct xc_dom_image *dom)
 {
     return 0;
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 589b095..2473b10 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -504,9 +504,11 @@ void vcpu_destroy(struct vcpu *v)
     free_xenheap_pages(v->arch.stack, STACK_ORDER);
 }
 
-int arch_domain_create(struct domain *d, unsigned int domcr_flags)
+int arch_domain_create(struct domain *d, unsigned int domcr_flags,
+                       struct xen_arch_domainconfig *config)
 {
     int rc;
+    uint8_t gic_version;
 
     d->arch.relmem = RELMEM_not_started;
 
@@ -514,6 +516,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
     if ( is_idle_domain(d) )
         return 0;
 
+    ASSERT(config != NULL);
     if ( (rc = p2m_init(d)) != 0 )
         goto fail;
 
@@ -534,6 +537,29 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
     if ( (rc = p2m_alloc_table(d)) != 0 )
         goto fail;
 
+    /*
+     * Currently the vGIC is emulating the same version of the
+     * hardware GIC. Only the value XEN_DOMCTL_CONFIG_GIC_DEFAULT
+     * is allowed. The DOMCTL will return the actual version of the
+     * GIC.
+     */
+    rc = -EOPNOTSUPP;
+    if ( config->gic_version != XEN_DOMCTL_CONFIG_GIC_DEFAULT )
+        goto fail;
+
+    switch ( gic_hw_version() )
+    {
+    case GIC_V3:
+        gic_version = XEN_DOMCTL_CONFIG_GIC_V3;
+        break;
+    case GIC_V2:
+        gic_version = XEN_DOMCTL_CONFIG_GIC_V2;
+        break;
+    default:
+        BUG();
+    }
+    config->gic_version = gic_version;
+
     if ( (rc = gicv_setup(d)) != 0 )
         goto fail;
 
diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
index d246e84..485d3aa 100644
--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -32,40 +32,6 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
 
         return p2m_cache_flush(d, s, e);
     }
-    case XEN_DOMCTL_arm_configure_domain:
-    {
-        uint8_t gic_version;
-
-        /*
-         * Currently the vGIC is emulating the same version of the
-         * hardware GIC. Only the value XEN_DOMCTL_CONFIG_GIC_DEFAULT
-         * is allowed. The DOMCTL will return the actual version of the
-         * GIC.
-         */
-        if ( domctl->u.configuredomain.gic_version != XEN_DOMCTL_CONFIG_GIC_DEFAULT )
-            return -EOPNOTSUPP;
-
-        switch ( gic_hw_version() )
-        {
-        case GIC_V3:
-            gic_version = XEN_DOMCTL_CONFIG_GIC_V3;
-            break;
-        case GIC_V2:
-            gic_version = XEN_DOMCTL_CONFIG_GIC_V2;
-            break;
-        default:
-            BUG();
-        }
-
-        domctl->u.configuredomain.gic_version = gic_version;
-
-        /* TODO: Make the copy generic for all ARCH domctl */
-        if ( __copy_to_guest(u_domctl, domctl, 1) )
-            return -EFAULT;
-
-        return 0;
-    }
-
     default:
         return subarch_do_domctl(domctl, d, u_domctl);
     }
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 7d4ba0c..9128af1 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -399,7 +399,7 @@ void __init arch_init_memory(void)
      * Any Xen-heap pages that we will allow to be mapped will have
      * their domain field set to dom_xen.
      */
-    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0);
+    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0, NULL);
     BUG_ON(IS_ERR(dom_xen));
 
     /*
@@ -407,14 +407,14 @@ void __init arch_init_memory(void)
      * This domain owns I/O pages that are within the range of the page_info
      * array. Mappings occur at the priv of the caller.
      */
-    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0);
+    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0, NULL);
     BUG_ON(IS_ERR(dom_io));
 
     /*
      * Initialise our COW domain.
      * This domain owns sharable pages.
      */
-    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0);
+    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0, NULL);
     BUG_ON(IS_ERR(dom_cow));
 }
 
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index f49569d..4d242e0 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -697,6 +697,7 @@ void __init start_xen(unsigned long boot_phys_offset,
     const char *cmdline;
     struct bootmodule *xen_bootmodule;
     struct domain *dom0;
+    struct xen_arch_domainconfig config;
 
     setup_cache();
 
@@ -811,7 +812,10 @@ void __init start_xen(unsigned long boot_phys_offset,
     do_initcalls();
 
     /* Create initial domain 0. */
-    dom0 = domain_create(0, 0, 0);
+    /* The vGIC for DOM0 is exactly emulated the hardware GIC */
+    config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
+
+    dom0 = domain_create(0, 0, 0, &config);
     if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
             panic("Error creating domain 0");
 
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index c8832c6..e174f28 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -514,7 +514,8 @@ void vcpu_destroy(struct vcpu *v)
         xfree(v->arch.pv_vcpu.trap_ctxt);
 }
 
-int arch_domain_create(struct domain *d, unsigned int domcr_flags)
+int arch_domain_create(struct domain *d, unsigned int domcr_flags,
+                       struct xen_arch_domainconfig *config)
 {
     int i, paging_initialised = 0;
     int rc = -ENOMEM;
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 6e9c2c0..ef4d149 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -275,7 +275,7 @@ void __init arch_init_memory(void)
      * Hidden PCI devices will also be associated with this domain
      * (but be [partly] controlled by Dom0 nevertheless).
      */
-    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0);
+    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0, NULL);
     BUG_ON(IS_ERR(dom_xen));
     INIT_LIST_HEAD(&dom_xen->arch.pdev_list);
 
@@ -284,14 +284,14 @@ void __init arch_init_memory(void)
      * This domain owns I/O pages that are within the range of the page_info
      * array. Mappings occur at the priv of the caller.
      */
-    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0);
+    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0, NULL);
     BUG_ON(IS_ERR(dom_io));
     
     /*
      * Initialise our COW domain.
      * This domain owns sharable pages.
      */
-    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0);
+    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0, NULL);
     BUG_ON(IS_ERR(dom_cow));
 
     /* First 1MB of RAM is historically marked as I/O. */
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index c27c49c..6ce51f6 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1347,8 +1347,12 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     if ( opt_dom0pvh )
         domcr_flags |= DOMCRF_pvh | DOMCRF_hap;
 
-    /* Create initial domain 0. */
-    dom0 = domain_create(0, domcr_flags, 0);
+    /*
+     * Create initial domain 0.
+     * x86 doesn't support arch-configuration. So it's fine to pass
+     * NULL.
+     */
+    dom0 = domain_create(0, domcr_flags, 0, NULL);
     if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
         panic("Error creating domain 0");
 
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 336e9ea..9448bf6 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -242,8 +242,9 @@ static void __init parse_extra_guest_irqs(const char *s)
 }
 custom_param("extra_guest_irqs", parse_extra_guest_irqs);
 
-struct domain *domain_create(
-    domid_t domid, unsigned int domcr_flags, uint32_t ssidref)
+struct domain *domain_create(domid_t domid, unsigned int domcr_flags,
+                             uint32_t ssidref,
+                             struct xen_arch_domainconfig *config)
 {
     struct domain *d, **pd, *old_hwdom = NULL;
     enum { INIT_xsm = 1u<<0, INIT_watchdog = 1u<<1, INIT_rangeset = 1u<<2,
@@ -353,7 +354,7 @@ struct domain *domain_create(
             goto fail;
     }
 
-    if ( (err = arch_domain_create(d, domcr_flags)) != 0 )
+    if ( (err = arch_domain_create(d, domcr_flags, config)) != 0 )
         goto fail;
     init_status |= INIT_arch;
 
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index ee578c0..6a0f53a 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -582,7 +582,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
         if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_oos_off )
             domcr_flags |= DOMCRF_oos_off;
 
-        d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref);
+        d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref,
+                          &op->u.createdomain.config);
         if ( IS_ERR(d) )
         {
             ret = PTR_ERR(d);
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 6285a6e..ab2561a 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -1421,7 +1421,8 @@ void __init scheduler_init(void)
         sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
     }
 
-    idle_domain = domain_create(DOMID_IDLE, 0, 0);
+    /* There is no need of arch-specific configuration for an idle domain */
+    idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
     BUG_ON(IS_ERR(idle_domain));
     idle_domain->vcpu = idle_vcpu;
     idle_domain->max_vcpus = nr_cpu_ids;
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index e711606..4c1b9f9 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -314,6 +314,14 @@ struct arch_shared_info {
 typedef struct arch_shared_info arch_shared_info_t;
 typedef uint64_t xen_callback_t;
 
+#define XEN_DOMCTL_CONFIG_GIC_DEFAULT   0
+#define XEN_DOMCTL_CONFIG_GIC_V2        1
+#define XEN_DOMCTL_CONFIG_GIC_V3        2
+struct xen_arch_domainconfig {
+    /* IN/OUT */
+    uint8_t gic_version;
+};
+
 #endif
 
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
diff --git a/xen/include/public/arch-x86/xen.h b/xen/include/public/arch-x86/xen.h
index c5e880b..d07d550 100644
--- a/xen/include/public/arch-x86/xen.h
+++ b/xen/include/public/arch-x86/xen.h
@@ -258,6 +258,10 @@ struct arch_shared_info {
 };
 typedef struct arch_shared_info arch_shared_info_t;
 
+struct xen_arch_domainconfig {
+    char dummy;
+};
+
 #endif /* !__ASSEMBLY__ */
 
 /*
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 57e2ed7..b742b23 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -64,23 +64,11 @@ struct xen_domctl_createdomain {
 #define _XEN_DOMCTL_CDF_pvh_guest     4
 #define XEN_DOMCTL_CDF_pvh_guest      (1U<<_XEN_DOMCTL_CDF_pvh_guest)
     uint32_t flags;
+    struct xen_arch_domainconfig config;
 };
 typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t);
 
-#if defined(__arm__) || defined(__aarch64__)
-#define XEN_DOMCTL_CONFIG_GIC_DEFAULT   0
-#define XEN_DOMCTL_CONFIG_GIC_V2        1
-#define XEN_DOMCTL_CONFIG_GIC_V3        2
-/* XEN_DOMCTL_configure_domain */
-struct xen_domctl_arm_configuredomain {
-    /* IN/OUT parameters */
-    uint8_t gic_version;
-};
-typedef struct xen_domctl_arm_configuredomain xen_domctl_arm_configuredomain_t;
-DEFINE_XEN_GUEST_HANDLE(xen_domctl_arm_configuredomain_t);
-#endif
-
 /* XEN_DOMCTL_getdomaininfo */
 struct xen_domctl_getdomaininfo {
     /* OUT variables. */
@@ -1069,7 +1057,6 @@ struct xen_domctl {
 #define XEN_DOMCTL_set_vcpu_msrs                 73
 #define XEN_DOMCTL_setvnumainfo                  74
 #define XEN_DOMCTL_psr_cmt_op                    75
-#define XEN_DOMCTL_arm_configure_domain          76
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
@@ -1078,9 +1065,6 @@ struct xen_domctl {
     domid_t  domain;
     union {
         struct xen_domctl_createdomain      createdomain;
-#if defined(__arm__) || defined(__aarch64__)
-        struct xen_domctl_arm_configuredomain configuredomain;
-#endif
         struct xen_domctl_getdomaininfo     getdomaininfo;
         struct xen_domctl_getmemlist        getmemlist;
         struct xen_domctl_getpageframeinfo  getpageframeinfo;
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index 72667da..6b5c0c5 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -55,7 +55,8 @@ void vcpu_destroy(struct vcpu *v);
 int map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned offset);
 void unmap_vcpu_info(struct vcpu *v);
 
-int arch_domain_create(struct domain *d, unsigned int domcr_flags);
+int arch_domain_create(struct domain *d, unsigned int domcr_flags,
+                       struct xen_arch_domainconfig *config);
 
 void arch_domain_destroy(struct domain *d);
 
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 46fc6e3..9759015 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -525,8 +525,13 @@ static inline void get_knownalive_domain(struct domain *d)
 int domain_set_node_affinity(struct domain *d, const nodemask_t *affinity);
 void domain_update_node_affinity(struct domain *d);
 
-struct domain *domain_create(
-    domid_t domid, unsigned int domcr_flags, uint32_t ssidref);
+/*
+ * Create a domain: the configuration is only necessary for real domain
+ * (i.e !DOMCRF_dummy, excluded idle domain).
+ */
+struct domain *domain_create(domid_t domid, unsigned int domcr_flags,
+                             uint32_t ssidref,
+                             struct xen_arch_domainconfig *config);
  /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */
 #define _DOMCRF_hvm           0
 #define DOMCRF_hvm            (1U<<_DOMCRF_hvm)
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index d48463f..36410cc 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -729,9 +729,6 @@ static int flask_domctl(struct domain *d, int cmd)
     case XEN_DOMCTL_psr_cmt_op:
         return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__PSR_CMT_OP);
 
-    case XEN_DOMCTL_arm_configure_domain:
-        return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__CONFIGURE_DOMAIN);
-
     default:
         printk("flask_domctl: Unknown op %d\n", cmd);
         return -EPERM;
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index 1da9f63..9a98fc3 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -218,8 +218,6 @@ class domain2
     get_vnumainfo
 # XEN_DOMCTL_psr_cmt_op
     psr_cmt_op
-# XEN_DOMCTL_configure_domain
-    configure_domain
 }
 
 # Similar to class domain, but primarily contains domctls related to HVM domains
-- 
2.1.4

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

* [PATCH v3 02/24] xen/arm: Divide GIC initialization in 2 parts
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
  2015-01-13 14:25 ` [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-28 16:09   ` Stefano Stabellini
  2015-02-20 15:19   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 03/24] xen/dts: Allow only IRQ translation that are mapped to main GIC Julien Grall
                   ` (23 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

Currently the function to translate IRQ from the device tree is set
unconditionally  to be able to be able to retrieve serial/timer IRQ before the
GIC has been initialized.

It assumes that the xlate function won't never changed. We may also need to
have the primary interrupt controller very early.

Rework the gic initialization in 2 parts:
    - gic_preinit: Get the interrupt controller device tree node and set
up GIC and xlate callbacks
    - gic_init: Initialize the interrupt controller and the boot CPU
    interrupts.

The former function will be called just after the IRQ subsystem as been
initialized.

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v3:
        - Patch was previously sent in a separate series [1]
        - Reorder the function to avoid forward declaration
        - Make gic-v3 driver compliant to the new interface
        - Remove spurious field addition in gicv2 structure

    Changelog based on the separate series:

    Changes in v3:
        - Patch added.

    [1] https://patches.linaro.org/33313/
---
 xen/arch/arm/gic-v2.c     | 70 ++++++++++++++++++++++---------------------
 xen/arch/arm/gic-v3.c     | 75 ++++++++++++++++++++++++-----------------------
 xen/arch/arm/gic.c        | 16 ++++++++--
 xen/arch/arm/setup.c      |  3 +-
 xen/include/asm-arm/gic.h |  8 +++++
 5 files changed, 100 insertions(+), 72 deletions(-)

diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 15916c9..016b0fd 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -655,37 +655,10 @@ static hw_irq_controller gicv2_guest_irq_type = {
     .set_affinity = gicv2_irq_set_affinity,
 };
 
-const static struct gic_hw_operations gicv2_ops = {
-    .info                = &gicv2_info,
-    .secondary_init      = gicv2_secondary_cpu_init,
-    .save_state          = gicv2_save_state,
-    .restore_state       = gicv2_restore_state,
-    .dump_state          = gicv2_dump_state,
-    .gicv_setup          = gicv2v_setup,
-    .gic_host_irq_type   = &gicv2_host_irq_type,
-    .gic_guest_irq_type  = &gicv2_guest_irq_type,
-    .eoi_irq             = gicv2_eoi_irq,
-    .deactivate_irq      = gicv2_dir_irq,
-    .read_irq            = gicv2_read_irq,
-    .set_irq_properties  = gicv2_set_irq_properties,
-    .send_SGI            = gicv2_send_SGI,
-    .disable_interface   = gicv2_disable_interface,
-    .update_lr           = gicv2_update_lr,
-    .update_hcr_status   = gicv2_hcr_status,
-    .clear_lr            = gicv2_clear_lr,
-    .read_lr             = gicv2_read_lr,
-    .write_lr            = gicv2_write_lr,
-    .read_vmcr_priority  = gicv2_read_vmcr_priority,
-    .read_apr            = gicv2_read_apr,
-    .make_dt_node        = gicv2_make_dt_node,
-};
-
-/* Set up the GIC */
-static int __init gicv2_init(struct dt_device_node *node, const void *data)
+static int __init gicv2_init(void)
 {
     int res;
-
-    dt_device_set_used_by(node, DOMID_XEN);
+    const struct dt_device_node *node = gicv2_info.node;
 
     res = dt_device_get_address(node, 0, &gicv2.dbase, NULL);
     if ( res || !gicv2.dbase || (gicv2.dbase & ~PAGE_MASK) )
@@ -708,9 +681,6 @@ static int __init gicv2_init(struct dt_device_node *node, const void *data)
         panic("GICv2: Cannot find the maintenance IRQ");
     gicv2_info.maintenance_irq = res;
 
-    /* Set the GIC as the primary interrupt controller */
-    dt_interrupt_controller = node;
-
     /* TODO: Add check on distributor, cpu size */
 
     printk("GICv2 initialization:\n"
@@ -755,8 +725,42 @@ static int __init gicv2_init(struct dt_device_node *node, const void *data)
 
     spin_unlock(&gicv2.lock);
 
+    return 0;
+}
+
+const static struct gic_hw_operations gicv2_ops = {
+    .info                = &gicv2_info,
+    .init                = gicv2_init,
+    .secondary_init      = gicv2_secondary_cpu_init,
+    .save_state          = gicv2_save_state,
+    .restore_state       = gicv2_restore_state,
+    .dump_state          = gicv2_dump_state,
+    .gicv_setup          = gicv2v_setup,
+    .gic_host_irq_type   = &gicv2_host_irq_type,
+    .gic_guest_irq_type  = &gicv2_guest_irq_type,
+    .eoi_irq             = gicv2_eoi_irq,
+    .deactivate_irq      = gicv2_dir_irq,
+    .read_irq            = gicv2_read_irq,
+    .set_irq_properties  = gicv2_set_irq_properties,
+    .send_SGI            = gicv2_send_SGI,
+    .disable_interface   = gicv2_disable_interface,
+    .update_lr           = gicv2_update_lr,
+    .update_hcr_status   = gicv2_hcr_status,
+    .clear_lr            = gicv2_clear_lr,
+    .read_lr             = gicv2_read_lr,
+    .write_lr            = gicv2_write_lr,
+    .read_vmcr_priority  = gicv2_read_vmcr_priority,
+    .read_apr            = gicv2_read_apr,
+    .make_dt_node        = gicv2_make_dt_node,
+};
+
+/* Set up the GIC */
+static int __init gicv2_preinit(struct dt_device_node *node, const void *data)
+{
     gicv2_info.hw_version = GIC_V2;
+    gicv2_info.node = node;
     register_gic_ops(&gicv2_ops);
+    dt_irq_xlate = gic_irq_xlate;
 
     return 0;
 }
@@ -769,7 +773,7 @@ static const struct dt_device_match gicv2_dt_match[] __initconst =
 
 DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
         .dt_match = gicv2_dt_match,
-        .init = gicv2_init,
+        .init = gicv2_preinit,
 DT_DEVICE_END
 
 /*
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 2ddcbab..f650756 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -1141,37 +1141,13 @@ static const hw_irq_controller gicv3_guest_irq_type = {
     .set_affinity = gicv3_irq_set_affinity,
 };
 
-static const struct gic_hw_operations gicv3_ops = {
-    .info                = &gicv3_info,
-    .save_state          = gicv3_save_state,
-    .restore_state       = gicv3_restore_state,
-    .dump_state          = gicv3_dump_state,
-    .gicv_setup          = gicv_v3_init,
-    .gic_host_irq_type   = &gicv3_host_irq_type,
-    .gic_guest_irq_type  = &gicv3_guest_irq_type,
-    .eoi_irq             = gicv3_eoi_irq,
-    .deactivate_irq      = gicv3_dir_irq,
-    .read_irq            = gicv3_read_irq,
-    .set_irq_properties  = gicv3_set_irq_properties,
-    .send_SGI            = gicv3_send_sgi,
-    .disable_interface   = gicv3_disable_interface,
-    .update_lr           = gicv3_update_lr,
-    .update_hcr_status   = gicv3_hcr_status,
-    .clear_lr            = gicv3_clear_lr,
-    .read_lr             = gicv3_read_lr,
-    .write_lr            = gicv3_write_lr,
-    .read_vmcr_priority  = gicv3_read_vmcr_priority,
-    .read_apr            = gicv3_read_apr,
-    .secondary_init      = gicv3_secondary_cpu_init,
-    .make_dt_node        = gicv3_make_dt_node,
-};
-
 /* Set up the GIC */
-static int __init gicv3_init(struct dt_device_node *node, const void *data)
+static int __init gicv3_init(void)
 {
     struct rdist_region *rdist_regs;
     int res, i;
     uint32_t reg;
+    const struct dt_device_node *node = gicv3_info.node;
 
     if ( !cpu_has_gicv3 )
     {
@@ -1179,8 +1155,6 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data)
         return -ENODEV;
     }
 
-    dt_device_set_used_by(node, DOMID_XEN);
-
     res = dt_device_get_address(node, 0, &gicv3.dbase, &gicv3.dbase_size);
     if ( res || !gicv3.dbase )
         panic("GICv3: Cannot find a valid distributor address");
@@ -1232,9 +1206,6 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data)
         panic("GICv3: Cannot find the maintenance IRQ");
     gicv3_info.maintenance_irq = res;
 
-    /* Set the GIC as the primary interrupt controller */
-    dt_interrupt_controller = node;
-
     for ( i = 0; i < gicv3.rdist_count; i++ )
     {
         /* map dbase & rdist regions */
@@ -1269,15 +1240,47 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data)
     res = gicv3_cpu_init();
     gicv3_hyp_init();
 
-    gicv3_info.hw_version = GIC_V3;
-    /* Register hw ops*/
-    register_gic_ops(&gicv3_ops);
-
     spin_unlock(&gicv3.lock);
 
     return res;
 }
 
+static const struct gic_hw_operations gicv3_ops = {
+    .info                = &gicv3_info,
+    .init                = gicv3_init,
+    .save_state          = gicv3_save_state,
+    .restore_state       = gicv3_restore_state,
+    .dump_state          = gicv3_dump_state,
+    .gicv_setup          = gicv_v3_init,
+    .gic_host_irq_type   = &gicv3_host_irq_type,
+    .gic_guest_irq_type  = &gicv3_guest_irq_type,
+    .eoi_irq             = gicv3_eoi_irq,
+    .deactivate_irq      = gicv3_dir_irq,
+    .read_irq            = gicv3_read_irq,
+    .set_irq_properties  = gicv3_set_irq_properties,
+    .send_SGI            = gicv3_send_sgi,
+    .disable_interface   = gicv3_disable_interface,
+    .update_lr           = gicv3_update_lr,
+    .update_hcr_status   = gicv3_hcr_status,
+    .clear_lr            = gicv3_clear_lr,
+    .read_lr             = gicv3_read_lr,
+    .write_lr            = gicv3_write_lr,
+    .read_vmcr_priority  = gicv3_read_vmcr_priority,
+    .read_apr            = gicv3_read_apr,
+    .secondary_init      = gicv3_secondary_cpu_init,
+    .make_dt_node        = gicv3_make_dt_node,
+};
+
+static int __init gicv3_preinit(struct dt_device_node *node, const void *data)
+{
+    gicv3_info.hw_version = GIC_V3;
+    gicv3_info.node = node;
+    register_gic_ops(&gicv3_ops);
+    dt_irq_xlate = gic_irq_xlate;
+
+    return 0;
+}
+
 static const struct dt_device_match gicv3_dt_match[] __initconst =
 {
     DT_MATCH_GIC_V3,
@@ -1286,7 +1289,7 @@ static const struct dt_device_match gicv3_dt_match[] __initconst =
 
 DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
         .dt_match = gicv3_dt_match,
-        .init = gicv3_init,
+        .init = gicv3_preinit,
 DT_DEVICE_END
 
 /*
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index d1ab6b5..63147f3 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -163,8 +163,10 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
     return 0;
 }
 
-/* Set up the GIC */
-void __init gic_init(void)
+/* Find the interrupt controller and set up the callback to translate
+ * device tree IRQ.
+ */
+void __init gic_preinit(void)
 {
     int rc;
     struct dt_device_node *node;
@@ -189,6 +191,16 @@ void __init gic_init(void)
     if ( !num_gics )
         panic("Unable to find compatible GIC in the device tree");
 
+    /* Set the GIC as the primary interrupt controller */
+    dt_interrupt_controller = node;
+    dt_device_set_used_by(node, DOMID_XEN);
+}
+
+/* Set up the GIC */
+void __init gic_init(void)
+{
+    if ( gic_hw_ops->init() )
+        panic("Failed to initialize the GIC drivers");
     /* Clear LR mask for cpu0 */
     clear_cpu_lr_mask();
 }
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 4d242e0..18227f6 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -740,10 +740,11 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     vm_init();
     dt_unflatten_host_device_tree();
-    dt_irq_xlate = gic_irq_xlate;
 
     init_IRQ();
 
+    gic_preinit();
+
     dt_uart_init();
     console_init_preirq();
     console_init_ring();
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 73ca3cf..6286c71 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -229,6 +229,10 @@ extern void gic_remove_from_queues(struct vcpu *v, unsigned int virtual_irq);
 
 /* Accept an interrupt from the GIC and dispatch its handler */
 extern void gic_interrupt(struct cpu_user_regs *regs, int is_fiq);
+/* Find the interrupt controller and set up the callback to translate
+ * device tree IRQ.
+ */
+extern void gic_preinit(void);
 /* Bring up the interrupt controller, and report # cpus attached */
 extern void gic_init(void);
 /* Bring up a secondary CPU's per-CPU GIC interface */
@@ -281,11 +285,15 @@ struct gic_info {
     uint8_t nr_lrs;
     /* Maintenance irq number */
     unsigned int maintenance_irq;
+    /* Pointer to the device tree node representing the interrupt controller */
+    const struct dt_device_node *node;
 };
 
 struct gic_hw_operations {
     /* Hold GIC HW information */
     const struct gic_info *info;
+    /* Initialize the GIC and the boot CPU */
+    int (*init)(void);
     /* Save GIC registers */
     void (*save_state)(struct vcpu *);
     /* Restore GIC registers */
-- 
2.1.4

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

* [PATCH v3 03/24] xen/dts: Allow only IRQ translation that are mapped to main GIC
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
  2015-01-13 14:25 ` [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration Julien Grall
  2015-01-13 14:25 ` [PATCH v3 02/24] xen/arm: Divide GIC initialization in 2 parts Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-28 16:11   ` Stefano Stabellini
  2015-02-20 15:20   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest Julien Grall
                   ` (22 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

Xen is only able to handle one GIC controller. Some platform may contain
other interrupt controller.

Make sure to only translate IRQ mapped into the GIC handled by Xen.

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---

    Changes in v3:
        - Patch was previously sent a separate series [1]
        - Rework the comment in dt_irq_translate.

    Changelog based on the separate series:

    Changes in v3:
        - Add an ASSERT to check that dt_interrupt_controller is not
        NULL.

    Changes in v2:
        - Fix compilation...

    [1] https://patches.linaro.org/33312/
---
 xen/common/device_tree.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index f471008..bb9d7ce 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -1058,8 +1058,14 @@ int dt_irq_translate(const struct dt_raw_irq *raw,
                      struct dt_irq *out_irq)
 {
     ASSERT(dt_irq_xlate != NULL);
+    ASSERT(dt_interrupt_controller != NULL);
 
-    /* TODO: Retrieve the right irq_xlate. This is only work for the gic */
+    /*
+     * TODO: Retrieve the right irq_xlate. This is only works for the primary
+     * interrupt controller.
+     */
+    if ( raw->controller != dt_interrupt_controller )
+        return -EINVAL;
 
     return dt_irq_xlate(raw->specifier, raw->size,
                         &out_irq->irq, &out_irq->type);
-- 
2.1.4

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

* [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (2 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 03/24] xen/dts: Allow only IRQ translation that are mapped to main GIC Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-13 15:10   ` Daniel De Graaf
                     ` (2 more replies)
  2015-01-13 14:25 ` [PATCH v3 05/24] xen/arm: vgic: Introduce a function to initialize pending_irq Julien Grall
                   ` (21 subsequent siblings)
  25 siblings, 3 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Keir Fraser, ian.campbell, tim, Julien Grall, Ian Jackson,
	stefano.stabellini, Jan Beulich, Daniel De Graaf

Flask code already provides an helper to copy a string from guest. In a later
patch, the new DT hypercalls will need a similar function.

To avoid code duplication, copy the flask helper (flask_copying_string) to
common code:
    - Rename into safe_copy_string_from_guest
    - Add comment to explain the extra +1
    - Return directly the buffer and use the macros provided by
    xen/err.h to return an error code if necessary.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>

---
    Changes in v3:
        - Use macros of xen/err.h to return either the buffer or an
        error code
        - Reuse size_t instead of unsigned long
        - Update comment and commit message

    Changes in v2:
        - Rename copy_string_from_guest into safe_copy_string_from_guest
        - Update commit message and comment in the code
---
 xen/common/Makefile            |  1 +
 xen/common/guestcopy.c         | 30 +++++++++++++++++++++++++++++
 xen/include/xen/guest_access.h |  5 +++++
 xen/xsm/flask/flask_op.c       | 43 ++++++++++--------------------------------
 4 files changed, 46 insertions(+), 33 deletions(-)
 create mode 100644 xen/common/guestcopy.c

diff --git a/xen/common/Makefile b/xen/common/Makefile
index 9ce75bb..3da774a 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -10,6 +10,7 @@ obj-y += event_2l.o
 obj-y += event_channel.o
 obj-y += event_fifo.o
 obj-y += grant_table.o
+obj-y += guestcopy.o
 obj-y += irq.o
 obj-y += kernel.o
 obj-y += keyhandler.o
diff --git a/xen/common/guestcopy.c b/xen/common/guestcopy.c
new file mode 100644
index 0000000..d974f5c
--- /dev/null
+++ b/xen/common/guestcopy.c
@@ -0,0 +1,30 @@
+#include <xen/config.h>
+#include <xen/lib.h>
+#include <xen/guest_access.h>
+#include <xen/err.h>
+
+/* The function copies a string from the guest and adds a NUL to
+ * make sure the string is correctly terminated.
+ */
+void *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
+                                  size_t size, size_t max_size)
+{
+    char *tmp;
+
+    if ( size > max_size )
+        return ERR_PTR(-ENOENT);
+
+    /* Add an extra +1 to append \0 */
+    tmp = xmalloc_array(char, size + 1);
+    if ( !tmp )
+        return ERR_PTR(-ENOMEM);
+
+    if ( copy_from_guest(tmp, u_buf, size) )
+    {
+        xfree(tmp);
+        return ERR_PTR(-EFAULT);
+    }
+    tmp[size] = 0;
+
+    return tmp;
+}
diff --git a/xen/include/xen/guest_access.h b/xen/include/xen/guest_access.h
index 373454e..55645e6 100644
--- a/xen/include/xen/guest_access.h
+++ b/xen/include/xen/guest_access.h
@@ -8,6 +8,8 @@
 #define __XEN_GUEST_ACCESS_H__
 
 #include <asm/guest_access.h>
+#include <xen/types.h>
+#include <public/xen.h>
 
 #define copy_to_guest(hnd, ptr, nr)                     \
     copy_to_guest_offset(hnd, 0, ptr, nr)
@@ -27,4 +29,7 @@
 #define __clear_guest(hnd, nr)                          \
     __clear_guest_offset(hnd, 0, nr)
 
+void *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
+                                 size_t size, size_t max_size);
+
 #endif /* __XEN_GUEST_ACCESS_H__ */
diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c
index 7743aac..b14d306 100644
--- a/xen/xsm/flask/flask_op.c
+++ b/xen/xsm/flask/flask_op.c
@@ -12,6 +12,7 @@
 #include <xen/event.h>
 #include <xsm/xsm.h>
 #include <xen/guest_access.h>
+#include <xen/err.h>
 
 #include <public/xsm/flask_op.h>
 
@@ -76,29 +77,6 @@ static int domain_has_security(struct domain *d, u32 perms)
                         perms, NULL);
 }
 
-static int flask_copyin_string(XEN_GUEST_HANDLE(char) u_buf, char **buf,
-                               size_t size, size_t max_size)
-{
-    char *tmp;
-
-    if ( size > max_size )
-        return -ENOENT;
-
-    tmp = xmalloc_array(char, size + 1);
-    if ( !tmp )
-        return -ENOMEM;
-
-    if ( copy_from_guest(tmp, u_buf, size) )
-    {
-        xfree(tmp);
-        return -EFAULT;
-    }
-    tmp[size] = 0;
-
-    *buf = tmp;
-    return 0;
-}
-
 #endif /* COMPAT */
 
 static int flask_security_user(struct xen_flask_userlist *arg)
@@ -112,9 +90,9 @@ static int flask_security_user(struct xen_flask_userlist *arg)
     if ( rv )
         return rv;
 
-    rv = flask_copyin_string(arg->u.user, &user, arg->size, PAGE_SIZE);
-    if ( rv )
-        return rv;
+    user = safe_copy_string_from_guest(arg->u.user, arg->size, PAGE_SIZE);
+    if ( IS_ERR(user) )
+        return PTR_ERR(user);
 
     rv = security_get_user_sids(arg->start_sid, user, &sids, &nsids);
     if ( rv < 0 )
@@ -227,9 +205,9 @@ static int flask_security_context(struct xen_flask_sid_context *arg)
     if ( rv )
         return rv;
 
-    rv = flask_copyin_string(arg->context, &buf, arg->size, PAGE_SIZE);
-    if ( rv )
-        return rv;
+    buf = safe_copy_string_from_guest(arg->context, arg->size, PAGE_SIZE);
+    if ( IS_ERR(buf) )
+        return PTR_ERR(buf);
 
     rv = security_context_to_sid(buf, arg->size, &arg->sid);
     if ( rv < 0 )
@@ -319,14 +297,13 @@ static int flask_security_setavc_threshold(struct xen_flask_setavc_threshold *ar
 static int flask_security_resolve_bool(struct xen_flask_boolean *arg)
 {
     char *name;
-    int rv;
 
     if ( arg->bool_id != -1 )
         return 0;
 
-    rv = flask_copyin_string(arg->name, &name, arg->size, bool_maxstr);
-    if ( rv )
-        return rv;
+    name = safe_copy_string_from_guest(arg->name, arg->size, bool_maxstr);
+    if ( IS_ERR(name) )
+        return PTR_ERR(name);
 
     arg->bool_id = security_find_bool(name);
     arg->size = 0;
-- 
2.1.4

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

* [PATCH v3 05/24] xen/arm: vgic: Introduce a function to initialize pending_irq
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (3 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-02-20 15:24   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 06/24] xen/arm: Map disabled device in DOM0 Julien Grall
                   ` (20 subsequent siblings)
  25 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

The structure pending_irq is initialized on the same way in 2 differents
place. Introduce vgic_init_pending_irq to avoid code duplication.

Also move the setting of the irq field in this function as we need to
initialize it once rather than every time an IRQ is injected to the guest.

Finally, use unsigned int for the "irq" field to be consistent with the
virq variable

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

---
    Changes in v3:
        - Add Stefano's acked
        - The irq field is now unsigned int
        - Update commit message to speak about the int -> unsigned int
        change
        - Use "unsigned int" rather than "unsigned"

    Changes in v2:
        - Patch added
---
 xen/arch/arm/gic.c         |  2 +-
 xen/arch/arm/vgic.c        | 19 ++++++++++---------
 xen/include/asm-arm/vgic.h |  2 +-
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 63147f3..eb0c5d6 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -627,7 +627,7 @@ void gic_dump_info(struct vcpu *v)
 
     list_for_each_entry ( p, &v->arch.vgic.inflight_irqs, inflight )
     {
-        printk("Inflight irq=%d lr=%u\n", p->irq, p->lr);
+        printk("Inflight irq=%u lr=%u\n", p->irq, p->lr);
     }
 
     list_for_each_entry( p, &v->arch.vgic.lr_pending, lr_queue )
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 0b24eec..38216f7 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -60,6 +60,13 @@ struct vgic_irq_rank *vgic_rank_irq(struct vcpu *v, unsigned int irq)
     return vgic_get_rank(v, rank);
 }
 
+static void vgic_init_pending_irq(struct pending_irq *p, unsigned int virq)
+{
+    INIT_LIST_HEAD(&p->inflight);
+    INIT_LIST_HEAD(&p->lr_queue);
+    p->irq = virq;
+}
+
 int domain_vgic_init(struct domain *d)
 {
     int i;
@@ -100,10 +107,8 @@ int domain_vgic_init(struct domain *d)
         return -ENOMEM;
 
     for (i=0; i<d->arch.vgic.nr_spis; i++)
-    {
-        INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
-        INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].lr_queue);
-    }
+        vgic_init_pending_irq(&d->arch.vgic.pending_irqs[i], i + 32);
+
     for (i=0; i<DOMAIN_NR_RANKS(d); i++)
         spin_lock_init(&d->arch.vgic.shared_irqs[i].lock);
 
@@ -147,10 +152,7 @@ int vcpu_vgic_init(struct vcpu *v)
 
     memset(&v->arch.vgic.pending_irqs, 0, sizeof(v->arch.vgic.pending_irqs));
     for (i = 0; i < 32; i++)
-    {
-        INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].inflight);
-        INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].lr_queue);
-    }
+        vgic_init_pending_irq(&v->arch.vgic.pending_irqs[i], i);
 
     INIT_LIST_HEAD(&v->arch.vgic.inflight_irqs);
     INIT_LIST_HEAD(&v->arch.vgic.lr_pending);
@@ -407,7 +409,6 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq)
         goto out;
     }
 
-    n->irq = irq;
     n->priority = priority;
 
     /* the irq is enabled */
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 460a2f3..8582d9d 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -67,7 +67,7 @@ struct pending_irq
 #define GIC_IRQ_GUEST_MIGRATING   4
     unsigned long status;
     struct irq_desc *desc; /* only set it the irq corresponds to a physical irq */
-    int irq;
+    unsigned int irq;
 #define GIC_INVALID_LR         ~(uint8_t)0
     uint8_t lr;
     uint8_t priority;
-- 
2.1.4

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

* [PATCH v3 06/24] xen/arm: Map disabled device in DOM0
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (4 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 05/24] xen/arm: vgic: Introduce a function to initialize pending_irq Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-28 16:18   ` Stefano Stabellini
  2015-02-20 15:27   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property Julien Grall
                   ` (19 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: stefano.stabellini, Julien Grall, tim, ian.campbell, Andrii Tseglytskyi

The check to avoid mapping disabled device in DOM0 was added in the anticipation
of the device passthrough. But, a brand new property will be added later to mark
device which will passthrough. At the same time, remove the memory type
check because those nodes has been blacklisted.

Futhermore, some platform (such as the OMAP) may try to poke device even
if the property "status" is set to "disabled".

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Andrii Tseglytskyi <andrii.tseglytskyi@globallogic.com>

---

    Changes in v3:
        - Patch added
        - "xen/arm: follow-up to allow DOM0 manage IRQ and MMIO" has
        been split in 2 patch [1]
        - Drop the check for memory type. Thoses nodes have been
        blacklisted.

[1] https://patches.linaro.org/34669/
---
 xen/arch/arm/domain_build.c    | 19 +++----------------
 xen/arch/arm/platforms/omap5.c | 12 ------------
 2 files changed, 3 insertions(+), 28 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 8f1b48e..f68755f 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1104,22 +1104,9 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo,
         return 0;
     }
 
-    /*
-     * Some device doesn't need to be mapped in Xen:
-     *  - Memory: the guest will see a different view of memory. It will
-     *  be allocated later.
-     *  - Disabled device: Linux is able to cope with status="disabled"
-     *  property. Therefore these device doesn't need to be mapped. This
-     *  solution can be use later for pass through.
-     */
-    if ( !dt_device_type_is_equal(node, "memory") &&
-         dt_device_is_available(node) )
-    {
-        res = map_device(d, node);
-
-        if ( res )
-            return res;
-    }
+    res = map_device(d, node);
+    if ( res)
+        return res;
 
     /*
      * The property "name" is used to have a different name on older FDT
diff --git a/xen/arch/arm/platforms/omap5.c b/xen/arch/arm/platforms/omap5.c
index 9d6e504..e7bf30d 100644
--- a/xen/arch/arm/platforms/omap5.c
+++ b/xen/arch/arm/platforms/omap5.c
@@ -155,17 +155,6 @@ static const char * const dra7_dt_compat[] __initconst =
     NULL
 };
 
-static const struct dt_device_match dra7_blacklist_dev[] __initconst =
-{
-    /* OMAP Linux kernel handles devices with status "disabled" in a
-     * weird manner - tries to reset them. While their memory ranges
-     * are not mapped, this leads to data aborts, so skip these devices
-     * from DT for dom0.
-     */
-    DT_MATCH_NOT_AVAILABLE(),
-    { /* sentinel */ },
-};
-
 PLATFORM_START(omap5, "TI OMAP5")
     .compatible = omap5_dt_compat,
     .init_time = omap5_init_time,
@@ -185,7 +174,6 @@ PLATFORM_START(dra7, "TI DRA7")
 
     .dom0_gnttab_start = 0x4b000000,
     .dom0_gnttab_size = 0x20000,
-    .blacklist_dev = dra7_blacklist_dev,
 PLATFORM_END
 
 /*
-- 
2.1.4

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

* [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (5 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 06/24] xen/arm: Map disabled device in DOM0 Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-28 16:36   ` Stefano Stabellini
                     ` (2 more replies)
  2015-01-13 14:25 ` [PATCH v3 08/24] xen/arm: Allow virq != irq Julien Grall
                   ` (18 subsequent siblings)
  25 siblings, 3 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

When a device is marked for passthrough (via the new property "xen,passthrough"),
dom0 must not access to the device (i.e not loading a driver), but should
be able to manage the MMIO/interrupt of the passthrough device.

The latter part will allow the toolstack to map MMIO/IRQ when a device
is pass through to a guest.

The property "xen,passthrough" will be translated as 'status="disabled"'
in the device tree to avoid DOM0 using the device. We assume that DOM0 is
able to cope with this property (already the case for Linux).

Rework the function map_device (renamed into handle_device) to:

* For a given device node:
    - Give permission to manage IRQ/MMIO for this device
    - Retrieve the IRQ configuration (i.e edge/level) from the device
    tree
* When the device is not marked for guest passthrough:
    - Assign the device to the guest if it's protected by an IOMMU
    - Map the IRQs and MMIOs regions to the guest

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v3:
        - This patch was formely "xen/arm: Follow-up to allow DOM0
        manage IRQ and MMIO". It has been split in 2 parts [1].
        - Update commit title and improve message
        - Remove spurious change

[1] https://patches.linaro.org/34669/
---
 docs/misc/arm/device-tree/passthrough.txt |   7 ++
 xen/arch/arm/device.c                     |   2 +-
 xen/arch/arm/domain_build.c               | 102 ++++++++++++++++++++++--------
 xen/common/device_tree.c                  |   6 ++
 xen/include/xen/device_tree.h             |  11 ++++
 5 files changed, 100 insertions(+), 28 deletions(-)
 create mode 100644 docs/misc/arm/device-tree/passthrough.txt

diff --git a/docs/misc/arm/device-tree/passthrough.txt b/docs/misc/arm/device-tree/passthrough.txt
new file mode 100644
index 0000000..04645b3
--- /dev/null
+++ b/docs/misc/arm/device-tree/passthrough.txt
@@ -0,0 +1,7 @@
+Device passthrough
+===================
+
+Any device that will be passthrough to a guest should have a property
+"xen,passthrough" in their device tree node.
+
+The device won't be exposed to DOM0 and therefore no driver will be loaded.
diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
index 1993929..1a01793 100644
--- a/xen/arch/arm/device.c
+++ b/xen/arch/arm/device.c
@@ -30,7 +30,7 @@ int __init device_init(struct dt_device_node *dev, enum device_match type,
 
     ASSERT(dev != NULL);
 
-    if ( !dt_device_is_available(dev) )
+    if ( !dt_device_is_available(dev) || dt_device_for_passthrough(dev) )
         return  -ENODEV;
 
     for ( desc = _sdevice; desc != _edevice; desc++ )
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index f68755f..b48b5d0 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -402,7 +402,7 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
                             const struct dt_device_node *node)
 {
     const char *bootargs = NULL;
-    const struct dt_property *prop;
+    const struct dt_property *prop, *status = NULL;
     int res = 0;
     int had_dom0_bootargs = 0;
 
@@ -457,6 +457,17 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
             }
         }
 
+        /* Don't expose the property "xen,passthrough" to the guest */
+        if ( dt_property_name_is_equal(prop, "xen,passthrough") )
+            continue;
+
+        /* Remember and skip the status property as Xen may modify it later */
+        if ( dt_property_name_is_equal(prop, "status") )
+        {
+            status = prop;
+            continue;
+        }
+
         res = fdt_property(kinfo->fdt, prop->name, prop_data, prop_len);
 
         xfree(new_data);
@@ -465,6 +476,19 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
             return res;
     }
 
+    /*
+     * Override the property "status" to disable the device when it's
+     * marked for passthrough.
+     */
+    if ( dt_device_for_passthrough(node) )
+        res = fdt_property_string(kinfo->fdt, "status", "disabled");
+    else if ( status )
+        res = fdt_property(kinfo->fdt, "status", status->value,
+                           status->length);
+
+    if ( res )
+        return res;
+
     if ( dt_node_path_is_equal(node, "/chosen") )
     {
         const struct bootmodule *mod = kinfo->initrd_bootmodule;
@@ -919,8 +943,14 @@ static int make_timer_node(const struct domain *d, void *fdt,
     return res;
 }
 
-/* Map the device in the domain */
-static int map_device(struct domain *d, struct dt_device_node *dev)
+/* For a given device node:
+ *  - Give permission to the guest to manage IRQ and MMIO range
+ *  - Retrieve the IRQ configuration (i.e edge/level) from device tree
+ * When the device is not marked for guest passthrough:
+ *  - Assign the device to the guest if it's protected by an IOMMU
+ *  - Map the IRQs and iomem regions to DOM0
+ */
+static int handle_device(struct domain *d, struct dt_device_node *dev)
 {
     unsigned int nirq;
     unsigned int naddr;
@@ -929,13 +959,15 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
     unsigned int irq;
     struct dt_raw_irq rirq;
     u64 addr, size;
+    bool_t need_mapping = !dt_device_for_passthrough(dev);
 
     nirq = dt_number_of_irq(dev);
     naddr = dt_number_of_address(dev);
 
-    DPRINT("%s nirq = %d naddr = %u\n", dt_node_full_name(dev), nirq, naddr);
+    DPRINT("%s passthrough = %d nirq = %d naddr = %u\n", dt_node_full_name(dev),
+           need_mapping, nirq, naddr);
 
-    if ( dt_device_is_protected(dev) )
+    if ( dt_device_is_protected(dev) && need_mapping )
     {
         DPRINT("%s setup iommu\n", dt_node_full_name(dev));
         res = iommu_assign_dt_device(d, dev);
@@ -947,7 +979,7 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
         }
     }
 
-    /* Map IRQs */
+    /* Give permission and  map IRQs */
     for ( i = 0; i < nirq; i++ )
     {
         res = dt_device_get_raw_irq(dev, i, &rirq);
@@ -980,22 +1012,34 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
         irq = res;
 
         DPRINT("irq %u = %u\n", i, irq);
-        /*
-         * Checking the return of vgic_reserve_virq is not
-         * necessary. It should not fail except when we try to map
-         * twice the IRQ. This can happen if the IRQ is shared
-         */
-        vgic_reserve_virq(d, irq);
-        res = route_irq_to_guest(d, irq, dt_node_name(dev));
+
+        res = irq_permit_access(d, irq);
         if ( res )
         {
-            printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
-                   irq, d->domain_id);
+            printk(XENLOG_ERR "Unable to permit to dom%u access to IRQ %u\n",
+                   d->domain_id, irq);
             return res;
         }
+
+        if ( need_mapping )
+        {
+            /*
+             * Checking the return of vgic_reserve_virq is not
+             * necessary. It should not fail except when we try to map
+             * twice the IRQ. This can happen if the IRQ is shared
+             */
+            vgic_reserve_virq(d, irq);
+            res = route_irq_to_guest(d, irq, dt_node_name(dev));
+            if ( res )
+            {
+                printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
+                       irq, d->domain_id);
+                return res;
+            }
+        }
     }
 
-    /* Map the address ranges */
+    /* Give permission and map MMIOs */
     for ( i = 0; i < naddr; i++ )
     {
         res = dt_device_get_address(dev, i, &addr, &size);
@@ -1019,17 +1063,21 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
                    addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1);
             return res;
         }
-        res = map_mmio_regions(d,
-                               paddr_to_pfn(addr & PAGE_MASK),
-                               DIV_ROUND_UP(size, PAGE_SIZE),
-                               paddr_to_pfn(addr & PAGE_MASK));
-        if ( res )
+
+        if ( need_mapping )
         {
-            printk(XENLOG_ERR "Unable to map 0x%"PRIx64
-                   " - 0x%"PRIx64" in domain %d\n",
-                   addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1,
-                   d->domain_id);
-            return res;
+            res = map_mmio_regions(d,
+                                   paddr_to_pfn(addr & PAGE_MASK),
+                                   DIV_ROUND_UP(size, PAGE_SIZE),
+                                   paddr_to_pfn(addr & PAGE_MASK));
+            if ( res )
+            {
+                printk(XENLOG_ERR "Unable to map 0x%"PRIx64
+                       " - 0x%"PRIx64" in domain %d\n",
+                       addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1,
+                       d->domain_id);
+                return res;
+            }
         }
     }
 
@@ -1104,7 +1152,7 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo,
         return 0;
     }
 
-    res = map_device(d, node);
+    res = handle_device(d, node);
     if ( res)
         return res;
 
diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index bb9d7ce..ce10574 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -1103,6 +1103,12 @@ bool_t dt_device_is_available(const struct dt_device_node *device)
     return 0;
 }
 
+bool_t dt_device_for_passthrough(const struct dt_device_node *device)
+{
+    return (dt_find_property(device, "xen,passthrough", NULL) != NULL);
+
+}
+
 static int __dt_parse_phandle_with_args(const struct dt_device_node *np,
                                         const char *list_name,
                                         const char *cells_name,
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index 890d356..caaf65f 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -555,6 +555,17 @@ int dt_n_addr_cells(const struct dt_device_node *np);
 bool_t dt_device_is_available(const struct dt_device_node *device);
 
 /**
+ * dt_device_for_passthrough - Check if a device will be used for
+ * passthrough later
+ *
+ * @device: Node to check
+ *
+ * Return true if the property "xen,passthrough" is present in the node,
+ * false otherwise.
+ */
+bool_t dt_device_for_passthrough(const struct dt_device_node *device);
+
+/**
  * dt_match_node - Tell if a device_node has a matching of dt_device_match
  * @matches: array of dt_device_match structures to search in
  * @node: the dt_device_node structure to match against
-- 
2.1.4

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

* [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (6 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-28 16:47   ` Stefano Stabellini
  2015-02-20 15:52   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ Julien Grall
                   ` (17 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

Actually Xen is assuming that the virtual IRQ will always be the same as IRQ.

Modify route_guest_irq to take the virtual IRQ in parameter and let Xen
assign a different IRQ number. Also store the vIRQ in the desc action to
easily retrieve easily the IRQ target when we need to inject the interrupt.

As DOM0 will get most the devices, the vIRQ is equal to the IRQ in that case.

At the same time modify the behavior of irq_get_domain. The function now
assumes that the irq_desc belongs to an IRQ assigned to a guest.

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v3
        - Spelling/grammar nits
        - Fix compilation on ARM64. Forgot to update route_irq_to_guest
          call for xgene platform.
        - Add a word about irq_get_domain behavior change
        - More s/irq/virq/ because of the rebasing on the latest staging

    Changes in v2:
        - Patch added
---
 xen/arch/arm/domain_build.c          |  2 +-
 xen/arch/arm/gic.c                   |  5 ++--
 xen/arch/arm/irq.c                   | 47 ++++++++++++++++++++++++++----------
 xen/arch/arm/platforms/xgene-storm.c |  2 +-
 xen/arch/arm/vgic.c                  | 20 +++++++--------
 xen/include/asm-arm/gic.h            |  3 ++-
 xen/include/asm-arm/irq.h            |  4 +--
 xen/include/asm-arm/vgic.h           |  4 +--
 8 files changed, 55 insertions(+), 32 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index b48b5d0..06c1dec 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1029,7 +1029,7 @@ static int handle_device(struct domain *d, struct dt_device_node *dev)
              * twice the IRQ. This can happen if the IRQ is shared
              */
             vgic_reserve_virq(d, irq);
-            res = route_irq_to_guest(d, irq, dt_node_name(dev));
+            res = route_irq_to_guest(d, irq, irq, dt_node_name(dev));
             if ( res )
             {
                 printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index eb0c5d6..15de283 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -126,7 +126,8 @@ void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
 /* Program the GIC to route an interrupt to a guest
  *   - desc.lock must be held
  */
-void gic_route_irq_to_guest(struct domain *d, struct irq_desc *desc,
+void gic_route_irq_to_guest(struct domain *d, unsigned int virq,
+                            struct irq_desc *desc,
                             const cpumask_t *cpu_mask, unsigned int priority)
 {
     struct pending_irq *p;
@@ -139,7 +140,7 @@ void gic_route_irq_to_guest(struct domain *d, struct irq_desc *desc,
 
     /* Use vcpu0 to retrieve the pending_irq struct. Given that we only
      * route SPIs to guests, it doesn't make any difference. */
-    p = irq_to_pending(d->vcpu[0], desc->irq);
+    p = irq_to_pending(d->vcpu[0], virq);
     p->desc = desc;
 }
 
diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index 25ecf1d..830832c 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -31,6 +31,13 @@
 static unsigned int local_irqs_type[NR_LOCAL_IRQS];
 static DEFINE_SPINLOCK(local_irqs_type_lock);
 
+/* Describe an IRQ assigned to a guest */
+struct irq_guest
+{
+    struct domain *d;
+    unsigned int virq;
+};
+
 static void ack_none(struct irq_desc *irq)
 {
     printk("unexpected IRQ trap at irq %02x\n", irq->irq);
@@ -122,18 +129,20 @@ void __cpuinit init_secondary_IRQ(void)
     BUG_ON(init_local_irq_data() < 0);
 }
 
-static inline struct domain *irq_get_domain(struct irq_desc *desc)
+static inline struct irq_guest *irq_get_guest_info(struct irq_desc *desc)
 {
     ASSERT(spin_is_locked(&desc->lock));
-
-    if ( !test_bit(_IRQ_GUEST, &desc->status) )
-        return dom_xen;
-
+    ASSERT(test_bit(_IRQ_GUEST, &desc->status));
     ASSERT(desc->action != NULL);
 
     return desc->action->dev_id;
 }
 
+static inline struct domain *irq_get_domain(struct irq_desc *desc)
+{
+    return irq_get_guest_info(desc)->d;
+}
+
 void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
 {
     if ( desc != NULL )
@@ -197,7 +206,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq)
 
     if ( test_bit(_IRQ_GUEST, &desc->status) )
     {
-        struct domain *d = irq_get_domain(desc);
+        struct irq_guest *info = irq_get_guest_info(desc);
 
         desc->handler->end(desc);
 
@@ -206,7 +215,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq)
 
         /* the irq cannot be a PPI, we only support delivery of SPIs to
          * guests */
-        vgic_vcpu_inject_spi(d, irq);
+        vgic_vcpu_inject_spi(info->d, info->virq);
         goto out_no_end;
     }
 
@@ -370,19 +379,30 @@ err:
     return rc;
 }
 
-int route_irq_to_guest(struct domain *d, unsigned int irq,
-                       const char * devname)
+int route_irq_to_guest(struct domain *d, unsigned int virq,
+                       unsigned int irq, const char * devname)
 {
     struct irqaction *action;
-    struct irq_desc *desc = irq_to_desc(irq);
+    struct irq_guest *info;
+    struct irq_desc *desc;
     unsigned long flags;
     int retval = 0;
 
     action = xmalloc(struct irqaction);
-    if (!action)
+    if ( !action )
+        return -ENOMEM;
+
+    info = xmalloc(struct irq_guest);
+    if ( !info )
+    {
+        xfree(action);
         return -ENOMEM;
+    }
+
+    info->d = d;
+    info->virq = virq;
 
-    action->dev_id = d;
+    action->dev_id = info;
     action->name = devname;
     action->free_on_release = 1;
 
@@ -413,7 +433,7 @@ int route_irq_to_guest(struct domain *d, unsigned int irq,
     if ( retval )
         goto out;
 
-    gic_route_irq_to_guest(d, desc, cpumask_of(smp_processor_id()),
+    gic_route_irq_to_guest(d, virq, desc, cpumask_of(smp_processor_id()),
                            GIC_PRI_IRQ);
     spin_unlock_irqrestore(&desc->lock, flags);
     return 0;
@@ -421,6 +441,7 @@ int route_irq_to_guest(struct domain *d, unsigned int irq,
 out:
     spin_unlock_irqrestore(&desc->lock, flags);
     xfree(action);
+    xfree(info);
 
     return retval;
 }
diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
index b0808b8..e2f8b89 100644
--- a/xen/arch/arm/platforms/xgene-storm.c
+++ b/xen/arch/arm/platforms/xgene-storm.c
@@ -75,7 +75,7 @@ static int map_one_spi(struct domain *d, const char *what,
         printk("Failed to reserve the vIRQ %u on dom%d\n",
                irq, d->domain_id);
 
-    ret = route_irq_to_guest(d, irq, what);
+    ret = route_irq_to_guest(d, irq, irq, what);
     if ( ret )
         printk("Failed to route %s to dom%d\n", what, d->domain_id);
 
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 38216f7..c915670 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -380,16 +380,16 @@ void vgic_clear_pending_irqs(struct vcpu *v)
     spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
 }
 
-void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq)
+void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq)
 {
     uint8_t priority;
-    struct vgic_irq_rank *rank = vgic_rank_irq(v, irq);
-    struct pending_irq *iter, *n = irq_to_pending(v, irq);
+    struct vgic_irq_rank *rank = vgic_rank_irq(v, virq);
+    struct pending_irq *iter, *n = irq_to_pending(v, virq);
     unsigned long flags;
     bool_t running;
 
     vgic_lock_rank(v, rank, flags);
-    priority = v->domain->arch.vgic.handler->get_irq_priority(v, irq);
+    priority = v->domain->arch.vgic.handler->get_irq_priority(v, virq);
     vgic_unlock_rank(v, rank, flags);
 
     spin_lock_irqsave(&v->arch.vgic.lock, flags);
@@ -405,7 +405,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq)
 
     if ( !list_empty(&n->inflight) )
     {
-        gic_raise_inflight_irq(v, irq);
+        gic_raise_inflight_irq(v, virq);
         goto out;
     }
 
@@ -413,7 +413,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq)
 
     /* the irq is enabled */
     if ( test_bit(GIC_IRQ_GUEST_ENABLED, &n->status) )
-        gic_raise_guest_irq(v, irq, priority);
+        gic_raise_guest_irq(v, virq, priority);
 
     list_for_each_entry ( iter, &v->arch.vgic.inflight_irqs, inflight )
     {
@@ -433,15 +433,15 @@ out:
         smp_send_event_check_mask(cpumask_of(v->processor));
 }
 
-void vgic_vcpu_inject_spi(struct domain *d, unsigned int irq)
+void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq)
 {
     struct vcpu *v;
 
     /* the IRQ needs to be an SPI */
-    ASSERT(irq >= 32 && irq <= gic_number_lines());
+    ASSERT(virq >= 32 && virq <= vgic_num_irqs(d));
 
-    v = vgic_get_target_vcpu(d->vcpu[0], irq);
-    vgic_vcpu_inject_irq(v, irq);
+    v = vgic_get_target_vcpu(d->vcpu[0], virq);
+    vgic_vcpu_inject_irq(v, virq);
 }
 
 void arch_evtchn_inject(struct vcpu *v)
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 6286c71..cf9f257 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -213,7 +213,8 @@ extern enum gic_version gic_hw_version(void);
 /* Program the GIC to route an interrupt */
 extern void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
                                  unsigned int priority);
-extern void gic_route_irq_to_guest(struct domain *, struct irq_desc *desc,
+extern void gic_route_irq_to_guest(struct domain *, unsigned int virq,
+                                   struct irq_desc *desc,
                                    const cpumask_t *cpu_mask,
                                    unsigned int priority);
 
diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
index 435dfcd..f00eb11 100644
--- a/xen/include/asm-arm/irq.h
+++ b/xen/include/asm-arm/irq.h
@@ -40,8 +40,8 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq);
 void init_IRQ(void);
 void init_secondary_IRQ(void);
 
-int route_irq_to_guest(struct domain *d, unsigned int irq,
-                       const char *devname);
+int route_irq_to_guest(struct domain *d, unsigned int virq,
+                       unsigned int irq, const char *devname);
 void arch_move_irqs(struct vcpu *v);
 
 /* Set IRQ type for an SPI */
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 8582d9d..1cd7808 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -181,8 +181,8 @@ extern int domain_vgic_init(struct domain *d);
 extern void domain_vgic_free(struct domain *d);
 extern int vcpu_vgic_init(struct vcpu *v);
 extern struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int irq);
-extern void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq);
-extern void vgic_vcpu_inject_spi(struct domain *d, unsigned int irq);
+extern void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq);
+extern void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq);
 extern void vgic_clear_pending_irqs(struct vcpu *v);
 extern struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq);
 extern struct vgic_irq_rank *vgic_rank_offset(struct vcpu *v, int b, int n, int s);
-- 
2.1.4

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

* [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (7 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 08/24] xen/arm: Allow virq != irq Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-28 17:55   ` Stefano Stabellini
  2015-02-20 16:00   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest Julien Grall
                   ` (16 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

Currently Xen only supports SPIs routing for guest, add a function
is_assignable_irq to check if we can assign a given IRQ to the guest.

Secondly, make sure the vIRQ is not the greater that the number of IRQs handle
to the vGIC and it's an SPIs.

Thirdly, when the IRQ is already assigned to the domain, check the user
is not asking to use a different vIRQ than the one already bound.

Finally, desc->arch.type which contains the IRQ type (i.e level/edge) must
be correctly configured before. The IRQ type won't be configure when:
    - the device has been blacklist for the current platform
    - the IRQ has not been describe in the device tree

I think we can safely assume that a user won't never ask to route
as such IRQ to the guest.

Also, use XENLOG_G_ERR in the error message within the function as it will
be later called from a guest.

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v3:
        - Fix typo in commit message and comment
        - Add a check that the vIRQ is an SPI
        - Check if the user is not asking for a different vIRQ when the
        IRQ is already assigned to the guest

    Changes in v2:
        - Rename is_routable_irq into is_assignable_irq
        - Check if the IRQ is not greater than the number handled by the
        number of IRQs handled by the gic
        - Move is_assignable_irq in irq.c rather than defining in the
        header irq.h
        - Retrieve the irq descriptor after checking the validity of the
        IRQ
        - vgic_num_irqs has been moved in a separate patch
        - Fix the irq check against vgic_num_irqs
        - Use virq instead of irq for vGIC sanity check
---
 xen/arch/arm/irq.c        | 58 +++++++++++++++++++++++++++++++++++++++++++----
 xen/include/asm-arm/irq.h |  2 ++
 2 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index 830832c..af408ac 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -379,6 +379,15 @@ err:
     return rc;
 }
 
+bool_t is_assignable_irq(unsigned int irq)
+{
+    /* For now, we can only route SPIs to the guest */
+    return ((irq >= NR_LOCAL_IRQS) && (irq < gic_number_lines()));
+}
+
+/* Route an IRQ to a specific guest.
+ * For now only SPIs are assignabled to the guest.
+ */
 int route_irq_to_guest(struct domain *d, unsigned int virq,
                        unsigned int irq, const char * devname)
 {
@@ -388,6 +397,29 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
     unsigned long flags;
     int retval = 0;
 
+    if ( !is_assignable_irq(irq) )
+    {
+        dprintk(XENLOG_G_ERR, "the IRQ%u is not routable\n", irq);
+        return -EINVAL;
+    }
+
+    desc = irq_to_desc(irq);
+
+    if ( virq >= vgic_num_irqs(d) )
+    {
+        dprintk(XENLOG_G_ERR,
+                "the vIRQ number %u is too high for domain %u (max = %u)\n",
+                irq, d->domain_id, vgic_num_irqs(d));
+        return -EINVAL;
+    }
+
+    /* Only routing to virtual SPIs is supported */
+    if ( virq < 32 )
+    {
+        dprintk(XENLOG_G_ERR, "IRQ can only be routed to a virtual SPIs");
+        return -EINVAL;
+    }
+
     action = xmalloc(struct irqaction);
     if ( !action )
         return -ENOMEM;
@@ -408,8 +440,18 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
 
     spin_lock_irqsave(&desc->lock, flags);
 
+    if ( desc->arch.type == DT_IRQ_TYPE_INVALID )
+    {
+        dprintk(XENLOG_G_ERR, "IRQ %u has not been configured\n",
+                irq);
+        retval = -EIO;
+        goto out;
+    }
+
     /* If the IRQ is already used by someone
-     *  - If it's the same domain -> Xen doesn't need to update the IRQ desc
+     *  - If it's the same domain -> Xen doesn't need to update the IRQ desc.
+     *  For safety check if we are not trying to assign the IRQ to a
+     *  different vIRQ.
      *  - Otherwise -> For now, don't allow the IRQ to be shared between
      *  Xen and domains.
      */
@@ -418,13 +460,21 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
         struct domain *ad = irq_get_domain(desc);
 
         if ( test_bit(_IRQ_GUEST, &desc->status) && d == ad )
+        {
+            if ( irq_get_guest_info(desc)->virq != virq )
+            {
+                dprintk(XENLOG_G_ERR, "d%u: IRQ %u is already assigned to vIRQ %u\n",
+                        d->domain_id, irq, irq_get_guest_info(desc)->virq);
+                retval = -EPERM;
+            }
             goto out;
+        }
 
         if ( test_bit(_IRQ_GUEST, &desc->status) )
-            printk(XENLOG_ERR "ERROR: IRQ %u is already used by domain %u\n",
-                   irq, ad->domain_id);
+            dprintk(XENLOG_G_ERR, "IRQ %u is already used by domain %u\n",
+                    irq, ad->domain_id);
         else
-            printk(XENLOG_ERR "ERROR: IRQ %u is already used by Xen\n", irq);
+            dprintk(XENLOG_G_ERR, "IRQ %u is already used by Xen\n", irq);
         retval = -EBUSY;
         goto out;
     }
diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
index f00eb11..71b39e7 100644
--- a/xen/include/asm-arm/irq.h
+++ b/xen/include/asm-arm/irq.h
@@ -37,6 +37,8 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq);
 
 #define domain_pirq_to_irq(d, pirq) (pirq)
 
+bool_t is_assignable_irq(unsigned int irq);
+
 void init_IRQ(void);
 void init_secondary_IRQ(void);
 
-- 
2.1.4

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

* [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (8 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-28 18:15   ` Stefano Stabellini
  2015-02-20 16:07   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs Julien Grall
                   ` (15 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

With the addition of interrupt assignment to guest, we need to make sure
the guest don't blow up the interrupt management in Xen.

Before associating the IRQ to a vIRQ we need to make sure:
    - the vIRQ is not already associated to another IRQ
    - the guest didn't enable the vIRQ

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v3:
        - Patch added
---
 xen/arch/arm/gic.c        | 34 ++++++++++++++++++++++++++--------
 xen/arch/arm/irq.c        | 12 ++++++++++--
 xen/include/asm-arm/gic.h |  7 +++----
 3 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 15de283..240870f 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -126,22 +126,40 @@ void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
 /* Program the GIC to route an interrupt to a guest
  *   - desc.lock must be held
  */
-void gic_route_irq_to_guest(struct domain *d, unsigned int virq,
-                            struct irq_desc *desc,
-                            const cpumask_t *cpu_mask, unsigned int priority)
+int gic_route_irq_to_guest(struct domain *d, unsigned int virq,
+                           struct irq_desc *desc, unsigned int priority)
 {
-    struct pending_irq *p;
+    unsigned long flags;
+    /* Use vcpu0 to retrieve the pending_irq struct. Given that we only
+     * route SPIs to guests, it doesn't make any difference. */
+    struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq);
+    struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq);
+    struct pending_irq *p = irq_to_pending(v_target, virq);
+    int res = -EBUSY;
+
     ASSERT(spin_is_locked(&desc->lock));
+    /* We only support SPIs */
+    ASSERT(virq >= 32 && virq < vgic_num_irqs(d));
+
+    vgic_lock_rank(v_target, rank, flags);
+
+    if ( p->desc ||
+         /* The VIRQ should not be already enabled by the guest */
+         test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) )
+        goto out;
 
     desc->handler = gic_hw_ops->gic_guest_irq_type;
     set_bit(_IRQ_GUEST, &desc->status);
 
-    gic_set_irq_properties(desc, cpumask_of(smp_processor_id()), GIC_PRI_IRQ);
+    gic_set_irq_properties(desc, cpumask_of(v_target->processor), priority);
 
-    /* Use vcpu0 to retrieve the pending_irq struct. Given that we only
-     * route SPIs to guests, it doesn't make any difference. */
-    p = irq_to_pending(d->vcpu[0], virq);
     p->desc = desc;
+    res = 0;
+
+out:
+    vgic_unlock_rank(v_target, rank, flags);
+
+    return res;
 }
 
 int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index af408ac..0072347 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -483,14 +483,22 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
     if ( retval )
         goto out;
 
-    gic_route_irq_to_guest(d, virq, desc, cpumask_of(smp_processor_id()),
-                           GIC_PRI_IRQ);
+    retval = gic_route_irq_to_guest(d, virq, desc, GIC_PRI_IRQ);
+
     spin_unlock_irqrestore(&desc->lock, flags);
+
+    if ( retval )
+    {
+        release_irq(desc->irq, info);
+        goto free_info;
+    }
+
     return 0;
 
 out:
     spin_unlock_irqrestore(&desc->lock, flags);
     xfree(action);
+free_info:
     xfree(info);
 
     return retval;
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index cf9f257..a8ac294 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -213,10 +213,9 @@ extern enum gic_version gic_hw_version(void);
 /* Program the GIC to route an interrupt */
 extern void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
                                  unsigned int priority);
-extern void gic_route_irq_to_guest(struct domain *, unsigned int virq,
-                                   struct irq_desc *desc,
-                                   const cpumask_t *cpu_mask,
-                                   unsigned int priority);
+extern int gic_route_irq_to_guest(struct domain *, unsigned int virq,
+                                  struct irq_desc *desc,
+                                  unsigned int priority);
 
 extern void gic_inject(void);
 extern void gic_clear_pending_irqs(struct vcpu *v);
-- 
2.1.4

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

* [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (9 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-28 18:26   ` Stefano Stabellini
  2015-02-20 16:23   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying Julien Grall
                   ` (14 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, ian.campbell, tim, Julien Grall, Ian Jackson,
	stefano.stabellini, Jan Beulich

Each domain may have a different number of IRQs depending on the devices
assigned to it.

Rather re-using the number of IRQs used by the hardwared GIC, let the
toolstack specify the number of SPIs when the domain is created. This
will avoid to waste memory.

To calculate the number of SPIs, we assume that any IRQ given via the option
"irqs=" in xl is mapped 1:1 to the guest.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Wei Liu <wei.liu2@citrix.com>

---
    Changes in v3:
        - Fix typoes
        - A separate has been created to extend the DOMCTL create domain

    Changes in v2:
        - Patch added
---
 tools/libxc/xc_domain.c       |  1 +
 tools/libxl/libxl_arm.c       | 19 +++++++++++++++++++
 xen/arch/arm/domain.c         |  7 ++++++-
 xen/arch/arm/setup.c          |  1 +
 xen/arch/arm/vgic.c           | 10 +++++-----
 xen/include/asm-arm/domain.h  |  2 ++
 xen/include/asm-arm/setup.h   |  1 +
 xen/include/asm-arm/vgic.h    |  2 +-
 xen/include/public/arch-arm.h |  2 ++
 9 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index eebc121..eb066cf 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -67,6 +67,7 @@ int xc_domain_create(xc_interface *xch,
     /* No arch-specific configuration for now */
 #elif defined (__arm__) || defined(__aarch64__)
     config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
+    config.nr_spis = 0;
 #else
     errno = ENOSYS;
     return -1;
diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index cddce6e..53177eb 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -39,6 +39,25 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
                                       libxl_domain_config *d_config,
                                       xc_domain_configuration_t *xc_config)
 {
+    uint32_t nr_spis = 0;
+    unsigned int i;
+
+    for (i = 0; i < d_config->b_info.num_irqs; i++) {
+        int irq = d_config->b_info.irqs[i];
+        int spi = irq - 32;
+
+        if (irq < 32)
+            continue;
+
+        if (nr_spis <= spi)
+            nr_spis = spi + 1;
+    }
+
+    LOG(DEBUG, "Configure the domain");
+
+    xc_config->nr_spis = nr_spis;
+    LOG(DEBUG, " - Allocate %u SPIs", nr_spis);
+
     xc_config->gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
 
     return 0;
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 2473b10..6e56665 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -560,10 +560,15 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
     }
     config->gic_version = gic_version;
 
+    /* Sanity check on the number of SPIs */
+    rc = -EINVAL;
+    if ( config->nr_spis > (gic_number_lines() - 32) )
+        goto fail;
+
     if ( (rc = gicv_setup(d)) != 0 )
         goto fail;
 
-    if ( (rc = domain_vgic_init(d)) != 0 )
+    if ( (rc = domain_vgic_init(d, config->nr_spis)) != 0 )
         goto fail;
 
     if ( (rc = domain_vtimer_init(d)) != 0 )
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 18227f6..b28a708 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -815,6 +815,7 @@ void __init start_xen(unsigned long boot_phys_offset,
     /* Create initial domain 0. */
     /* The vGIC for DOM0 is exactly emulated the hardware GIC */
     config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
+    config.nr_spis = gic_number_lines() - 32;
 
     dom0 = domain_create(0, 0, 0, &config);
     if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index c915670..fc8a270 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -67,16 +67,16 @@ static void vgic_init_pending_irq(struct pending_irq *p, unsigned int virq)
     p->irq = virq;
 }
 
-int domain_vgic_init(struct domain *d)
+int domain_vgic_init(struct domain *d, unsigned int nr_spis)
 {
     int i;
 
     d->arch.vgic.ctlr = 0;
 
-    if ( is_hardware_domain(d) )
-        d->arch.vgic.nr_spis = gic_number_lines() - 32;
-    else
-        d->arch.vgic.nr_spis = 0; /* We don't need SPIs for the guest */
+    /* The number of SPIs has to be aligned to 32 see
+     * GICD_TYPER.ITLinesNumber definition
+     */
+    d->arch.vgic.nr_spis = ROUNDUP(nr_spis, 32);
 
     switch ( gic_hw_version() )
     {
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index d302fc9..101b4e9 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -121,6 +121,8 @@ struct arch_domain
     unsigned int evtchn_irq;
 }  __cacheline_aligned;
 
+#define domain_is_configured(d) ((d)->arch.is_configured)
+
 struct arch_vcpu
 {
     struct {
diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h
index ba5a67d..254cc17 100644
--- a/xen/include/asm-arm/setup.h
+++ b/xen/include/asm-arm/setup.h
@@ -54,6 +54,7 @@ void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 void arch_get_xen_caps(xen_capabilities_info_t *info);
 
 int construct_dom0(struct domain *d);
+int configure_dom0(struct domain *d);
 
 void discard_initial_modules(void);
 
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 1cd7808..e97a5eb 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -177,7 +177,7 @@ enum gic_sgi_mode;
 
 #define vgic_num_irqs(d)        ((d)->arch.vgic.nr_spis + 32)
 
-extern int domain_vgic_init(struct domain *d);
+extern int domain_vgic_init(struct domain *d, unsigned int nr_spis);
 extern void domain_vgic_free(struct domain *d);
 extern int vcpu_vgic_init(struct vcpu *v);
 extern struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int irq);
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index 4c1b9f9..45d3b1f 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -320,6 +320,8 @@ typedef uint64_t xen_callback_t;
 struct xen_arch_domainconfig {
     /* IN/OUT */
     uint8_t gic_version;
+    /* IN */
+    uint32_t nr_spis;
 };
 
 #endif
-- 
2.1.4

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

* [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (10 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-28 18:38   ` Stefano Stabellini
  2015-02-20 16:31   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq Julien Grall
                   ` (13 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

Xen has to release IRQ routed to a domain in order to reuse later. Currently
only SPIs can be routed to the guest so we only need to browse SPIs for a
specific domain.

Futhermore, a guest can crash and let the IRQ in an incorrect state (i.e has
not being EOIed). Xen will have to reset the IRQ in order to be able to reuse
the IRQ later.

Introduce 2 new functions for release an IRQ routed to a domain:
    - release_guest_irq: upper level to retrieve the IRQ, call the GIC
    code and release the action
    - gic_remove_guest_irq: Check if we can remove the IRQ, and reset
    it if necessary

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v3:
        - Take the vgic rank lock to protect p->desc
        - Correctly check if the IRQ is disabled
        - Extend the check on the virq in release_guest_irq
        - Use vgic_get_target_vcpu to get the target vCPU
        - Remove spurious change

    Changes in v2:
        - Drop the desc->handler = &no_irq_type in release_irq as it's
        buggy if the IRQ is routed to Xen
        - Add release_guest_irq and gic_remove_guest_irq
---
 xen/arch/arm/gic.c        | 46 +++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/irq.c        | 48 +++++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/vgic.c       | 16 ++++++++++++++++
 xen/include/asm-arm/gic.h |  4 ++++
 xen/include/asm-arm/irq.h |  2 ++
 5 files changed, 116 insertions(+)

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 240870f..bb298e9 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -162,6 +162,52 @@ out:
     return res;
 }
 
+/* This function only works with SPIs for now */
+int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
+                              struct irq_desc *desc)
+{
+    struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq);
+    struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq);
+    struct pending_irq *p = irq_to_pending(v_target, virq);
+    unsigned long flags;
+
+    ASSERT(spin_is_locked(&desc->lock));
+    ASSERT(test_bit(_IRQ_GUEST, &desc->status));
+    ASSERT(p->desc == desc);
+
+    vgic_lock_rank(v_target, rank, flags);
+
+    /* If the IRQ is removed when the domain is dying, we only need to
+     * EOI the IRQ if it has not been done by the guest
+     */
+    if ( d->is_dying )
+    {
+        desc->handler->shutdown(desc);
+        if ( test_bit(_IRQ_INPROGRESS, &desc->status) )
+            gic_hw_ops->deactivate_irq(desc);
+        clear_bit(_IRQ_INPROGRESS, &desc->status);
+        goto end;
+    }
+
+    /* TODO: Handle eviction from LRs. For now, deny remove if the IRQ
+     * is inflight and not disabled.
+     */
+    if ( test_bit(_IRQ_INPROGRESS, &desc->status) ||
+         !test_bit(_IRQ_DISABLED, &desc->status) )
+        return -EBUSY;
+
+end:
+    clear_bit(_IRQ_GUEST, &desc->status);
+    desc->handler = &no_irq_type;
+
+    p->desc = NULL;
+
+    vgic_unlock_rank(v_target, rank, flags);
+
+
+    return 0;
+}
+
 int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
                   unsigned int *out_hwirq,
                   unsigned int *out_type)
diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index 0072347..ce5ae1a 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -504,6 +504,54 @@ free_info:
     return retval;
 }
 
+int release_guest_irq(struct domain *d, unsigned int virq)
+{
+    struct irq_desc *desc;
+    struct irq_guest *info;
+    unsigned long flags;
+    struct pending_irq *p;
+    int ret;
+
+    /* Only SPIs are supported */
+    if ( virq < 32 || virq >= vgic_num_irqs(d) )
+        return -EINVAL;
+
+    p = irq_to_pending(d->vcpu[0], virq);
+    if ( !p->desc )
+        return -EINVAL;
+
+    desc = p->desc;
+
+    spin_lock_irqsave(&desc->lock, flags);
+
+    ret = -EINVAL;
+    if ( !test_bit(_IRQ_GUEST, &desc->status) )
+        goto unlock;
+
+    ret = -EINVAL;
+
+    info = irq_get_guest_info(desc);
+    if ( d != info->d )
+        goto unlock;
+
+    ret = gic_remove_irq_from_guest(d, virq, desc);
+
+    spin_unlock_irqrestore(&desc->lock, flags);
+
+    if ( !ret )
+    {
+        release_irq(desc->irq, info);
+        xfree(info);
+    }
+
+    return ret;
+
+unlock:
+    spin_unlock_irqrestore(&desc->lock, flags);
+
+    return ret;
+}
+
 /*
  * pirq event channels. We don't use these on ARM, instead we use the
  * features of the GIC to inject virtualised normal interrupts.
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index fc8a270..4ddfd73 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -133,6 +133,22 @@ void register_vgic_ops(struct domain *d, const struct vgic_ops *ops)
 
 void domain_vgic_free(struct domain *d)
 {
+    int i;
+    int ret;
+
+    for ( i = 0; i < (d->arch.vgic.nr_spis); i++ )
+    {
+        struct pending_irq *p = &d->arch.vgic.pending_irqs[i];
+
+        if ( p->desc )
+        {
+            ret = release_guest_irq(d, p->irq);
+            if ( ret )
+                dprintk(XENLOG_G_WARNING, "d%u: Failed to release virq %u ret = %d\n",
+                        d->domain_id, p->irq, ret);
+        }
+    }
+
     xfree(d->arch.vgic.shared_irqs);
     xfree(d->arch.vgic.pending_irqs);
     xfree(d->arch.vgic.allocated_irqs);
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index a8ac294..5571189 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -217,6 +217,10 @@ extern int gic_route_irq_to_guest(struct domain *, unsigned int virq,
                                   struct irq_desc *desc,
                                   unsigned int priority);
 
+/* Remove an IRQ passthrough to a guest */
+int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
+                              struct irq_desc *desc);
+
 extern void gic_inject(void);
 extern void gic_clear_pending_irqs(struct vcpu *v);
 extern int gic_events_need_delivery(void);
diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
index 71b39e7..34b492b 100644
--- a/xen/include/asm-arm/irq.h
+++ b/xen/include/asm-arm/irq.h
@@ -44,6 +44,8 @@ void init_secondary_IRQ(void);
 
 int route_irq_to_guest(struct domain *d, unsigned int virq,
                        unsigned int irq, const char *devname);
+int release_guest_irq(struct domain *d, unsigned int irq);
+
 void arch_move_irqs(struct vcpu *v);
 
 /* Set IRQ type for an SPI */
-- 
2.1.4

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

* [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (11 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-19 16:54   ` Jan Beulich
  2015-01-28 18:52   ` Stefano Stabellini
  2015-01-13 14:25 ` [PATCH v3 14/24] xen/dts: Use unsigned int for MMIO and IRQ index Julien Grall
                   ` (12 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: stefano.stabellini, Julien Grall, tim, ian.campbell, Jan Beulich

The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
assign/deassign a physical IRQ to the guest (via the config options "irqs"
for xl). The x86 version is using them with PIRQ (IRQ bound to an event
channel). As ARM doesn't have a such concept, we could reuse it to bound
a physical IRQ to a virtual IRQ.

For now, we allow only SPIs to be mapped to the guest.
The type MAP_PIRQ_TYPE_GSI is used for this purpose.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Jan Beulich <jbeulich@suse.com>

---
    I'm not sure it's the best solution to reuse hypercalls for a
    different purpose. If x86 plan to have a such concept (i.e binding a
    physical IRQ to a virtual IRQ), we could introduce new hypercalls.
    Any thoughs?

    TODO: This patch is lacking of support of vIRQ != IRQ. I plan to
    handle it correctly on the next version.

    Changes in v3:
        - Functions to allocate/release/reserved a VIRQ has been moved
        in a separate patch
        - Make clear that only MAP_PIRQ_GSI is only supported for now

    Changes in v2:
        - Add PHYSDEVOP_unmap_pirq
        - Rework commit message
        - Add functions to allocate/release a VIRQ
        - is_routable_irq has been renamed into is_assignable_irq
---
 xen/arch/arm/physdev.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 134 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/physdev.c b/xen/arch/arm/physdev.c
index 61b4a18..0cf9bbd 100644
--- a/xen/arch/arm/physdev.c
+++ b/xen/arch/arm/physdev.c
@@ -8,13 +8,145 @@
 #include <xen/types.h>
 #include <xen/lib.h>
 #include <xen/errno.h>
+#include <xen/iocap.h>
+#include <xen/guest_access.h>
+#include <xsm/xsm.h>
+#include <asm/current.h>
 #include <asm/hypercall.h>
+#include <public/physdev.h>
 
+static int physdev_map_pirq(domid_t domid, int type, int index, int *pirq_p)
+{
+    struct domain *d;
+    int ret;
+    int irq = index;
+    int virq;
+
+    d = rcu_lock_domain_by_any_id(domid);
+    if ( d == NULL )
+        return -ESRCH;
+
+    ret = xsm_map_domain_pirq(XSM_TARGET, d);
+    if ( ret )
+        goto free_domain;
+
+    /* For now we only suport GSI */
+    if ( type != MAP_PIRQ_TYPE_GSI )
+    {
+        ret = -EINVAL;
+        dprintk(XENLOG_G_ERR,
+                "dom%u: wrong map_pirq type 0x%x, only MAP_PIRQ_TYPE_GSI is supported.\n",
+                d->domain_id, type);
+        goto free_domain;
+    }
+
+    if ( !is_assignable_irq(irq) )
+    {
+        ret = -EINVAL;
+        dprintk(XENLOG_G_ERR, "IRQ%u is not routable to a guest\n", irq);
+        goto free_domain;
+    }
+
+    ret = -EPERM;
+    if ( !irq_access_permitted(current->domain, irq) )
+        goto free_domain;
+
+    if ( *pirq_p < 0 )
+    {
+        BUG_ON(irq < 16);   /* is_assignable_irq already denies SGIs */
+        virq = vgic_allocate_virq(d, (irq >= 32));
+
+        ret = -ENOSPC;
+        if ( virq < 0 )
+            goto free_domain;
+    }
+    else
+    {
+        ret = -EBUSY;
+        virq = *pirq_p;
+
+        if ( !vgic_reserve_virq(d, virq) )
+            goto free_domain;
+    }
+
+    gdprintk(XENLOG_DEBUG, "irq = %u virq = %u\n", irq, virq);
+
+    ret = route_irq_to_guest(d, virq, irq, "routed IRQ");
+
+    if ( !ret )
+        *pirq_p = virq;
+    else
+        vgic_free_virq(d, virq);
+
+free_domain:
+    rcu_unlock_domain(d);
+
+    return ret;
+}
+
+int physdev_unmap_pirq(domid_t domid, int pirq)
+{
+    struct domain *d;
+    int ret;
+
+    d = rcu_lock_domain_by_any_id(domid);
+    if ( d == NULL )
+        return -ESRCH;
+
+    ret = xsm_unmap_domain_pirq(XSM_TARGET, d);
+    if ( ret )
+        goto free_domain;
+
+    ret = release_guest_irq(d, pirq);
+    if ( ret )
+        goto free_domain;
+
+    vgic_free_virq(d, pirq);
+
+free_domain:
+    rcu_unlock_domain(d);
+
+    return ret;
+}
 
 int do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 {
-    printk("%s %d cmd=%d: not implemented yet\n", __func__, __LINE__, cmd);
-    return -ENOSYS;
+    int ret;
+
+    switch ( cmd )
+    {
+    case PHYSDEVOP_map_pirq:
+        {
+            physdev_map_pirq_t map;
+
+            ret = -EFAULT;
+            if ( copy_from_guest(&map, arg, 1) != 0 )
+                break;
+
+            ret = physdev_map_pirq(map.domid, map.type, map.index, &map.pirq);
+
+            if ( __copy_to_guest(arg, &map, 1) )
+                ret = -EFAULT;
+        }
+        break;
+
+    case PHYSDEVOP_unmap_pirq:
+        {
+            physdev_unmap_pirq_t unmap;
+
+            ret = -EFAULT;
+            if ( copy_from_guest(&unmap, arg, 1) != 0 )
+                break;
+
+            ret = physdev_unmap_pirq(unmap.domid, unmap.pirq);
+        }
+
+    default:
+        ret = -ENOSYS;
+        break;
+    }
+
+    return ret;
 }
 
 /*
-- 
2.1.4

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

* [PATCH v3 14/24] xen/dts: Use unsigned int for MMIO and IRQ index
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (12 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-02-20 16:55   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest Julien Grall
                   ` (11 subsequent siblings)
  25 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

There is no reason to use signed integer for an index.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

---
    Changes in v3:
        - Slightly update commit message to drop the reference to new
        hypercalls.
        - Add Stefano's acked

    Changes in v2:
        - Use unsigned int instead fancy one like unsigned or uint32_t
---
 xen/common/device_tree.c      | 11 ++++++-----
 xen/include/xen/device_tree.h |  7 ++++---
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index ce10574..af73b3b 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -496,7 +496,7 @@ static const struct dt_bus *dt_match_bus(const struct dt_device_node *np)
 }
 
 static const __be32 *dt_get_address(const struct dt_device_node *dev,
-                                    int index, u64 *size,
+                                    unsigned int index, u64 *size,
                                     unsigned int *flags)
 {
     const __be32 *prop;
@@ -683,7 +683,7 @@ bail:
 }
 
 /* dt_device_address - Translate device tree address and return it */
-int dt_device_get_address(const struct dt_device_node *dev, int index,
+int dt_device_get_address(const struct dt_device_node *dev, unsigned int index,
                           u64 *addr, u64 *size)
 {
     const __be32 *addrp;
@@ -1006,7 +1006,8 @@ fail:
     return -EINVAL;
 }
 
-int dt_device_get_raw_irq(const struct dt_device_node *device, int index,
+int dt_device_get_raw_irq(const struct dt_device_node *device,
+                          unsigned int index,
                           struct dt_raw_irq *out_irq)
 {
     const struct dt_device_node *p;
@@ -1014,7 +1015,7 @@ int dt_device_get_raw_irq(const struct dt_device_node *device, int index,
     u32 intsize, intlen;
     int res = -EINVAL;
 
-    dt_dprintk("dt_device_get_raw_irq: dev=%s, index=%d\n",
+    dt_dprintk("dt_device_get_raw_irq: dev=%s, index=%u\n",
                device->full_name, index);
 
     /* Get the interrupts property */
@@ -1071,7 +1072,7 @@ int dt_irq_translate(const struct dt_raw_irq *raw,
                         &out_irq->irq, &out_irq->type);
 }
 
-int dt_device_get_irq(const struct dt_device_node *device, int index,
+int dt_device_get_irq(const struct dt_device_node *device, unsigned int index,
                       struct dt_irq *out_irq)
 {
     struct dt_raw_irq raw;
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index caaf65f..19d0e45 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -474,7 +474,7 @@ const struct dt_device_node *dt_get_parent(const struct dt_device_node *node);
  * This function resolves an address, walking the tree, for a give
  * device-tree node. It returns 0 on success.
  */
-int dt_device_get_address(const struct dt_device_node *dev, int index,
+int dt_device_get_address(const struct dt_device_node *dev, unsigned int index,
                           u64 *addr, u64 *size);
 
 /**
@@ -504,7 +504,7 @@ unsigned int dt_number_of_address(const struct dt_device_node *device);
  * This function resolves an interrupt, walking the tree, for a given
  * device-tree node. It's the high level pendant to dt_device_get_raw_irq().
  */
-int dt_device_get_irq(const struct dt_device_node *device, int index,
+int dt_device_get_irq(const struct dt_device_node *device, unsigned int index,
                       struct dt_irq *irq);
 
 /**
@@ -516,7 +516,8 @@ int dt_device_get_irq(const struct dt_device_node *device, int index,
  * This function resolves an interrupt for a device, no translation is
  * made. dt_irq_translate can be called after.
  */
-int dt_device_get_raw_irq(const struct dt_device_node *device, int index,
+int dt_device_get_raw_irq(const struct dt_device_node *device,
+                          unsigned int index,
                           struct dt_raw_irq *irq);
 
 /**
-- 
2.1.4

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

* [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (13 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 14/24] xen/dts: Use unsigned int for MMIO and IRQ index Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-02-20 16:56   ` Ian Campbell
  2015-02-23 15:30   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct Julien Grall
                   ` (10 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel; +Cc: stefano.stabellini, Julien Grall, tim, ian.campbell

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v3:
        - Use the new prototype of safe_copy_string_from_guest

    Changes in v2:
        - guest_copy_string_from_guest has been renamed into
        safe_copy_string_from_guest
---
 xen/common/device_tree.c      | 19 +++++++++++++++++++
 xen/include/xen/device_tree.h | 17 +++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index af73b3b..4c9daea 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -13,6 +13,7 @@
 #include <xen/config.h>
 #include <xen/types.h>
 #include <xen/init.h>
+#include <xen/guest_access.h>
 #include <xen/device_tree.h>
 #include <xen/kernel.h>
 #include <xen/lib.h>
@@ -23,6 +24,7 @@
 #include <xen/cpumask.h>
 #include <xen/ctype.h>
 #include <asm/setup.h>
+#include <xen/err.h>
 
 const void *device_tree_flattened;
 dt_irq_xlate_func dt_irq_xlate;
@@ -277,6 +279,23 @@ struct dt_device_node *dt_find_node_by_path(const char *path)
     return np;
 }
 
+int dt_find_node_by_gpath(XEN_GUEST_HANDLE(char) u_path, uint32_t u_plen,
+                          struct dt_device_node **node)
+{
+    char *path;
+
+    path = safe_copy_string_from_guest(u_path, u_plen,
+                                       DEVICE_TREE_MAX_PATHLEN);
+    if ( IS_ERR(path) )
+        return PTR_ERR(path);
+
+    *node = dt_find_node_by_path(path);
+
+    xfree(path);
+
+    return (*node == NULL) ? -ESRCH : 0;
+}
+
 struct dt_device_node *dt_find_node_by_alias(const char *alias)
 {
     const struct dt_alias_prop *app;
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index 19d0e45..9b0ed00 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -22,6 +22,9 @@
 
 #define DEVICE_TREE_MAX_DEPTH 16
 
+/* This limit is used by the hypercalls to restrict the size of the path */
+#define DEVICE_TREE_MAX_PATHLEN 1024
+
 /*
  * Struct used for matching a device
  */
@@ -456,6 +459,20 @@ struct dt_device_node *dt_find_node_by_alias(const char *alias);
  */
 struct dt_device_node *dt_find_node_by_path(const char *path);
 
+
+/**
+ * dt_find_node_by_gpath - Same as dt_find_node_by_path but retrieve the
+ * path from the guest
+ *
+ * @u_path: Xen Guest handle to the buffer containing the path
+ * @u_plen: Length of the buffer
+ * @node: TODO
+ *
+ * Return 0 if succeed otherwise -errno
+ */
+int dt_find_node_by_gpath(XEN_GUEST_HANDLE(char) u_path, uint32_t u_plen,
+                          struct dt_device_node **node);
+
 /**
  * dt_get_parent - Get a node's parent if any
  * @node: Node to get parent
-- 
2.1.4

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

* [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (14 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-19 17:02   ` Jan Beulich
  2015-02-20 16:58   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest Julien Grall
                   ` (9 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: stefano.stabellini, Julien Grall, tim, ian.campbell, Jan Beulich

This new function will correctly initialize the IOMMU page table for the
current domain.

Also use it in iommu_assign_dt_device even though the current IOMMU
implementation on ARM shares P2M with the processor.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Jan Beulich <jbeulich@suse.com>

---
    Changes in v3:
        - The ASSERT in iommu_construct was redundant with the if ()
        - Remove d->need_iommu = 1 in assign_device has it's already
        done by iommu_construct.
        - Simplify the code in the caller of iommu_construct

    Changes in v2:
        - Add missing Signed-off-by
        - Rename iommu_buildup to iommu_construct
---
 xen/drivers/passthrough/arm/iommu.c   |  6 ++++++
 xen/drivers/passthrough/device_tree.c |  4 ++++
 xen/drivers/passthrough/iommu.c       | 19 +++++++++++++++++++
 xen/drivers/passthrough/pci.c         | 15 ++++-----------
 xen/include/xen/iommu.h               |  2 ++
 5 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/xen/drivers/passthrough/arm/iommu.c b/xen/drivers/passthrough/arm/iommu.c
index 3e9303a..5870aef 100644
--- a/xen/drivers/passthrough/arm/iommu.c
+++ b/xen/drivers/passthrough/arm/iommu.c
@@ -68,3 +68,9 @@ void arch_iommu_domain_destroy(struct domain *d)
 {
     iommu_dt_domain_destroy(d);
 }
+
+int arch_iommu_populate_page_table(struct domain *d)
+{
+    /* The IOMMU shares the p2m with the CPU */
+    return -ENOSYS;
+}
diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
index 377d41d..88e496e 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -41,6 +41,10 @@ int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev)
     if ( !list_empty(&dev->domain_list) )
         goto fail;
 
+    rc = iommu_construct(d);
+    if ( rc )
+        goto fail;
+
     rc = hd->platform_ops->assign_device(d, 0, dt_to_dev(dev));
 
     if ( rc )
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index cc12735..8915244 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -187,6 +187,25 @@ void iommu_teardown(struct domain *d)
     tasklet_schedule(&iommu_pt_cleanup_tasklet);
 }
 
+int iommu_construct(struct domain *d)
+{
+    int rc = 0;
+
+    if ( need_iommu(d) > 0 )
+        return 0;
+
+    if ( !iommu_use_hap_pt(d) )
+    {
+        rc = arch_iommu_populate_page_table(d);
+        if ( rc )
+            return rc;
+    }
+
+    d->need_iommu = 1;
+
+    return rc;
+}
+
 void iommu_domain_destroy(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 43ce5dc..9a47a37 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -1355,18 +1355,11 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
     if ( !spin_trylock(&pcidevs_lock) )
         return -ERESTART;
 
-    if ( need_iommu(d) <= 0 )
+    rc = iommu_construct(d);
+    if ( rc )
     {
-        if ( !iommu_use_hap_pt(d) )
-        {
-            rc = arch_iommu_populate_page_table(d);
-            if ( rc )
-            {
-                spin_unlock(&pcidevs_lock);
-                return rc;
-            }
-        }
-        d->need_iommu = 1;
+        spin_unlock(&pcidevs_lock);
+        return rc;
     }
 
     pdev = pci_get_pdev_by_domain(hardware_domain, seg, bus, devfn);
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index d0f99ef..c146ee4 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -65,6 +65,8 @@ int arch_iommu_domain_init(struct domain *d);
 int arch_iommu_populate_page_table(struct domain *d);
 void arch_iommu_check_autotranslated_hwdom(struct domain *d);
 
+int iommu_construct(struct domain *d);
+
 /* Function used internally, use iommu_domain_destroy */
 void iommu_teardown(struct domain *d);
 
-- 
2.1.4

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

* [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (15 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-20  9:19   ` Jan Beulich
                     ` (2 more replies)
  2015-01-13 14:25 ` [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody Julien Grall
                   ` (8 subsequent siblings)
  25 siblings, 3 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: stefano.stabellini, Julien Grall, tim, ian.campbell, Jan Beulich

The toolstack may not have deassign every device used by a guest.
Therefore we have to go through the device list and removing them before
asking the IOMMU drivers to release memory for this domain.

This can be done by moving the call to the release function when we
relinquish the resources. The IOMMU part will be destroyed later when
the domain is freed.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Jan Beulich <jbeulich@suse.com>

---
    Changes in v3:
        - Patch added. Superseed the patch "xen/passthrough: call
        arch_iommu_domain_destroy before calling iommu teardown" in
        the previous patch series.
---
 xen/arch/arm/domain.c                 | 4 ++++
 xen/drivers/passthrough/arm/iommu.c   | 1 -
 xen/drivers/passthrough/device_tree.c | 5 ++++-
 xen/include/xen/iommu.h               | 2 +-
 4 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 6e56665..d85748a 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -772,6 +772,10 @@ int domain_relinquish_resources(struct domain *d)
     switch ( d->arch.relmem )
     {
     case RELMEM_not_started:
+        ret = iommu_release_dt_devices(d);
+        if ( ret )
+            return ret;
+
         d->arch.relmem = RELMEM_xen;
         /* Falltrough */
 
diff --git a/xen/drivers/passthrough/arm/iommu.c b/xen/drivers/passthrough/arm/iommu.c
index 5870aef..8223a39 100644
--- a/xen/drivers/passthrough/arm/iommu.c
+++ b/xen/drivers/passthrough/arm/iommu.c
@@ -66,7 +66,6 @@ int arch_iommu_domain_init(struct domain *d)
 
 void arch_iommu_domain_destroy(struct domain *d)
 {
-    iommu_dt_domain_destroy(d);
 }
 
 int arch_iommu_populate_page_table(struct domain *d)
diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
index 88e496e..e7eb34f 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -97,7 +97,7 @@ int iommu_dt_domain_init(struct domain *d)
     return 0;
 }
 
-void iommu_dt_domain_destroy(struct domain *d)
+int iommu_release_dt_devices(struct domain *d)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(d);
     struct dt_device_node *dev, *_dev;
@@ -109,5 +109,8 @@ void iommu_dt_domain_destroy(struct domain *d)
         if ( rc )
             dprintk(XENLOG_ERR, "Failed to deassign %s in domain %u\n",
                     dt_node_full_name(dev), d->domain_id);
+        return rc;
     }
+
+    return 0;
 }
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index c146ee4..d03df14 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -117,7 +117,7 @@ void iommu_read_msi_from_ire(struct msi_desc *msi_desc, struct msi_msg *msg);
 int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev);
 int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev);
 int iommu_dt_domain_init(struct domain *d);
-void iommu_dt_domain_destroy(struct domain *d);
+int iommu_release_dt_devices(struct domain *d);
 
 #endif /* HAS_DEVICE_TREE */
 
-- 
2.1.4

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

* [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (16 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-20  9:21   ` Jan Beulich
                     ` (2 more replies)
  2015-01-13 14:25 ` [PATCH v3 19/24] xen/iommu: arm: Wire iommu DOMCTL for ARM Julien Grall
                   ` (7 subsequent siblings)
  25 siblings, 3 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: stefano.stabellini, Julien Grall, tim, ian.campbell, Jan Beulich

Currently, when the device is deassigned from a domain, we directly reassign
to DOM0.

As the device may not have been correctly reset, this may lead to corruption or
expose some part of DOM0 memory. Also, we may have no way to reset some
platform devices.

If Xen reassigns the device to "nobody", it may receive some global/context
fault because the transaction has failed (indeed the context has been
marked invalid). Unfortunately there is no simple way to quiesce a buggy
hardware. I think we could live with that for a first version of platform
device passthrough.

DOM0 will have to issue an hypercall to assign the device to itself if it
wants to use it.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Jan Beulich <jbeulich@suse.com>

---
    Changes in v3:
        - Use the coding style of the new SMMU drivers

    Changes in v2:
        - Fix typoes in the commit message
        - Update commit message
---
 xen/drivers/passthrough/arm/smmu.c    | 8 +++++++-
 xen/drivers/passthrough/device_tree.c | 9 +++------
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
index 3cf1773..45a2db8 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -2774,7 +2774,7 @@ static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
 	int ret = 0;
 
 	/* Don't allow remapping on other domain than hwdom */
-	if (t != hardware_domain)
+	if (t && t != hardware_domain)
 		return -EPERM;
 
 	if (t == s)
@@ -2784,6 +2784,12 @@ static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
 	if (ret)
 		return ret;
 
+	if (t) {
+		ret = arm_smmu_assign_dev(t, devfn, dev);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
index e7eb34f..d9b486e 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -72,15 +72,12 @@ int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev)
 
     spin_lock(&dtdevs_lock);
 
-    rc = hd->platform_ops->reassign_device(d, hardware_domain,
-                                           0, dt_to_dev(dev));
+    rc = hd->platform_ops->reassign_device(d, NULL, 0, dt_to_dev(dev));
     if ( rc )
         goto fail;
 
-    list_del(&dev->domain_list);
-
-    dt_device_set_used_by(dev, hardware_domain->domain_id);
-    list_add(&dev->domain_list, &domain_hvm_iommu(hardware_domain)->dt_devices);
+    list_del_init(&dev->domain_list);
+    dt_device_set_used_by(dev, DOMID_IO);
 
 fail:
     spin_unlock(&dtdevs_lock);
-- 
2.1.4

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

* [PATCH v3 19/24] xen/iommu: arm: Wire iommu DOMCTL for ARM
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (17 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-20  9:22   ` Jan Beulich
  2015-02-20 17:06   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device Julien Grall
                   ` (6 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: stefano.stabellini, Julien Grall, tim, ian.campbell, Jan Beulich

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>

---
    Changes in v3:
        - Add Stefano's ack

    Changes in v2:
        - Don't move the call in common code.
---
 xen/arch/arm/domctl.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
index 485d3aa..cc4894e 100644
--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -33,7 +33,16 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
         return p2m_cache_flush(d, s, e);
     }
     default:
-        return subarch_do_domctl(domctl, d, u_domctl);
+    {
+        int rc;
+
+        rc = subarch_do_domctl(domctl, d, u_domctl);
+
+        if ( rc == -ENOSYS )
+            rc = iommu_do_domctl(domctl, d, u_domctl);
+
+        return rc;
+    }
     }
 }
 
-- 
2.1.4

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

* [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (18 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 19/24] xen/iommu: arm: Wire iommu DOMCTL for ARM Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-20  9:34   ` Jan Beulich
                     ` (2 more replies)
  2015-01-13 14:25 ` [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM Julien Grall
                   ` (5 subsequent siblings)
  25 siblings, 3 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, ian.campbell, tim, Julien Grall, Ian Jackson,
	stefano.stabellini, Jan Beulich

TODO: Update the commit message

A device node is described by a path. It will be used to retrieved the
node in the device tree and assign the related device to the domain.

Only device protected by an IOMMU can be assigned to a guest.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>

---
    Changes in v2:
        - Use a different number for XEN_DOMCTL_assign_dt_device
---
 tools/libxc/include/xenctrl.h         | 10 ++++
 tools/libxc/xc_domain.c               | 95 ++++++++++++++++++++++++++++++++--
 xen/drivers/passthrough/device_tree.c | 97 +++++++++++++++++++++++++++++++++--
 xen/drivers/passthrough/iommu.c       |  7 +++
 xen/drivers/passthrough/pci.c         | 43 +++++++++++-----
 xen/include/public/domctl.h           | 15 +++++-
 xen/include/xen/iommu.h               |  3 ++
 7 files changed, 249 insertions(+), 21 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index d66571f..db45475 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2055,6 +2055,16 @@ int xc_deassign_device(xc_interface *xch,
                      uint32_t domid,
                      uint32_t machine_bdf);
 
+int xc_assign_dt_device(xc_interface *xch,
+                        uint32_t domid,
+                        char *path);
+int xc_test_assign_dt_device(xc_interface *xch,
+                             uint32_t domid,
+                             char *path);
+int xc_deassign_dt_device(xc_interface *xch,
+                          uint32_t domid,
+                          char *path);
+
 int xc_domain_memory_mapping(xc_interface *xch,
                              uint32_t domid,
                              unsigned long first_gfn,
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index eb066cf..bca3aee 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -1637,7 +1637,8 @@ int xc_assign_device(
 
     domctl.cmd = XEN_DOMCTL_assign_device;
     domctl.domain = domid;
-    domctl.u.assign_device.machine_sbdf = machine_sbdf;
+    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_PCI;
+    domctl.u.assign_device.u.pci.machine_sbdf = machine_sbdf;
 
     return do_domctl(xch, &domctl);
 }
@@ -1686,7 +1687,8 @@ int xc_test_assign_device(
 
     domctl.cmd = XEN_DOMCTL_test_assign_device;
     domctl.domain = domid;
-    domctl.u.assign_device.machine_sbdf = machine_sbdf;
+    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_PCI;
+    domctl.u.assign_device.u.pci.machine_sbdf = machine_sbdf;
 
     return do_domctl(xch, &domctl);
 }
@@ -1700,11 +1702,96 @@ int xc_deassign_device(
 
     domctl.cmd = XEN_DOMCTL_deassign_device;
     domctl.domain = domid;
-    domctl.u.assign_device.machine_sbdf = machine_sbdf;
- 
+    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_PCI;
+    domctl.u.assign_device.u.pci.machine_sbdf = machine_sbdf;
+
     return do_domctl(xch, &domctl);
 }
 
+int xc_assign_dt_device(
+    xc_interface *xch,
+    uint32_t domid,
+    char *path)
+{
+    int rc;
+    size_t size = strlen(path);
+    DECLARE_DOMCTL;
+    DECLARE_HYPERCALL_BOUNCE(path, size, XC_HYPERCALL_BUFFER_BOUNCE_IN);
+
+    if ( xc_hypercall_bounce_pre(xch, path) )
+        return -1;
+
+    domctl.cmd = XEN_DOMCTL_assign_device;
+    domctl.domain = (domid_t)domid;
+
+    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT;
+    domctl.u.assign_device.u.dt.size = size;
+    set_xen_guest_handle(domctl.u.assign_device.u.dt.path, path);
+
+    rc = do_domctl(xch, &domctl);
+
+    xc_hypercall_bounce_post(xch, path);
+
+    return rc;
+}
+
+int xc_test_assign_dt_device(
+    xc_interface *xch,
+    uint32_t domid,
+    char *path)
+{
+    int rc;
+    size_t size = strlen(path);
+    DECLARE_DOMCTL;
+    DECLARE_HYPERCALL_BOUNCE(path, size, XC_HYPERCALL_BUFFER_BOUNCE_IN);
+
+    if ( xc_hypercall_bounce_pre(xch, path) )
+        return -1;
+
+    domctl.cmd = XEN_DOMCTL_test_assign_device;
+    domctl.domain = (domid_t)domid;
+
+    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT;
+    domctl.u.assign_device.u.dt.size = size;
+    set_xen_guest_handle(domctl.u.assign_device.u.dt.path, path);
+
+    rc = do_domctl(xch, &domctl);
+
+    xc_hypercall_bounce_post(xch, path);
+
+    return rc;
+}
+
+int xc_deassign_dt_device(
+    xc_interface *xch,
+    uint32_t domid,
+    char *path)
+{
+    int rc;
+    size_t size = strlen(path);
+    DECLARE_DOMCTL;
+    DECLARE_HYPERCALL_BOUNCE(path, size, XC_HYPERCALL_BUFFER_BOUNCE_IN);
+
+    if ( xc_hypercall_bounce_pre(xch, path) )
+        return -1;
+
+    domctl.cmd = XEN_DOMCTL_deassign_device;
+    domctl.domain = (domid_t)domid;
+
+    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT;
+    domctl.u.assign_device.u.dt.size = size;
+    set_xen_guest_handle(domctl.u.assign_device.u.dt.path, path);
+
+    rc = do_domctl(xch, &domctl);
+
+    xc_hypercall_bounce_post(xch, path);
+
+    return rc;
+}
+
+
+
+
 int xc_domain_update_msi_irq(
     xc_interface *xch,
     uint32_t domid,
diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
index d9b486e..11deb1d 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -1,9 +1,6 @@
 /*
  * Code to passthrough a device tree node to a guest
  *
- * TODO: This contains only the necessary code to protected device passed to
- * dom0. It will need some updates when device passthrough will is added.
- *
  * Julien Grall <julien.grall@linaro.org>
  * Copyright (c) 2014 Linaro Limited.
  *
@@ -20,6 +17,7 @@
 
 #include <xen/lib.h>
 #include <xen/sched.h>
+#include <xen/guest_access.h>
 #include <xen/iommu.h>
 #include <xen/device_tree.h>
 
@@ -85,6 +83,20 @@ fail:
     return rc;
 }
 
+static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev)
+{
+    bool_t assigned = 0;
+
+    if ( !dt_device_is_protected(dev) )
+        return 1;
+
+    spin_lock(&dtdevs_lock);
+    assigned = !list_empty(&dev->domain_list);
+    spin_unlock(&dtdevs_lock);
+
+    return assigned;
+}
+
 int iommu_dt_domain_init(struct domain *d)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(d);
@@ -111,3 +123,82 @@ int iommu_release_dt_devices(struct domain *d)
 
     return 0;
 }
+
+int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
+                       XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
+{
+    int ret;
+    struct dt_device_node *dev;
+
+    /* TODO: How to deal with XSM? */
+    /* TODO: Do we need to check is_dying? Mostly to protect against
+     * hypercall trying to passthrough a device while we are
+     * dying.
+     */
+
+    switch ( domctl->cmd )
+    {
+    case XEN_DOMCTL_assign_device:
+        ret = -ENOSYS;
+        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
+            break;
+
+        ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
+                                    domctl->u.assign_device.u.dt.size,
+                                    &dev);
+        if ( ret )
+            break;
+
+        ret = iommu_assign_dt_device(d, dev);
+
+        if ( ret )
+            printk(XENLOG_G_ERR "XEN_DOMCTL_assign_dt_device: assign \"%s\""
+                   " to dom%u failed (%d)\n",
+                   dt_node_full_name(dev), d->domain_id, ret);
+        break;
+
+    case XEN_DOMCTL_deassign_device:
+        ret = -ENOSYS;
+        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
+            break;
+
+        ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
+                                    domctl->u.assign_device.u.dt.size,
+                                    &dev);
+        if ( ret )
+            break;
+
+        ret = iommu_deassign_dt_device(d, dev);
+
+        if ( ret )
+            printk(XENLOG_G_ERR "XEN_DOMCTL_assign_dt_device: assign \"%s\""
+                   " to dom%u failed (%d)\n",
+                   dt_node_full_name(dev), d->domain_id, ret);
+        break;
+
+    case XEN_DOMCTL_test_assign_device:
+        ret = -ENOSYS;
+        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
+            break;
+
+        ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
+                                    domctl->u.assign_device.u.dt.size,
+                                    &dev);
+        if ( ret )
+            break;
+
+        if ( iommu_dt_device_is_assigned(dev) )
+        {
+            printk(XENLOG_G_ERR "%s already assigned, or not protected\n",
+                   dt_node_full_name(dev));
+            ret = -EINVAL;
+        }
+        break;
+
+    default:
+        ret = -ENOSYS;
+        break;
+    }
+
+    return ret;
+}
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 8915244..02d5ec1 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -337,6 +337,13 @@ int iommu_do_domctl(
     ret = iommu_do_pci_domctl(domctl, d, u_domctl);
 #endif
 
+    if ( ret != -ENOSYS )
+        return ret;
+
+#ifdef HAS_DEVICE_TREE
+    ret = iommu_do_dt_domctl(domctl, d, u_domctl);
+#endif
+
     return ret;
 }
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 9a47a37..ecc0cd1 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -1497,6 +1497,7 @@ int iommu_do_pci_domctl(
     u16 seg;
     u8 bus, devfn;
     int ret = 0;
+    uint32_t machine_sbdf;
 
     switch ( domctl->cmd )
     {
@@ -1533,13 +1534,19 @@ int iommu_do_pci_domctl(
     break;
 
     case XEN_DOMCTL_test_assign_device:
-        ret = xsm_test_assign_device(XSM_HOOK, domctl->u.assign_device.machine_sbdf);
+        ret = -ENOSYS;
+        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
+            break;
+
+        machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
+
+        ret = xsm_test_assign_device(XSM_HOOK, machine_sbdf);
         if ( ret )
             break;
 
-        seg = domctl->u.assign_device.machine_sbdf >> 16;
-        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
-        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
+        seg = machine_sbdf >> 16;
+        bus = (machine_sbdf >> 8) & 0xff;
+        devfn = machine_sbdf & 0xff;
 
         if ( device_assigned(seg, bus, devfn) )
         {
@@ -1551,19 +1558,25 @@ int iommu_do_pci_domctl(
         break;
 
     case XEN_DOMCTL_assign_device:
+        ret = -ENOSYS;
+        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
+            break;
+
         if ( unlikely(d->is_dying) )
         {
             ret = -EINVAL;
             break;
         }
 
-        ret = xsm_assign_device(XSM_HOOK, d, domctl->u.assign_device.machine_sbdf);
+        machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
+
+        ret = xsm_assign_device(XSM_HOOK, d, machine_sbdf);
         if ( ret )
             break;
 
-        seg = domctl->u.assign_device.machine_sbdf >> 16;
-        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
-        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
+        seg = machine_sbdf >> 16;
+        bus = (machine_sbdf >> 8) & 0xff;
+        devfn = machine_sbdf & 0xff;
 
         ret = device_assigned(seg, bus, devfn) ?:
               assign_device(d, seg, bus, devfn);
@@ -1579,13 +1592,19 @@ int iommu_do_pci_domctl(
         break;
 
     case XEN_DOMCTL_deassign_device:
-        ret = xsm_deassign_device(XSM_HOOK, d, domctl->u.assign_device.machine_sbdf);
+        ret = -ENOSYS;
+        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
+            break;
+
+        machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
+
+        ret = xsm_deassign_device(XSM_HOOK, d, machine_sbdf);
         if ( ret )
             break;
 
-        seg = domctl->u.assign_device.machine_sbdf >> 16;
-        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
-        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
+        seg = machine_sbdf >> 16;
+        bus = (machine_sbdf >> 8) & 0xff;
+        devfn = machine_sbdf & 0xff;
 
         spin_lock(&pcidevs_lock);
         ret = deassign_device(d, seg, bus, devfn);
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index b742b23..d905ab0 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -475,12 +475,23 @@ typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t);
 
 
-/* Assign PCI device to HVM guest. Sets up IOMMU structures. */
+/* Assign a device to a guest. Sets up IOMMU structures. */
 /* XEN_DOMCTL_assign_device */
 /* XEN_DOMCTL_test_assign_device */
 /* XEN_DOMCTL_deassign_device */
+#define XEN_DOMCTL_DEV_PCI      0
+#define XEN_DOMCTL_DEV_DT       1
 struct xen_domctl_assign_device {
-    uint32_t  machine_sbdf;   /* machine PCI ID of assigned device */
+    uint32_t dev;   /* XEN_DOMCTL_DEV_* */
+    union {
+        struct {
+            uint32_t machine_sbdf;   /* machine PCI ID of assigned device */
+        } pci;
+        struct {
+            uint32_t size; /* Length of the path */
+            XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */
+        } dt;
+    } u;
 };
 typedef struct xen_domctl_assign_device xen_domctl_assign_device_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t);
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index d03df14..d261277 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -119,6 +119,9 @@ int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev);
 int iommu_dt_domain_init(struct domain *d);
 int iommu_release_dt_devices(struct domain *d);
 
+int iommu_do_dt_domctl(struct xen_domctl *, struct domain *,
+                       XEN_GUEST_HANDLE_PARAM(xen_domctl_t));
+
 #endif /* HAS_DEVICE_TREE */
 
 struct page_info;
-- 
2.1.4

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

* [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (19 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-29 11:03   ` Stefano Stabellini
                     ` (2 more replies)
  2015-01-13 14:25 ` [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle Julien Grall
                   ` (4 subsequent siblings)
  25 siblings, 3 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, ian.campbell, tim, Julien Grall, Ian Jackson,
	stefano.stabellini

Let the user to pass additional nodes to the guest device tree. For this
purpose, everything in the node /passthrough from the partial device tree will
be copied into the guest device tree.

The node /aliases will be also copied to allow the user to define aliases
which can be used by the guest kernel.

A simple partial device tree will look like:

/dts-v1/;

/ {
        #address-cells = <2>;
        #size-cells = <2>;

        passthrough {
            compatible = "simple-bus";
            ranges;
            #address-cells = <2>;
            #size-cells = <2>;

            /* List of your nodes */
        }
};

Note that:
    * The interrupt-parent proporties will be added by the toolstack in
    the root node
    * The properties compatible, ranges, #address-cells and #size-cells
    in /passthrough are mandatory.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>

---
    Changes in v3:
        - Patch added
---
 docs/man/xl.cfg.pod.5       |   7 ++
 tools/libxl/libxl_arm.c     | 253 ++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_types.idl |   1 +
 tools/libxl/xl_cmdimpl.c    |   1 +
 4 files changed, 262 insertions(+)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index e2f91fc..225b782 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -398,6 +398,13 @@ not emulated.
 Specify that this domain is a driver domain. This enables certain
 features needed in order to run a driver domain.
 
+=item B<device_tree=PATH>
+
+Specify a partial device tree (compiled via the Device Tree Compiler).
+Everything under the node "/passthrough" will be copied into the guest
+device tree. For convenience, the node "/aliases" is also copied to allow
+the user to defined aliases which can be used by the guest kernel.
+
 =back
 
 =head2 Devices
diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index 53177eb..619458b 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -540,6 +540,238 @@ out:
     }
 }
 
+static bool check_overrun(uint64_t a, uint64_t b, uint32_t max)
+{
+    return ((a + b) > UINT_MAX || (a + b) > max);
+}
+
+/* Only FDT v17 is supported */
+#define FDT_REQUIRED_VERSION    0x11
+
+static int check_partial_fdt(libxl__gc *gc, void *fdt, size_t size)
+{
+    int r;
+
+    if (size < FDT_V17_SIZE) {
+        LOG(ERROR, "Partial FDT is too small");
+        return ERROR_FAIL;
+    }
+
+    if (fdt_magic(fdt) != FDT_MAGIC) {
+        LOG(ERROR, "Partial FDT is not a valid Flat Device Tree");
+        return ERROR_FAIL;
+    }
+
+    if (fdt_version(fdt) != FDT_REQUIRED_VERSION) {
+        LOG(ERROR, "Partial FDT version not supported. Required 0x%x got 0x%x",
+            FDT_REQUIRED_VERSION, fdt_version(fdt));
+        return ERROR_FAIL;
+    }
+
+    r = fdt_check_header(fdt);
+    if (r) {
+        LOG(ERROR, "Failed to check the partial FDT (%d)", r);
+        return ERROR_FAIL;
+    }
+
+    /* Check if the *size and off* fields doesn't overrun the totalsize
+     * of the partial FDT.
+     */
+    if (fdt_totalsize(fdt) > size) {
+        LOG(ERROR, "Partial FDT totalsize is too big");
+        return ERROR_FAIL;
+    }
+
+    size = fdt_totalsize(fdt);
+    if (fdt_off_dt_struct(fdt) > size ||
+        fdt_off_dt_strings(fdt) > size ||
+        check_overrun(fdt_off_dt_struct(fdt), fdt_size_dt_struct(fdt), size) ||
+        check_overrun(fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt), size)) {
+        LOG(ERROR, "Failed to validate the header of the partial FDT");
+        return ERROR_FAIL;
+    }
+
+    return 0;
+}
+
+/*
+ * Check if a string stored the strings block section is correctly
+ * nul-terminated.
+ * off_dt_strings and size_dt_strings fields have been validity-check
+ * earlier, so it's safe to use them here.
+ */
+static bool check_string(void *fdt, int nameoffset)
+{
+    const char *str = fdt_string(fdt, nameoffset);
+
+    for (; nameoffset < fdt_size_dt_strings(fdt); nameoffset++, str++) {
+        if (*str == '\0')
+            return true;
+    }
+
+    return false;
+}
+
+static int copy_properties(libxl__gc *gc, void *fdt, void *pfdt,
+                           int nodeoff)
+{
+    int propoff, nameoff, r;
+    const struct fdt_property *prop;
+
+    for (propoff = fdt_first_property_offset(pfdt, nodeoff);
+         propoff >= 0;
+         propoff = fdt_next_property_offset(pfdt, propoff)) {
+
+        if (!(prop = fdt_get_property_by_offset(pfdt, propoff, NULL))) {
+            return -FDT_ERR_INTERNAL;
+        }
+
+        /*
+         * Libfdt doesn't perform any check on the validity of a string
+         * stored in the strings block section. As the property name is
+         * stored there, check it.
+         */
+        nameoff = fdt32_to_cpu(prop->nameoff);
+        if (!check_string(pfdt, nameoff)) {
+            LOG(ERROR, "The strings block section of the partial FDT is malformed");
+            return -FDT_ERR_BADSTRUCTURE;
+        }
+
+        r = fdt_property(fdt, fdt_string(pfdt, nameoff),
+                         prop->data, fdt32_to_cpu(prop->len));
+        if (r) return r;
+    }
+
+    /* FDT_ERR_NOTFOUND => There is no more properties for this node */
+    return (propoff != -FDT_ERR_NOTFOUND)? propoff : 0;
+}
+
+/*
+ * Based on fdt_first_subnode and fdt_next_subnode.
+ * We can't use the one helpers provided by libfdt because:
+ *      - It has been introduced in 2013 => Doesn't work on wheezy
+ *      - The prototypes exist but the functions are not exported. Don't
+ *      ask why...
+ *      - There is no version in the header (might be better to use
+ *      configure for this purpose?)
+ */
+static int _fdt_first_subnode(const void *fdt, int offset)
+{
+    int depth = 0;
+
+    offset = fdt_next_node(fdt, offset, &depth);
+    if (offset < 0 || depth != 1)
+        return -FDT_ERR_NOTFOUND;
+
+    return offset;
+}
+
+static int _fdt_next_subnode(const void *fdt, int offset)
+{
+    int depth = 1;
+
+    /*
+     * With respect to the parent, the depth of the next subnode will be
+     * the same as the last.
+     */
+    do {
+        offset = fdt_next_node(fdt, offset, &depth);
+        if (offset < 0 || depth < 1)
+            return -FDT_ERR_NOTFOUND;
+    } while (depth > 1);
+
+    return offset;
+}
+
+/* Limit the maxixum depth of a node because of the recursion */
+#define MAX_DEPTH   8
+
+/* Copy a node from the partial device tree to the guest device tree */
+static int copy_node(libxl__gc *gc, void *fdt, void *pfdt,
+                     int nodeoff, int depth)
+{
+    int r;
+
+    if (depth >= MAX_DEPTH) {
+        LOG(ERROR, "Partial FDT contains a too depth node");
+        return -FDT_ERR_INTERNAL;
+    }
+
+    r = fdt_begin_node(fdt, fdt_get_name(pfdt, nodeoff, NULL));
+    if (r) return r;
+
+    r = copy_properties(gc, fdt, pfdt, nodeoff);
+    if (r) return r;
+
+    for (nodeoff = _fdt_first_subnode(pfdt, nodeoff);
+         nodeoff >= 0;
+         nodeoff = _fdt_next_subnode(pfdt, nodeoff)) {
+        r = copy_node(gc, fdt, pfdt, nodeoff, depth + 1);
+        if (r) return r;
+    }
+
+    if (nodeoff != -FDT_ERR_NOTFOUND)
+        return nodeoff;
+
+    r = fdt_end_node(fdt);
+    if (r) return r;
+
+    return 0;
+}
+
+static int copy_node_by_path(libxl__gc *gc, const char *path,
+                             void *fdt, void *pfdt)
+{
+    int nodeoff, r;
+    const char *name = strrchr(path, '/');
+
+    if (!name)
+        return -FDT_ERR_INTERNAL;
+
+    name++;
+
+    /* The FDT function to look at node doesn't take into account the
+     * unit (i.e anything after @) when search by name. Check if the
+     * name exactly match.
+     */
+    nodeoff = fdt_path_offset(pfdt, path);
+    if (nodeoff < 0)
+        return nodeoff;
+
+    if (strcmp(fdt_get_name(pfdt, nodeoff, NULL), name))
+        return -FDT_ERR_NOTFOUND;
+
+    r = copy_node(gc, fdt, pfdt, nodeoff, 0);
+    if (r) return r;
+
+    return 0;
+}
+
+/*
+ * The partial device tree is not copied entirely. Only the relevant bits are
+ * copied to the guest device tree:
+ *  - /passthrough node
+ *  - /aliases node
+ */
+static int copy_partial_fdt(libxl__gc *gc, void *fdt, void *pfdt)
+{
+    int r;
+
+    r = copy_node_by_path(gc, "/passthrough", fdt, pfdt);
+    if (r < 0) {
+        LOG(ERROR, "Can't copy the node \"/passthrough\" from the partial FDT");
+        return r;
+    }
+
+    r = copy_node_by_path(gc, "/aliases", fdt, pfdt);
+    if (r < 0 && r != -FDT_ERR_NOTFOUND) {
+        LOG(ERROR, "Can't copy the node \"/aliases\" from the partial FDT");
+        return r;
+    }
+
+    return 0;
+}
+
 #define FDT_MAX_SIZE (1<<20)
 
 int libxl__arch_domain_init_hw_description(libxl__gc *gc,
@@ -548,8 +780,10 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
                                            struct xc_dom_image *dom)
 {
     void *fdt = NULL;
+    void *pfdt = NULL;
     int rc, res;
     size_t fdt_size = 0;
+    int pfdt_size = 0;
 
     const libxl_version_info *vers;
     const struct arch_info *ainfo;
@@ -569,6 +803,22 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
         vers->xen_version_major, vers->xen_version_minor);
     LOG(DEBUG, " - vGIC version: %s\n", gicv_to_string(xc_config->gic_version));
 
+    if (info->device_tree) {
+        LOG(DEBUG, " - Partial device tree provided: %s", info->device_tree);
+
+        rc = libxl_read_file_contents(CTX, info->device_tree,
+                                      &pfdt, &pfdt_size);
+        if (rc) {
+            LOGEV(ERROR, rc, "failed to read the partial device file %s",
+                  info->device_tree);
+            return ERROR_FAIL;
+        }
+        libxl__ptr_add(gc, pfdt);
+
+        if (check_partial_fdt(gc, pfdt, pfdt_size))
+            return ERROR_FAIL;
+    }
+
 /*
  * Call "call" handling FDT_ERR_*. Will either:
  * - loop back to retry_resize
@@ -635,6 +885,9 @@ next_resize:
         FDT( make_timer_node(gc, fdt, ainfo) );
         FDT( make_hypervisor_node(gc, fdt, vers) );
 
+        if (pfdt)
+            FDT( copy_partial_fdt(gc, fdt, pfdt) );
+
         FDT( fdt_end_node(fdt) );
 
         FDT( fdt_finish(fdt) );
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 1214d2e..5651110 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -399,6 +399,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
     ("kernel",           string),
     ("cmdline",          string),
     ("ramdisk",          string),
+    ("device_tree",      string),
     ("u", KeyedUnion(None, libxl_domain_type, "type",
                 [("hvm", Struct(None, [("firmware",         string),
                                        ("bios",             libxl_bios_type),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 0b02a6c..31e89e8 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1184,6 +1184,7 @@ static void parse_config_data(const char *config_source,
 
     xlu_cfg_replace_string (config, "kernel", &b_info->kernel, 0);
     xlu_cfg_replace_string (config, "ramdisk", &b_info->ramdisk, 0);
+    xlu_cfg_replace_string (config, "device_tree", &b_info->device_tree, 0);
     b_info->cmdline = parse_cmdline(config);
 
     xlu_cfg_get_defbool(config, "driver_domain", &c_info->driver_domain, 0);
-- 
2.1.4

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

* [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (20 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-29 11:07   ` Stefano Stabellini
  2015-01-13 14:25 ` [PATCH v3 23/24] libxl: Add support for non-PCI passthrough Julien Grall
                   ` (3 subsequent siblings)
  25 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, ian.campbell, tim, Julien Grall, Ian Jackson,
	stefano.stabellini

The partial device tree may contains phandle. The Device Tree Compiler
tends to allocate the phandle from 1.

Reserve the ID 65000 for the GIC phandle. I think we can safely assume
that the partial device tree will never contain a such ID.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>

---
    Changes in v3:
        - Patch added
---
 tools/libxl/libxl_arm.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index 619458b..dc745fb 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -78,10 +78,11 @@ static struct arch_info {
     {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8" },
 };
 
-enum {
-    PHANDLE_NONE = 0,
-    PHANDLE_GIC,
-};
+/*
+ * The device tree compiler (DTC) is allocating the phandle from 1 to
+ * onwards. Reserve a high value for the GIC phandle.
+ */
+#define PHANDLE_GIC (65000)
 
 typedef uint32_t be32;
 typedef be32 gic_interrupt[3];
-- 
2.1.4

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

* [PATCH v3 23/24] libxl: Add support for non-PCI passthrough
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (21 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-29 11:12   ` Stefano Stabellini
  2015-02-23 14:42   ` Ian Campbell
  2015-01-13 14:25 ` [PATCH v3 24/24] xl: Add new option dtdev Julien Grall
                   ` (2 subsequent siblings)
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, ian.campbell, tim, Julien Grall, Ian Jackson,
	stefano.stabellini

On ARM, every non-PCI device are described in the device tree. Each of them
can be found via a path.

This patch introduces a very basic support, only the IOMMU will be set
up correctly. The user will have to:
    - Describe the device in the partial device tree
    - Map manually MMIO/IRQ

This is a first approach, that will allow to have a basic non-PCI
passthrough support in Xen. This could be improved later.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>

---
    Changes in v3:
        - Dynamic allocation has been dropped
        - Rework the commit message in accordance with the previous
        item

    Changes in v2:
        - Get DT infos earlier
        - Allocate/map IRQ in libxl__arch_domain_create rather than in
        libxl__device_dt_add
        - Use VIRQ rather than the PIRQ to construct the interrupts
        properties of the device tree
        - Correct cpumask in make_dtdev_node. We allow the interrupt to
        be used on the 8 CPUs
        - Fix LOGE when we map the MMIO region in the guest in
        libxl__device_dt_add. The domain and the IRQ were inverted
        - Calculate the number of SPIs to configure the VGIC
        - xc_physdev_dtdev_* helpers has been renamed to xc_dtdev_*
        - Rename libxl_device_dt to libxl_device_dtdev
---
 tools/libxl/Makefile         |  2 +-
 tools/libxl/libxl_create.c   | 10 ++++++++++
 tools/libxl/libxl_dtdev.c    | 34 ++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |  5 +++++
 tools/libxl/libxl_types.idl  |  5 +++++
 5 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 tools/libxl/libxl_dtdev.c

diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index b417372..98e1bab 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -96,7 +96,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
 			libxl_json.o libxl_aoutils.o libxl_numa.o \
 			libxl_save_callout.o _libxl_save_msgs_callout.o \
 			libxl_qmp.o libxl_event.o libxl_fork.o $(LIBXL_OBJS-y)
-LIBXL_OBJS += libxl_genid.o
+LIBXL_OBJS += libxl_genid.o libxl_dtdev.o
 LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
 
 LIBXL_TESTS += timedereg
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 029d2e2..b7ef528 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1430,6 +1430,16 @@ static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev,
         }
     }
 
+    for (i = 0; i < d_config->num_dtdevs; i++) {
+
+        ret = libxl__device_dt_add(gc, domid, &d_config->dtdevs[i]);
+        if (ret < 0) {
+            LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+                       "libxl__device_dt_add failed: %d\n", ret);
+            goto error_out;
+        }
+    }
+
     domcreate_console_available(egc, dcs);
 
     domcreate_complete(egc, dcs, 0);
diff --git a/tools/libxl/libxl_dtdev.c b/tools/libxl/libxl_dtdev.c
new file mode 100644
index 0000000..5de57f0
--- /dev/null
+++ b/tools/libxl/libxl_dtdev.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014      Linaro Limited.
+ * Author Julien Grall <julien.grall@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_osdeps.h" /* Must come before other headers */
+
+#include "libxl_internal.h"
+
+int libxl__device_dt_add(libxl__gc *gc, uint32_t domid,
+                         const libxl_device_dtdev *dtdev)
+{
+    LOG(DEBUG, "Assign device \"%s\" to dom%u", dtdev->path, domid);
+
+    return xc_assign_dt_device(CTX->xch, domid, dtdev->path);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index be5ed82..c00516a 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1179,6 +1179,11 @@ _hidden int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
                                       libxl_device_pci *pcidev, int num);
 _hidden int libxl__device_pci_destroy_all(libxl__gc *gc, uint32_t domid);
 
+/* from libxl_dtdev */
+
+_hidden int libxl__device_dt_add(libxl__gc *gc, uint32_t domid,
+                                 const libxl_device_dtdev *dtdev);
+
 /*----- xswait: wait for a xenstore node to be suitable -----*/
 
 typedef struct libxl__xswait_state libxl__xswait_state;
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 5651110..c10fd2f 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -522,6 +522,10 @@ libxl_device_pci = Struct("device_pci", [
     ("seize", bool),
     ])
 
+libxl_device_dtdev = Struct("device_dtdev", [
+    ("path", string),
+    ])
+
 libxl_device_vtpm = Struct("device_vtpm", [
     ("backend_domid",    libxl_domid),
     ("backend_domname",  string),
@@ -548,6 +552,7 @@ libxl_domain_config = Struct("domain_config", [
     ("disks", Array(libxl_device_disk, "num_disks")),
     ("nics", Array(libxl_device_nic, "num_nics")),
     ("pcidevs", Array(libxl_device_pci, "num_pcidevs")),
+    ("dtdevs", Array(libxl_device_dtdev, "num_dtdevs")),
     ("vfbs", Array(libxl_device_vfb, "num_vfbs")),
     ("vkbs", Array(libxl_device_vkb, "num_vkbs")),
     ("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
-- 
2.1.4

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

* [PATCH v3 24/24] xl: Add new option dtdev
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (22 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 23/24] libxl: Add support for non-PCI passthrough Julien Grall
@ 2015-01-13 14:25 ` Julien Grall
  2015-01-29 11:18   ` Stefano Stabellini
  2015-02-23 14:45   ` Ian Campbell
  2015-01-13 17:56 ` [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
  2015-02-20 17:18 ` Ian Campbell
  25 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 14:25 UTC (permalink / raw)
  To: xen-devel
  Cc: Wei Liu, ian.campbell, tim, Julien Grall, Ian Jackson,
	stefano.stabellini

The option "dtdev" will be used to passthrough a non-PCI device described
in the device tree to a guest.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>

---
    Changes in v2:
        - libxl_device_dt has been rename to libxl_device_dtdev
        - use xrealloc instead of realloc
---
 docs/man/xl.cfg.pod.5    |  5 +++++
 tools/libxl/xl_cmdimpl.c | 21 ++++++++++++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index 225b782..cfd3d5f 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -721,6 +721,11 @@ More information about Xen gfx_passthru feature is available
 on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
 wiki page.
 
+=item B<dtdev=[ "DTDEV_PATH", "DTDEV_PATH", ... ]>
+
+Specifies the host device node to passthrough to this guest. Each DTDEV_PATH
+is the absolute path in the device tree.
+
 =item B<ioports=[ "IOPORT_RANGE", "IOPORT_RANGE", ... ]>
 
 Allow guest to access specific legacy I/O ports. Each B<IOPORT_RANGE>
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 31e89e8..80c9df6 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -986,7 +986,7 @@ static void parse_config_data(const char *config_source,
     long l;
     XLU_Config *config;
     XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms;
-    XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian;
+    XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs;
     int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian;
     int pci_power_mgmt = 0;
     int pci_msitranslate = 0;
@@ -1746,6 +1746,25 @@ skip_vfb:
             libxl_defbool_set(&b_info->u.pv.e820_host, true);
     }
 
+    if (!xlu_cfg_get_list (config, "dtdev", &dtdevs, 0, 0)) {
+        d_config->num_dtdevs = 0;
+        d_config->dtdevs = NULL;
+        for (i = 0; (buf = xlu_cfg_get_listitem(dtdevs, i)) != NULL; i++) {
+            libxl_device_dtdev *dtdev;
+
+            d_config->dtdevs = (libxl_device_dtdev *) xrealloc(d_config->dtdevs, sizeof (libxl_device_dtdev) * (d_config->num_dtdevs + 1));
+            dtdev = d_config->dtdevs + d_config->num_dtdevs;
+            libxl_device_dtdev_init(dtdev);
+
+            dtdev->path = strdup(buf);
+            if (dtdev->path == NULL) {
+                fprintf(stderr, "unable to duplicate string for dtdevs\n");
+                exit(-1);
+            }
+            d_config->num_dtdevs++;
+        }
+    }
+
     switch (xlu_cfg_get_list(config, "cpuid", &cpuids, 0, 1)) {
     case 0:
         {
-- 
2.1.4

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-01-13 14:25 ` [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration Julien Grall
@ 2015-01-13 15:08   ` Daniel De Graaf
  2015-01-19 16:46   ` Jan Beulich
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 251+ messages in thread
From: Daniel De Graaf @ 2015-01-13 15:08 UTC (permalink / raw)
  To: Julien Grall, xen-devel
  Cc: Keir Fraser, ian.campbell, George Dunlap, tim, Ian Jackson,
	stefano.stabellini, Jan Beulich, Andrew Cooper, Wei Liu

On 01/13/2015 09:25 AM, Julien Grall wrote:
> On ARM the virtual GIC may differ between each guest (emulated GIC version,
> number of SPIs...). Those informations are already known at the domain creation
> and can never change.
>
> For now only the gic_version is set. In long run, there will be more parameters
> such as the number of SPIs. All will be required to be set at the same time.
>
> A new arch-specific structure arch_domainconfig has been created, the x86
> one doesn't have any specific configuration, a dummy structure
> (C-spec compliant) has been created to factorize the code on the toolstack.
>
> Some external tools (qemu, xenstore) may require to create a domain. Rather
> than asking them to take care of the arch-specific domain configuration, let
> the current function (xc_domain_create) to chose a default configuration and
> introduce a new one (xc_domain_create_config).
>
> This patch also drop the previously DOMCTL arm_configure_domain introduced
> in Xen 4.5, as it has been made useless.
>
> Signed-off-by: Julien Grall <julien.grall@linaro.org>

Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>

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

* Re: [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest
  2015-01-13 14:25 ` [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest Julien Grall
@ 2015-01-13 15:10   ` Daniel De Graaf
  2015-01-19 16:51   ` Jan Beulich
  2015-02-20 15:22   ` Ian Campbell
  2 siblings, 0 replies; 251+ messages in thread
From: Daniel De Graaf @ 2015-01-13 15:10 UTC (permalink / raw)
  To: Julien Grall, xen-devel
  Cc: Keir Fraser, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	Jan Beulich

On 01/13/2015 09:25 AM, Julien Grall wrote:
> Flask code already provides an helper to copy a string from guest. In a later
> patch, the new DT hypercalls will need a similar function.
>
> To avoid code duplication, copy the flask helper (flask_copying_string) to
> common code:
>      - Rename into safe_copy_string_from_guest
>      - Add comment to explain the extra +1
>      - Return directly the buffer and use the macros provided by
>      xen/err.h to return an error code if necessary.
>
> Signed-off-by: Julien Grall <julien.grall@linaro.org>

Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>

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

* Re: [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (23 preceding siblings ...)
  2015-01-13 14:25 ` [PATCH v3 24/24] xl: Add new option dtdev Julien Grall
@ 2015-01-13 17:56 ` Julien Grall
  2015-02-20 17:18 ` Ian Campbell
  25 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-13 17:56 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.campbell, manish.jaggi, tim, stefano.stabellini,
	suravee.suthikulpanit, andrii.tseglytskyi

On 13/01/15 14:25, Julien Grall wrote:
> This series has been tested on Midway by assigning the secondary network card
> to a guest (see instruction below). I plan to do futher testing on other
> boards.

I forgot to precise that only changes has only been build tested on x86.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-01-13 14:25 ` [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration Julien Grall
  2015-01-13 15:08   ` Daniel De Graaf
@ 2015-01-19 16:46   ` Jan Beulich
  2015-01-20 12:40     ` Julien Grall
  2015-01-28 15:50   ` Stefano Stabellini
  2015-02-20 15:15   ` Ian Campbell
  3 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-19 16:46 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, George Dunlap, Andrew Cooper, Ian Jackson,
	tim, stefano.stabellini, xen-devel, Daniel De Graaf, Keir Fraser

>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
> @@ -1069,7 +1057,6 @@ struct xen_domctl {
>  #define XEN_DOMCTL_set_vcpu_msrs                 73
>  #define XEN_DOMCTL_setvnumainfo                  74
>  #define XEN_DOMCTL_psr_cmt_op                    75
> -#define XEN_DOMCTL_arm_configure_domain          76

This and the other removals from this file requires
XEN_DOMCTL_INTERFACE_VERSION to be bumped.

With that fixed, for x86 and the common hypervisor pieces
Acked-by: Jan Beulich <jbeulich@suse.com>

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

* Re: [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest
  2015-01-13 14:25 ` [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest Julien Grall
  2015-01-13 15:10   ` Daniel De Graaf
@ 2015-01-19 16:51   ` Jan Beulich
  2015-01-20 12:45     ` Julien Grall
  2015-02-20 15:22   ` Ian Campbell
  2 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-19 16:51 UTC (permalink / raw)
  To: Julien Grall
  Cc: Keir Fraser, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	xen-devel, Daniel De Graaf

>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
> --- /dev/null
> +++ b/xen/common/guestcopy.c
> @@ -0,0 +1,30 @@
> +#include <xen/config.h>
> +#include <xen/lib.h>
> +#include <xen/guest_access.h>
> +#include <xen/err.h>
> +
> +/* The function copies a string from the guest and adds a NUL to
> + * make sure the string is correctly terminated.
> + */

Coding style.

> +void *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
> +                                  size_t size, size_t max_size)

Is the "safe_" prefix really meaningful? I.e. is this function more
safe than e.g. copy_from_guest()?

> +{
> +    char *tmp;
> +
> +    if ( size > max_size )
> +        return ERR_PTR(-ENOENT);

-ENOBUFS?

Jan

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-01-13 14:25 ` [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq Julien Grall
@ 2015-01-19 16:54   ` Jan Beulich
  2015-01-20 14:01     ` Julien Grall
  2015-01-28 18:52   ` Stefano Stabellini
  1 sibling, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-19 16:54 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
> assign/deassign a physical IRQ to the guest (via the config options "irqs"
> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
> channel). As ARM doesn't have a such concept, we could reuse it to bound
> a physical IRQ to a virtual IRQ.
> 
> For now, we allow only SPIs to be mapped to the guest.
> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> 
> ---
>     I'm not sure it's the best solution to reuse hypercalls for a
>     different purpose. If x86 plan to have a such concept (i.e binding a
>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
>     Any thoughs?

I'm not sure either - much depends on the possible confusion this
may cause to the callers (i.e. if they live in common code, they
may expect the hypercall to do a certain thing, whereas if the
callers are all [expected to be] in arch code, then I'd consider such
overloading okay).

Jan

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-13 14:25 ` [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct Julien Grall
@ 2015-01-19 17:02   ` Jan Beulich
  2015-01-20 14:28     ` Julien Grall
  2015-02-20 16:58   ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-19 17:02 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
> --- a/xen/drivers/passthrough/device_tree.c
> +++ b/xen/drivers/passthrough/device_tree.c
> @@ -41,6 +41,10 @@ int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev)
>      if ( !list_empty(&dev->domain_list) )
>          goto fail;
>  
> +    rc = iommu_construct(d);
> +    if ( rc )
> +        goto fail;

Considering that the only (current) caller of this it domain_build.c I'm
afraid you're going to get into trouble if you get back -ERESTART
here. Note that on x86 Dom0 setup works via iommu_hwdom_init(),
which deals with the preemption needs (at that point in time) by
calling process_pending_softirqs() every once in a while.

Jan

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

* Re: [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-01-13 14:25 ` [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest Julien Grall
@ 2015-01-20  9:19   ` Jan Beulich
  2015-01-20 14:30     ` Julien Grall
  2015-01-28 18:59   ` Stefano Stabellini
  2015-02-20 17:03   ` Ian Campbell
  2 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-20  9:19 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -117,7 +117,7 @@ void iommu_read_msi_from_ire(struct msi_desc *msi_desc, struct msi_msg *msg);
>  int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev);
>  int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev);
>  int iommu_dt_domain_init(struct domain *d);
> -void iommu_dt_domain_destroy(struct domain *d);
> +int iommu_release_dt_devices(struct domain *d);

I don't think you really need an ack from me on this trivial change,
but in case you feel otherwise, don't hesitate to add it.

Jan

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-01-13 14:25 ` [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody Julien Grall
@ 2015-01-20  9:21   ` Jan Beulich
  2015-01-20 14:31     ` Julien Grall
  2015-01-29 10:20   ` Stefano Stabellini
  2015-02-20 17:04   ` Ian Campbell
  2 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-20  9:21 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
> Currently, when the device is deassigned from a domain, we directly reassign
> to DOM0.
> 
> As the device may not have been correctly reset, this may lead to corruption 
> or
> expose some part of DOM0 memory. Also, we may have no way to reset some
> platform devices.
> 
> If Xen reassigns the device to "nobody", it may receive some global/context
> fault because the transaction has failed (indeed the context has been
> marked invalid). Unfortunately there is no simple way to quiesce a buggy
> hardware. I think we could live with that for a first version of platform
> device passthrough.
> 
> DOM0 will have to issue an hypercall to assign the device to itself if it
> wants to use it.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Jan Beulich <jbeulich@suse.com>

Looks like this is because of ...

>  xen/drivers/passthrough/device_tree.c | 9 +++------

... this. Which I think is a mistake, as I wasn't involved in the addition
of that file. I'd appreciate an update to ./MAINTAINERS adding this
file to the ARM section.

Jan

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

* Re: [PATCH v3 19/24] xen/iommu: arm: Wire iommu DOMCTL for ARM
  2015-01-13 14:25 ` [PATCH v3 19/24] xen/iommu: arm: Wire iommu DOMCTL for ARM Julien Grall
@ 2015-01-20  9:22   ` Jan Beulich
  2015-01-20 14:32     ` Julien Grall
  2015-02-20 17:06   ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-20  9:22 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>

Is this a leftover from ...

> ---
>     Changes in v3:
>         - Add Stefano's ack
> 
>     Changes in v2:
>         - Don't move the call in common code.

... before this?

Jan

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-13 14:25 ` [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device Julien Grall
@ 2015-01-20  9:34   ` Jan Beulich
  2015-01-20 14:37     ` Julien Grall
  2015-01-29 10:29     ` Stefano Stabellini
  2015-01-29 10:29   ` Stefano Stabellini
  2015-02-20 17:17   ` Ian Campbell
  2 siblings, 2 replies; 251+ messages in thread
From: Jan Beulich @ 2015-01-20  9:34 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
> --- a/xen/drivers/passthrough/iommu.c
> +++ b/xen/drivers/passthrough/iommu.c
> @@ -337,6 +337,13 @@ int iommu_do_domctl(
>      ret = iommu_do_pci_domctl(domctl, d, u_domctl);
>  #endif
>  
> +    if ( ret != -ENOSYS )
> +        return ret;
> +
> +#ifdef HAS_DEVICE_TREE
> +    ret = iommu_do_dt_domctl(domctl, d, u_domctl);
> +#endif

Please move the (inverted) if() into the #ifdef block (but also see
below regarding the specific error code used).

> @@ -1533,13 +1534,19 @@ int iommu_do_pci_domctl(
>      break;
>  
>      case XEN_DOMCTL_test_assign_device:
> -        ret = xsm_test_assign_device(XSM_HOOK, domctl->u.assign_device.machine_sbdf);
> +        ret = -ENOSYS;
> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
> +            break;

I'm rather uncertain about the use of -ENOSYS here: The hypercall
isn't unimplemented after all. Provided you use consistent error
codes in the PCI and DT variants, there's no problem calling the
other variant if that specific error code got returned from the first
one - the second would then just return the same one again, even
if the first one failed on something other than the device type
check. As a result, I'd much prefer -ENODEV here.

> +
> +        machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
> +
> +        ret = xsm_test_assign_device(XSM_HOOK, machine_sbdf);
>          if ( ret )
>              break;
>  
> -        seg = domctl->u.assign_device.machine_sbdf >> 16;
> -        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
> -        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
> +        seg = machine_sbdf >> 16;
> +        bus = (machine_sbdf >> 8) & 0xff;
> +        devfn = machine_sbdf & 0xff;

If you fiddle with these, please make them use at least PCI_BUS()
and PCI_DEVFN2() (we don't have a matching macro for retrieving
the segment).

> --- a/xen/include/public/domctl.h
> +++ b/xen/include/public/domctl.h
> @@ -475,12 +475,23 @@ typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t);
>  
>  
> -/* Assign PCI device to HVM guest. Sets up IOMMU structures. */
> +/* Assign a device to a guest. Sets up IOMMU structures. */
>  /* XEN_DOMCTL_assign_device */
>  /* XEN_DOMCTL_test_assign_device */
>  /* XEN_DOMCTL_deassign_device */
> +#define XEN_DOMCTL_DEV_PCI      0
> +#define XEN_DOMCTL_DEV_DT       1
>  struct xen_domctl_assign_device {
> -    uint32_t  machine_sbdf;   /* machine PCI ID of assigned device */
> +    uint32_t dev;   /* XEN_DOMCTL_DEV_* */
> +    union {
> +        struct {
> +            uint32_t machine_sbdf;   /* machine PCI ID of assigned device */
> +        } pci;
> +        struct {
> +            uint32_t size; /* Length of the path */
> +            XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */
> +        } dt;
> +    } u;
>  };

An incompatible change like this requires bumping
XEN_DOMCTL_INTERFACE_VERSION when not already done during
the current release cycle.

Jan

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-01-19 16:46   ` Jan Beulich
@ 2015-01-20 12:40     ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-20 12:40 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Wei Liu, ian.campbell, George Dunlap, Andrew Cooper, Ian Jackson,
	tim, stefano.stabellini, xen-devel, Daniel De Graaf, Keir Fraser

Hi Jan,

On 19/01/15 16:46, Jan Beulich wrote:
>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>> @@ -1069,7 +1057,6 @@ struct xen_domctl {
>>  #define XEN_DOMCTL_set_vcpu_msrs                 73
>>  #define XEN_DOMCTL_setvnumainfo                  74
>>  #define XEN_DOMCTL_psr_cmt_op                    75
>> -#define XEN_DOMCTL_arm_configure_domain          76
> 
> This and the other removals from this file requires
> XEN_DOMCTL_INTERFACE_VERSION to be bumped.

I will do.

> With that fixed, for x86 and the common hypervisor pieces
> Acked-by: Jan Beulich <jbeulich@suse.com>

Thanks,

-- 
Julien Grall

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

* Re: [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest
  2015-01-19 16:51   ` Jan Beulich
@ 2015-01-20 12:45     ` Julien Grall
  2015-01-20 13:16       ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-20 12:45 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Keir Fraser, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	xen-devel, Daniel De Graaf

Hi Jan,

On 19/01/15 16:51, Jan Beulich wrote:
>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>> --- /dev/null
>> +++ b/xen/common/guestcopy.c
>> @@ -0,0 +1,30 @@
>> +#include <xen/config.h>
>> +#include <xen/lib.h>
>> +#include <xen/guest_access.h>
>> +#include <xen/err.h>
>> +
>> +/* The function copies a string from the guest and adds a NUL to
>> + * make sure the string is correctly terminated.
>> + */
> 
> Coding style.

Ok.

> 
>> +void *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
>> +                                  size_t size, size_t max_size)
> 
> Is the "safe_" prefix really meaningful? I.e. is this function more
> safe than e.g. copy_from_guest()?

It's safe in the sense, the function adds a NUL to make sure the strings
is correctly terminated.

On the first v1, you said that name "copy_string_from_guest" doesn't
match the behavior of the generic helper [1]. So which name do you
suggest for this function?

> 
>> +{
>> +    char *tmp;
>> +
>> +    if ( size > max_size )
>> +        return ERR_PTR(-ENOENT);
> 
> -ENOBUFS?

I will use it.

Regards,

[1] http://lists.xen.org/archives/html/xen-devel/2014-06/msg02361.html

-- 
Julien Grall

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

* Re: [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest
  2015-01-20 12:45     ` Julien Grall
@ 2015-01-20 13:16       ` Jan Beulich
  0 siblings, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-01-20 13:16 UTC (permalink / raw)
  To: Julien Grall
  Cc: Keir Fraser, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	xen-devel, Daniel De Graaf

>>> On 20.01.15 at 13:45, <julien.grall@linaro.org> wrote:
> On 19/01/15 16:51, Jan Beulich wrote:
>>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>>> +void *safe_copy_string_from_guest(XEN_GUEST_HANDLE(char) u_buf,
>>> +                                  size_t size, size_t max_size)
>> 
>> Is the "safe_" prefix really meaningful? I.e. is this function more
>> safe than e.g. copy_from_guest()?
> 
> It's safe in the sense, the function adds a NUL to make sure the strings
> is correctly terminated.
> 
> On the first v1, you said that name "copy_string_from_guest" doesn't
> match the behavior of the generic helper [1]. So which name do you
> suggest for this function?

Ah, so the safe_ here follows safe_str{cat,cpy}() - that's fine then
I guess.

Jan

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-01-19 16:54   ` Jan Beulich
@ 2015-01-20 14:01     ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-20 14:01 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

On 19/01/15 16:54, Jan Beulich wrote:
>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
>> assign/deassign a physical IRQ to the guest (via the config options "irqs"
>> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
>> channel). As ARM doesn't have a such concept, we could reuse it to bound
>> a physical IRQ to a virtual IRQ.
>>
>> For now, we allow only SPIs to be mapped to the guest.
>> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Jan Beulich <jbeulich@suse.com>
>>
>> ---
>>     I'm not sure it's the best solution to reuse hypercalls for a
>>     different purpose. If x86 plan to have a such concept (i.e binding a
>>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
>>     Any thoughs?
> 
> I'm not sure either - much depends on the possible confusion this
> may cause to the callers (i.e. if they live in common code, they
> may expect the hypercall to do a certain thing, whereas if the
> callers are all [expected to be] in arch code, then I'd consider such
> overloading okay).

PHYSDEVOP_{,un}map_pirq hypercalls are used in common code such as libxl
(tools/libxl/libxc_create.c and pci code). There is a similar problem
with XEN_DOMCTL_irq_permission.

AFAIK, Linux is also using PHYSDEVOP_{,un}map_pirq to map an interrupt
into itself.

It may have confusion, if we decide to implement PIRQ in ARM. I believe
it will never happen because the interrupt can be delivered via a
virtual interface.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-19 17:02   ` Jan Beulich
@ 2015-01-20 14:28     ` Julien Grall
  2015-01-20 16:40       ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-20 14:28 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

Hi Jan,

On 19/01/15 17:02, Jan Beulich wrote:
>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>> --- a/xen/drivers/passthrough/device_tree.c
>> +++ b/xen/drivers/passthrough/device_tree.c
>> @@ -41,6 +41,10 @@ int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev)
>>      if ( !list_empty(&dev->domain_list) )
>>          goto fail;
>>  
>> +    rc = iommu_construct(d);
>> +    if ( rc )
>> +        goto fail;
> 
> Considering that the only (current) caller of this it domain_build.c I'm
> afraid you're going to get into trouble if you get back -ERESTART
> here. Note that on x86 Dom0 setup works via iommu_hwdom_init(),
> which deals with the preemption needs (at that point in time) by
> calling process_pending_softirqs() every once in a while.

iommu_hwdom_init is also called for ARM (it's part of the common domain
creation code). So, I don't see any issue here as we match the same
behavior as PCI.

FWIW, on the previous version you asked to check the need_iommu(d) in
iommu_construct. For DOM0 it will return 0 and therefore never return
-ERESTART.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-01-20  9:19   ` Jan Beulich
@ 2015-01-20 14:30     ` Julien Grall
  2015-01-20 16:42       ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-20 14:30 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

Hi Jan,

On 20/01/15 09:19, Jan Beulich wrote:
>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>> --- a/xen/include/xen/iommu.h
>> +++ b/xen/include/xen/iommu.h
>> @@ -117,7 +117,7 @@ void iommu_read_msi_from_ire(struct msi_desc *msi_desc, struct msi_msg *msg);
>>  int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev);
>>  int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev);
>>  int iommu_dt_domain_init(struct domain *d);
>> -void iommu_dt_domain_destroy(struct domain *d);
>> +int iommu_release_dt_devices(struct domain *d);
> 
> I don't think you really need an ack from me on this trivial change,
> but in case you feel otherwise, don't hesitate to add it.

I wasn't sure if I add to cc you. You were in the list of maintainers
with scripts/get_maintainers.pl because the include is part of the
"IOMMU VENDOR INDEPENDENT CODE".

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-01-20  9:21   ` Jan Beulich
@ 2015-01-20 14:31     ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-20 14:31 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

Hi Jan,

On 20/01/15 09:21, Jan Beulich wrote:
>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>> Currently, when the device is deassigned from a domain, we directly reassign
>> to DOM0.
>>
>> As the device may not have been correctly reset, this may lead to corruption 
>> or
>> expose some part of DOM0 memory. Also, we may have no way to reset some
>> platform devices.
>>
>> If Xen reassigns the device to "nobody", it may receive some global/context
>> fault because the transaction has failed (indeed the context has been
>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
>> hardware. I think we could live with that for a first version of platform
>> device passthrough.
>>
>> DOM0 will have to issue an hypercall to assign the device to itself if it
>> wants to use it.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Jan Beulich <jbeulich@suse.com>
> 
> Looks like this is because of ...
> 
>>  xen/drivers/passthrough/device_tree.c | 9 +++------
> 
> ... this. Which I think is a mistake, as I wasn't involved in the addition
> of that file. I'd appreciate an update to ./MAINTAINERS adding this
> file to the ARM section.

Ok. I will send a patch to add xen/drivers/passthrough/device_tree.c in
the "ARM section".

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 19/24] xen/iommu: arm: Wire iommu DOMCTL for ARM
  2015-01-20  9:22   ` Jan Beulich
@ 2015-01-20 14:32     ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-20 14:32 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

Hi Jan,

On 20/01/15 09:22, Jan Beulich wrote:
>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>> Cc: Jan Beulich <jbeulich@suse.com>
> 
> Is this a leftover from ...
> 
>> ---
>>     Changes in v3:
>>         - Add Stefano's ack
>>
>>     Changes in v2:
>>         - Don't move the call in common code.
> 
> ... before this?

Yes. Sorry for the spam.

Regards,


-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-20  9:34   ` Jan Beulich
@ 2015-01-20 14:37     ` Julien Grall
  2015-01-20 16:43       ` Jan Beulich
  2015-01-29 10:29     ` Stefano Stabellini
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-20 14:37 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On 20/01/15 09:34, Jan Beulich wrote:
>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>> --- a/xen/drivers/passthrough/iommu.c
>> +++ b/xen/drivers/passthrough/iommu.c
>> @@ -337,6 +337,13 @@ int iommu_do_domctl(
>>      ret = iommu_do_pci_domctl(domctl, d, u_domctl);
>>  #endif
>>  
>> +    if ( ret != -ENOSYS )
>> +        return ret;
>> +
>> +#ifdef HAS_DEVICE_TREE
>> +    ret = iommu_do_dt_domctl(domctl, d, u_domctl);
>> +#endif
> 
> Please move the (inverted) if() into the #ifdef block (but also see
> below regarding the specific error code used).

What do you mean by the "inverted if()"?

>> @@ -1533,13 +1534,19 @@ int iommu_do_pci_domctl(
>>      break;
>>  
>>      case XEN_DOMCTL_test_assign_device:
>> -        ret = xsm_test_assign_device(XSM_HOOK, domctl->u.assign_device.machine_sbdf);
>> +        ret = -ENOSYS;
>> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
>> +            break;
> 
> I'm rather uncertain about the use of -ENOSYS here: The hypercall
> isn't unimplemented after all. Provided you use consistent error
> codes in the PCI and DT variants, there's no problem calling the
> other variant if that specific error code got returned from the first
> one - the second would then just return the same one again, even
> if the first one failed on something other than the device type
> check. As a result, I'd much prefer -ENODEV here.

I will use -ENODEV on the next version.

>> +
>> +        machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
>> +
>> +        ret = xsm_test_assign_device(XSM_HOOK, machine_sbdf);
>>          if ( ret )
>>              break;
>>  
>> -        seg = domctl->u.assign_device.machine_sbdf >> 16;
>> -        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
>> -        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
>> +        seg = machine_sbdf >> 16;
>> +        bus = (machine_sbdf >> 8) & 0xff;
>> +        devfn = machine_sbdf & 0xff;
> 
> If you fiddle with these, please make them use at least PCI_BUS()
> and PCI_DEVFN2() (we don't have a matching macro for retrieving
> the segment).

Ok.

> 
>> --- a/xen/include/public/domctl.h
>> +++ b/xen/include/public/domctl.h
>> @@ -475,12 +475,23 @@ typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t;
>>  DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t);
>>  
>>  
>> -/* Assign PCI device to HVM guest. Sets up IOMMU structures. */
>> +/* Assign a device to a guest. Sets up IOMMU structures. */
>>  /* XEN_DOMCTL_assign_device */
>>  /* XEN_DOMCTL_test_assign_device */
>>  /* XEN_DOMCTL_deassign_device */
>> +#define XEN_DOMCTL_DEV_PCI      0
>> +#define XEN_DOMCTL_DEV_DT       1
>>  struct xen_domctl_assign_device {
>> -    uint32_t  machine_sbdf;   /* machine PCI ID of assigned device */
>> +    uint32_t dev;   /* XEN_DOMCTL_DEV_* */
>> +    union {
>> +        struct {
>> +            uint32_t machine_sbdf;   /* machine PCI ID of assigned device */
>> +        } pci;
>> +        struct {
>> +            uint32_t size; /* Length of the path */
>> +            XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */
>> +        } dt;
>> +    } u;
>>  };
> 
> An incompatible change like this requires bumping
> XEN_DOMCTL_INTERFACE_VERSION when not already done during
> the current release cycle.

The XEN_DOMCTL_INTERFACE_VERSION will be bumped in patch #1 of this
series [1].

Regards,

[1] https://patches.linaro.org/43014/

-- 
Julien Grall

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-20 14:28     ` Julien Grall
@ 2015-01-20 16:40       ` Jan Beulich
  2015-01-20 17:11         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-20 16:40 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 20.01.15 at 15:28, <julien.grall@linaro.org> wrote:
> On 19/01/15 17:02, Jan Beulich wrote:
>>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>>> --- a/xen/drivers/passthrough/device_tree.c
>>> +++ b/xen/drivers/passthrough/device_tree.c
>>> @@ -41,6 +41,10 @@ int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev)
>>>      if ( !list_empty(&dev->domain_list) )
>>>          goto fail;
>>>  
>>> +    rc = iommu_construct(d);
>>> +    if ( rc )
>>> +        goto fail;
>> 
>> Considering that the only (current) caller of this it domain_build.c I'm
>> afraid you're going to get into trouble if you get back -ERESTART
>> here. Note that on x86 Dom0 setup works via iommu_hwdom_init(),
>> which deals with the preemption needs (at that point in time) by
>> calling process_pending_softirqs() every once in a while.
> 
> iommu_hwdom_init is also called for ARM (it's part of the common domain
> creation code). So, I don't see any issue here as we match the same
> behavior as PCI.
> 
> FWIW, on the previous version you asked to check the need_iommu(d) in
> iommu_construct. For DOM0 it will return 0 and therefore never return
> -ERESTART.

Quoting the function:

+int iommu_construct(struct domain *d)
+{
+    int rc = 0;
+
+    if ( need_iommu(d) > 0 )
+        return 0;
+
+    if ( !iommu_use_hap_pt(d) )
+    {
+        rc = arch_iommu_populate_page_table(d);
+        if ( rc )
+            return rc;
+    }
+
+    d->need_iommu = 1;
+
+    return rc;
+}

If need_iommu() returns 0 for Dom0, then the early return won't get
used. Hence I don't follow your comment above. And if what you say
there was correct, then I don't understand why you add the call
quoted at the very top in the first place (again taking into consideration
that - afaict - the only [current] caller is in domain_build.c).

Jan

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

* Re: [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-01-20 14:30     ` Julien Grall
@ 2015-01-20 16:42       ` Jan Beulich
  0 siblings, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-01-20 16:42 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 20.01.15 at 15:30, <julien.grall@linaro.org> wrote:
> Hi Jan,
> 
> On 20/01/15 09:19, Jan Beulich wrote:
>>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>>> --- a/xen/include/xen/iommu.h
>>> +++ b/xen/include/xen/iommu.h
>>> @@ -117,7 +117,7 @@ void iommu_read_msi_from_ire(struct msi_desc *msi_desc, 
> struct msi_msg *msg);
>>>  int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev);
>>>  int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev);
>>>  int iommu_dt_domain_init(struct domain *d);
>>> -void iommu_dt_domain_destroy(struct domain *d);
>>> +int iommu_release_dt_devices(struct domain *d);
>> 
>> I don't think you really need an ack from me on this trivial change,
>> but in case you feel otherwise, don't hesitate to add it.
> 
> I wasn't sure if I add to cc you. You were in the list of maintainers
> with scripts/get_maintainers.pl because the include is part of the
> "IOMMU VENDOR INDEPENDENT CODE".

Which is fine - I merely wanted to point out that a trivial prototype
adjustment can imo go in without requiring an ack.

Jan

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-20 14:37     ` Julien Grall
@ 2015-01-20 16:43       ` Jan Beulich
  0 siblings, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-01-20 16:43 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

>>> On 20.01.15 at 15:37, <julien.grall@linaro.org> wrote:
> On 20/01/15 09:34, Jan Beulich wrote:
>>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>>> --- a/xen/drivers/passthrough/iommu.c
>>> +++ b/xen/drivers/passthrough/iommu.c
>>> @@ -337,6 +337,13 @@ int iommu_do_domctl(
>>>      ret = iommu_do_pci_domctl(domctl, d, u_domctl);
>>>  #endif
>>>  
>>> +    if ( ret != -ENOSYS )
>>> +        return ret;
>>> +
>>> +#ifdef HAS_DEVICE_TREE
>>> +    ret = iommu_do_dt_domctl(domctl, d, u_domctl);
>>> +#endif
>> 
>> Please move the (inverted) if() into the #ifdef block (but also see
>> below regarding the specific error code used).
> 
> What do you mean by the "inverted if()"?

#ifdef HAS_DEVICE_TREE
    if ( ret == -ENOSYS )
        ret = iommu_do_dt_domctl(domctl, d, u_domctl);
#endif

Jan

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-20 16:40       ` Jan Beulich
@ 2015-01-20 17:11         ` Julien Grall
  2015-01-21 10:23           ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-20 17:11 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

On 20/01/15 16:40, Jan Beulich wrote:
>>>> On 20.01.15 at 15:28, <julien.grall@linaro.org> wrote:
>> On 19/01/15 17:02, Jan Beulich wrote:
>>>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>>>> --- a/xen/drivers/passthrough/device_tree.c
>>>> +++ b/xen/drivers/passthrough/device_tree.c
>>>> @@ -41,6 +41,10 @@ int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev)
>>>>      if ( !list_empty(&dev->domain_list) )
>>>>          goto fail;
>>>>  
>>>> +    rc = iommu_construct(d);
>>>> +    if ( rc )
>>>> +        goto fail;
>>>
>>> Considering that the only (current) caller of this it domain_build.c I'm
>>> afraid you're going to get into trouble if you get back -ERESTART
>>> here. Note that on x86 Dom0 setup works via iommu_hwdom_init(),
>>> which deals with the preemption needs (at that point in time) by
>>> calling process_pending_softirqs() every once in a while.
>>
>> iommu_hwdom_init is also called for ARM (it's part of the common domain
>> creation code). So, I don't see any issue here as we match the same
>> behavior as PCI.
>>
>> FWIW, on the previous version you asked to check the need_iommu(d) in
>> iommu_construct. For DOM0 it will return 0 and therefore never return
>> -ERESTART.
> 
> Quoting the function:
> 
> +int iommu_construct(struct domain *d)
> +{
> +    int rc = 0;
> +
> +    if ( need_iommu(d) > 0 )
> +        return 0;
> +
> +    if ( !iommu_use_hap_pt(d) )
> +    {
> +        rc = arch_iommu_populate_page_table(d);
> +        if ( rc )
> +            return rc;
> +    }
> +
> +    d->need_iommu = 1;
> +
> +    return rc;
> +}

> If need_iommu() returns 0 for Dom0, then the early return won't get
> used. Hence I don't follow your comment above. And if what you say
> there was correct, then I don't understand why you add the call
> quoted at the very top in the first place (again taking into consideration
> that - afaict - the only [current] caller is in domain_build.c).

I don't understand what is the issue in the device tree use case. As I
said, assign_device in the pci do exactly the same things.

While this function is currently only used for DOM0, this will be used
in a later patch for guest non-PCI passthrough.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-20 17:11         ` Julien Grall
@ 2015-01-21 10:23           ` Jan Beulich
  2015-01-21 10:37             ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-21 10:23 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 20.01.15 at 18:11, <julien.grall@linaro.org> wrote:
> On 20/01/15 16:40, Jan Beulich wrote:
>>>>> On 20.01.15 at 15:28, <julien.grall@linaro.org> wrote:
>>> On 19/01/15 17:02, Jan Beulich wrote:
>>>>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>>>>> --- a/xen/drivers/passthrough/device_tree.c
>>>>> +++ b/xen/drivers/passthrough/device_tree.c
>>>>> @@ -41,6 +41,10 @@ int iommu_assign_dt_device(struct domain *d, struct 
> dt_device_node *dev)
>>>>>      if ( !list_empty(&dev->domain_list) )
>>>>>          goto fail;
>>>>>  
>>>>> +    rc = iommu_construct(d);
>>>>> +    if ( rc )
>>>>> +        goto fail;
>>>>
>>>> Considering that the only (current) caller of this it domain_build.c I'm
>>>> afraid you're going to get into trouble if you get back -ERESTART
>>>> here. Note that on x86 Dom0 setup works via iommu_hwdom_init(),
>>>> which deals with the preemption needs (at that point in time) by
>>>> calling process_pending_softirqs() every once in a while.
>>>
>>> iommu_hwdom_init is also called for ARM (it's part of the common domain
>>> creation code). So, I don't see any issue here as we match the same
>>> behavior as PCI.
>>>
>>> FWIW, on the previous version you asked to check the need_iommu(d) in
>>> iommu_construct. For DOM0 it will return 0 and therefore never return
>>> -ERESTART.
>> 
>> Quoting the function:
>> 
>> +int iommu_construct(struct domain *d)
>> +{
>> +    int rc = 0;
>> +
>> +    if ( need_iommu(d) > 0 )
>> +        return 0;
>> +
>> +    if ( !iommu_use_hap_pt(d) )
>> +    {
>> +        rc = arch_iommu_populate_page_table(d);
>> +        if ( rc )
>> +            return rc;
>> +    }
>> +
>> +    d->need_iommu = 1;
>> +
>> +    return rc;
>> +}
> 
>> If need_iommu() returns 0 for Dom0, then the early return won't get
>> used. Hence I don't follow your comment above. And if what you say
>> there was correct, then I don't understand why you add the call
>> quoted at the very top in the first place (again taking into consideration
>> that - afaict - the only [current] caller is in domain_build.c).
> 
> I don't understand what is the issue in the device tree use case. As I
> said, assign_device in the pci do exactly the same things.

Sure, but it's not being called for Dom0, but only out of the domctl
handler.

> While this function is currently only used for DOM0, this will be used
> in a later patch for guest non-PCI passthrough.

Okay, but you shouldn't break (or alter in [seemingly] benign ways) the
Dom0 case imo.

Jan

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-21 10:23           ` Jan Beulich
@ 2015-01-21 10:37             ` Julien Grall
  2015-01-21 10:48               ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-21 10:37 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim



On 21/01/2015 10:23, Jan Beulich wrote:
>>>> On 20.01.15 at 18:11, <julien.grall@linaro.org> wrote:
>> On 20/01/15 16:40, Jan Beulich wrote:
>>>>>> On 20.01.15 at 15:28, <julien.grall@linaro.org> wrote:
>>>> On 19/01/15 17:02, Jan Beulich wrote:
>>>>>>>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>>>>>> --- a/xen/drivers/passthrough/device_tree.c
>>>>>> +++ b/xen/drivers/passthrough/device_tree.c
>>>>>> @@ -41,6 +41,10 @@ int iommu_assign_dt_device(struct domain *d, struct
>> dt_device_node *dev)
>>>>>>       if ( !list_empty(&dev->domain_list) )
>>>>>>           goto fail;
>>>>>>
>>>>>> +    rc = iommu_construct(d);
>>>>>> +    if ( rc )
>>>>>> +        goto fail;
>>>>>
>>>>> Considering that the only (current) caller of this it domain_build.c I'm
>>>>> afraid you're going to get into trouble if you get back -ERESTART
>>>>> here. Note that on x86 Dom0 setup works via iommu_hwdom_init(),
>>>>> which deals with the preemption needs (at that point in time) by
>>>>> calling process_pending_softirqs() every once in a while.
>>>>
>>>> iommu_hwdom_init is also called for ARM (it's part of the common domain
>>>> creation code). So, I don't see any issue here as we match the same
>>>> behavior as PCI.
>>>>
>>>> FWIW, on the previous version you asked to check the need_iommu(d) in
>>>> iommu_construct. For DOM0 it will return 0 and therefore never return
>>>> -ERESTART.
>>>
>>> Quoting the function:
>>>
>>> +int iommu_construct(struct domain *d)
>>> +{
>>> +    int rc = 0;
>>> +
>>> +    if ( need_iommu(d) > 0 )
>>> +        return 0;
>>> +
>>> +    if ( !iommu_use_hap_pt(d) )
>>> +    {
>>> +        rc = arch_iommu_populate_page_table(d);
>>> +        if ( rc )
>>> +            return rc;
>>> +    }
>>> +
>>> +    d->need_iommu = 1;
>>> +
>>> +    return rc;
>>> +}
>>
>>> If need_iommu() returns 0 for Dom0, then the early return won't get
>>> used. Hence I don't follow your comment above. And if what you say
>>> there was correct, then I don't understand why you add the call
>>> quoted at the very top in the first place (again taking into consideration
>>> that - afaict - the only [current] caller is in domain_build.c).
>>
>> I don't understand what is the issue in the device tree use case. As I
>> said, assign_device in the pci do exactly the same things.
>
> Sure, but it's not being called for Dom0, but only out of the domctl
> handler.

Hmmm right. It's the main difference between non-PCI and PCI passthrough.

>
>> While this function is currently only used for DOM0, this will be used
>> in a later patch for guest non-PCI passthrough.
>
> Okay, but you shouldn't break (or alter in [seemingly] benign ways) the
> Dom0 case imo.

As iommu_hwdom_init is initialized correctly the IOMMU for DOM0, 
iommu_construct is a no-op.

Would an if ( need_iommu(d) ) will be more clear? Maybe we an assert 
(!is_hardware_domain(d)).

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-21 10:37             ` Julien Grall
@ 2015-01-21 10:48               ` Jan Beulich
  2015-01-21 12:13                 ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-21 10:48 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 21.01.15 at 11:37, <julien.grall@linaro.org> wrote:
> On 21/01/2015 10:23, Jan Beulich wrote:
>>>>> On 20.01.15 at 18:11, <julien.grall@linaro.org> wrote:
>>> While this function is currently only used for DOM0, this will be used
>>> in a later patch for guest non-PCI passthrough.
>>
>> Okay, but you shouldn't break (or alter in [seemingly] benign ways) the
>> Dom0 case imo.
> 
> As iommu_hwdom_init is initialized correctly the IOMMU for DOM0, 
> iommu_construct is a no-op.
> 
> Would an if ( need_iommu(d) ) will be more clear? Maybe we an assert 
> (!is_hardware_domain(d)).

Just think this through properly: iommu_hwdom_init() may leave
Dom0's ->need_iommu at 0 or 1 (depending on iommu_dom0_strict).
And iommu_construct() specifically is a nop only when ->need_iommu
is positive (x86's arch_iommu_populate_page_table() sets it to a
negative value to indicate "being set up", and I wonder how ARM
gets away without doing so).

Jan

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-21 10:48               ` Jan Beulich
@ 2015-01-21 12:13                 ` Julien Grall
  2015-01-21 14:13                   ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-21 12:13 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

Hi Jan,

On 21/01/15 10:48, Jan Beulich wrote:
>>>> On 21.01.15 at 11:37, <julien.grall@linaro.org> wrote:
>> On 21/01/2015 10:23, Jan Beulich wrote:
>>>>>> On 20.01.15 at 18:11, <julien.grall@linaro.org> wrote:
>>>> While this function is currently only used for DOM0, this will be used
>>>> in a later patch for guest non-PCI passthrough.
>>>
>>> Okay, but you shouldn't break (or alter in [seemingly] benign ways) the
>>> Dom0 case imo.
>>
>> As iommu_hwdom_init is initialized correctly the IOMMU for DOM0, 
>> iommu_construct is a no-op.
>>
>> Would an if ( need_iommu(d) ) will be more clear? Maybe we an assert 
>> (!is_hardware_domain(d)).
> 
> Just think this through properly: iommu_hwdom_init() may leave
> Dom0's ->need_iommu at 0 or 1 (depending on iommu_dom0_strict).
> And iommu_construct() specifically is a nop only when ->need_iommu
> is positive (x86's arch_iommu_populate_page_table() sets it to a
> negative value to indicate "being set up", and I wonder how ARM
> gets away without doing so).

iommu_dom0_strict is always set to 1 when IOMMU is used on ARM (see
check_hwdom_reqs).

Futhermore, we always share the page table with the processor, so we
never need to populate the page table.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-21 12:13                 ` Julien Grall
@ 2015-01-21 14:13                   ` Jan Beulich
  2015-01-21 14:22                     ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-01-21 14:13 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 21.01.15 at 13:13, <julien.grall@linaro.org> wrote:
> Hi Jan,
> 
> On 21/01/15 10:48, Jan Beulich wrote:
>>>>> On 21.01.15 at 11:37, <julien.grall@linaro.org> wrote:
>>> On 21/01/2015 10:23, Jan Beulich wrote:
>>>>>>> On 20.01.15 at 18:11, <julien.grall@linaro.org> wrote:
>>>>> While this function is currently only used for DOM0, this will be used
>>>>> in a later patch for guest non-PCI passthrough.
>>>>
>>>> Okay, but you shouldn't break (or alter in [seemingly] benign ways) the
>>>> Dom0 case imo.
>>>
>>> As iommu_hwdom_init is initialized correctly the IOMMU for DOM0, 
>>> iommu_construct is a no-op.
>>>
>>> Would an if ( need_iommu(d) ) will be more clear? Maybe we an assert 
>>> (!is_hardware_domain(d)).
>> 
>> Just think this through properly: iommu_hwdom_init() may leave
>> Dom0's ->need_iommu at 0 or 1 (depending on iommu_dom0_strict).
>> And iommu_construct() specifically is a nop only when ->need_iommu
>> is positive (x86's arch_iommu_populate_page_table() sets it to a
>> negative value to indicate "being set up", and I wonder how ARM
>> gets away without doing so).
> 
> iommu_dom0_strict is always set to 1 when IOMMU is used on ARM (see
> check_hwdom_reqs).
> 
> Futhermore, we always share the page table with the processor, so we
> never need to populate the page table.

That's all far from obvious looking at the patch at hand. And you
can then only hope that these two "always" will always remain to
be that way.

Jan

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-21 14:13                   ` Jan Beulich
@ 2015-01-21 14:22                     ` Julien Grall
  2015-01-21 14:29                       ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-21 14:22 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

On 21/01/15 14:13, Jan Beulich wrote:
>>>> On 21.01.15 at 13:13, <julien.grall@linaro.org> wrote:
>> Hi Jan,
>>
>> On 21/01/15 10:48, Jan Beulich wrote:
>>>>>> On 21.01.15 at 11:37, <julien.grall@linaro.org> wrote:
>>>> On 21/01/2015 10:23, Jan Beulich wrote:
>>>>>>>> On 20.01.15 at 18:11, <julien.grall@linaro.org> wrote:
>>>>>> While this function is currently only used for DOM0, this will be used
>>>>>> in a later patch for guest non-PCI passthrough.
>>>>>
>>>>> Okay, but you shouldn't break (or alter in [seemingly] benign ways) the
>>>>> Dom0 case imo.
>>>>
>>>> As iommu_hwdom_init is initialized correctly the IOMMU for DOM0, 
>>>> iommu_construct is a no-op.
>>>>
>>>> Would an if ( need_iommu(d) ) will be more clear? Maybe we an assert 
>>>> (!is_hardware_domain(d)).
>>>
>>> Just think this through properly: iommu_hwdom_init() may leave
>>> Dom0's ->need_iommu at 0 or 1 (depending on iommu_dom0_strict).
>>> And iommu_construct() specifically is a nop only when ->need_iommu
>>> is positive (x86's arch_iommu_populate_page_table() sets it to a
>>> negative value to indicate "being set up", and I wonder how ARM
>>> gets away without doing so).
>>
>> iommu_dom0_strict is always set to 1 when IOMMU is used on ARM (see
>> check_hwdom_reqs).
>>
>> Futhermore, we always share the page table with the processor, so we
>> never need to populate the page table.
> 
> That's all far from obvious looking at the patch at hand. And you
> can then only hope that these two "always" will always remain to
> be that way.

Hence the suggested ASSERT on a previous mail. I could also add a
comment in the code explaining the ASSERT().

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-21 14:22                     ` Julien Grall
@ 2015-01-21 14:29                       ` Jan Beulich
  0 siblings, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-01-21 14:29 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, ian.campbell, tim

>>> On 21.01.15 at 15:22, <julien.grall@linaro.org> wrote:
> On 21/01/15 14:13, Jan Beulich wrote:
>>>>> On 21.01.15 at 13:13, <julien.grall@linaro.org> wrote:
>>> iommu_dom0_strict is always set to 1 when IOMMU is used on ARM (see
>>> check_hwdom_reqs).
>>>
>>> Futhermore, we always share the page table with the processor, so we
>>> never need to populate the page table.
>> 
>> That's all far from obvious looking at the patch at hand. And you
>> can then only hope that these two "always" will always remain to
>> be that way.
> 
> Hence the suggested ASSERT on a previous mail. I could also add a
> comment in the code explaining the ASSERT().

Yes please, for both parts.

Jan

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-01-13 14:25 ` [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration Julien Grall
  2015-01-13 15:08   ` Daniel De Graaf
  2015-01-19 16:46   ` Jan Beulich
@ 2015-01-28 15:50   ` Stefano Stabellini
  2015-02-20 15:15   ` Ian Campbell
  3 siblings, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 15:50 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, George Dunlap, tim, Ian Jackson,
	stefano.stabellini, Jan Beulich, Andrew Cooper, xen-devel,
	Daniel De Graaf, Keir Fraser

On Tue, 13 Jan 2015, Julien Grall wrote:
> On ARM the virtual GIC may differ between each guest (emulated GIC version,
> number of SPIs...). Those informations are already known at the domain creation
> and can never change.
> 
> For now only the gic_version is set. In long run, there will be more parameters
> such as the number of SPIs. All will be required to be set at the same time.
> 
> A new arch-specific structure arch_domainconfig has been created, the x86
> one doesn't have any specific configuration, a dummy structure
> (C-spec compliant) has been created to factorize the code on the toolstack.
> 
> Some external tools (qemu, xenstore) may require to create a domain. Rather
> than asking them to take care of the arch-specific domain configuration, let
> the current function (xc_domain_create) to chose a default configuration and
> introduce a new one (xc_domain_create_config).
> 
> This patch also drop the previously DOMCTL arm_configure_domain introduced
> in Xen 4.5, as it has been made useless.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: George Dunlap <george.dunlap@eu.citrix.com>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>     This is a follow-up of http://lists.xen.org/archives/html/xen-devel/2014-11/msg00522.html
> 
>     TODO: What about migration? For now the configuration lives in internal
>     libxl structure. We need a way to pass the domain configuration to the
>     other end.
> 
>     I'm not sure if we should care of this right now as migration doesn't
>     yet exists on ARM.
> 
>     For the xc_domain_create, Stefano S. was looking to drop PV domain
>     creation support in QEMU. So maybe I could simply extend xc_domain_create
>     and drop the xc_domain_create_config.
> 
>     Changes in v3:
>         - Patch was previously sent in a separate series [1]
>         - Rename arch_domainconfig to xen_arch_domainconfig
>         - Drop the typedef
>         - Pass NULL for DOM0 config on x86
>         - Drop spurious changes
>         - Update comment in start_xen in arch/arm/setup.c
> 
>         [1] https://patches.linaro.org/41083/
> ---
>  tools/flask/policy/policy/modules/xen/xen.if |  2 +-
>  tools/libxc/include/xenctrl.h                | 14 +++++----
>  tools/libxc/xc_domain.c                      | 46 ++++++++++++++++------------
>  tools/libxl/libxl_arch.h                     |  6 ++++
>  tools/libxl/libxl_arm.c                      | 28 ++++++++++-------
>  tools/libxl/libxl_create.c                   | 21 ++++++++++---
>  tools/libxl/libxl_dm.c                       |  3 +-
>  tools/libxl/libxl_dom.c                      |  2 +-
>  tools/libxl/libxl_internal.h                 |  7 +++--
>  tools/libxl/libxl_x86.c                      | 10 ++++++
>  xen/arch/arm/domain.c                        | 28 ++++++++++++++++-
>  xen/arch/arm/domctl.c                        | 34 --------------------
>  xen/arch/arm/mm.c                            |  6 ++--
>  xen/arch/arm/setup.c                         |  6 +++-
>  xen/arch/x86/domain.c                        |  3 +-
>  xen/arch/x86/mm.c                            |  6 ++--
>  xen/arch/x86/setup.c                         |  8 +++--
>  xen/common/domain.c                          |  7 +++--
>  xen/common/domctl.c                          |  3 +-
>  xen/common/schedule.c                        |  3 +-
>  xen/include/public/arch-arm.h                |  8 +++++
>  xen/include/public/arch-x86/xen.h            |  4 +++
>  xen/include/public/domctl.h                  | 18 +----------
>  xen/include/xen/domain.h                     |  3 +-
>  xen/include/xen/sched.h                      |  9 ++++--
>  xen/xsm/flask/hooks.c                        |  3 --
>  xen/xsm/flask/policy/access_vectors          |  2 --
>  27 files changed, 170 insertions(+), 120 deletions(-)
> 
> diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if
> index 2d32e1c..620d151 100644
> --- a/tools/flask/policy/policy/modules/xen/xen.if
> +++ b/tools/flask/policy/policy/modules/xen/xen.if
> @@ -51,7 +51,7 @@ define(`create_domain_common', `
>  			getaffinity setaffinity setvcpuextstate };
>  	allow $1 $2:domain2 { set_cpuid settsc setscheduler setclaim
>  			set_max_evtchn set_vnumainfo get_vnumainfo cacheflush
> -			psr_cmt_op configure_domain };
> +			psr_cmt_op };
>  	allow $1 $2:security check_context;
>  	allow $1 $2:shadow enable;
>  	allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op updatemp };
> diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
> index 0ad8b8d..d66571f 100644
> --- a/tools/libxc/include/xenctrl.h
> +++ b/tools/libxc/include/xenctrl.h
> @@ -477,18 +477,20 @@ typedef union
>  } start_info_any_t;
>  #endif
>  
> +
> +typedef struct xen_arch_domainconfig xc_domain_configuration_t;
> +int xc_domain_create_config(xc_interface *xch,
> +                            uint32_t ssidref,
> +                            xen_domain_handle_t handle,
> +                            uint32_t flags,
> +                            uint32_t *pdomid,
> +                            xc_domain_configuration_t *config);
>  int xc_domain_create(xc_interface *xch,
>                       uint32_t ssidref,
>                       xen_domain_handle_t handle,
>                       uint32_t flags,
>                       uint32_t *pdomid);
>  
> -#if defined(__arm__) || defined(__aarch64__)
> -typedef xen_domctl_arm_configuredomain_t xc_domain_configuration_t;
> -
> -int xc_domain_configure(xc_interface *xch, uint32_t domid,
> -                        xc_domain_configuration_t *config);
> -#endif
>  
>  /* Functions to produce a dump of a given domain
>   *  xc_domain_dumpcore - produces a dump to a specified file
> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
> index b864872..eebc121 100644
> --- a/tools/libxc/xc_domain.c
> +++ b/tools/libxc/xc_domain.c
> @@ -27,11 +27,12 @@
>  #include <xen/memory.h>
>  #include <xen/hvm/hvm_op.h>
>  
> -int xc_domain_create(xc_interface *xch,
> -                     uint32_t ssidref,
> -                     xen_domain_handle_t handle,
> -                     uint32_t flags,
> -                     uint32_t *pdomid)
> +int xc_domain_create_config(xc_interface *xch,
> +                            uint32_t ssidref,
> +                            xen_domain_handle_t handle,
> +                            uint32_t flags,
> +                            uint32_t *pdomid,
> +                            xc_domain_configuration_t *config)
>  {
>      int err;
>      DECLARE_DOMCTL;
> @@ -41,32 +42,39 @@ int xc_domain_create(xc_interface *xch,
>      domctl.u.createdomain.ssidref = ssidref;
>      domctl.u.createdomain.flags   = flags;
>      memcpy(domctl.u.createdomain.handle, handle, sizeof(xen_domain_handle_t));
> +    /* xc_domain_configure_t is an alias of arch_domainconfig_t */
> +    memcpy(&domctl.u.createdomain.config, config, sizeof(*config));
>      if ( (err = do_domctl(xch, &domctl)) != 0 )
>          return err;
>  
>      *pdomid = (uint16_t)domctl.domain;
> +    memcpy(config, &domctl.u.createdomain.config, sizeof(*config));
> +
>      return 0;
>  }
>  
> -#if defined(__arm__) || defined(__aarch64__)
> -int xc_domain_configure(xc_interface *xch, uint32_t domid,
> -                        xc_domain_configuration_t *config)
> +int xc_domain_create(xc_interface *xch,
> +                     uint32_t ssidref,
> +                     xen_domain_handle_t handle,
> +                     uint32_t flags,
> +                     uint32_t *pdomid)
>  {
> -    int rc;
> -    DECLARE_DOMCTL;
> +    xc_domain_configuration_t config;
>  
> -    domctl.cmd = XEN_DOMCTL_arm_configure_domain;
> -    domctl.domain = (domid_t)domid;
> -    /* xc_domain_configure_t is an alias of xen_domctl_arm_configuredomain */
> -    memcpy(&domctl.u.configuredomain, config, sizeof(*config));
> +    memset(&config, 0, sizeof(config));
>  
> -    rc = do_domctl(xch, &domctl);
> -    if ( !rc )
> -        memcpy(config, &domctl.u.configuredomain, sizeof(*config));
> +#if defined (__i386) || defined(__x86_64__)
> +    /* No arch-specific configuration for now */
> +#elif defined (__arm__) || defined(__aarch64__)
> +    config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
> +#else
> +    errno = ENOSYS;
> +    return -1;
> +#endif
>  
> -    return rc;
> +    return xc_domain_create_config(xch, ssidref, handle,
> +                                   flags, pdomid, &config);
>  }
> -#endif
>  
>  int xc_domain_cacheflush(xc_interface *xch, uint32_t domid,
>                           xen_pfn_t start_pfn, xen_pfn_t nr_pfns)
> diff --git a/tools/libxl/libxl_arch.h b/tools/libxl/libxl_arch.h
> index d3bc136..f806ed1 100644
> --- a/tools/libxl/libxl_arch.h
> +++ b/tools/libxl/libxl_arch.h
> @@ -15,6 +15,11 @@
>  #ifndef LIBXL_ARCH_H
>  #define LIBXL_ARCH_H
>  
> +/* fill the arch specific configuration for the domain */
> +int libxl__arch_domain_prepare_config(libxl__gc *gc,
> +                                      libxl_domain_config *d_config,
> +                                      xc_domain_configuration_t *xc_config);
> +
>  /* arch specific internal domain creation function */
>  int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
>                 uint32_t domid);
> @@ -22,6 +27,7 @@ int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
>  /* setup arch specific hardware description, i.e. DTB on ARM */
>  int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>                                             libxl_domain_build_info *info,
> +                                           libxl__domain_build_state *state,
>                                             struct xc_dom_image *dom);
>  /* finalize arch specific hardware description. */
>  int libxl__arch_domain_finalise_hw_description(libxl__gc *gc,
> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> index 65a762b..cddce6e 100644
> --- a/tools/libxl/libxl_arm.c
> +++ b/tools/libxl/libxl_arm.c
> @@ -35,6 +35,15 @@ static const char *gicv_to_string(uint8_t gic_version)
>      }
>  }
>  
> +int libxl__arch_domain_prepare_config(libxl__gc *gc,
> +                                      libxl_domain_config *d_config,
> +                                      xc_domain_configuration_t *xc_config)
> +{
> +    xc_config->gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
> +
> +    return 0;
> +}
> +
>  int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
>                                uint32_t domid)
>  {
> @@ -516,9 +525,9 @@ out:
>  
>  int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>                                             libxl_domain_build_info *info,
> +                                           libxl__domain_build_state *state,
>                                             struct xc_dom_image *dom)
>  {
> -    xc_domain_configuration_t config;
>      void *fdt = NULL;
>      int rc, res;
>      size_t fdt_size = 0;
> @@ -526,6 +535,9 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>      const libxl_version_info *vers;
>      const struct arch_info *ainfo;
>  
> +    /* convenience aliases */
> +    xc_domain_configuration_t *xc_config = &state->config;
> +
>      assert(info->type == LIBXL_DOMAIN_TYPE_PV);
>  
>      vers = libxl_get_version_info(CTX);
> @@ -534,16 +546,9 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>      ainfo = get_arch_info(gc, dom);
>      if (ainfo == NULL) return ERROR_FAIL;
>  
> -    LOG(DEBUG, "configure the domain");
> -    config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
> -    if (xc_domain_configure(CTX->xch, dom->guest_domid, &config) != 0) {
> -        LOG(ERROR, "couldn't configure the domain");
> -        return ERROR_FAIL;
> -    }
> -
>      LOG(DEBUG, "constructing DTB for Xen version %d.%d guest",
>          vers->xen_version_major, vers->xen_version_minor);
> -    LOG(DEBUG, "  - vGIC version: %s", gicv_to_string(config.gic_version));
> +    LOG(DEBUG, " - vGIC version: %s\n", gicv_to_string(xc_config->gic_version));
>  
>  /*
>   * Call "call" handling FDT_ERR_*. Will either:
> @@ -592,7 +597,7 @@ next_resize:
>  
>          FDT( make_memory_nodes(gc, fdt, dom) );
>  
> -        switch (config.gic_version) {
> +        switch (xc_config->gic_version) {
>          case XEN_DOMCTL_CONFIG_GIC_V2:
>              FDT( make_gicv2_node(gc, fdt,
>                                   GUEST_GICD_BASE, GUEST_GICD_SIZE,
> @@ -602,7 +607,8 @@ next_resize:
>              FDT( make_gicv3_node(gc, fdt) );
>              break;
>          default:
> -            LOG(ERROR, "Unknown GIC version %d", config.gic_version);
> +            LOG(ERROR, "Unknown GIC version %s",
> +                gicv_to_string(xc_config->gic_version));
>              rc = ERROR_FAIL;
>              goto out;
>          }
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index 6f87d1c..029d2e2 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -489,8 +489,8 @@ out:
>      return ret;
>  }
>  
> -int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
> -                       uint32_t *domid)
> +int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config,
> +                       uint32_t *domid, xc_domain_configuration_t *xc_config)
>  {
>      libxl_ctx *ctx = libxl__gc_owner(gc);
>      int flags, ret, rc, nb_vm;
> @@ -503,6 +503,8 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
>      xen_domain_handle_t handle;
>      libxl_vminfo *vm_list;
>  
> +    /* convenience aliases */
> +    libxl_domain_create_info *info = &d_config->c_info;
>  
>      assert(!libxl_domid_valid_guest(*domid));
>  
> @@ -531,7 +533,16 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
>      /* Ultimately, handle is an array of 16 uint8_t, same as uuid */
>      libxl_uuid_copy(ctx, (libxl_uuid *)handle, &info->uuid);
>  
> -    ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
> +    ret = libxl__arch_domain_prepare_config(gc, d_config, xc_config);
> +    if (ret < 0) {
> +        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "fail to get domain config");
> +        rc = ERROR_FAIL;
> +        goto out;
> +    }
> +
> +    ret = xc_domain_create_config(ctx->xch, info->ssidref,
> +                                  handle, flags, domid,
> +                                  xc_config);
>      if (ret < 0) {
>          LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "domain creation fail");
>          rc = ERROR_FAIL;
> @@ -764,9 +775,11 @@ static void initiate_domain_create(libxl__egc *egc,
>  
>      /* convenience aliases */
>      libxl_domain_config *const d_config = dcs->guest_config;
> +    libxl__domain_build_state *const state = &dcs->build_state;
>      const int restore_fd = dcs->restore_fd;
>      memset(&dcs->build_state, 0, sizeof(dcs->build_state));
>  
> +
>      domid = 0;
>  
>      if (d_config->c_info.ssid_label) {
> @@ -848,7 +861,7 @@ static void initiate_domain_create(libxl__egc *egc,
>      ret = libxl__domain_create_info_setdefault(gc, &d_config->c_info);
>      if (ret) goto error_out;
>  
> -    ret = libxl__domain_make(gc, &d_config->c_info, &domid);
> +    ret = libxl__domain_make(gc, d_config, &domid, &state->config);
>      if (ret) {
>          LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot make domain: %d", ret);
>          dcs->guest_domid = domid;
> diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
> index c2b0487..f5f9e6d 100644
> --- a/tools/libxl/libxl_dm.c
> +++ b/tools/libxl/libxl_dm.c
> @@ -1063,7 +1063,8 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
>      stubdom_state->pv_ramdisk.path = "";
>  
>      /* fixme: this function can leak the stubdom if it fails */
> -    ret = libxl__domain_make(gc, &dm_config->c_info, &sdss->pvqemu.guest_domid);
> +    ret = libxl__domain_make(gc, dm_config, &sdss->pvqemu.guest_domid,
> +                             &stubdom_state->config);
>      if (ret)
>          goto out;
>      uint32_t dm_domid = sdss->pvqemu.guest_domid;
> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> index 48d661a..1bea260 100644
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -586,7 +586,7 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
>          LOGE(ERROR, "xc_dom_parse_image failed");
>          goto out;
>      }
> -    if ( (ret = libxl__arch_domain_init_hw_description(gc, info, dom)) != 0 ) {
> +    if ( (ret = libxl__arch_domain_init_hw_description(gc, info, state, dom)) != 0 ) {
>          LOGE(ERROR, "libxl__arch_domain_init_hw_description failed");
>          goto out;
>      }
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index 934465a..be5ed82 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -973,6 +973,8 @@ typedef struct {
>      libxl__file_reference pv_ramdisk;
>      const char * pv_cmdline;
>      bool pvh_enabled;
> +
> +    xc_domain_configuration_t config;
>  } libxl__domain_build_state;
>  
>  _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid,
> @@ -1462,8 +1464,9 @@ _hidden  void libxl__exec(libxl__gc *gc, int stdinfd, int stdoutfd,
>   /* on entry, libxl_domid_valid_guest(domid) must be false;
>    * on exit (even error exit), domid may be valid and refer to a domain */
>  _hidden int libxl__domain_make(libxl__gc *gc,
> -                               libxl_domain_create_info *info,
> -                               uint32_t *domid);
> +                               libxl_domain_config *d_config,
> +                               uint32_t *domid,
> +                               xc_domain_configuration_t *xc_config);
>  
>  _hidden int libxl__domain_build(libxl__gc *gc,
>                                  libxl_domain_config *d_config,
> diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c
> index 9ceb373..b054d9d 100644
> --- a/tools/libxl/libxl_x86.c
> +++ b/tools/libxl/libxl_x86.c
> @@ -1,6 +1,15 @@
>  #include "libxl_internal.h"
>  #include "libxl_arch.h"
>  
> +int libxl__arch_domain_prepare_config(libxl__gc *gc,
> +                                      libxl_domain_config *d_config,
> +                                      xc_domain_configuration_t *xc_config)
> +{
> +    /* No specific configuration right now */
> +
> +    return 0;
> +}
> +
>  static const char *e820_names(int type)
>  {
>      switch (type) {
> @@ -313,6 +322,7 @@ int libxl__arch_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
>  
>  int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>                                             libxl_domain_build_info *info,
> +                                           libxl__domain_build_state *state,
>                                             struct xc_dom_image *dom)
>  {
>      return 0;
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 589b095..2473b10 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -504,9 +504,11 @@ void vcpu_destroy(struct vcpu *v)
>      free_xenheap_pages(v->arch.stack, STACK_ORDER);
>  }
>  
> -int arch_domain_create(struct domain *d, unsigned int domcr_flags)
> +int arch_domain_create(struct domain *d, unsigned int domcr_flags,
> +                       struct xen_arch_domainconfig *config)
>  {
>      int rc;
> +    uint8_t gic_version;
>  
>      d->arch.relmem = RELMEM_not_started;
>  
> @@ -514,6 +516,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
>      if ( is_idle_domain(d) )
>          return 0;
>  
> +    ASSERT(config != NULL);
>      if ( (rc = p2m_init(d)) != 0 )
>          goto fail;
>  
> @@ -534,6 +537,29 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
>      if ( (rc = p2m_alloc_table(d)) != 0 )
>          goto fail;
>  
> +    /*
> +     * Currently the vGIC is emulating the same version of the
> +     * hardware GIC. Only the value XEN_DOMCTL_CONFIG_GIC_DEFAULT
> +     * is allowed. The DOMCTL will return the actual version of the
> +     * GIC.
> +     */
> +    rc = -EOPNOTSUPP;
> +    if ( config->gic_version != XEN_DOMCTL_CONFIG_GIC_DEFAULT )
> +        goto fail;
> +
> +    switch ( gic_hw_version() )
> +    {
> +    case GIC_V3:
> +        gic_version = XEN_DOMCTL_CONFIG_GIC_V3;
> +        break;
> +    case GIC_V2:
> +        gic_version = XEN_DOMCTL_CONFIG_GIC_V2;
> +        break;
> +    default:
> +        BUG();
> +    }
> +    config->gic_version = gic_version;
> +
>      if ( (rc = gicv_setup(d)) != 0 )
>          goto fail;
>  
> diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
> index d246e84..485d3aa 100644
> --- a/xen/arch/arm/domctl.c
> +++ b/xen/arch/arm/domctl.c
> @@ -32,40 +32,6 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
>  
>          return p2m_cache_flush(d, s, e);
>      }
> -    case XEN_DOMCTL_arm_configure_domain:
> -    {
> -        uint8_t gic_version;
> -
> -        /*
> -         * Currently the vGIC is emulating the same version of the
> -         * hardware GIC. Only the value XEN_DOMCTL_CONFIG_GIC_DEFAULT
> -         * is allowed. The DOMCTL will return the actual version of the
> -         * GIC.
> -         */
> -        if ( domctl->u.configuredomain.gic_version != XEN_DOMCTL_CONFIG_GIC_DEFAULT )
> -            return -EOPNOTSUPP;
> -
> -        switch ( gic_hw_version() )
> -        {
> -        case GIC_V3:
> -            gic_version = XEN_DOMCTL_CONFIG_GIC_V3;
> -            break;
> -        case GIC_V2:
> -            gic_version = XEN_DOMCTL_CONFIG_GIC_V2;
> -            break;
> -        default:
> -            BUG();
> -        }
> -
> -        domctl->u.configuredomain.gic_version = gic_version;
> -
> -        /* TODO: Make the copy generic for all ARCH domctl */
> -        if ( __copy_to_guest(u_domctl, domctl, 1) )
> -            return -EFAULT;
> -
> -        return 0;
> -    }
> -
>      default:
>          return subarch_do_domctl(domctl, d, u_domctl);
>      }
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index 7d4ba0c..9128af1 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -399,7 +399,7 @@ void __init arch_init_memory(void)
>       * Any Xen-heap pages that we will allow to be mapped will have
>       * their domain field set to dom_xen.
>       */
> -    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0);
> +    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0, NULL);
>      BUG_ON(IS_ERR(dom_xen));
>  
>      /*
> @@ -407,14 +407,14 @@ void __init arch_init_memory(void)
>       * This domain owns I/O pages that are within the range of the page_info
>       * array. Mappings occur at the priv of the caller.
>       */
> -    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0);
> +    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0, NULL);
>      BUG_ON(IS_ERR(dom_io));
>  
>      /*
>       * Initialise our COW domain.
>       * This domain owns sharable pages.
>       */
> -    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0);
> +    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0, NULL);
>      BUG_ON(IS_ERR(dom_cow));
>  }
>  
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index f49569d..4d242e0 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -697,6 +697,7 @@ void __init start_xen(unsigned long boot_phys_offset,
>      const char *cmdline;
>      struct bootmodule *xen_bootmodule;
>      struct domain *dom0;
> +    struct xen_arch_domainconfig config;
>  
>      setup_cache();
>  
> @@ -811,7 +812,10 @@ void __init start_xen(unsigned long boot_phys_offset,
>      do_initcalls();
>  
>      /* Create initial domain 0. */
> -    dom0 = domain_create(0, 0, 0);
> +    /* The vGIC for DOM0 is exactly emulated the hardware GIC */
> +    config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
> +
> +    dom0 = domain_create(0, 0, 0, &config);
>      if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
>              panic("Error creating domain 0");
>  
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index c8832c6..e174f28 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -514,7 +514,8 @@ void vcpu_destroy(struct vcpu *v)
>          xfree(v->arch.pv_vcpu.trap_ctxt);
>  }
>  
> -int arch_domain_create(struct domain *d, unsigned int domcr_flags)
> +int arch_domain_create(struct domain *d, unsigned int domcr_flags,
> +                       struct xen_arch_domainconfig *config)
>  {
>      int i, paging_initialised = 0;
>      int rc = -ENOMEM;
> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index 6e9c2c0..ef4d149 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -275,7 +275,7 @@ void __init arch_init_memory(void)
>       * Hidden PCI devices will also be associated with this domain
>       * (but be [partly] controlled by Dom0 nevertheless).
>       */
> -    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0);
> +    dom_xen = domain_create(DOMID_XEN, DOMCRF_dummy, 0, NULL);
>      BUG_ON(IS_ERR(dom_xen));
>      INIT_LIST_HEAD(&dom_xen->arch.pdev_list);
>  
> @@ -284,14 +284,14 @@ void __init arch_init_memory(void)
>       * This domain owns I/O pages that are within the range of the page_info
>       * array. Mappings occur at the priv of the caller.
>       */
> -    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0);
> +    dom_io = domain_create(DOMID_IO, DOMCRF_dummy, 0, NULL);
>      BUG_ON(IS_ERR(dom_io));
>      
>      /*
>       * Initialise our COW domain.
>       * This domain owns sharable pages.
>       */
> -    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0);
> +    dom_cow = domain_create(DOMID_COW, DOMCRF_dummy, 0, NULL);
>      BUG_ON(IS_ERR(dom_cow));
>  
>      /* First 1MB of RAM is historically marked as I/O. */
> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index c27c49c..6ce51f6 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -1347,8 +1347,12 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      if ( opt_dom0pvh )
>          domcr_flags |= DOMCRF_pvh | DOMCRF_hap;
>  
> -    /* Create initial domain 0. */
> -    dom0 = domain_create(0, domcr_flags, 0);
> +    /*
> +     * Create initial domain 0.
> +     * x86 doesn't support arch-configuration. So it's fine to pass
> +     * NULL.
> +     */
> +    dom0 = domain_create(0, domcr_flags, 0, NULL);
>      if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
>          panic("Error creating domain 0");
>  
> diff --git a/xen/common/domain.c b/xen/common/domain.c
> index 336e9ea..9448bf6 100644
> --- a/xen/common/domain.c
> +++ b/xen/common/domain.c
> @@ -242,8 +242,9 @@ static void __init parse_extra_guest_irqs(const char *s)
>  }
>  custom_param("extra_guest_irqs", parse_extra_guest_irqs);
>  
> -struct domain *domain_create(
> -    domid_t domid, unsigned int domcr_flags, uint32_t ssidref)
> +struct domain *domain_create(domid_t domid, unsigned int domcr_flags,
> +                             uint32_t ssidref,
> +                             struct xen_arch_domainconfig *config)
>  {
>      struct domain *d, **pd, *old_hwdom = NULL;
>      enum { INIT_xsm = 1u<<0, INIT_watchdog = 1u<<1, INIT_rangeset = 1u<<2,
> @@ -353,7 +354,7 @@ struct domain *domain_create(
>              goto fail;
>      }
>  
> -    if ( (err = arch_domain_create(d, domcr_flags)) != 0 )
> +    if ( (err = arch_domain_create(d, domcr_flags, config)) != 0 )
>          goto fail;
>      init_status |= INIT_arch;
>  
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index ee578c0..6a0f53a 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -582,7 +582,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>          if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_oos_off )
>              domcr_flags |= DOMCRF_oos_off;
>  
> -        d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref);
> +        d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref,
> +                          &op->u.createdomain.config);
>          if ( IS_ERR(d) )
>          {
>              ret = PTR_ERR(d);
> diff --git a/xen/common/schedule.c b/xen/common/schedule.c
> index 6285a6e..ab2561a 100644
> --- a/xen/common/schedule.c
> +++ b/xen/common/schedule.c
> @@ -1421,7 +1421,8 @@ void __init scheduler_init(void)
>          sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US;
>      }
>  
> -    idle_domain = domain_create(DOMID_IDLE, 0, 0);
> +    /* There is no need of arch-specific configuration for an idle domain */
> +    idle_domain = domain_create(DOMID_IDLE, 0, 0, NULL);
>      BUG_ON(IS_ERR(idle_domain));
>      idle_domain->vcpu = idle_vcpu;
>      idle_domain->max_vcpus = nr_cpu_ids;
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index e711606..4c1b9f9 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -314,6 +314,14 @@ struct arch_shared_info {
>  typedef struct arch_shared_info arch_shared_info_t;
>  typedef uint64_t xen_callback_t;
>  
> +#define XEN_DOMCTL_CONFIG_GIC_DEFAULT   0
> +#define XEN_DOMCTL_CONFIG_GIC_V2        1
> +#define XEN_DOMCTL_CONFIG_GIC_V3        2
> +struct xen_arch_domainconfig {
> +    /* IN/OUT */
> +    uint8_t gic_version;
> +};
> +
>  #endif
>  
>  #if defined(__XEN__) || defined(__XEN_TOOLS__)
> diff --git a/xen/include/public/arch-x86/xen.h b/xen/include/public/arch-x86/xen.h
> index c5e880b..d07d550 100644
> --- a/xen/include/public/arch-x86/xen.h
> +++ b/xen/include/public/arch-x86/xen.h
> @@ -258,6 +258,10 @@ struct arch_shared_info {
>  };
>  typedef struct arch_shared_info arch_shared_info_t;
>  
> +struct xen_arch_domainconfig {
> +    char dummy;
> +};
> +
>  #endif /* !__ASSEMBLY__ */
>  
>  /*
> diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
> index 57e2ed7..b742b23 100644
> --- a/xen/include/public/domctl.h
> +++ b/xen/include/public/domctl.h
> @@ -64,23 +64,11 @@ struct xen_domctl_createdomain {
>  #define _XEN_DOMCTL_CDF_pvh_guest     4
>  #define XEN_DOMCTL_CDF_pvh_guest      (1U<<_XEN_DOMCTL_CDF_pvh_guest)
>      uint32_t flags;
> +    struct xen_arch_domainconfig config;
>  };
>  typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t);
>  
> -#if defined(__arm__) || defined(__aarch64__)
> -#define XEN_DOMCTL_CONFIG_GIC_DEFAULT   0
> -#define XEN_DOMCTL_CONFIG_GIC_V2        1
> -#define XEN_DOMCTL_CONFIG_GIC_V3        2
> -/* XEN_DOMCTL_configure_domain */
> -struct xen_domctl_arm_configuredomain {
> -    /* IN/OUT parameters */
> -    uint8_t gic_version;
> -};
> -typedef struct xen_domctl_arm_configuredomain xen_domctl_arm_configuredomain_t;
> -DEFINE_XEN_GUEST_HANDLE(xen_domctl_arm_configuredomain_t);
> -#endif
> -
>  /* XEN_DOMCTL_getdomaininfo */
>  struct xen_domctl_getdomaininfo {
>      /* OUT variables. */
> @@ -1069,7 +1057,6 @@ struct xen_domctl {
>  #define XEN_DOMCTL_set_vcpu_msrs                 73
>  #define XEN_DOMCTL_setvnumainfo                  74
>  #define XEN_DOMCTL_psr_cmt_op                    75
> -#define XEN_DOMCTL_arm_configure_domain          76
>  #define XEN_DOMCTL_gdbsx_guestmemio            1000
>  #define XEN_DOMCTL_gdbsx_pausevcpu             1001
>  #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
> @@ -1078,9 +1065,6 @@ struct xen_domctl {
>      domid_t  domain;
>      union {
>          struct xen_domctl_createdomain      createdomain;
> -#if defined(__arm__) || defined(__aarch64__)
> -        struct xen_domctl_arm_configuredomain configuredomain;
> -#endif
>          struct xen_domctl_getdomaininfo     getdomaininfo;
>          struct xen_domctl_getmemlist        getmemlist;
>          struct xen_domctl_getpageframeinfo  getpageframeinfo;
> diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
> index 72667da..6b5c0c5 100644
> --- a/xen/include/xen/domain.h
> +++ b/xen/include/xen/domain.h
> @@ -55,7 +55,8 @@ void vcpu_destroy(struct vcpu *v);
>  int map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned offset);
>  void unmap_vcpu_info(struct vcpu *v);
>  
> -int arch_domain_create(struct domain *d, unsigned int domcr_flags);
> +int arch_domain_create(struct domain *d, unsigned int domcr_flags,
> +                       struct xen_arch_domainconfig *config);
>  
>  void arch_domain_destroy(struct domain *d);
>  
> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
> index 46fc6e3..9759015 100644
> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -525,8 +525,13 @@ static inline void get_knownalive_domain(struct domain *d)
>  int domain_set_node_affinity(struct domain *d, const nodemask_t *affinity);
>  void domain_update_node_affinity(struct domain *d);
>  
> -struct domain *domain_create(
> -    domid_t domid, unsigned int domcr_flags, uint32_t ssidref);
> +/*
> + * Create a domain: the configuration is only necessary for real domain
> + * (i.e !DOMCRF_dummy, excluded idle domain).
> + */
> +struct domain *domain_create(domid_t domid, unsigned int domcr_flags,
> +                             uint32_t ssidref,
> +                             struct xen_arch_domainconfig *config);
>   /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */
>  #define _DOMCRF_hvm           0
>  #define DOMCRF_hvm            (1U<<_DOMCRF_hvm)
> diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
> index d48463f..36410cc 100644
> --- a/xen/xsm/flask/hooks.c
> +++ b/xen/xsm/flask/hooks.c
> @@ -729,9 +729,6 @@ static int flask_domctl(struct domain *d, int cmd)
>      case XEN_DOMCTL_psr_cmt_op:
>          return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__PSR_CMT_OP);
>  
> -    case XEN_DOMCTL_arm_configure_domain:
> -        return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__CONFIGURE_DOMAIN);
> -
>      default:
>          printk("flask_domctl: Unknown op %d\n", cmd);
>          return -EPERM;
> diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
> index 1da9f63..9a98fc3 100644
> --- a/xen/xsm/flask/policy/access_vectors
> +++ b/xen/xsm/flask/policy/access_vectors
> @@ -218,8 +218,6 @@ class domain2
>      get_vnumainfo
>  # XEN_DOMCTL_psr_cmt_op
>      psr_cmt_op
> -# XEN_DOMCTL_configure_domain
> -    configure_domain
>  }
>  
>  # Similar to class domain, but primarily contains domctls related to HVM domains
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 02/24] xen/arm: Divide GIC initialization in 2 parts
  2015-01-13 14:25 ` [PATCH v3 02/24] xen/arm: Divide GIC initialization in 2 parts Julien Grall
@ 2015-01-28 16:09   ` Stefano Stabellini
  2015-02-20 15:19     ` Ian Campbell
  2015-02-20 15:19   ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 16:09 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> Currently the function to translate IRQ from the device tree is set
> unconditionally  to be able to be able to retrieve serial/timer IRQ before the
> GIC has been initialized.
> 
> It assumes that the xlate function won't never changed. We may also need to
> have the primary interrupt controller very early.
> 
> Rework the gic initialization in 2 parts:
>     - gic_preinit: Get the interrupt controller device tree node and set
> up GIC and xlate callbacks
>     - gic_init: Initialize the interrupt controller and the boot CPU
>     interrupts.
> 
> The former function will be called just after the IRQ subsystem as been
> initialized.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


> ---
>     Changes in v3:
>         - Patch was previously sent in a separate series [1]
>         - Reorder the function to avoid forward declaration
>         - Make gic-v3 driver compliant to the new interface
>         - Remove spurious field addition in gicv2 structure
> 
>     Changelog based on the separate series:
> 
>     Changes in v3:
>         - Patch added.
> 
>     [1] https://patches.linaro.org/33313/
> ---
>  xen/arch/arm/gic-v2.c     | 70 ++++++++++++++++++++++---------------------
>  xen/arch/arm/gic-v3.c     | 75 ++++++++++++++++++++++++-----------------------
>  xen/arch/arm/gic.c        | 16 ++++++++--
>  xen/arch/arm/setup.c      |  3 +-
>  xen/include/asm-arm/gic.h |  8 +++++
>  5 files changed, 100 insertions(+), 72 deletions(-)
> 
> diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
> index 15916c9..016b0fd 100644
> --- a/xen/arch/arm/gic-v2.c
> +++ b/xen/arch/arm/gic-v2.c
> @@ -655,37 +655,10 @@ static hw_irq_controller gicv2_guest_irq_type = {
>      .set_affinity = gicv2_irq_set_affinity,
>  };
>  
> -const static struct gic_hw_operations gicv2_ops = {
> -    .info                = &gicv2_info,
> -    .secondary_init      = gicv2_secondary_cpu_init,
> -    .save_state          = gicv2_save_state,
> -    .restore_state       = gicv2_restore_state,
> -    .dump_state          = gicv2_dump_state,
> -    .gicv_setup          = gicv2v_setup,
> -    .gic_host_irq_type   = &gicv2_host_irq_type,
> -    .gic_guest_irq_type  = &gicv2_guest_irq_type,
> -    .eoi_irq             = gicv2_eoi_irq,
> -    .deactivate_irq      = gicv2_dir_irq,
> -    .read_irq            = gicv2_read_irq,
> -    .set_irq_properties  = gicv2_set_irq_properties,
> -    .send_SGI            = gicv2_send_SGI,
> -    .disable_interface   = gicv2_disable_interface,
> -    .update_lr           = gicv2_update_lr,
> -    .update_hcr_status   = gicv2_hcr_status,
> -    .clear_lr            = gicv2_clear_lr,
> -    .read_lr             = gicv2_read_lr,
> -    .write_lr            = gicv2_write_lr,
> -    .read_vmcr_priority  = gicv2_read_vmcr_priority,
> -    .read_apr            = gicv2_read_apr,
> -    .make_dt_node        = gicv2_make_dt_node,
> -};
> -
> -/* Set up the GIC */
> -static int __init gicv2_init(struct dt_device_node *node, const void *data)
> +static int __init gicv2_init(void)
>  {
>      int res;
> -
> -    dt_device_set_used_by(node, DOMID_XEN);
> +    const struct dt_device_node *node = gicv2_info.node;
>  
>      res = dt_device_get_address(node, 0, &gicv2.dbase, NULL);
>      if ( res || !gicv2.dbase || (gicv2.dbase & ~PAGE_MASK) )
> @@ -708,9 +681,6 @@ static int __init gicv2_init(struct dt_device_node *node, const void *data)
>          panic("GICv2: Cannot find the maintenance IRQ");
>      gicv2_info.maintenance_irq = res;
>  
> -    /* Set the GIC as the primary interrupt controller */
> -    dt_interrupt_controller = node;
> -
>      /* TODO: Add check on distributor, cpu size */
>  
>      printk("GICv2 initialization:\n"
> @@ -755,8 +725,42 @@ static int __init gicv2_init(struct dt_device_node *node, const void *data)
>  
>      spin_unlock(&gicv2.lock);
>  
> +    return 0;
> +}
> +
> +const static struct gic_hw_operations gicv2_ops = {
> +    .info                = &gicv2_info,
> +    .init                = gicv2_init,
> +    .secondary_init      = gicv2_secondary_cpu_init,
> +    .save_state          = gicv2_save_state,
> +    .restore_state       = gicv2_restore_state,
> +    .dump_state          = gicv2_dump_state,
> +    .gicv_setup          = gicv2v_setup,
> +    .gic_host_irq_type   = &gicv2_host_irq_type,
> +    .gic_guest_irq_type  = &gicv2_guest_irq_type,
> +    .eoi_irq             = gicv2_eoi_irq,
> +    .deactivate_irq      = gicv2_dir_irq,
> +    .read_irq            = gicv2_read_irq,
> +    .set_irq_properties  = gicv2_set_irq_properties,
> +    .send_SGI            = gicv2_send_SGI,
> +    .disable_interface   = gicv2_disable_interface,
> +    .update_lr           = gicv2_update_lr,
> +    .update_hcr_status   = gicv2_hcr_status,
> +    .clear_lr            = gicv2_clear_lr,
> +    .read_lr             = gicv2_read_lr,
> +    .write_lr            = gicv2_write_lr,
> +    .read_vmcr_priority  = gicv2_read_vmcr_priority,
> +    .read_apr            = gicv2_read_apr,
> +    .make_dt_node        = gicv2_make_dt_node,
> +};
> +
> +/* Set up the GIC */
> +static int __init gicv2_preinit(struct dt_device_node *node, const void *data)
> +{
>      gicv2_info.hw_version = GIC_V2;
> +    gicv2_info.node = node;
>      register_gic_ops(&gicv2_ops);
> +    dt_irq_xlate = gic_irq_xlate;
>  
>      return 0;
>  }
> @@ -769,7 +773,7 @@ static const struct dt_device_match gicv2_dt_match[] __initconst =
>  
>  DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC)
>          .dt_match = gicv2_dt_match,
> -        .init = gicv2_init,
> +        .init = gicv2_preinit,
>  DT_DEVICE_END
>  
>  /*
> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
> index 2ddcbab..f650756 100644
> --- a/xen/arch/arm/gic-v3.c
> +++ b/xen/arch/arm/gic-v3.c
> @@ -1141,37 +1141,13 @@ static const hw_irq_controller gicv3_guest_irq_type = {
>      .set_affinity = gicv3_irq_set_affinity,
>  };
>  
> -static const struct gic_hw_operations gicv3_ops = {
> -    .info                = &gicv3_info,
> -    .save_state          = gicv3_save_state,
> -    .restore_state       = gicv3_restore_state,
> -    .dump_state          = gicv3_dump_state,
> -    .gicv_setup          = gicv_v3_init,
> -    .gic_host_irq_type   = &gicv3_host_irq_type,
> -    .gic_guest_irq_type  = &gicv3_guest_irq_type,
> -    .eoi_irq             = gicv3_eoi_irq,
> -    .deactivate_irq      = gicv3_dir_irq,
> -    .read_irq            = gicv3_read_irq,
> -    .set_irq_properties  = gicv3_set_irq_properties,
> -    .send_SGI            = gicv3_send_sgi,
> -    .disable_interface   = gicv3_disable_interface,
> -    .update_lr           = gicv3_update_lr,
> -    .update_hcr_status   = gicv3_hcr_status,
> -    .clear_lr            = gicv3_clear_lr,
> -    .read_lr             = gicv3_read_lr,
> -    .write_lr            = gicv3_write_lr,
> -    .read_vmcr_priority  = gicv3_read_vmcr_priority,
> -    .read_apr            = gicv3_read_apr,
> -    .secondary_init      = gicv3_secondary_cpu_init,
> -    .make_dt_node        = gicv3_make_dt_node,
> -};
> -
>  /* Set up the GIC */
> -static int __init gicv3_init(struct dt_device_node *node, const void *data)
> +static int __init gicv3_init(void)
>  {
>      struct rdist_region *rdist_regs;
>      int res, i;
>      uint32_t reg;
> +    const struct dt_device_node *node = gicv3_info.node;
>  
>      if ( !cpu_has_gicv3 )
>      {
> @@ -1179,8 +1155,6 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data)
>          return -ENODEV;
>      }
>  
> -    dt_device_set_used_by(node, DOMID_XEN);
> -
>      res = dt_device_get_address(node, 0, &gicv3.dbase, &gicv3.dbase_size);
>      if ( res || !gicv3.dbase )
>          panic("GICv3: Cannot find a valid distributor address");
> @@ -1232,9 +1206,6 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data)
>          panic("GICv3: Cannot find the maintenance IRQ");
>      gicv3_info.maintenance_irq = res;
>  
> -    /* Set the GIC as the primary interrupt controller */
> -    dt_interrupt_controller = node;
> -
>      for ( i = 0; i < gicv3.rdist_count; i++ )
>      {
>          /* map dbase & rdist regions */
> @@ -1269,15 +1240,47 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data)
>      res = gicv3_cpu_init();
>      gicv3_hyp_init();
>  
> -    gicv3_info.hw_version = GIC_V3;
> -    /* Register hw ops*/
> -    register_gic_ops(&gicv3_ops);
> -
>      spin_unlock(&gicv3.lock);
>  
>      return res;
>  }
>  
> +static const struct gic_hw_operations gicv3_ops = {
> +    .info                = &gicv3_info,
> +    .init                = gicv3_init,
> +    .save_state          = gicv3_save_state,
> +    .restore_state       = gicv3_restore_state,
> +    .dump_state          = gicv3_dump_state,
> +    .gicv_setup          = gicv_v3_init,
> +    .gic_host_irq_type   = &gicv3_host_irq_type,
> +    .gic_guest_irq_type  = &gicv3_guest_irq_type,
> +    .eoi_irq             = gicv3_eoi_irq,
> +    .deactivate_irq      = gicv3_dir_irq,
> +    .read_irq            = gicv3_read_irq,
> +    .set_irq_properties  = gicv3_set_irq_properties,
> +    .send_SGI            = gicv3_send_sgi,
> +    .disable_interface   = gicv3_disable_interface,
> +    .update_lr           = gicv3_update_lr,
> +    .update_hcr_status   = gicv3_hcr_status,
> +    .clear_lr            = gicv3_clear_lr,
> +    .read_lr             = gicv3_read_lr,
> +    .write_lr            = gicv3_write_lr,
> +    .read_vmcr_priority  = gicv3_read_vmcr_priority,
> +    .read_apr            = gicv3_read_apr,
> +    .secondary_init      = gicv3_secondary_cpu_init,
> +    .make_dt_node        = gicv3_make_dt_node,
> +};
> +
> +static int __init gicv3_preinit(struct dt_device_node *node, const void *data)
> +{
> +    gicv3_info.hw_version = GIC_V3;
> +    gicv3_info.node = node;
> +    register_gic_ops(&gicv3_ops);
> +    dt_irq_xlate = gic_irq_xlate;
> +
> +    return 0;
> +}
> +
>  static const struct dt_device_match gicv3_dt_match[] __initconst =
>  {
>      DT_MATCH_GIC_V3,
> @@ -1286,7 +1289,7 @@ static const struct dt_device_match gicv3_dt_match[] __initconst =
>  
>  DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC)
>          .dt_match = gicv3_dt_match,
> -        .init = gicv3_init,
> +        .init = gicv3_preinit,
>  DT_DEVICE_END
>  
>  /*
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index d1ab6b5..63147f3 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -163,8 +163,10 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
>      return 0;
>  }
>  
> -/* Set up the GIC */
> -void __init gic_init(void)
> +/* Find the interrupt controller and set up the callback to translate
> + * device tree IRQ.
> + */
> +void __init gic_preinit(void)
>  {
>      int rc;
>      struct dt_device_node *node;
> @@ -189,6 +191,16 @@ void __init gic_init(void)
>      if ( !num_gics )
>          panic("Unable to find compatible GIC in the device tree");
>  
> +    /* Set the GIC as the primary interrupt controller */
> +    dt_interrupt_controller = node;
> +    dt_device_set_used_by(node, DOMID_XEN);
> +}
> +
> +/* Set up the GIC */
> +void __init gic_init(void)
> +{
> +    if ( gic_hw_ops->init() )
> +        panic("Failed to initialize the GIC drivers");
>      /* Clear LR mask for cpu0 */
>      clear_cpu_lr_mask();
>  }
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index 4d242e0..18227f6 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -740,10 +740,11 @@ void __init start_xen(unsigned long boot_phys_offset,
>  
>      vm_init();
>      dt_unflatten_host_device_tree();
> -    dt_irq_xlate = gic_irq_xlate;
>  
>      init_IRQ();
>  
> +    gic_preinit();
> +
>      dt_uart_init();
>      console_init_preirq();
>      console_init_ring();
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index 73ca3cf..6286c71 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -229,6 +229,10 @@ extern void gic_remove_from_queues(struct vcpu *v, unsigned int virtual_irq);
>  
>  /* Accept an interrupt from the GIC and dispatch its handler */
>  extern void gic_interrupt(struct cpu_user_regs *regs, int is_fiq);
> +/* Find the interrupt controller and set up the callback to translate
> + * device tree IRQ.
> + */
> +extern void gic_preinit(void);
>  /* Bring up the interrupt controller, and report # cpus attached */
>  extern void gic_init(void);
>  /* Bring up a secondary CPU's per-CPU GIC interface */
> @@ -281,11 +285,15 @@ struct gic_info {
>      uint8_t nr_lrs;
>      /* Maintenance irq number */
>      unsigned int maintenance_irq;
> +    /* Pointer to the device tree node representing the interrupt controller */
> +    const struct dt_device_node *node;
>  };
>  
>  struct gic_hw_operations {
>      /* Hold GIC HW information */
>      const struct gic_info *info;
> +    /* Initialize the GIC and the boot CPU */
> +    int (*init)(void);
>      /* Save GIC registers */
>      void (*save_state)(struct vcpu *);
>      /* Restore GIC registers */
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 03/24] xen/dts: Allow only IRQ translation that are mapped to main GIC
  2015-01-13 14:25 ` [PATCH v3 03/24] xen/dts: Allow only IRQ translation that are mapped to main GIC Julien Grall
@ 2015-01-28 16:11   ` Stefano Stabellini
  2015-02-20 15:20   ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 16:11 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> Xen is only able to handle one GIC controller. Some platform may contain
> other interrupt controller.
> 
> Make sure to only translate IRQ mapped into the GIC handled by Xen.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

> 
>     Changes in v3:
>         - Patch was previously sent a separate series [1]
>         - Rework the comment in dt_irq_translate.
> 
>     Changelog based on the separate series:
> 
>     Changes in v3:
>         - Add an ASSERT to check that dt_interrupt_controller is not
>         NULL.
> 
>     Changes in v2:
>         - Fix compilation...
> 
>     [1] https://patches.linaro.org/33312/
> ---
>  xen/common/device_tree.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
> index f471008..bb9d7ce 100644
> --- a/xen/common/device_tree.c
> +++ b/xen/common/device_tree.c
> @@ -1058,8 +1058,14 @@ int dt_irq_translate(const struct dt_raw_irq *raw,
>                       struct dt_irq *out_irq)
>  {
>      ASSERT(dt_irq_xlate != NULL);
> +    ASSERT(dt_interrupt_controller != NULL);
>  
> -    /* TODO: Retrieve the right irq_xlate. This is only work for the gic */
> +    /*
> +     * TODO: Retrieve the right irq_xlate. This is only works for the primary
> +     * interrupt controller.
> +     */
> +    if ( raw->controller != dt_interrupt_controller )
> +        return -EINVAL;
>  
>      return dt_irq_xlate(raw->specifier, raw->size,
>                          &out_irq->irq, &out_irq->type);
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 06/24] xen/arm: Map disabled device in DOM0
  2015-01-13 14:25 ` [PATCH v3 06/24] xen/arm: Map disabled device in DOM0 Julien Grall
@ 2015-01-28 16:18   ` Stefano Stabellini
  2015-01-28 16:23     ` Julien Grall
  2015-02-20 15:27   ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 16:18 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, tim, ian.campbell, stefano.stabellini, Andrii Tseglytskyi

On Tue, 13 Jan 2015, Julien Grall wrote:
> The check to avoid mapping disabled device in DOM0 was added in the anticipation
> of the device passthrough. But, a brand new property will be added later to mark
> device which will passthrough. At the same time, remove the memory type
> check because those nodes has been blacklisted.

Sorry, I don't understand the explanation on why you removed the check
on dt_device_type_is_equal(node, "memory") too.



> Futhermore, some platform (such as the OMAP) may try to poke device even
> if the property "status" is set to "disabled".
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Andrii Tseglytskyi <andrii.tseglytskyi@globallogic.com>
> 
> ---
> 
>     Changes in v3:
>         - Patch added
>         - "xen/arm: follow-up to allow DOM0 manage IRQ and MMIO" has
>         been split in 2 patch [1]
>         - Drop the check for memory type. Thoses nodes have been
>         blacklisted.
> 
> [1] https://patches.linaro.org/34669/
> ---
>  xen/arch/arm/domain_build.c    | 19 +++----------------
>  xen/arch/arm/platforms/omap5.c | 12 ------------
>  2 files changed, 3 insertions(+), 28 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 8f1b48e..f68755f 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1104,22 +1104,9 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo,
>          return 0;
>      }
>  
> -    /*
> -     * Some device doesn't need to be mapped in Xen:
> -     *  - Memory: the guest will see a different view of memory. It will
> -     *  be allocated later.
> -     *  - Disabled device: Linux is able to cope with status="disabled"
> -     *  property. Therefore these device doesn't need to be mapped. This
> -     *  solution can be use later for pass through.
> -     */
> -    if ( !dt_device_type_is_equal(node, "memory") &&
> -         dt_device_is_available(node) )
> -    {
> -        res = map_device(d, node);
> -
> -        if ( res )
> -            return res;
> -    }
> +    res = map_device(d, node);
> +    if ( res)
> +        return res;
>  
>      /*
>       * The property "name" is used to have a different name on older FDT
> diff --git a/xen/arch/arm/platforms/omap5.c b/xen/arch/arm/platforms/omap5.c
> index 9d6e504..e7bf30d 100644
> --- a/xen/arch/arm/platforms/omap5.c
> +++ b/xen/arch/arm/platforms/omap5.c
> @@ -155,17 +155,6 @@ static const char * const dra7_dt_compat[] __initconst =
>      NULL
>  };
>  
> -static const struct dt_device_match dra7_blacklist_dev[] __initconst =
> -{
> -    /* OMAP Linux kernel handles devices with status "disabled" in a
> -     * weird manner - tries to reset them. While their memory ranges
> -     * are not mapped, this leads to data aborts, so skip these devices
> -     * from DT for dom0.
> -     */
> -    DT_MATCH_NOT_AVAILABLE(),
> -    { /* sentinel */ },
> -};
> -
>  PLATFORM_START(omap5, "TI OMAP5")
>      .compatible = omap5_dt_compat,
>      .init_time = omap5_init_time,
> @@ -185,7 +174,6 @@ PLATFORM_START(dra7, "TI DRA7")
>  
>      .dom0_gnttab_start = 0x4b000000,
>      .dom0_gnttab_size = 0x20000,
> -    .blacklist_dev = dra7_blacklist_dev,
>  PLATFORM_END
>  
>  /*
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 06/24] xen/arm: Map disabled device in DOM0
  2015-01-28 16:18   ` Stefano Stabellini
@ 2015-01-28 16:23     ` Julien Grall
  2015-01-29 11:41       ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-28 16:23 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: xen-devel, tim, ian.campbell, stefano.stabellini, Andrii Tseglytskyi

Hi Stefano,

On 28/01/15 16:18, Stefano Stabellini wrote:
> On Tue, 13 Jan 2015, Julien Grall wrote:
>> The check to avoid mapping disabled device in DOM0 was added in the anticipation
>> of the device passthrough. But, a brand new property will be added later to mark
>> device which will passthrough. At the same time, remove the memory type
>> check because those nodes has been blacklisted.
> 
> Sorry, I don't understand the explanation on why you removed the check
> on dt_device_type_is_equal(node, "memory") too.

The memory nodes has been skipped earlier via the skip_matches variable.

How about "Also, remove the memory type check as we already skipped them
earlier in the function"?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-01-13 14:25 ` [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property Julien Grall
@ 2015-01-28 16:36   ` Stefano Stabellini
  2015-01-28 16:53     ` Julien Grall
  2015-02-20 15:38   ` Ian Campbell
  2015-02-20 15:42   ` Ian Campbell
  2 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 16:36 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> When a device is marked for passthrough (via the new property "xen,passthrough"),
> dom0 must not access to the device (i.e not loading a driver), but should
> be able to manage the MMIO/interrupt of the passthrough device.
> 
> The latter part will allow the toolstack to map MMIO/IRQ when a device
> is pass through to a guest.
> 
> The property "xen,passthrough" will be translated as 'status="disabled"'
> in the device tree to avoid DOM0 using the device. We assume that DOM0 is
> able to cope with this property (already the case for Linux).
> 
> Rework the function map_device (renamed into handle_device) to:
> 
> * For a given device node:
>     - Give permission to manage IRQ/MMIO for this device
>     - Retrieve the IRQ configuration (i.e edge/level) from the device
>     tree
> * When the device is not marked for guest passthrough:
>     - Assign the device to the guest if it's protected by an IOMMU
>     - Map the IRQs and MMIOs regions to the guest
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> ---
>     Changes in v3:
>         - This patch was formely "xen/arm: Follow-up to allow DOM0
>         manage IRQ and MMIO". It has been split in 2 parts [1].
>         - Update commit title and improve message
>         - Remove spurious change
> 
> [1] https://patches.linaro.org/34669/
> ---
>  docs/misc/arm/device-tree/passthrough.txt |   7 ++
>  xen/arch/arm/device.c                     |   2 +-
>  xen/arch/arm/domain_build.c               | 102 ++++++++++++++++++++++--------
>  xen/common/device_tree.c                  |   6 ++
>  xen/include/xen/device_tree.h             |  11 ++++
>  5 files changed, 100 insertions(+), 28 deletions(-)
>  create mode 100644 docs/misc/arm/device-tree/passthrough.txt
> 
> diff --git a/docs/misc/arm/device-tree/passthrough.txt b/docs/misc/arm/device-tree/passthrough.txt
> new file mode 100644
> index 0000000..04645b3
> --- /dev/null
> +++ b/docs/misc/arm/device-tree/passthrough.txt
> @@ -0,0 +1,7 @@
> +Device passthrough
> +===================
> +
> +Any device that will be passthrough to a guest should have a property
> +"xen,passthrough" in their device tree node.
> +
> +The device won't be exposed to DOM0 and therefore no driver will be loaded.
> diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
> index 1993929..1a01793 100644
> --- a/xen/arch/arm/device.c
> +++ b/xen/arch/arm/device.c
> @@ -30,7 +30,7 @@ int __init device_init(struct dt_device_node *dev, enum device_match type,
>  
>      ASSERT(dev != NULL);
>  
> -    if ( !dt_device_is_available(dev) )
> +    if ( !dt_device_is_available(dev) || dt_device_for_passthrough(dev) )
>          return  -ENODEV;
>  
>      for ( desc = _sdevice; desc != _edevice; desc++ )
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index f68755f..b48b5d0 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -402,7 +402,7 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
>                              const struct dt_device_node *node)
>  {
>      const char *bootargs = NULL;
> -    const struct dt_property *prop;
> +    const struct dt_property *prop, *status = NULL;
>      int res = 0;
>      int had_dom0_bootargs = 0;
>  
> @@ -457,6 +457,17 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
>              }
>          }
>  
> +        /* Don't expose the property "xen,passthrough" to the guest */
> +        if ( dt_property_name_is_equal(prop, "xen,passthrough") )
> +            continue;
> +
> +        /* Remember and skip the status property as Xen may modify it later */
> +        if ( dt_property_name_is_equal(prop, "status") )
> +        {
> +            status = prop;
> +            continue;
> +        }
> +
>          res = fdt_property(kinfo->fdt, prop->name, prop_data, prop_len);
>  
>          xfree(new_data);
> @@ -465,6 +476,19 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
>              return res;
>      }
>  
> +    /*
> +     * Override the property "status" to disable the device when it's
> +     * marked for passthrough.
> +     */
> +    if ( dt_device_for_passthrough(node) )
> +        res = fdt_property_string(kinfo->fdt, "status", "disabled");
> +    else if ( status )
> +        res = fdt_property(kinfo->fdt, "status", status->value,
> +                           status->length);

Why is the "else" needed? Wouldn't the status property for
non-passtrough devices already be covered by the
dt_for_each_property_node loop above?


> +    if ( res )
> +        return res;
> +
>      if ( dt_node_path_is_equal(node, "/chosen") )
>      {
>          const struct bootmodule *mod = kinfo->initrd_bootmodule;
> @@ -919,8 +943,14 @@ static int make_timer_node(const struct domain *d, void *fdt,
>      return res;
>  }
>  
> -/* Map the device in the domain */
> -static int map_device(struct domain *d, struct dt_device_node *dev)
> +/* For a given device node:
> + *  - Give permission to the guest to manage IRQ and MMIO range
> + *  - Retrieve the IRQ configuration (i.e edge/level) from device tree
> + * When the device is not marked for guest passthrough:
> + *  - Assign the device to the guest if it's protected by an IOMMU
> + *  - Map the IRQs and iomem regions to DOM0
> + */
> +static int handle_device(struct domain *d, struct dt_device_node *dev)
>  {
>      unsigned int nirq;
>      unsigned int naddr;
> @@ -929,13 +959,15 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
>      unsigned int irq;
>      struct dt_raw_irq rirq;
>      u64 addr, size;
> +    bool_t need_mapping = !dt_device_for_passthrough(dev);
>
>      nirq = dt_number_of_irq(dev);
>      naddr = dt_number_of_address(dev);
>  
> -    DPRINT("%s nirq = %d naddr = %u\n", dt_node_full_name(dev), nirq, naddr);
> +    DPRINT("%s passthrough = %d nirq = %d naddr = %u\n", dt_node_full_name(dev),
> +           need_mapping, nirq, naddr);
>  
> -    if ( dt_device_is_protected(dev) )
> +    if ( dt_device_is_protected(dev) && need_mapping )
>      {
>          DPRINT("%s setup iommu\n", dt_node_full_name(dev));
>          res = iommu_assign_dt_device(d, dev);
> @@ -947,7 +979,7 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
>          }
>      }
>  
> -    /* Map IRQs */
> +    /* Give permission and  map IRQs */
>      for ( i = 0; i < nirq; i++ )
>      {
>          res = dt_device_get_raw_irq(dev, i, &rirq);
> @@ -980,22 +1012,34 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
>          irq = res;
>  
>          DPRINT("irq %u = %u\n", i, irq);
> -        /*
> -         * Checking the return of vgic_reserve_virq is not
> -         * necessary. It should not fail except when we try to map
> -         * twice the IRQ. This can happen if the IRQ is shared
> -         */
> -        vgic_reserve_virq(d, irq);
> -        res = route_irq_to_guest(d, irq, dt_node_name(dev));
> +
> +        res = irq_permit_access(d, irq);
>          if ( res )
>          {
> -            printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
> -                   irq, d->domain_id);
> +            printk(XENLOG_ERR "Unable to permit to dom%u access to IRQ %u\n",
> +                   d->domain_id, irq);
>              return res;
>          }
> +
> +        if ( need_mapping )
> +        {
> +            /*
> +             * Checking the return of vgic_reserve_virq is not
> +             * necessary. It should not fail except when we try to map
> +             * twice the IRQ. This can happen if the IRQ is shared
> +             */
> +            vgic_reserve_virq(d, irq);
> +            res = route_irq_to_guest(d, irq, dt_node_name(dev));
> +            if ( res )
> +            {
> +                printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
> +                       irq, d->domain_id);
> +                return res;
> +            }
> +        }
>      }
>  
> -    /* Map the address ranges */
> +    /* Give permission and map MMIOs */
>      for ( i = 0; i < naddr; i++ )
>      {
>          res = dt_device_get_address(dev, i, &addr, &size);
> @@ -1019,17 +1063,21 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
>                     addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1);
>              return res;
>          }
> -        res = map_mmio_regions(d,
> -                               paddr_to_pfn(addr & PAGE_MASK),
> -                               DIV_ROUND_UP(size, PAGE_SIZE),
> -                               paddr_to_pfn(addr & PAGE_MASK));
> -        if ( res )
> +
> +        if ( need_mapping )
>          {
> -            printk(XENLOG_ERR "Unable to map 0x%"PRIx64
> -                   " - 0x%"PRIx64" in domain %d\n",
> -                   addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1,
> -                   d->domain_id);
> -            return res;
> +            res = map_mmio_regions(d,
> +                                   paddr_to_pfn(addr & PAGE_MASK),
> +                                   DIV_ROUND_UP(size, PAGE_SIZE),
> +                                   paddr_to_pfn(addr & PAGE_MASK));
> +            if ( res )
> +            {
> +                printk(XENLOG_ERR "Unable to map 0x%"PRIx64
> +                       " - 0x%"PRIx64" in domain %d\n",
> +                       addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1,
> +                       d->domain_id);
> +                return res;
> +            }
>          }
>      }
>  
> @@ -1104,7 +1152,7 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo,
>          return 0;
>      }
>  
> -    res = map_device(d, node);
> +    res = handle_device(d, node);
>      if ( res)
>          return res;
>  
> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
> index bb9d7ce..ce10574 100644
> --- a/xen/common/device_tree.c
> +++ b/xen/common/device_tree.c
> @@ -1103,6 +1103,12 @@ bool_t dt_device_is_available(const struct dt_device_node *device)
>      return 0;
>  }
>  
> +bool_t dt_device_for_passthrough(const struct dt_device_node *device)
> +{
> +    return (dt_find_property(device, "xen,passthrough", NULL) != NULL);
> +
> +}
> +
>  static int __dt_parse_phandle_with_args(const struct dt_device_node *np,
>                                          const char *list_name,
>                                          const char *cells_name,
> diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
> index 890d356..caaf65f 100644
> --- a/xen/include/xen/device_tree.h
> +++ b/xen/include/xen/device_tree.h
> @@ -555,6 +555,17 @@ int dt_n_addr_cells(const struct dt_device_node *np);
>  bool_t dt_device_is_available(const struct dt_device_node *device);
>  
>  /**
> + * dt_device_for_passthrough - Check if a device will be used for
> + * passthrough later
> + *
> + * @device: Node to check
> + *
> + * Return true if the property "xen,passthrough" is present in the node,
> + * false otherwise.
> + */
> +bool_t dt_device_for_passthrough(const struct dt_device_node *device);
> +
> +/**
>   * dt_match_node - Tell if a device_node has a matching of dt_device_match
>   * @matches: array of dt_device_match structures to search in
>   * @node: the dt_device_node structure to match against
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-01-13 14:25 ` [PATCH v3 08/24] xen/arm: Allow virq != irq Julien Grall
@ 2015-01-28 16:47   ` Stefano Stabellini
  2015-01-28 16:56     ` Julien Grall
  2015-02-20 15:52   ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 16:47 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> Actually Xen is assuming that the virtual IRQ will always be the same as IRQ.
> 
> Modify route_guest_irq to take the virtual IRQ in parameter and let Xen
> assign a different IRQ number. Also store the vIRQ in the desc action to
> easily retrieve easily the IRQ target when we need to inject the interrupt.
> 
> As DOM0 will get most the devices, the vIRQ is equal to the IRQ in that case.
> 
> At the same time modify the behavior of irq_get_domain. The function now
> assumes that the irq_desc belongs to an IRQ assigned to a guest.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> ---
>     Changes in v3
>         - Spelling/grammar nits
>         - Fix compilation on ARM64. Forgot to update route_irq_to_guest
>           call for xgene platform.
>         - Add a word about irq_get_domain behavior change
>         - More s/irq/virq/ because of the rebasing on the latest staging
> 
>     Changes in v2:
>         - Patch added
> ---
>  xen/arch/arm/domain_build.c          |  2 +-
>  xen/arch/arm/gic.c                   |  5 ++--
>  xen/arch/arm/irq.c                   | 47 ++++++++++++++++++++++++++----------
>  xen/arch/arm/platforms/xgene-storm.c |  2 +-
>  xen/arch/arm/vgic.c                  | 20 +++++++--------
>  xen/include/asm-arm/gic.h            |  3 ++-
>  xen/include/asm-arm/irq.h            |  4 +--
>  xen/include/asm-arm/vgic.h           |  4 +--
>  8 files changed, 55 insertions(+), 32 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index b48b5d0..06c1dec 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1029,7 +1029,7 @@ static int handle_device(struct domain *d, struct dt_device_node *dev)
>               * twice the IRQ. This can happen if the IRQ is shared
>               */
>              vgic_reserve_virq(d, irq);
> -            res = route_irq_to_guest(d, irq, dt_node_name(dev));
> +            res = route_irq_to_guest(d, irq, irq, dt_node_name(dev));
>              if ( res )
>              {
>                  printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index eb0c5d6..15de283 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -126,7 +126,8 @@ void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
>  /* Program the GIC to route an interrupt to a guest
>   *   - desc.lock must be held
>   */
> -void gic_route_irq_to_guest(struct domain *d, struct irq_desc *desc,
> +void gic_route_irq_to_guest(struct domain *d, unsigned int virq,
> +                            struct irq_desc *desc,
>                              const cpumask_t *cpu_mask, unsigned int priority)
>  {
>      struct pending_irq *p;
> @@ -139,7 +140,7 @@ void gic_route_irq_to_guest(struct domain *d, struct irq_desc *desc,
>  
>      /* Use vcpu0 to retrieve the pending_irq struct. Given that we only
>       * route SPIs to guests, it doesn't make any difference. */
> -    p = irq_to_pending(d->vcpu[0], desc->irq);
> +    p = irq_to_pending(d->vcpu[0], virq);
>      p->desc = desc;
>  }
>  
> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> index 25ecf1d..830832c 100644
> --- a/xen/arch/arm/irq.c
> +++ b/xen/arch/arm/irq.c
> @@ -31,6 +31,13 @@
>  static unsigned int local_irqs_type[NR_LOCAL_IRQS];
>  static DEFINE_SPINLOCK(local_irqs_type_lock);
>  
> +/* Describe an IRQ assigned to a guest */
> +struct irq_guest
> +{
> +    struct domain *d;
> +    unsigned int virq;
> +};

I would prefer if you didn't use dev_id for this and just added a virq
field to irqaction.



>  static void ack_none(struct irq_desc *irq)
>  {
>      printk("unexpected IRQ trap at irq %02x\n", irq->irq);
> @@ -122,18 +129,20 @@ void __cpuinit init_secondary_IRQ(void)
>      BUG_ON(init_local_irq_data() < 0);
>  }
>  
> -static inline struct domain *irq_get_domain(struct irq_desc *desc)
> +static inline struct irq_guest *irq_get_guest_info(struct irq_desc *desc)
>  {
>      ASSERT(spin_is_locked(&desc->lock));
> -
> -    if ( !test_bit(_IRQ_GUEST, &desc->status) )
> -        return dom_xen;
> -
> +    ASSERT(test_bit(_IRQ_GUEST, &desc->status));
>      ASSERT(desc->action != NULL);
>  
>      return desc->action->dev_id;
>  }
>  
> +static inline struct domain *irq_get_domain(struct irq_desc *desc)
> +{
> +    return irq_get_guest_info(desc)->d;
> +}
> +
>  void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
>  {
>      if ( desc != NULL )
> @@ -197,7 +206,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq)
>  
>      if ( test_bit(_IRQ_GUEST, &desc->status) )
>      {
> -        struct domain *d = irq_get_domain(desc);
> +        struct irq_guest *info = irq_get_guest_info(desc);
>  
>          desc->handler->end(desc);
>  
> @@ -206,7 +215,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq)
>  
>          /* the irq cannot be a PPI, we only support delivery of SPIs to
>           * guests */
> -        vgic_vcpu_inject_spi(d, irq);
> +        vgic_vcpu_inject_spi(info->d, info->virq);
>          goto out_no_end;
>      }
>  
> @@ -370,19 +379,30 @@ err:
>      return rc;
>  }
>  
> -int route_irq_to_guest(struct domain *d, unsigned int irq,
> -                       const char * devname)
> +int route_irq_to_guest(struct domain *d, unsigned int virq,
> +                       unsigned int irq, const char * devname)
>  {
>      struct irqaction *action;
> -    struct irq_desc *desc = irq_to_desc(irq);
> +    struct irq_guest *info;
> +    struct irq_desc *desc;
>      unsigned long flags;
>      int retval = 0;
>  
>      action = xmalloc(struct irqaction);
> -    if (!action)
> +    if ( !action )
> +        return -ENOMEM;
> +
> +    info = xmalloc(struct irq_guest);
> +    if ( !info )
> +    {
> +        xfree(action);
>          return -ENOMEM;
> +    }
> +
> +    info->d = d;
> +    info->virq = virq;
>  
> -    action->dev_id = d;
> +    action->dev_id = info;
>      action->name = devname;
>      action->free_on_release = 1;
>  
> @@ -413,7 +433,7 @@ int route_irq_to_guest(struct domain *d, unsigned int irq,
>      if ( retval )
>          goto out;
>  
> -    gic_route_irq_to_guest(d, desc, cpumask_of(smp_processor_id()),
> +    gic_route_irq_to_guest(d, virq, desc, cpumask_of(smp_processor_id()),
>                             GIC_PRI_IRQ);
>      spin_unlock_irqrestore(&desc->lock, flags);
>      return 0;
> @@ -421,6 +441,7 @@ int route_irq_to_guest(struct domain *d, unsigned int irq,
>  out:
>      spin_unlock_irqrestore(&desc->lock, flags);
>      xfree(action);
> +    xfree(info);
>  
>      return retval;
>  }
> diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
> index b0808b8..e2f8b89 100644
> --- a/xen/arch/arm/platforms/xgene-storm.c
> +++ b/xen/arch/arm/platforms/xgene-storm.c
> @@ -75,7 +75,7 @@ static int map_one_spi(struct domain *d, const char *what,
>          printk("Failed to reserve the vIRQ %u on dom%d\n",
>                 irq, d->domain_id);
>  
> -    ret = route_irq_to_guest(d, irq, what);
> +    ret = route_irq_to_guest(d, irq, irq, what);
>      if ( ret )
>          printk("Failed to route %s to dom%d\n", what, d->domain_id);
>  
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 38216f7..c915670 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -380,16 +380,16 @@ void vgic_clear_pending_irqs(struct vcpu *v)
>      spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
>  }
>  
> -void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq)
> +void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq)
>  {
>      uint8_t priority;
> -    struct vgic_irq_rank *rank = vgic_rank_irq(v, irq);
> -    struct pending_irq *iter, *n = irq_to_pending(v, irq);
> +    struct vgic_irq_rank *rank = vgic_rank_irq(v, virq);
> +    struct pending_irq *iter, *n = irq_to_pending(v, virq);
>      unsigned long flags;
>      bool_t running;
>  
>      vgic_lock_rank(v, rank, flags);
> -    priority = v->domain->arch.vgic.handler->get_irq_priority(v, irq);
> +    priority = v->domain->arch.vgic.handler->get_irq_priority(v, virq);
>      vgic_unlock_rank(v, rank, flags);
>  
>      spin_lock_irqsave(&v->arch.vgic.lock, flags);
> @@ -405,7 +405,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq)
>  
>      if ( !list_empty(&n->inflight) )
>      {
> -        gic_raise_inflight_irq(v, irq);
> +        gic_raise_inflight_irq(v, virq);
>          goto out;
>      }
>  
> @@ -413,7 +413,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq)
>  
>      /* the irq is enabled */
>      if ( test_bit(GIC_IRQ_GUEST_ENABLED, &n->status) )
> -        gic_raise_guest_irq(v, irq, priority);
> +        gic_raise_guest_irq(v, virq, priority);
>  
>      list_for_each_entry ( iter, &v->arch.vgic.inflight_irqs, inflight )
>      {
> @@ -433,15 +433,15 @@ out:
>          smp_send_event_check_mask(cpumask_of(v->processor));
>  }
>  
> -void vgic_vcpu_inject_spi(struct domain *d, unsigned int irq)
> +void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq)
>  {
>      struct vcpu *v;
>  
>      /* the IRQ needs to be an SPI */
> -    ASSERT(irq >= 32 && irq <= gic_number_lines());
> +    ASSERT(virq >= 32 && virq <= vgic_num_irqs(d));
>  
> -    v = vgic_get_target_vcpu(d->vcpu[0], irq);
> -    vgic_vcpu_inject_irq(v, irq);
> +    v = vgic_get_target_vcpu(d->vcpu[0], virq);
> +    vgic_vcpu_inject_irq(v, virq);
>  }
>  
>  void arch_evtchn_inject(struct vcpu *v)
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index 6286c71..cf9f257 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -213,7 +213,8 @@ extern enum gic_version gic_hw_version(void);
>  /* Program the GIC to route an interrupt */
>  extern void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
>                                   unsigned int priority);
> -extern void gic_route_irq_to_guest(struct domain *, struct irq_desc *desc,
> +extern void gic_route_irq_to_guest(struct domain *, unsigned int virq,
> +                                   struct irq_desc *desc,
>                                     const cpumask_t *cpu_mask,
>                                     unsigned int priority);
>  
> diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
> index 435dfcd..f00eb11 100644
> --- a/xen/include/asm-arm/irq.h
> +++ b/xen/include/asm-arm/irq.h
> @@ -40,8 +40,8 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq);
>  void init_IRQ(void);
>  void init_secondary_IRQ(void);
>  
> -int route_irq_to_guest(struct domain *d, unsigned int irq,
> -                       const char *devname);
> +int route_irq_to_guest(struct domain *d, unsigned int virq,
> +                       unsigned int irq, const char *devname);
>  void arch_move_irqs(struct vcpu *v);
>  
>  /* Set IRQ type for an SPI */
> diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
> index 8582d9d..1cd7808 100644
> --- a/xen/include/asm-arm/vgic.h
> +++ b/xen/include/asm-arm/vgic.h
> @@ -181,8 +181,8 @@ extern int domain_vgic_init(struct domain *d);
>  extern void domain_vgic_free(struct domain *d);
>  extern int vcpu_vgic_init(struct vcpu *v);
>  extern struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int irq);
> -extern void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq);
> -extern void vgic_vcpu_inject_spi(struct domain *d, unsigned int irq);
> +extern void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq);
> +extern void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq);
>  extern void vgic_clear_pending_irqs(struct vcpu *v);
>  extern struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq);
>  extern struct vgic_irq_rank *vgic_rank_offset(struct vcpu *v, int b, int n, int s);
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-01-28 16:36   ` Stefano Stabellini
@ 2015-01-28 16:53     ` Julien Grall
  2015-01-29 11:43       ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-28 16:53 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On 28/01/15 16:36, Stefano Stabellini wrote:
> On Tue, 13 Jan 2015, Julien Grall wrote:
>> When a device is marked for passthrough (via the new property "xen,passthrough"),
>> dom0 must not access to the device (i.e not loading a driver), but should
>> be able to manage the MMIO/interrupt of the passthrough device.
>>
>> The latter part will allow the toolstack to map MMIO/IRQ when a device
>> is pass through to a guest.
>>
>> The property "xen,passthrough" will be translated as 'status="disabled"'
>> in the device tree to avoid DOM0 using the device. We assume that DOM0 is
>> able to cope with this property (already the case for Linux).
>>
>> Rework the function map_device (renamed into handle_device) to:
>>
>> * For a given device node:
>>     - Give permission to manage IRQ/MMIO for this device
>>     - Retrieve the IRQ configuration (i.e edge/level) from the device
>>     tree
>> * When the device is not marked for guest passthrough:
>>     - Assign the device to the guest if it's protected by an IOMMU
>>     - Map the IRQs and MMIOs regions to the guest
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>
>> ---
>>     Changes in v3:
>>         - This patch was formely "xen/arm: Follow-up to allow DOM0
>>         manage IRQ and MMIO". It has been split in 2 parts [1].
>>         - Update commit title and improve message
>>         - Remove spurious change
>>
>> [1] https://patches.linaro.org/34669/
>> ---
>>  docs/misc/arm/device-tree/passthrough.txt |   7 ++
>>  xen/arch/arm/device.c                     |   2 +-
>>  xen/arch/arm/domain_build.c               | 102 ++++++++++++++++++++++--------
>>  xen/common/device_tree.c                  |   6 ++
>>  xen/include/xen/device_tree.h             |  11 ++++
>>  5 files changed, 100 insertions(+), 28 deletions(-)
>>  create mode 100644 docs/misc/arm/device-tree/passthrough.txt
>>
>> diff --git a/docs/misc/arm/device-tree/passthrough.txt b/docs/misc/arm/device-tree/passthrough.txt
>> new file mode 100644
>> index 0000000..04645b3
>> --- /dev/null
>> +++ b/docs/misc/arm/device-tree/passthrough.txt
>> @@ -0,0 +1,7 @@
>> +Device passthrough
>> +===================
>> +
>> +Any device that will be passthrough to a guest should have a property
>> +"xen,passthrough" in their device tree node.
>> +
>> +The device won't be exposed to DOM0 and therefore no driver will be loaded.
>> diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
>> index 1993929..1a01793 100644
>> --- a/xen/arch/arm/device.c
>> +++ b/xen/arch/arm/device.c
>> @@ -30,7 +30,7 @@ int __init device_init(struct dt_device_node *dev, enum device_match type,
>>  
>>      ASSERT(dev != NULL);
>>  
>> -    if ( !dt_device_is_available(dev) )
>> +    if ( !dt_device_is_available(dev) || dt_device_for_passthrough(dev) )
>>          return  -ENODEV;
>>  
>>      for ( desc = _sdevice; desc != _edevice; desc++ )
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index f68755f..b48b5d0 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -402,7 +402,7 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
>>                              const struct dt_device_node *node)
>>  {
>>      const char *bootargs = NULL;
>> -    const struct dt_property *prop;
>> +    const struct dt_property *prop, *status = NULL;
>>      int res = 0;
>>      int had_dom0_bootargs = 0;
>>  
>> @@ -457,6 +457,17 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
>>              }
>>          }
>>  
>> +        /* Don't expose the property "xen,passthrough" to the guest */
>> +        if ( dt_property_name_is_equal(prop, "xen,passthrough") )
>> +            continue;
>> +
>> +        /* Remember and skip the status property as Xen may modify it later */
>> +        if ( dt_property_name_is_equal(prop, "status") )
>> +        {
>> +            status = prop;
>> +            continue;
>> +        }
>> +
>>          res = fdt_property(kinfo->fdt, prop->name, prop_data, prop_len);
>>  
>>          xfree(new_data);
>> @@ -465,6 +476,19 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
>>              return res;
>>      }
>>  
>> +    /*
>> +     * Override the property "status" to disable the device when it's
>> +     * marked for passthrough.
>> +     */
>> +    if ( dt_device_for_passthrough(node) )
>> +        res = fdt_property_string(kinfo->fdt, "status", "disabled");
>> +    else if ( status )
>> +        res = fdt_property(kinfo->fdt, "status", status->value,
>> +                           status->length);
> 
> Why is the "else" needed? Wouldn't the status property for
> non-passtrough devices already be covered by the
> dt_for_each_property_node loop above?


Because the property "status" is skipped earlier in any case.


Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-01-28 16:47   ` Stefano Stabellini
@ 2015-01-28 16:56     ` Julien Grall
  2015-01-28 17:00       ` Julien Grall
  2015-01-29 11:50       ` Stefano Stabellini
  0 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-28 16:56 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On 28/01/15 16:47, Stefano Stabellini wrote:
>> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
>> index 25ecf1d..830832c 100644
>> --- a/xen/arch/arm/irq.c
>> +++ b/xen/arch/arm/irq.c
>> @@ -31,6 +31,13 @@
>>  static unsigned int local_irqs_type[NR_LOCAL_IRQS];
>>  static DEFINE_SPINLOCK(local_irqs_type_lock);
>>  
>> +/* Describe an IRQ assigned to a guest */
>> +struct irq_guest
>> +{
>> +    struct domain *d;
>> +    unsigned int virq;
>> +};
> 
> I would prefer if you didn't use dev_id for this and just added a virq
> field to irqaction.

We already talked about it on v2. You were fine with the idea and acked
the patch. Although, I haven't add your acked-by here because of the new
changes in the code.

Here my answer to the same question on v2:

"I though about it. If we add another field in arch_irq_desc, we will
likely use more memory than xmalloc. This is because most of the
platform doesn't use 1024 interrupts but about 256 interrupts.

As the new field will be a pointer (on ARM64, 8 bytes), that would make
Xen use statically about 8K more.

We could allocate irq_desc dynamically during Xen boot."

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-01-28 16:56     ` Julien Grall
@ 2015-01-28 17:00       ` Julien Grall
  2015-01-29 11:50       ` Stefano Stabellini
  1 sibling, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-28 17:00 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On 28/01/15 16:56, Julien Grall wrote:
> On 28/01/15 16:47, Stefano Stabellini wrote:
>>> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
>>> index 25ecf1d..830832c 100644
>>> --- a/xen/arch/arm/irq.c
>>> +++ b/xen/arch/arm/irq.c
>>> @@ -31,6 +31,13 @@
>>>  static unsigned int local_irqs_type[NR_LOCAL_IRQS];
>>>  static DEFINE_SPINLOCK(local_irqs_type_lock);
>>>  
>>> +/* Describe an IRQ assigned to a guest */
>>> +struct irq_guest
>>> +{
>>> +    struct domain *d;
>>> +    unsigned int virq;
>>> +};
>>
>> I would prefer if you didn't use dev_id for this and just added a virq
>> field to irqaction.
> 
> We already talked about it on v2. You were fine with the idea and acked
> the patch. Although, I haven't add your acked-by here because of the new
> changes in the code.

For reference: https://patches.linaro.org/34671/

> Here my answer to the same question on v2:
> 
> "I though about it. If we add another field in arch_irq_desc, we will
> likely use more memory than xmalloc. This is because most of the
> platform doesn't use 1024 interrupts but about 256 interrupts.
> 
> As the new field will be a pointer (on ARM64, 8 bytes), that would make
> Xen use statically about 8K more.
> 
> We could allocate irq_desc dynamically during Xen boot."


-- 
Julien Grall

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

* Re: [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ
  2015-01-13 14:25 ` [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ Julien Grall
@ 2015-01-28 17:55   ` Stefano Stabellini
  2015-01-28 18:05     ` Julien Grall
  2015-02-20 16:00   ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 17:55 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> Currently Xen only supports SPIs routing for guest, add a function
> is_assignable_irq to check if we can assign a given IRQ to the guest.
> 
> Secondly, make sure the vIRQ is not the greater that the number of IRQs handle
> to the vGIC and it's an SPIs.
> 
> Thirdly, when the IRQ is already assigned to the domain, check the user
> is not asking to use a different vIRQ than the one already bound.
> 
> Finally, desc->arch.type which contains the IRQ type (i.e level/edge) must
> be correctly configured before. The IRQ type won't be configure when:
>     - the device has been blacklist for the current platform
>     - the IRQ has not been describe in the device tree
> 
> I think we can safely assume that a user won't never ask to route
> as such IRQ to the guest.
> 
> Also, use XENLOG_G_ERR in the error message within the function as it will
> be later called from a guest.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> ---
>     Changes in v3:
>         - Fix typo in commit message and comment
>         - Add a check that the vIRQ is an SPI
>         - Check if the user is not asking for a different vIRQ when the
>         IRQ is already assigned to the guest
> 
>     Changes in v2:
>         - Rename is_routable_irq into is_assignable_irq
>         - Check if the IRQ is not greater than the number handled by the
>         number of IRQs handled by the gic
>         - Move is_assignable_irq in irq.c rather than defining in the
>         header irq.h
>         - Retrieve the irq descriptor after checking the validity of the
>         IRQ
>         - vgic_num_irqs has been moved in a separate patch
>         - Fix the irq check against vgic_num_irqs
>         - Use virq instead of irq for vGIC sanity check
> ---
>  xen/arch/arm/irq.c        | 58 +++++++++++++++++++++++++++++++++++++++++++----
>  xen/include/asm-arm/irq.h |  2 ++
>  2 files changed, 56 insertions(+), 4 deletions(-)
> 
> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> index 830832c..af408ac 100644
> --- a/xen/arch/arm/irq.c
> +++ b/xen/arch/arm/irq.c
> @@ -379,6 +379,15 @@ err:
>      return rc;
>  }
>  
> +bool_t is_assignable_irq(unsigned int irq)

static inline?


> +{
> +    /* For now, we can only route SPIs to the guest */
> +    return ((irq >= NR_LOCAL_IRQS) && (irq < gic_number_lines()));
> +}
> +
> +/* Route an IRQ to a specific guest.
> + * For now only SPIs are assignabled to the guest.
> + */
>  int route_irq_to_guest(struct domain *d, unsigned int virq,
>                         unsigned int irq, const char * devname)
>  {
> @@ -388,6 +397,29 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
>      unsigned long flags;
>      int retval = 0;
>  
> +    if ( !is_assignable_irq(irq) )
> +    {
> +        dprintk(XENLOG_G_ERR, "the IRQ%u is not routable\n", irq);
> +        return -EINVAL;
> +    }
> +
> +    desc = irq_to_desc(irq);
> +
> +    if ( virq >= vgic_num_irqs(d) )
> +    {
> +        dprintk(XENLOG_G_ERR,
> +                "the vIRQ number %u is too high for domain %u (max = %u)\n",
> +                irq, d->domain_id, vgic_num_irqs(d));
> +        return -EINVAL;
> +    }
> +
> +    /* Only routing to virtual SPIs is supported */
> +    if ( virq < 32 )
> +    {
> +        dprintk(XENLOG_G_ERR, "IRQ can only be routed to a virtual SPIs");
> +        return -EINVAL;
> +    }
> +
>      action = xmalloc(struct irqaction);
>      if ( !action )
>          return -ENOMEM;
> @@ -408,8 +440,18 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
>  
>      spin_lock_irqsave(&desc->lock, flags);
>  
> +    if ( desc->arch.type == DT_IRQ_TYPE_INVALID )
> +    {
> +        dprintk(XENLOG_G_ERR, "IRQ %u has not been configured\n",
> +                irq);
> +        retval = -EIO;
> +        goto out;
> +    }
> +
>      /* If the IRQ is already used by someone
> -     *  - If it's the same domain -> Xen doesn't need to update the IRQ desc
> +     *  - If it's the same domain -> Xen doesn't need to update the IRQ desc.
> +     *  For safety check if we are not trying to assign the IRQ to a
> +     *  different vIRQ.
>       *  - Otherwise -> For now, don't allow the IRQ to be shared between
>       *  Xen and domains.
>       */
> @@ -418,13 +460,21 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
>          struct domain *ad = irq_get_domain(desc);
>  
>          if ( test_bit(_IRQ_GUEST, &desc->status) && d == ad )
> +        {
> +            if ( irq_get_guest_info(desc)->virq != virq )
> +            {
> +                dprintk(XENLOG_G_ERR, "d%u: IRQ %u is already assigned to vIRQ %u\n",
> +                        d->domain_id, irq, irq_get_guest_info(desc)->virq);
> +                retval = -EPERM;

I don't think that EPERM is the right error for this. Maybe EBUSY?

> +            }

Should we return error for this too? Maybe EEXIST?

>              goto out;
> +        }
>  
>          if ( test_bit(_IRQ_GUEST, &desc->status) )
> -            printk(XENLOG_ERR "ERROR: IRQ %u is already used by domain %u\n",
> -                   irq, ad->domain_id);
> +            dprintk(XENLOG_G_ERR, "IRQ %u is already used by domain %u\n",
> +                    irq, ad->domain_id);
>          else
> -            printk(XENLOG_ERR "ERROR: IRQ %u is already used by Xen\n", irq);
> +            dprintk(XENLOG_G_ERR, "IRQ %u is already used by Xen\n", irq);
>          retval = -EBUSY;
>          goto out;
>      }
> diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
> index f00eb11..71b39e7 100644
> --- a/xen/include/asm-arm/irq.h
> +++ b/xen/include/asm-arm/irq.h
> @@ -37,6 +37,8 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq);
>  
>  #define domain_pirq_to_irq(d, pirq) (pirq)
>  
> +bool_t is_assignable_irq(unsigned int irq);
> +
>  void init_IRQ(void);
>  void init_secondary_IRQ(void);
>  
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ
  2015-01-28 17:55   ` Stefano Stabellini
@ 2015-01-28 18:05     ` Julien Grall
  2015-01-29 11:52       ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-28 18:05 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On 28/01/15 17:55, Stefano Stabellini wrote:
>> ---
>>  xen/arch/arm/irq.c        | 58 +++++++++++++++++++++++++++++++++++++++++++----
>>  xen/include/asm-arm/irq.h |  2 ++
>>  2 files changed, 56 insertions(+), 4 deletions(-)
>>
>> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
>> index 830832c..af408ac 100644
>> --- a/xen/arch/arm/irq.c
>> +++ b/xen/arch/arm/irq.c
>> @@ -379,6 +379,15 @@ err:
>>      return rc;
>>  }
>>  
>> +bool_t is_assignable_irq(unsigned int irq)
> 
> static inline?

It's exported (will be used later) and not possible to inline in irq.h
because of interdependency between irq.h and gic.h

[..]

>> @@ -418,13 +460,21 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
>>          struct domain *ad = irq_get_domain(desc);
>>  
>>          if ( test_bit(_IRQ_GUEST, &desc->status) && d == ad )
>> +        {
>> +            if ( irq_get_guest_info(desc)->virq != virq )
>> +            {
>> +                dprintk(XENLOG_G_ERR, "d%u: IRQ %u is already assigned to vIRQ %u\n",
>> +                        d->domain_id, irq, irq_get_guest_info(desc)->virq);
>> +                retval = -EPERM;
> 
> I don't think that EPERM is the right error for this. Maybe EBUSY?

Right.

> 
>> +            }
> 
> Should we return error for this too? Maybe EEXIST?

No, this is a valid use case especially for DOM0.  The device tree may
expose twice the same IRQ.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  2015-01-13 14:25 ` [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest Julien Grall
@ 2015-01-28 18:15   ` Stefano Stabellini
  2015-02-20 16:07   ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 18:15 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> With the addition of interrupt assignment to guest, we need to make sure
> the guest don't blow up the interrupt management in Xen.
> 
> Before associating the IRQ to a vIRQ we need to make sure:
>     - the vIRQ is not already associated to another IRQ
>     - the guest didn't enable the vIRQ
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>     Changes in v3:
>         - Patch added
> ---
>  xen/arch/arm/gic.c        | 34 ++++++++++++++++++++++++++--------
>  xen/arch/arm/irq.c        | 12 ++++++++++--
>  xen/include/asm-arm/gic.h |  7 +++----
>  3 files changed, 39 insertions(+), 14 deletions(-)
> 
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 15de283..240870f 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -126,22 +126,40 @@ void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
>  /* Program the GIC to route an interrupt to a guest
>   *   - desc.lock must be held
>   */
> -void gic_route_irq_to_guest(struct domain *d, unsigned int virq,
> -                            struct irq_desc *desc,
> -                            const cpumask_t *cpu_mask, unsigned int priority)
> +int gic_route_irq_to_guest(struct domain *d, unsigned int virq,
> +                           struct irq_desc *desc, unsigned int priority)
>  {
> -    struct pending_irq *p;
> +    unsigned long flags;
> +    /* Use vcpu0 to retrieve the pending_irq struct. Given that we only
> +     * route SPIs to guests, it doesn't make any difference. */
> +    struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq);
> +    struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq);
> +    struct pending_irq *p = irq_to_pending(v_target, virq);
> +    int res = -EBUSY;
> +
>      ASSERT(spin_is_locked(&desc->lock));
> +    /* We only support SPIs */
> +    ASSERT(virq >= 32 && virq < vgic_num_irqs(d));
> +
> +    vgic_lock_rank(v_target, rank, flags);
> +
> +    if ( p->desc ||
> +         /* The VIRQ should not be already enabled by the guest */
> +         test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) )
> +        goto out;
>  
>      desc->handler = gic_hw_ops->gic_guest_irq_type;
>      set_bit(_IRQ_GUEST, &desc->status);
>  
> -    gic_set_irq_properties(desc, cpumask_of(smp_processor_id()), GIC_PRI_IRQ);
> +    gic_set_irq_properties(desc, cpumask_of(v_target->processor), priority);
>  
> -    /* Use vcpu0 to retrieve the pending_irq struct. Given that we only
> -     * route SPIs to guests, it doesn't make any difference. */
> -    p = irq_to_pending(d->vcpu[0], virq);
>      p->desc = desc;
> +    res = 0;
> +
> +out:
> +    vgic_unlock_rank(v_target, rank, flags);
> +
> +    return res;
>  }
>  
>  int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> index af408ac..0072347 100644
> --- a/xen/arch/arm/irq.c
> +++ b/xen/arch/arm/irq.c
> @@ -483,14 +483,22 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
>      if ( retval )
>          goto out;
>  
> -    gic_route_irq_to_guest(d, virq, desc, cpumask_of(smp_processor_id()),
> -                           GIC_PRI_IRQ);
> +    retval = gic_route_irq_to_guest(d, virq, desc, GIC_PRI_IRQ);
> +
>      spin_unlock_irqrestore(&desc->lock, flags);
> +
> +    if ( retval )
> +    {
> +        release_irq(desc->irq, info);
> +        goto free_info;
> +    }
> +
>      return 0;
>  
>  out:
>      spin_unlock_irqrestore(&desc->lock, flags);
>      xfree(action);
> +free_info:
>      xfree(info);
>  
>      return retval;
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index cf9f257..a8ac294 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -213,10 +213,9 @@ extern enum gic_version gic_hw_version(void);
>  /* Program the GIC to route an interrupt */
>  extern void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
>                                   unsigned int priority);
> -extern void gic_route_irq_to_guest(struct domain *, unsigned int virq,
> -                                   struct irq_desc *desc,
> -                                   const cpumask_t *cpu_mask,
> -                                   unsigned int priority);
> +extern int gic_route_irq_to_guest(struct domain *, unsigned int virq,
> +                                  struct irq_desc *desc,
> +                                  unsigned int priority);
>  
>  extern void gic_inject(void);
>  extern void gic_clear_pending_irqs(struct vcpu *v);
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-01-13 14:25 ` [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs Julien Grall
@ 2015-01-28 18:26   ` Stefano Stabellini
  2015-01-28 18:58     ` Julien Grall
  2015-02-20 16:08     ` Ian Campbell
  2015-02-20 16:23   ` Ian Campbell
  1 sibling, 2 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 18:26 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	Jan Beulich, xen-devel

On Tue, 13 Jan 2015, Julien Grall wrote:
> Each domain may have a different number of IRQs depending on the devices
> assigned to it.
> 
> Rather re-using the number of IRQs used by the hardwared GIC, let the
> toolstack specify the number of SPIs when the domain is created. This
> will avoid to waste memory.
> 
> To calculate the number of SPIs, we assume that any IRQ given via the option
> "irqs=" in xl is mapped 1:1 to the guest.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> 
> ---
>     Changes in v3:
>         - Fix typoes
>         - A separate has been created to extend the DOMCTL create domain
> 
>     Changes in v2:
>         - Patch added
> ---
>  tools/libxc/xc_domain.c       |  1 +
>  tools/libxl/libxl_arm.c       | 19 +++++++++++++++++++
>  xen/arch/arm/domain.c         |  7 ++++++-
>  xen/arch/arm/setup.c          |  1 +
>  xen/arch/arm/vgic.c           | 10 +++++-----
>  xen/include/asm-arm/domain.h  |  2 ++
>  xen/include/asm-arm/setup.h   |  1 +
>  xen/include/asm-arm/vgic.h    |  2 +-
>  xen/include/public/arch-arm.h |  2 ++
>  9 files changed, 38 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
> index eebc121..eb066cf 100644
> --- a/tools/libxc/xc_domain.c
> +++ b/tools/libxc/xc_domain.c
> @@ -67,6 +67,7 @@ int xc_domain_create(xc_interface *xch,
>      /* No arch-specific configuration for now */
>  #elif defined (__arm__) || defined(__aarch64__)
>      config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
> +    config.nr_spis = 0;
>  #else
>      errno = ENOSYS;
>      return -1;
> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> index cddce6e..53177eb 100644
> --- a/tools/libxl/libxl_arm.c
> +++ b/tools/libxl/libxl_arm.c
> @@ -39,6 +39,25 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
>                                        libxl_domain_config *d_config,
>                                        xc_domain_configuration_t *xc_config)
>  {
> +    uint32_t nr_spis = 0;
> +    unsigned int i;
> +
> +    for (i = 0; i < d_config->b_info.num_irqs; i++) {
> +        int irq = d_config->b_info.irqs[i];

unsigned int

> +        int spi = irq - 32;

unsigned int


> +        if (irq < 32)
> +            continue;
> +
> +        if (nr_spis <= spi)
> +            nr_spis = spi + 1;

overflow check?


> +    }
> +
> +    LOG(DEBUG, "Configure the domain");
> +
> +    xc_config->nr_spis = nr_spis;
> +    LOG(DEBUG, " - Allocate %u SPIs", nr_spis);
> +
>      xc_config->gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
>  
>      return 0;
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 2473b10..6e56665 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -560,10 +560,15 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
>      }
>      config->gic_version = gic_version;
>  
> +    /* Sanity check on the number of SPIs */
> +    rc = -EINVAL;
> +    if ( config->nr_spis > (gic_number_lines() - 32) )
> +        goto fail;
> +
>      if ( (rc = gicv_setup(d)) != 0 )
>          goto fail;
>  
> -    if ( (rc = domain_vgic_init(d)) != 0 )
> +    if ( (rc = domain_vgic_init(d, config->nr_spis)) != 0 )
>          goto fail;
>  
>      if ( (rc = domain_vtimer_init(d)) != 0 )
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index 18227f6..b28a708 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -815,6 +815,7 @@ void __init start_xen(unsigned long boot_phys_offset,
>      /* Create initial domain 0. */
>      /* The vGIC for DOM0 is exactly emulated the hardware GIC */
>      config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
> +    config.nr_spis = gic_number_lines() - 32;
>  
>      dom0 = domain_create(0, 0, 0, &config);
>      if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index c915670..fc8a270 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -67,16 +67,16 @@ static void vgic_init_pending_irq(struct pending_irq *p, unsigned int virq)
>      p->irq = virq;
>  }
>  
> -int domain_vgic_init(struct domain *d)
> +int domain_vgic_init(struct domain *d, unsigned int nr_spis)
>  {
>      int i;
>  
>      d->arch.vgic.ctlr = 0;
>  
> -    if ( is_hardware_domain(d) )
> -        d->arch.vgic.nr_spis = gic_number_lines() - 32;
> -    else
> -        d->arch.vgic.nr_spis = 0; /* We don't need SPIs for the guest */
> +    /* The number of SPIs has to be aligned to 32 see
> +     * GICD_TYPER.ITLinesNumber definition
> +     */
> +    d->arch.vgic.nr_spis = ROUNDUP(nr_spis, 32);
>  
>      switch ( gic_hw_version() )
>      {
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index d302fc9..101b4e9 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -121,6 +121,8 @@ struct arch_domain
>      unsigned int evtchn_irq;
>  }  __cacheline_aligned;
>  
> +#define domain_is_configured(d) ((d)->arch.is_configured)

This is unused. Moreover it cannot find "is_configured" anywhere.


>  struct arch_vcpu
>  {
>      struct {
> diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h
> index ba5a67d..254cc17 100644
> --- a/xen/include/asm-arm/setup.h
> +++ b/xen/include/asm-arm/setup.h
> @@ -54,6 +54,7 @@ void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
>  void arch_get_xen_caps(xen_capabilities_info_t *info);
>  
>  int construct_dom0(struct domain *d);
> +int configure_dom0(struct domain *d);
>  
>  void discard_initial_modules(void);
>  
> diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
> index 1cd7808..e97a5eb 100644
> --- a/xen/include/asm-arm/vgic.h
> +++ b/xen/include/asm-arm/vgic.h
> @@ -177,7 +177,7 @@ enum gic_sgi_mode;
>  
>  #define vgic_num_irqs(d)        ((d)->arch.vgic.nr_spis + 32)
>  
> -extern int domain_vgic_init(struct domain *d);
> +extern int domain_vgic_init(struct domain *d, unsigned int nr_spis);
>  extern void domain_vgic_free(struct domain *d);
>  extern int vcpu_vgic_init(struct vcpu *v);
>  extern struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int irq);
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index 4c1b9f9..45d3b1f 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -320,6 +320,8 @@ typedef uint64_t xen_callback_t;
>  struct xen_arch_domainconfig {
>      /* IN/OUT */
>      uint8_t gic_version;
> +    /* IN */
> +    uint32_t nr_spis;
>  };
>  
>  #endif
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying
  2015-01-13 14:25 ` [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying Julien Grall
@ 2015-01-28 18:38   ` Stefano Stabellini
  2015-02-20 16:31   ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 18:38 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> Xen has to release IRQ routed to a domain in order to reuse later. Currently
> only SPIs can be routed to the guest so we only need to browse SPIs for a
> specific domain.
> 
> Futhermore, a guest can crash and let the IRQ in an incorrect state (i.e has
> not being EOIed). Xen will have to reset the IRQ in order to be able to reuse
> the IRQ later.
> 
> Introduce 2 new functions for release an IRQ routed to a domain:
>     - release_guest_irq: upper level to retrieve the IRQ, call the GIC
>     code and release the action
>     - gic_remove_guest_irq: Check if we can remove the IRQ, and reset
>     it if necessary
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


> ---
>     Changes in v3:
>         - Take the vgic rank lock to protect p->desc
>         - Correctly check if the IRQ is disabled
>         - Extend the check on the virq in release_guest_irq
>         - Use vgic_get_target_vcpu to get the target vCPU
>         - Remove spurious change
> 
>     Changes in v2:
>         - Drop the desc->handler = &no_irq_type in release_irq as it's
>         buggy if the IRQ is routed to Xen
>         - Add release_guest_irq and gic_remove_guest_irq
> ---
>  xen/arch/arm/gic.c        | 46 +++++++++++++++++++++++++++++++++++++++++++++
>  xen/arch/arm/irq.c        | 48 +++++++++++++++++++++++++++++++++++++++++++++++
>  xen/arch/arm/vgic.c       | 16 ++++++++++++++++
>  xen/include/asm-arm/gic.h |  4 ++++
>  xen/include/asm-arm/irq.h |  2 ++
>  5 files changed, 116 insertions(+)
> 
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 240870f..bb298e9 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -162,6 +162,52 @@ out:
>      return res;
>  }
>  
> +/* This function only works with SPIs for now */
> +int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
> +                              struct irq_desc *desc)
> +{
> +    struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq);
> +    struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq);
> +    struct pending_irq *p = irq_to_pending(v_target, virq);
> +    unsigned long flags;
> +
> +    ASSERT(spin_is_locked(&desc->lock));
> +    ASSERT(test_bit(_IRQ_GUEST, &desc->status));
> +    ASSERT(p->desc == desc);
> +
> +    vgic_lock_rank(v_target, rank, flags);
> +
> +    /* If the IRQ is removed when the domain is dying, we only need to
> +     * EOI the IRQ if it has not been done by the guest
> +     */
> +    if ( d->is_dying )
> +    {
> +        desc->handler->shutdown(desc);
> +        if ( test_bit(_IRQ_INPROGRESS, &desc->status) )
> +            gic_hw_ops->deactivate_irq(desc);
> +        clear_bit(_IRQ_INPROGRESS, &desc->status);
> +        goto end;
> +    }
> +
> +    /* TODO: Handle eviction from LRs. For now, deny remove if the IRQ
> +     * is inflight and not disabled.
> +     */
> +    if ( test_bit(_IRQ_INPROGRESS, &desc->status) ||
> +         !test_bit(_IRQ_DISABLED, &desc->status) )
> +        return -EBUSY;
> +
> +end:
> +    clear_bit(_IRQ_GUEST, &desc->status);
> +    desc->handler = &no_irq_type;
> +
> +    p->desc = NULL;
> +
> +    vgic_unlock_rank(v_target, rank, flags);
> +
> +
> +    return 0;
> +}
> +
>  int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
>                    unsigned int *out_hwirq,
>                    unsigned int *out_type)
> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> index 0072347..ce5ae1a 100644
> --- a/xen/arch/arm/irq.c
> +++ b/xen/arch/arm/irq.c
> @@ -504,6 +504,54 @@ free_info:
>      return retval;
>  }
>  
> +int release_guest_irq(struct domain *d, unsigned int virq)
> +{
> +    struct irq_desc *desc;
> +    struct irq_guest *info;
> +    unsigned long flags;
> +    struct pending_irq *p;
> +    int ret;
> +
> +    /* Only SPIs are supported */
> +    if ( virq < 32 || virq >= vgic_num_irqs(d) )
> +        return -EINVAL;
> +
> +    p = irq_to_pending(d->vcpu[0], virq);
> +    if ( !p->desc )
> +        return -EINVAL;
> +
> +    desc = p->desc;
> +
> +    spin_lock_irqsave(&desc->lock, flags);
> +
> +    ret = -EINVAL;
> +    if ( !test_bit(_IRQ_GUEST, &desc->status) )
> +        goto unlock;
> +
> +    ret = -EINVAL;
> +
> +    info = irq_get_guest_info(desc);
> +    if ( d != info->d )
> +        goto unlock;
> +
> +    ret = gic_remove_irq_from_guest(d, virq, desc);
> +
> +    spin_unlock_irqrestore(&desc->lock, flags);
> +
> +    if ( !ret )
> +    {
> +        release_irq(desc->irq, info);
> +        xfree(info);
> +    }
> +
> +    return ret;
> +
> +unlock:
> +    spin_unlock_irqrestore(&desc->lock, flags);
> +
> +    return ret;
> +}
> +
>  /*
>   * pirq event channels. We don't use these on ARM, instead we use the
>   * features of the GIC to inject virtualised normal interrupts.
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index fc8a270..4ddfd73 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -133,6 +133,22 @@ void register_vgic_ops(struct domain *d, const struct vgic_ops *ops)
>  
>  void domain_vgic_free(struct domain *d)
>  {
> +    int i;
> +    int ret;
> +
> +    for ( i = 0; i < (d->arch.vgic.nr_spis); i++ )
> +    {
> +        struct pending_irq *p = &d->arch.vgic.pending_irqs[i];
> +
> +        if ( p->desc )
> +        {
> +            ret = release_guest_irq(d, p->irq);
> +            if ( ret )
> +                dprintk(XENLOG_G_WARNING, "d%u: Failed to release virq %u ret = %d\n",
> +                        d->domain_id, p->irq, ret);
> +        }
> +    }
> +
>      xfree(d->arch.vgic.shared_irqs);
>      xfree(d->arch.vgic.pending_irqs);
>      xfree(d->arch.vgic.allocated_irqs);
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index a8ac294..5571189 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -217,6 +217,10 @@ extern int gic_route_irq_to_guest(struct domain *, unsigned int virq,
>                                    struct irq_desc *desc,
>                                    unsigned int priority);
>  
> +/* Remove an IRQ passthrough to a guest */
> +int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
> +                              struct irq_desc *desc);
> +
>  extern void gic_inject(void);
>  extern void gic_clear_pending_irqs(struct vcpu *v);
>  extern int gic_events_need_delivery(void);
> diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
> index 71b39e7..34b492b 100644
> --- a/xen/include/asm-arm/irq.h
> +++ b/xen/include/asm-arm/irq.h
> @@ -44,6 +44,8 @@ void init_secondary_IRQ(void);
>  
>  int route_irq_to_guest(struct domain *d, unsigned int virq,
>                         unsigned int irq, const char *devname);
> +int release_guest_irq(struct domain *d, unsigned int irq);
> +
>  void arch_move_irqs(struct vcpu *v);
>  
>  /* Set IRQ type for an SPI */
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-01-13 14:25 ` [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq Julien Grall
  2015-01-19 16:54   ` Jan Beulich
@ 2015-01-28 18:52   ` Stefano Stabellini
  2015-01-28 19:04     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 18:52 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, Jan Beulich, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
> assign/deassign a physical IRQ to the guest (via the config options "irqs"
> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
> channel). As ARM doesn't have a such concept, we could reuse it to bound
> a physical IRQ to a virtual IRQ.
> 
> For now, we allow only SPIs to be mapped to the guest.
> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> 
> ---
>     I'm not sure it's the best solution to reuse hypercalls for a
>     different purpose. If x86 plan to have a such concept (i.e binding a
>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
>     Any thoughs?

I think it is OK, as long as we write down very clearly what we are
doing.


>     TODO: This patch is lacking of support of vIRQ != IRQ. I plan to
>     handle it correctly on the next version.

Why do you say that? From the code in this patch it looks like it
supports vIRQ != IRQ already.


>     Changes in v3:
>         - Functions to allocate/release/reserved a VIRQ has been moved
>         in a separate patch

That might be a good idea, but then you need to move that patch before
this one, otherwise it won't compile. As is it would break the build.


>         - Make clear that only MAP_PIRQ_GSI is only supported for now
> 
>     Changes in v2:
>         - Add PHYSDEVOP_unmap_pirq
>         - Rework commit message
>         - Add functions to allocate/release a VIRQ
>         - is_routable_irq has been renamed into is_assignable_irq
> ---
>  xen/arch/arm/physdev.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 134 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/physdev.c b/xen/arch/arm/physdev.c
> index 61b4a18..0cf9bbd 100644
> --- a/xen/arch/arm/physdev.c
> +++ b/xen/arch/arm/physdev.c
> @@ -8,13 +8,145 @@
>  #include <xen/types.h>
>  #include <xen/lib.h>
>  #include <xen/errno.h>
> +#include <xen/iocap.h>
> +#include <xen/guest_access.h>
> +#include <xsm/xsm.h>
> +#include <asm/current.h>
>  #include <asm/hypercall.h>
> +#include <public/physdev.h>
>  
> +static int physdev_map_pirq(domid_t domid, int type, int index, int *pirq_p)
> +{
> +    struct domain *d;
> +    int ret;
> +    int irq = index;
> +    int virq;
> +
> +    d = rcu_lock_domain_by_any_id(domid);
> +    if ( d == NULL )
> +        return -ESRCH;
> +
> +    ret = xsm_map_domain_pirq(XSM_TARGET, d);
> +    if ( ret )
> +        goto free_domain;
> +
> +    /* For now we only suport GSI */
> +    if ( type != MAP_PIRQ_TYPE_GSI )
> +    {
> +        ret = -EINVAL;
> +        dprintk(XENLOG_G_ERR,
> +                "dom%u: wrong map_pirq type 0x%x, only MAP_PIRQ_TYPE_GSI is supported.\n",
> +                d->domain_id, type);
> +        goto free_domain;
> +    }
> +
> +    if ( !is_assignable_irq(irq) )
> +    {
> +        ret = -EINVAL;
> +        dprintk(XENLOG_G_ERR, "IRQ%u is not routable to a guest\n", irq);
> +        goto free_domain;
> +    }
> +
> +    ret = -EPERM;
> +    if ( !irq_access_permitted(current->domain, irq) )
> +        goto free_domain;
> +
> +    if ( *pirq_p < 0 )
> +    {



> +        BUG_ON(irq < 16);   /* is_assignable_irq already denies SGIs */
> +        virq = vgic_allocate_virq(d, (irq >= 32));
> +
> +        ret = -ENOSPC;
> +        if ( virq < 0 )
> +            goto free_domain;
> +    }
> +    else
> +    {
> +        ret = -EBUSY;
> +        virq = *pirq_p;
> +
> +        if ( !vgic_reserve_virq(d, virq) )
> +            goto free_domain;
> +    }
> +
> +    gdprintk(XENLOG_DEBUG, "irq = %u virq = %u\n", irq, virq);
> +
> +    ret = route_irq_to_guest(d, virq, irq, "routed IRQ");
> +
> +    if ( !ret )
> +        *pirq_p = virq;
> +    else
> +        vgic_free_virq(d, virq);
> +
> +free_domain:
> +    rcu_unlock_domain(d);
> +
> +    return ret;
> +}
> +
> +int physdev_unmap_pirq(domid_t domid, int pirq)
> +{
> +    struct domain *d;
> +    int ret;
> +
> +    d = rcu_lock_domain_by_any_id(domid);
> +    if ( d == NULL )
> +        return -ESRCH;
> +
> +    ret = xsm_unmap_domain_pirq(XSM_TARGET, d);
> +    if ( ret )
> +        goto free_domain;
> +
> +    ret = release_guest_irq(d, pirq);
> +    if ( ret )
> +        goto free_domain;
> +
> +    vgic_free_virq(d, pirq);
> +
> +free_domain:
> +    rcu_unlock_domain(d);
> +
> +    return ret;
> +}
>  
>  int do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
>  {
> -    printk("%s %d cmd=%d: not implemented yet\n", __func__, __LINE__, cmd);
> -    return -ENOSYS;
> +    int ret;
> +
> +    switch ( cmd )
> +    {
> +    case PHYSDEVOP_map_pirq:
> +        {
> +            physdev_map_pirq_t map;
> +
> +            ret = -EFAULT;
> +            if ( copy_from_guest(&map, arg, 1) != 0 )
> +                break;
> +
> +            ret = physdev_map_pirq(map.domid, map.type, map.index, &map.pirq);
> +
> +            if ( __copy_to_guest(arg, &map, 1) )
> +                ret = -EFAULT;
> +        }
> +        break;
> +
> +    case PHYSDEVOP_unmap_pirq:
> +        {
> +            physdev_unmap_pirq_t unmap;
> +
> +            ret = -EFAULT;
> +            if ( copy_from_guest(&unmap, arg, 1) != 0 )
> +                break;
> +
> +            ret = physdev_unmap_pirq(unmap.domid, unmap.pirq);
> +        }
> +
> +    default:
> +        ret = -ENOSYS;
> +        break;
> +    }
> +
> +    return ret;
>  }
>  
>  /*
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-01-28 18:26   ` Stefano Stabellini
@ 2015-01-28 18:58     ` Julien Grall
  2015-01-29 12:01       ` Stefano Stabellini
  2015-02-20 16:08     ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-28 18:58 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	Jan Beulich, xen-devel

Hi Stefano,

On 28/01/15 18:26, Stefano Stabellini wrote:
> On Tue, 13 Jan 2015, Julien Grall wrote:
>> Each domain may have a different number of IRQs depending on the devices
>> assigned to it.
>>
>> Rather re-using the number of IRQs used by the hardwared GIC, let the
>> toolstack specify the number of SPIs when the domain is created. This
>> will avoid to waste memory.
>>
>> To calculate the number of SPIs, we assume that any IRQ given via the option
>> "irqs=" in xl is mapped 1:1 to the guest.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Jan Beulich <jbeulich@suse.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>>
>> ---
>>     Changes in v3:
>>         - Fix typoes
>>         - A separate has been created to extend the DOMCTL create domain
>>
>>     Changes in v2:
>>         - Patch added
>> ---
>>  tools/libxc/xc_domain.c       |  1 +
>>  tools/libxl/libxl_arm.c       | 19 +++++++++++++++++++
>>  xen/arch/arm/domain.c         |  7 ++++++-
>>  xen/arch/arm/setup.c          |  1 +
>>  xen/arch/arm/vgic.c           | 10 +++++-----
>>  xen/include/asm-arm/domain.h  |  2 ++
>>  xen/include/asm-arm/setup.h   |  1 +
>>  xen/include/asm-arm/vgic.h    |  2 +-
>>  xen/include/public/arch-arm.h |  2 ++
>>  9 files changed, 38 insertions(+), 7 deletions(-)
>>
>> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
>> index eebc121..eb066cf 100644
>> --- a/tools/libxc/xc_domain.c
>> +++ b/tools/libxc/xc_domain.c
>> @@ -67,6 +67,7 @@ int xc_domain_create(xc_interface *xch,
>>      /* No arch-specific configuration for now */
>>  #elif defined (__arm__) || defined(__aarch64__)
>>      config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
>> +    config.nr_spis = 0;
>>  #else
>>      errno = ENOSYS;
>>      return -1;
>> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
>> index cddce6e..53177eb 100644
>> --- a/tools/libxl/libxl_arm.c
>> +++ b/tools/libxl/libxl_arm.c
>> @@ -39,6 +39,25 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
>>                                        libxl_domain_config *d_config,
>>                                        xc_domain_configuration_t *xc_config)
>>  {
>> +    uint32_t nr_spis = 0;
>> +    unsigned int i;
>> +
>> +    for (i = 0; i < d_config->b_info.num_irqs; i++) {
>> +        int irq = d_config->b_info.irqs[i];
> 
> unsigned int

I will use uint32_t.

>> +        int spi = irq - 32;

Same here.

> 
>> +        if (irq < 32)
>> +            continue;
>> +
>> +        if (nr_spis <= spi)
>> +            nr_spis = spi + 1;
> 
> overflow check?

If I use unsigned int, the overflow will go back to 0. While it won't
affect the code, the domain creation will fail later (unable to assign
the SPI).

So is it useful to add a check here?

[..]

>> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
>> index d302fc9..101b4e9 100644
>> --- a/xen/include/asm-arm/domain.h
>> +++ b/xen/include/asm-arm/domain.h
>> @@ -121,6 +121,8 @@ struct arch_domain
>>      unsigned int evtchn_irq;
>>  }  __cacheline_aligned;
>>  
>> +#define domain_is_configured(d) ((d)->arch.is_configured)
> 
> This is unused. Moreover it cannot find "is_configured" anywhere.

Left-over of a previous version. Sorry.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-01-13 14:25 ` [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest Julien Grall
  2015-01-20  9:19   ` Jan Beulich
@ 2015-01-28 18:59   ` Stefano Stabellini
  2015-02-20 17:03   ` Ian Campbell
  2 siblings, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-28 18:59 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, Jan Beulich, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> The toolstack may not have deassign every device used by a guest.
> Therefore we have to go through the device list and removing them before
> asking the IOMMU drivers to release memory for this domain.
> 
> This can be done by moving the call to the release function when we
> relinquish the resources. The IOMMU part will be destroyed later when
> the domain is freed.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> 
>     Changes in v3:
>         - Patch added. Superseed the patch "xen/passthrough: call
>         arch_iommu_domain_destroy before calling iommu teardown" in
>         the previous patch series.

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>  xen/arch/arm/domain.c                 | 4 ++++
>  xen/drivers/passthrough/arm/iommu.c   | 1 -
>  xen/drivers/passthrough/device_tree.c | 5 ++++-
>  xen/include/xen/iommu.h               | 2 +-
>  4 files changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 6e56665..d85748a 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -772,6 +772,10 @@ int domain_relinquish_resources(struct domain *d)
>      switch ( d->arch.relmem )
>      {
>      case RELMEM_not_started:
> +        ret = iommu_release_dt_devices(d);
> +        if ( ret )
> +            return ret;
> +
>          d->arch.relmem = RELMEM_xen;
>          /* Falltrough */
>  
> diff --git a/xen/drivers/passthrough/arm/iommu.c b/xen/drivers/passthrough/arm/iommu.c
> index 5870aef..8223a39 100644
> --- a/xen/drivers/passthrough/arm/iommu.c
> +++ b/xen/drivers/passthrough/arm/iommu.c
> @@ -66,7 +66,6 @@ int arch_iommu_domain_init(struct domain *d)
>  
>  void arch_iommu_domain_destroy(struct domain *d)
>  {
> -    iommu_dt_domain_destroy(d);
>  }
>  
>  int arch_iommu_populate_page_table(struct domain *d)
> diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
> index 88e496e..e7eb34f 100644
> --- a/xen/drivers/passthrough/device_tree.c
> +++ b/xen/drivers/passthrough/device_tree.c
> @@ -97,7 +97,7 @@ int iommu_dt_domain_init(struct domain *d)
>      return 0;
>  }
>  
> -void iommu_dt_domain_destroy(struct domain *d)
> +int iommu_release_dt_devices(struct domain *d)
>  {
>      struct hvm_iommu *hd = domain_hvm_iommu(d);
>      struct dt_device_node *dev, *_dev;
> @@ -109,5 +109,8 @@ void iommu_dt_domain_destroy(struct domain *d)
>          if ( rc )
>              dprintk(XENLOG_ERR, "Failed to deassign %s in domain %u\n",
>                      dt_node_full_name(dev), d->domain_id);
> +        return rc;
>      }
> +
> +    return 0;
>  }
> diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
> index c146ee4..d03df14 100644
> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -117,7 +117,7 @@ void iommu_read_msi_from_ire(struct msi_desc *msi_desc, struct msi_msg *msg);
>  int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev);
>  int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev);
>  int iommu_dt_domain_init(struct domain *d);
> -void iommu_dt_domain_destroy(struct domain *d);
> +int iommu_release_dt_devices(struct domain *d);
>  
>  #endif /* HAS_DEVICE_TREE */
>  
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-01-28 18:52   ` Stefano Stabellini
@ 2015-01-28 19:04     ` Julien Grall
  2015-01-29 12:17       ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-28 19:04 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: xen-devel, Jan Beulich, tim, ian.campbell, stefano.stabellini

Hi Stefano,

On 28/01/15 18:52, Stefano Stabellini wrote:
> On Tue, 13 Jan 2015, Julien Grall wrote:
>> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
>> assign/deassign a physical IRQ to the guest (via the config options "irqs"
>> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
>> channel). As ARM doesn't have a such concept, we could reuse it to bound
>> a physical IRQ to a virtual IRQ.
>>
>> For now, we allow only SPIs to be mapped to the guest.
>> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Jan Beulich <jbeulich@suse.com>
>>
>> ---
>>     I'm not sure it's the best solution to reuse hypercalls for a
>>     different purpose. If x86 plan to have a such concept (i.e binding a
>>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
>>     Any thoughs?
> 
> I think it is OK, as long as we write down very clearly what we are
> doing.
> 
> 
>>     TODO: This patch is lacking of support of vIRQ != IRQ. I plan to
>>     handle it correctly on the next version.
> 
> Why do you say that? From the code in this patch it looks like it
> supports vIRQ != IRQ already.

Because PHYSDEV_map_pirq is taking a vIRQ number in parameter. This vIRQ
is only valid for the domain which issue the hypercall.

In our use case, it's DOM0. DOM0 may not have all the time vIRQ == IRQ.

Futhermore, on PHYSDEV_unmap_pirq I assume the DOM0 virq == guest virq.

> 
>>     Changes in v3:
>>         - Functions to allocate/release/reserved a VIRQ has been moved
>>         in a separate patch
> 
> That might be a good idea, but then you need to move that patch before
> this one, otherwise it won't compile. As is it would break the build.

This patch belongs to a separate patch series. FIY, on the cover letter
I explicitly wrote the dependency in other to apply this series.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-01-13 14:25 ` [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody Julien Grall
  2015-01-20  9:21   ` Jan Beulich
@ 2015-01-29 10:20   ` Stefano Stabellini
  2015-02-20 17:04   ` Ian Campbell
  2 siblings, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 10:20 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, Jan Beulich, tim, ian.campbell, stefano.stabellini

On Tue, 13 Jan 2015, Julien Grall wrote:
> Currently, when the device is deassigned from a domain, we directly reassign
> to DOM0.
> 
> As the device may not have been correctly reset, this may lead to corruption or
> expose some part of DOM0 memory. Also, we may have no way to reset some
> platform devices.
> 
> If Xen reassigns the device to "nobody", it may receive some global/context
> fault because the transaction has failed (indeed the context has been
> marked invalid). Unfortunately there is no simple way to quiesce a buggy
> hardware. I think we could live with that for a first version of platform
> device passthrough.
> 
> DOM0 will have to issue an hypercall to assign the device to itself if it
> wants to use it.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> 

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>


>     Changes in v3:
>         - Use the coding style of the new SMMU drivers
> 
>     Changes in v2:
>         - Fix typoes in the commit message
>         - Update commit message
> ---
>  xen/drivers/passthrough/arm/smmu.c    | 8 +++++++-
>  xen/drivers/passthrough/device_tree.c | 9 +++------
>  2 files changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
> index 3cf1773..45a2db8 100644
> --- a/xen/drivers/passthrough/arm/smmu.c
> +++ b/xen/drivers/passthrough/arm/smmu.c
> @@ -2774,7 +2774,7 @@ static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
>  	int ret = 0;
>  
>  	/* Don't allow remapping on other domain than hwdom */
> -	if (t != hardware_domain)
> +	if (t && t != hardware_domain)
>  		return -EPERM;
>  
>  	if (t == s)
> @@ -2784,6 +2784,12 @@ static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
>  	if (ret)
>  		return ret;
>  
> +	if (t) {
> +		ret = arm_smmu_assign_dev(t, devfn, dev);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
> index e7eb34f..d9b486e 100644
> --- a/xen/drivers/passthrough/device_tree.c
> +++ b/xen/drivers/passthrough/device_tree.c
> @@ -72,15 +72,12 @@ int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev)
>  
>      spin_lock(&dtdevs_lock);
>  
> -    rc = hd->platform_ops->reassign_device(d, hardware_domain,
> -                                           0, dt_to_dev(dev));
> +    rc = hd->platform_ops->reassign_device(d, NULL, 0, dt_to_dev(dev));
>      if ( rc )
>          goto fail;
>  
> -    list_del(&dev->domain_list);
> -
> -    dt_device_set_used_by(dev, hardware_domain->domain_id);
> -    list_add(&dev->domain_list, &domain_hvm_iommu(hardware_domain)->dt_devices);
> +    list_del_init(&dev->domain_list);
> +    dt_device_set_used_by(dev, DOMID_IO);
>  
>  fail:
>      spin_unlock(&dtdevs_lock);
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-13 14:25 ` [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device Julien Grall
  2015-01-20  9:34   ` Jan Beulich
@ 2015-01-29 10:29   ` Stefano Stabellini
  2015-01-29 11:45     ` Julien Grall
  2015-02-20 17:17   ` Ian Campbell
  2 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 10:29 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	Jan Beulich, xen-devel

On Tue, 13 Jan 2015, Julien Grall wrote:
> TODO: Update the commit message
> 
> A device node is described by a path. It will be used to retrieved the
> node in the device tree and assign the related device to the domain.
> 
> Only device protected by an IOMMU can be assigned to a guest.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> 
> ---
>     Changes in v2:
>         - Use a different number for XEN_DOMCTL_assign_dt_device
> ---
>  tools/libxc/include/xenctrl.h         | 10 ++++
>  tools/libxc/xc_domain.c               | 95 ++++++++++++++++++++++++++++++++--
>  xen/drivers/passthrough/device_tree.c | 97 +++++++++++++++++++++++++++++++++--
>  xen/drivers/passthrough/iommu.c       |  7 +++
>  xen/drivers/passthrough/pci.c         | 43 +++++++++++-----
>  xen/include/public/domctl.h           | 15 +++++-
>  xen/include/xen/iommu.h               |  3 ++
>  7 files changed, 249 insertions(+), 21 deletions(-)
> 
> diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
> index d66571f..db45475 100644
> --- a/tools/libxc/include/xenctrl.h
> +++ b/tools/libxc/include/xenctrl.h
> @@ -2055,6 +2055,16 @@ int xc_deassign_device(xc_interface *xch,
>                       uint32_t domid,
>                       uint32_t machine_bdf);
>  
> +int xc_assign_dt_device(xc_interface *xch,
> +                        uint32_t domid,
> +                        char *path);
> +int xc_test_assign_dt_device(xc_interface *xch,
> +                             uint32_t domid,
> +                             char *path);
> +int xc_deassign_dt_device(xc_interface *xch,
> +                          uint32_t domid,
> +                          char *path);
> +
>  int xc_domain_memory_mapping(xc_interface *xch,
>                               uint32_t domid,
>                               unsigned long first_gfn,
> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
> index eb066cf..bca3aee 100644
> --- a/tools/libxc/xc_domain.c
> +++ b/tools/libxc/xc_domain.c
> @@ -1637,7 +1637,8 @@ int xc_assign_device(
>  
>      domctl.cmd = XEN_DOMCTL_assign_device;
>      domctl.domain = domid;
> -    domctl.u.assign_device.machine_sbdf = machine_sbdf;
> +    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_PCI;
> +    domctl.u.assign_device.u.pci.machine_sbdf = machine_sbdf;
>  
>      return do_domctl(xch, &domctl);
>  }
> @@ -1686,7 +1687,8 @@ int xc_test_assign_device(
>  
>      domctl.cmd = XEN_DOMCTL_test_assign_device;
>      domctl.domain = domid;
> -    domctl.u.assign_device.machine_sbdf = machine_sbdf;
> +    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_PCI;
> +    domctl.u.assign_device.u.pci.machine_sbdf = machine_sbdf;
>  
>      return do_domctl(xch, &domctl);
>  }
> @@ -1700,11 +1702,96 @@ int xc_deassign_device(
>  
>      domctl.cmd = XEN_DOMCTL_deassign_device;
>      domctl.domain = domid;
> -    domctl.u.assign_device.machine_sbdf = machine_sbdf;
> - 
> +    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_PCI;
> +    domctl.u.assign_device.u.pci.machine_sbdf = machine_sbdf;
> +
>      return do_domctl(xch, &domctl);
>  }
>  
> +int xc_assign_dt_device(
> +    xc_interface *xch,
> +    uint32_t domid,
> +    char *path)
> +{
> +    int rc;
> +    size_t size = strlen(path);
> +    DECLARE_DOMCTL;
> +    DECLARE_HYPERCALL_BOUNCE(path, size, XC_HYPERCALL_BUFFER_BOUNCE_IN);
> +
> +    if ( xc_hypercall_bounce_pre(xch, path) )
> +        return -1;
> +
> +    domctl.cmd = XEN_DOMCTL_assign_device;
> +    domctl.domain = (domid_t)domid;
> +
> +    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT;
> +    domctl.u.assign_device.u.dt.size = size;
> +    set_xen_guest_handle(domctl.u.assign_device.u.dt.path, path);
> +
> +    rc = do_domctl(xch, &domctl);
> +
> +    xc_hypercall_bounce_post(xch, path);
> +
> +    return rc;
> +}
> +
> +int xc_test_assign_dt_device(
> +    xc_interface *xch,
> +    uint32_t domid,
> +    char *path)
> +{
> +    int rc;
> +    size_t size = strlen(path);
> +    DECLARE_DOMCTL;
> +    DECLARE_HYPERCALL_BOUNCE(path, size, XC_HYPERCALL_BUFFER_BOUNCE_IN);
> +
> +    if ( xc_hypercall_bounce_pre(xch, path) )
> +        return -1;
> +
> +    domctl.cmd = XEN_DOMCTL_test_assign_device;
> +    domctl.domain = (domid_t)domid;
> +
> +    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT;
> +    domctl.u.assign_device.u.dt.size = size;
> +    set_xen_guest_handle(domctl.u.assign_device.u.dt.path, path);
> +
> +    rc = do_domctl(xch, &domctl);
> +
> +    xc_hypercall_bounce_post(xch, path);
> +
> +    return rc;
> +}
> +
> +int xc_deassign_dt_device(
> +    xc_interface *xch,
> +    uint32_t domid,
> +    char *path)
> +{
> +    int rc;
> +    size_t size = strlen(path);
> +    DECLARE_DOMCTL;
> +    DECLARE_HYPERCALL_BOUNCE(path, size, XC_HYPERCALL_BUFFER_BOUNCE_IN);
> +
> +    if ( xc_hypercall_bounce_pre(xch, path) )
> +        return -1;
> +
> +    domctl.cmd = XEN_DOMCTL_deassign_device;
> +    domctl.domain = (domid_t)domid;
> +
> +    domctl.u.assign_device.dev = XEN_DOMCTL_DEV_DT;
> +    domctl.u.assign_device.u.dt.size = size;
> +    set_xen_guest_handle(domctl.u.assign_device.u.dt.path, path);
> +
> +    rc = do_domctl(xch, &domctl);
> +
> +    xc_hypercall_bounce_post(xch, path);
> +
> +    return rc;
> +}
> +
> +
> +
> +
>  int xc_domain_update_msi_irq(
>      xc_interface *xch,
>      uint32_t domid,
> diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
> index d9b486e..11deb1d 100644
> --- a/xen/drivers/passthrough/device_tree.c
> +++ b/xen/drivers/passthrough/device_tree.c
> @@ -1,9 +1,6 @@
>  /*
>   * Code to passthrough a device tree node to a guest
>   *
> - * TODO: This contains only the necessary code to protected device passed to
> - * dom0. It will need some updates when device passthrough will is added.
> - *
>   * Julien Grall <julien.grall@linaro.org>
>   * Copyright (c) 2014 Linaro Limited.
>   *
> @@ -20,6 +17,7 @@
>  
>  #include <xen/lib.h>
>  #include <xen/sched.h>
> +#include <xen/guest_access.h>
>  #include <xen/iommu.h>
>  #include <xen/device_tree.h>
>  
> @@ -85,6 +83,20 @@ fail:
>      return rc;
>  }
>  
> +static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev)
> +{
> +    bool_t assigned = 0;
> +
> +    if ( !dt_device_is_protected(dev) )
> +        return 1;

Why return true here?


> +    spin_lock(&dtdevs_lock);
> +    assigned = !list_empty(&dev->domain_list);
> +    spin_unlock(&dtdevs_lock);
> +
> +    return assigned;
> +}
> +
>  int iommu_dt_domain_init(struct domain *d)
>  {
>      struct hvm_iommu *hd = domain_hvm_iommu(d);
> @@ -111,3 +123,82 @@ int iommu_release_dt_devices(struct domain *d)
>  
>      return 0;
>  }
> +
> +int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
> +                       XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
> +{
> +    int ret;
> +    struct dt_device_node *dev;
> +
> +    /* TODO: How to deal with XSM? */
> +    /* TODO: Do we need to check is_dying? Mostly to protect against
> +     * hypercall trying to passthrough a device while we are
> +     * dying.
> +     */
> +
> +    switch ( domctl->cmd )
> +    {
> +    case XEN_DOMCTL_assign_device:
> +        ret = -ENOSYS;
> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
> +            break;
> +
> +        ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
> +                                    domctl->u.assign_device.u.dt.size,
> +                                    &dev);
> +        if ( ret )
> +            break;
> +
> +        ret = iommu_assign_dt_device(d, dev);
> +
> +        if ( ret )
> +            printk(XENLOG_G_ERR "XEN_DOMCTL_assign_dt_device: assign \"%s\""
> +                   " to dom%u failed (%d)\n",
> +                   dt_node_full_name(dev), d->domain_id, ret);
> +        break;
> +
> +    case XEN_DOMCTL_deassign_device:
> +        ret = -ENOSYS;
> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
> +            break;
> +
> +        ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
> +                                    domctl->u.assign_device.u.dt.size,
> +                                    &dev);
> +        if ( ret )
> +            break;
> +
> +        ret = iommu_deassign_dt_device(d, dev);
> +
> +        if ( ret )
> +            printk(XENLOG_G_ERR "XEN_DOMCTL_assign_dt_device: assign \"%s\""
> +                   " to dom%u failed (%d)\n",
> +                   dt_node_full_name(dev), d->domain_id, ret);
> +        break;
> +
> +    case XEN_DOMCTL_test_assign_device:
> +        ret = -ENOSYS;
> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
> +            break;
> +
> +        ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
> +                                    domctl->u.assign_device.u.dt.size,
> +                                    &dev);
> +        if ( ret )
> +            break;
> +
> +        if ( iommu_dt_device_is_assigned(dev) )
> +        {
> +            printk(XENLOG_G_ERR "%s already assigned, or not protected\n",
> +                   dt_node_full_name(dev));
> +            ret = -EINVAL;
> +        }
> +        break;
> +
> +    default:
> +        ret = -ENOSYS;
> +        break;
> +    }
> +
> +    return ret;
> +}
> diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
> index 8915244..02d5ec1 100644
> --- a/xen/drivers/passthrough/iommu.c
> +++ b/xen/drivers/passthrough/iommu.c
> @@ -337,6 +337,13 @@ int iommu_do_domctl(
>      ret = iommu_do_pci_domctl(domctl, d, u_domctl);
>  #endif
>  
> +    if ( ret != -ENOSYS )
> +        return ret;
> +
> +#ifdef HAS_DEVICE_TREE
> +    ret = iommu_do_dt_domctl(domctl, d, u_domctl);
> +#endif
> +
>      return ret;
>  }
>  
> diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
> index 9a47a37..ecc0cd1 100644
> --- a/xen/drivers/passthrough/pci.c
> +++ b/xen/drivers/passthrough/pci.c
> @@ -1497,6 +1497,7 @@ int iommu_do_pci_domctl(
>      u16 seg;
>      u8 bus, devfn;
>      int ret = 0;
> +    uint32_t machine_sbdf;
>  
>      switch ( domctl->cmd )
>      {
> @@ -1533,13 +1534,19 @@ int iommu_do_pci_domctl(
>      break;
>  
>      case XEN_DOMCTL_test_assign_device:
> -        ret = xsm_test_assign_device(XSM_HOOK, domctl->u.assign_device.machine_sbdf);
> +        ret = -ENOSYS;
> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
> +            break;
> +
> +        machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
> +
> +        ret = xsm_test_assign_device(XSM_HOOK, machine_sbdf);
>          if ( ret )
>              break;
>  
> -        seg = domctl->u.assign_device.machine_sbdf >> 16;
> -        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
> -        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
> +        seg = machine_sbdf >> 16;
> +        bus = (machine_sbdf >> 8) & 0xff;
> +        devfn = machine_sbdf & 0xff;
>  
>          if ( device_assigned(seg, bus, devfn) )
>          {
> @@ -1551,19 +1558,25 @@ int iommu_do_pci_domctl(
>          break;
>  
>      case XEN_DOMCTL_assign_device:
> +        ret = -ENOSYS;
> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
> +            break;
> +
>          if ( unlikely(d->is_dying) )
>          {
>              ret = -EINVAL;
>              break;
>          }
>  
> -        ret = xsm_assign_device(XSM_HOOK, d, domctl->u.assign_device.machine_sbdf);
> +        machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
> +
> +        ret = xsm_assign_device(XSM_HOOK, d, machine_sbdf);
>          if ( ret )
>              break;
>  
> -        seg = domctl->u.assign_device.machine_sbdf >> 16;
> -        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
> -        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
> +        seg = machine_sbdf >> 16;
> +        bus = (machine_sbdf >> 8) & 0xff;
> +        devfn = machine_sbdf & 0xff;
>  
>          ret = device_assigned(seg, bus, devfn) ?:
>                assign_device(d, seg, bus, devfn);
> @@ -1579,13 +1592,19 @@ int iommu_do_pci_domctl(
>          break;
>  
>      case XEN_DOMCTL_deassign_device:
> -        ret = xsm_deassign_device(XSM_HOOK, d, domctl->u.assign_device.machine_sbdf);
> +        ret = -ENOSYS;
> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
> +            break;
> +
> +        machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
> +
> +        ret = xsm_deassign_device(XSM_HOOK, d, machine_sbdf);
>          if ( ret )
>              break;
>  
> -        seg = domctl->u.assign_device.machine_sbdf >> 16;
> -        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
> -        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
> +        seg = machine_sbdf >> 16;
> +        bus = (machine_sbdf >> 8) & 0xff;
> +        devfn = machine_sbdf & 0xff;
>  
>          spin_lock(&pcidevs_lock);
>          ret = deassign_device(d, seg, bus, devfn);
> diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
> index b742b23..d905ab0 100644
> --- a/xen/include/public/domctl.h
> +++ b/xen/include/public/domctl.h
> @@ -475,12 +475,23 @@ typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t);
>  
>  
> -/* Assign PCI device to HVM guest. Sets up IOMMU structures. */
> +/* Assign a device to a guest. Sets up IOMMU structures. */
>  /* XEN_DOMCTL_assign_device */
>  /* XEN_DOMCTL_test_assign_device */
>  /* XEN_DOMCTL_deassign_device */
> +#define XEN_DOMCTL_DEV_PCI      0
> +#define XEN_DOMCTL_DEV_DT       1
>  struct xen_domctl_assign_device {
> -    uint32_t  machine_sbdf;   /* machine PCI ID of assigned device */
> +    uint32_t dev;   /* XEN_DOMCTL_DEV_* */
> +    union {
> +        struct {
> +            uint32_t machine_sbdf;   /* machine PCI ID of assigned device */
> +        } pci;
> +        struct {
> +            uint32_t size; /* Length of the path */
> +            XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */
> +        } dt;
> +    } u;
>  };
>  typedef struct xen_domctl_assign_device xen_domctl_assign_device_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t);
> diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
> index d03df14..d261277 100644
> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -119,6 +119,9 @@ int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev);
>  int iommu_dt_domain_init(struct domain *d);
>  int iommu_release_dt_devices(struct domain *d);
>  
> +int iommu_do_dt_domctl(struct xen_domctl *, struct domain *,
> +                       XEN_GUEST_HANDLE_PARAM(xen_domctl_t));
> +
>  #endif /* HAS_DEVICE_TREE */
>  
>  struct page_info;
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-20  9:34   ` Jan Beulich
  2015-01-20 14:37     ` Julien Grall
@ 2015-01-29 10:29     ` Stefano Stabellini
  2015-01-29 10:37       ` Jan Beulich
  2015-01-29 11:40       ` Julien Grall
  1 sibling, 2 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 10:29 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Wei Liu, ian.campbell, tim, Julien Grall, Ian Jackson,
	stefano.stabellini, xen-devel

On Tue, 20 Jan 2015, Jan Beulich wrote:
> >>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
> > --- a/xen/drivers/passthrough/iommu.c
> > +++ b/xen/drivers/passthrough/iommu.c
> > @@ -337,6 +337,13 @@ int iommu_do_domctl(
> >      ret = iommu_do_pci_domctl(domctl, d, u_domctl);
> >  #endif
> >  
> > +    if ( ret != -ENOSYS )
> > +        return ret;
> > +
> > +#ifdef HAS_DEVICE_TREE
> > +    ret = iommu_do_dt_domctl(domctl, d, u_domctl);
> > +#endif
> 
> Please move the (inverted) if() into the #ifdef block (but also see
> below regarding the specific error code used).
> 
> > @@ -1533,13 +1534,19 @@ int iommu_do_pci_domctl(
> >      break;
> >  
> >      case XEN_DOMCTL_test_assign_device:
> > -        ret = xsm_test_assign_device(XSM_HOOK, domctl->u.assign_device.machine_sbdf);
> > +        ret = -ENOSYS;
> > +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_PCI )
> > +            break;
> 
> I'm rather uncertain about the use of -ENOSYS here: The hypercall
> isn't unimplemented after all. Provided you use consistent error
> codes in the PCI and DT variants, there's no problem calling the
> other variant if that specific error code got returned from the first
> one - the second would then just return the same one again, even
> if the first one failed on something other than the device type
> check. As a result, I'd much prefer -ENODEV here.
> 
> > +
> > +        machine_sbdf = domctl->u.assign_device.u.pci.machine_sbdf;
> > +
> > +        ret = xsm_test_assign_device(XSM_HOOK, machine_sbdf);
> >          if ( ret )
> >              break;
> >  
> > -        seg = domctl->u.assign_device.machine_sbdf >> 16;
> > -        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
> > -        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
> > +        seg = machine_sbdf >> 16;
> > +        bus = (machine_sbdf >> 8) & 0xff;
> > +        devfn = machine_sbdf & 0xff;
> 
> If you fiddle with these, please make them use at least PCI_BUS()
> and PCI_DEVFN2() (we don't have a matching macro for retrieving
> the segment).

Maybe we should?



> > --- a/xen/include/public/domctl.h
> > +++ b/xen/include/public/domctl.h
> > @@ -475,12 +475,23 @@ typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t;
> >  DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t);
> >  
> >  
> > -/* Assign PCI device to HVM guest. Sets up IOMMU structures. */
> > +/* Assign a device to a guest. Sets up IOMMU structures. */
> >  /* XEN_DOMCTL_assign_device */
> >  /* XEN_DOMCTL_test_assign_device */
> >  /* XEN_DOMCTL_deassign_device */
> > +#define XEN_DOMCTL_DEV_PCI      0
> > +#define XEN_DOMCTL_DEV_DT       1
> >  struct xen_domctl_assign_device {
> > -    uint32_t  machine_sbdf;   /* machine PCI ID of assigned device */
> > +    uint32_t dev;   /* XEN_DOMCTL_DEV_* */
> > +    union {
> > +        struct {
> > +            uint32_t machine_sbdf;   /* machine PCI ID of assigned device */
> > +        } pci;
> > +        struct {
> > +            uint32_t size; /* Length of the path */
> > +            XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */
> > +        } dt;
> > +    } u;
> >  };
> 
> An incompatible change like this requires bumping
> XEN_DOMCTL_INTERFACE_VERSION when not already done during
> the current release cycle.
> 
> Jan
> 

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-29 10:29     ` Stefano Stabellini
@ 2015-01-29 10:37       ` Jan Beulich
  2015-01-29 11:40       ` Julien Grall
  1 sibling, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-01-29 10:37 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Julien Grall, Ian Jackson, xen-devel

>>> On 29.01.15 at 11:29, <stefano.stabellini@eu.citrix.com> wrote:
> On Tue, 20 Jan 2015, Jan Beulich wrote:
>> >>> On 13.01.15 at 15:25, <julien.grall@linaro.org> wrote:
>> > -        seg = domctl->u.assign_device.machine_sbdf >> 16;
>> > -        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
>> > -        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
>> > +        seg = machine_sbdf >> 16;
>> > +        bus = (machine_sbdf >> 8) & 0xff;
>> > +        devfn = machine_sbdf & 0xff;
>> 
>> If you fiddle with these, please make them use at least PCI_BUS()
>> and PCI_DEVFN2() (we don't have a matching macro for retrieving
>> the segment).
> 
> Maybe we should?

Maybe, but it would be of pretty limited use, as generally we don't
pass around SBDFs, but (segment, BDF) pairs, or (segment, bus,
devfn) triplets, or all four values separately.

Jan

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-01-13 14:25 ` [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM Julien Grall
@ 2015-01-29 11:03   ` Stefano Stabellini
  2015-01-29 12:02     ` Julien Grall
  2015-02-23 11:31     ` Ian Campbell
  2015-02-23 11:46   ` Ian Campbell
  2015-02-23 12:03   ` Ian Jackson
  2 siblings, 2 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 11:03 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On Tue, 13 Jan 2015, Julien Grall wrote:
> Let the user to pass additional nodes to the guest device tree. For this
> purpose, everything in the node /passthrough from the partial device tree will
> be copied into the guest device tree.
> 
> The node /aliases will be also copied to allow the user to define aliases
> which can be used by the guest kernel.
> 
> A simple partial device tree will look like:
> 
> /dts-v1/;
> 
> / {
>         #address-cells = <2>;
>         #size-cells = <2>;
> 
>         passthrough {
>             compatible = "simple-bus";
>             ranges;
>             #address-cells = <2>;
>             #size-cells = <2>;
> 
>             /* List of your nodes */
>         }
> };

It would be nice to have an example of this under tools/examples.


> Note that:
>     * The interrupt-parent proporties will be added by the toolstack in
>     the root node
>     * The properties compatible, ranges, #address-cells and #size-cells
>     in /passthrough are mandatory.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> 
> ---
>     Changes in v3:
>         - Patch added
> ---
>  docs/man/xl.cfg.pod.5       |   7 ++
>  tools/libxl/libxl_arm.c     | 253 ++++++++++++++++++++++++++++++++++++++++++++
>  tools/libxl/libxl_types.idl |   1 +
>  tools/libxl/xl_cmdimpl.c    |   1 +
>  4 files changed, 262 insertions(+)
> 
> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
> index e2f91fc..225b782 100644
> --- a/docs/man/xl.cfg.pod.5
> +++ b/docs/man/xl.cfg.pod.5
> @@ -398,6 +398,13 @@ not emulated.
>  Specify that this domain is a driver domain. This enables certain
>  features needed in order to run a driver domain.
>  
> +=item B<device_tree=PATH>
> +
> +Specify a partial device tree (compiled via the Device Tree Compiler).
> +Everything under the node "/passthrough" will be copied into the guest
> +device tree. For convenience, the node "/aliases" is also copied to allow
> +the user to defined aliases which can be used by the guest kernel.
> +
>  =back
>  
>  =head2 Devices
> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> index 53177eb..619458b 100644
> --- a/tools/libxl/libxl_arm.c
> +++ b/tools/libxl/libxl_arm.c
> @@ -540,6 +540,238 @@ out:
>      }
>  }
>  
> +static bool check_overrun(uint64_t a, uint64_t b, uint32_t max)
> +{
> +    return ((a + b) > UINT_MAX || (a + b) > max);
> +}
> +
> +/* Only FDT v17 is supported */
> +#define FDT_REQUIRED_VERSION    0x11
> +
> +static int check_partial_fdt(libxl__gc *gc, void *fdt, size_t size)
> +{
> +    int r;
> +
> +    if (size < FDT_V17_SIZE) {
> +        LOG(ERROR, "Partial FDT is too small");
> +        return ERROR_FAIL;
> +    }
> +
> +    if (fdt_magic(fdt) != FDT_MAGIC) {
> +        LOG(ERROR, "Partial FDT is not a valid Flat Device Tree");
> +        return ERROR_FAIL;
> +    }
> +
> +    if (fdt_version(fdt) != FDT_REQUIRED_VERSION) {
> +        LOG(ERROR, "Partial FDT version not supported. Required 0x%x got 0x%x",
> +            FDT_REQUIRED_VERSION, fdt_version(fdt));
> +        return ERROR_FAIL;
> +    }
> +
> +    r = fdt_check_header(fdt);
> +    if (r) {
> +        LOG(ERROR, "Failed to check the partial FDT (%d)", r);
> +        return ERROR_FAIL;
> +    }
> +
> +    /* Check if the *size and off* fields doesn't overrun the totalsize
> +     * of the partial FDT.
> +     */
> +    if (fdt_totalsize(fdt) > size) {
> +        LOG(ERROR, "Partial FDT totalsize is too big");
> +        return ERROR_FAIL;
> +    }
> +
> +    size = fdt_totalsize(fdt);
> +    if (fdt_off_dt_struct(fdt) > size ||
> +        fdt_off_dt_strings(fdt) > size ||
> +        check_overrun(fdt_off_dt_struct(fdt), fdt_size_dt_struct(fdt), size) ||
> +        check_overrun(fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt), size)) {
> +        LOG(ERROR, "Failed to validate the header of the partial FDT");
> +        return ERROR_FAIL;
> +    }
> +
> +    return 0;
> +}
> +
> +/*
> + * Check if a string stored the strings block section is correctly
> + * nul-terminated.
> + * off_dt_strings and size_dt_strings fields have been validity-check
> + * earlier, so it's safe to use them here.
> + */
> +static bool check_string(void *fdt, int nameoffset)
> +{
> +    const char *str = fdt_string(fdt, nameoffset);
> +
> +    for (; nameoffset < fdt_size_dt_strings(fdt); nameoffset++, str++) {
> +        if (*str == '\0')
> +            return true;
> +    }
> +
> +    return false;
> +}

strnlen?


> +static int copy_properties(libxl__gc *gc, void *fdt, void *pfdt,
> +                           int nodeoff)
> +{
> +    int propoff, nameoff, r;
> +    const struct fdt_property *prop;
> +
> +    for (propoff = fdt_first_property_offset(pfdt, nodeoff);
> +         propoff >= 0;
> +         propoff = fdt_next_property_offset(pfdt, propoff)) {
> +
> +        if (!(prop = fdt_get_property_by_offset(pfdt, propoff, NULL))) {
> +            return -FDT_ERR_INTERNAL;
> +        }
> +
> +        /*
> +         * Libfdt doesn't perform any check on the validity of a string
> +         * stored in the strings block section. As the property name is
> +         * stored there, check it.
> +         */
> +        nameoff = fdt32_to_cpu(prop->nameoff);
> +        if (!check_string(pfdt, nameoff)) {
> +            LOG(ERROR, "The strings block section of the partial FDT is malformed");
> +            return -FDT_ERR_BADSTRUCTURE;
> +        }
> +
> +        r = fdt_property(fdt, fdt_string(pfdt, nameoff),
> +                         prop->data, fdt32_to_cpu(prop->len));
> +        if (r) return r;
> +    }
> +
> +    /* FDT_ERR_NOTFOUND => There is no more properties for this node */
> +    return (propoff != -FDT_ERR_NOTFOUND)? propoff : 0;
> +}
> +
> +/*
> + * Based on fdt_first_subnode and fdt_next_subnode.
> + * We can't use the one helpers provided by libfdt because:
> + *      - It has been introduced in 2013 => Doesn't work on wheezy
> + *      - The prototypes exist but the functions are not exported. Don't
> + *      ask why...
> + *      - There is no version in the header (might be better to use
> + *      configure for this purpose?)
> + */
> +static int _fdt_first_subnode(const void *fdt, int offset)
> +{
> +    int depth = 0;
> +
> +    offset = fdt_next_node(fdt, offset, &depth);
> +    if (offset < 0 || depth != 1)
> +        return -FDT_ERR_NOTFOUND;
> +
> +    return offset;
> +}
> +
> +static int _fdt_next_subnode(const void *fdt, int offset)
> +{
> +    int depth = 1;
> +
> +    /*
> +     * With respect to the parent, the depth of the next subnode will be
> +     * the same as the last.
> +     */
> +    do {
> +        offset = fdt_next_node(fdt, offset, &depth);
> +        if (offset < 0 || depth < 1)
> +            return -FDT_ERR_NOTFOUND;
> +    } while (depth > 1);
> +
> +    return offset;
> +}
> +
> +/* Limit the maxixum depth of a node because of the recursion */
> +#define MAX_DEPTH   8
> +
> +/* Copy a node from the partial device tree to the guest device tree */
> +static int copy_node(libxl__gc *gc, void *fdt, void *pfdt,
> +                     int nodeoff, int depth)
> +{
> +    int r;
> +
> +    if (depth >= MAX_DEPTH) {
> +        LOG(ERROR, "Partial FDT contains a too depth node");
> +        return -FDT_ERR_INTERNAL;
> +    }
> +
> +    r = fdt_begin_node(fdt, fdt_get_name(pfdt, nodeoff, NULL));
> +    if (r) return r;
> +
> +    r = copy_properties(gc, fdt, pfdt, nodeoff);
> +    if (r) return r;
> +
> +    for (nodeoff = _fdt_first_subnode(pfdt, nodeoff);
> +         nodeoff >= 0;
> +         nodeoff = _fdt_next_subnode(pfdt, nodeoff)) {
> +        r = copy_node(gc, fdt, pfdt, nodeoff, depth + 1);
> +        if (r) return r;
> +    }
> +
> +    if (nodeoff != -FDT_ERR_NOTFOUND)
> +        return nodeoff;
> +
> +    r = fdt_end_node(fdt);
> +    if (r) return r;
> +
> +    return 0;
> +}
> +
> +static int copy_node_by_path(libxl__gc *gc, const char *path,
> +                             void *fdt, void *pfdt)
> +{
> +    int nodeoff, r;
> +    const char *name = strrchr(path, '/');
> +
> +    if (!name)
> +        return -FDT_ERR_INTERNAL;
> +
> +    name++;
> +
> +    /* The FDT function to look at node doesn't take into account the
> +     * unit (i.e anything after @) when search by name. Check if the
> +     * name exactly match.
> +     */
> +    nodeoff = fdt_path_offset(pfdt, path);
> +    if (nodeoff < 0)
> +        return nodeoff;
> +
> +    if (strcmp(fdt_get_name(pfdt, nodeoff, NULL), name))
> +        return -FDT_ERR_NOTFOUND;

Are we sure that the string returned by fdt_get_name is NULL terminated?


> +    r = copy_node(gc, fdt, pfdt, nodeoff, 0);
> +    if (r) return r;
> +
> +    return 0;
> +}
> +
> +/*
> + * The partial device tree is not copied entirely. Only the relevant bits are
> + * copied to the guest device tree:
> + *  - /passthrough node
> + *  - /aliases node
> + */
> +static int copy_partial_fdt(libxl__gc *gc, void *fdt, void *pfdt)
> +{
> +    int r;
> +
> +    r = copy_node_by_path(gc, "/passthrough", fdt, pfdt);
> +    if (r < 0) {
> +        LOG(ERROR, "Can't copy the node \"/passthrough\" from the partial FDT");
> +        return r;
> +    }
> +
> +    r = copy_node_by_path(gc, "/aliases", fdt, pfdt);
> +    if (r < 0 && r != -FDT_ERR_NOTFOUND) {
> +        LOG(ERROR, "Can't copy the node \"/aliases\" from the partial FDT");
> +        return r;
> +    }
> +
> +    return 0;
> +}
> +
>  #define FDT_MAX_SIZE (1<<20)
>  
>  int libxl__arch_domain_init_hw_description(libxl__gc *gc,
> @@ -548,8 +780,10 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>                                             struct xc_dom_image *dom)
>  {
>      void *fdt = NULL;
> +    void *pfdt = NULL;
>      int rc, res;
>      size_t fdt_size = 0;
> +    int pfdt_size = 0;
>  
>      const libxl_version_info *vers;
>      const struct arch_info *ainfo;
> @@ -569,6 +803,22 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>          vers->xen_version_major, vers->xen_version_minor);
>      LOG(DEBUG, " - vGIC version: %s\n", gicv_to_string(xc_config->gic_version));
>  
> +    if (info->device_tree) {
> +        LOG(DEBUG, " - Partial device tree provided: %s", info->device_tree);
> +
> +        rc = libxl_read_file_contents(CTX, info->device_tree,
> +                                      &pfdt, &pfdt_size);
> +        if (rc) {
> +            LOGEV(ERROR, rc, "failed to read the partial device file %s",
> +                  info->device_tree);
> +            return ERROR_FAIL;
> +        }
> +        libxl__ptr_add(gc, pfdt);
> +
> +        if (check_partial_fdt(gc, pfdt, pfdt_size))
> +            return ERROR_FAIL;
> +    }
> +
>  /*
>   * Call "call" handling FDT_ERR_*. Will either:
>   * - loop back to retry_resize
> @@ -635,6 +885,9 @@ next_resize:
>          FDT( make_timer_node(gc, fdt, ainfo) );
>          FDT( make_hypervisor_node(gc, fdt, vers) );
>  
> +        if (pfdt)
> +            FDT( copy_partial_fdt(gc, fdt, pfdt) );
> +
>          FDT( fdt_end_node(fdt) );
>  
>          FDT( fdt_finish(fdt) );
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index 1214d2e..5651110 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -399,6 +399,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
>      ("kernel",           string),
>      ("cmdline",          string),
>      ("ramdisk",          string),
> +    ("device_tree",      string),
>      ("u", KeyedUnion(None, libxl_domain_type, "type",
>                  [("hvm", Struct(None, [("firmware",         string),
>                                         ("bios",             libxl_bios_type),
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> index 0b02a6c..31e89e8 100644
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -1184,6 +1184,7 @@ static void parse_config_data(const char *config_source,
>  
>      xlu_cfg_replace_string (config, "kernel", &b_info->kernel, 0);
>      xlu_cfg_replace_string (config, "ramdisk", &b_info->ramdisk, 0);
> +    xlu_cfg_replace_string (config, "device_tree", &b_info->device_tree, 0);
>      b_info->cmdline = parse_cmdline(config);
>  
>      xlu_cfg_get_defbool(config, "driver_domain", &c_info->driver_domain, 0);
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-01-13 14:25 ` [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle Julien Grall
@ 2015-01-29 11:07   ` Stefano Stabellini
  2015-01-29 12:05     ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 11:07 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On Tue, 13 Jan 2015, Julien Grall wrote:
> The partial device tree may contains phandle. The Device Tree Compiler
> tends to allocate the phandle from 1.
> 
> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
> that the partial device tree will never contain a such ID.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> 

Shouldn't we at least check that the partial device tree doesn't contain
a conflicting phandle?


>     Changes in v3:
>         - Patch added
> ---
>  tools/libxl/libxl_arm.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> index 619458b..dc745fb 100644
> --- a/tools/libxl/libxl_arm.c
> +++ b/tools/libxl/libxl_arm.c
> @@ -78,10 +78,11 @@ static struct arch_info {
>      {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8" },
>  };
>  
> -enum {
> -    PHANDLE_NONE = 0,
> -    PHANDLE_GIC,
> -};
> +/*
> + * The device tree compiler (DTC) is allocating the phandle from 1 to
> + * onwards. Reserve a high value for the GIC phandle.
> + */
> +#define PHANDLE_GIC (65000)
>  
>  typedef uint32_t be32;
>  typedef be32 gic_interrupt[3];
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 23/24] libxl: Add support for non-PCI passthrough
  2015-01-13 14:25 ` [PATCH v3 23/24] libxl: Add support for non-PCI passthrough Julien Grall
@ 2015-01-29 11:12   ` Stefano Stabellini
  2015-01-29 12:08     ` Julien Grall
  2015-02-23 14:42   ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 11:12 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On Tue, 13 Jan 2015, Julien Grall wrote:
> On ARM, every non-PCI device are described in the device tree. Each of them
> can be found via a path.
> 
> This patch introduces a very basic support, only the IOMMU will be set
> up correctly. The user will have to:
>     - Describe the device in the partial device tree
>     - Map manually MMIO/IRQ
> 
> This is a first approach, that will allow to have a basic non-PCI
> passthrough support in Xen. This could be improved later.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> 
> ---
>     Changes in v3:
>         - Dynamic allocation has been dropped
>         - Rework the commit message in accordance with the previous
>         item
> 
>     Changes in v2:
>         - Get DT infos earlier
>         - Allocate/map IRQ in libxl__arch_domain_create rather than in
>         libxl__device_dt_add
>         - Use VIRQ rather than the PIRQ to construct the interrupts
>         properties of the device tree
>         - Correct cpumask in make_dtdev_node. We allow the interrupt to
>         be used on the 8 CPUs
>         - Fix LOGE when we map the MMIO region in the guest in
>         libxl__device_dt_add. The domain and the IRQ were inverted
>         - Calculate the number of SPIs to configure the VGIC
>         - xc_physdev_dtdev_* helpers has been renamed to xc_dtdev_*
>         - Rename libxl_device_dt to libxl_device_dtdev
> ---
>  tools/libxl/Makefile         |  2 +-
>  tools/libxl/libxl_create.c   | 10 ++++++++++
>  tools/libxl/libxl_dtdev.c    | 34 ++++++++++++++++++++++++++++++++++
>  tools/libxl/libxl_internal.h |  5 +++++
>  tools/libxl/libxl_types.idl  |  5 +++++
>  5 files changed, 55 insertions(+), 1 deletion(-)
>  create mode 100644 tools/libxl/libxl_dtdev.c
> 
> diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
> index b417372..98e1bab 100644
> --- a/tools/libxl/Makefile
> +++ b/tools/libxl/Makefile
> @@ -96,7 +96,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
>  			libxl_json.o libxl_aoutils.o libxl_numa.o \
>  			libxl_save_callout.o _libxl_save_msgs_callout.o \
>  			libxl_qmp.o libxl_event.o libxl_fork.o $(LIBXL_OBJS-y)
> -LIBXL_OBJS += libxl_genid.o
> +LIBXL_OBJS += libxl_genid.o libxl_dtdev.o
>  LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
>  
>  LIBXL_TESTS += timedereg
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index 029d2e2..b7ef528 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -1430,6 +1430,16 @@ static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev,

I think you should at least rename domcreate_attach_pci to something
more generic, like domcreate_attach_dev.


>          }
>      }
>  
> +    for (i = 0; i < d_config->num_dtdevs; i++) {
> +
> +        ret = libxl__device_dt_add(gc, domid, &d_config->dtdevs[i]);
> +        if (ret < 0) {
> +            LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
> +                       "libxl__device_dt_add failed: %d\n", ret);
> +            goto error_out;
> +        }
> +    }

You are allowed to call xc_* functions from here. The
libxl__device_dt_add wrapper doesn't add much value.


>      domcreate_console_available(egc, dcs);
>  
>      domcreate_complete(egc, dcs, 0);
> diff --git a/tools/libxl/libxl_dtdev.c b/tools/libxl/libxl_dtdev.c
> new file mode 100644
> index 0000000..5de57f0
> --- /dev/null
> +++ b/tools/libxl/libxl_dtdev.c
> @@ -0,0 +1,34 @@
> +/*
> + * Copyright (C) 2014      Linaro Limited.
> + * Author Julien Grall <julien.grall@linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published
> + * by the Free Software Foundation; version 2.1 only. with the special
> + * exception on linking described in file LICENSE.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU Lesser General Public License for more details.
> + */
> +
> +#include "libxl_osdeps.h" /* Must come before other headers */
> +
> +#include "libxl_internal.h"
> +
> +int libxl__device_dt_add(libxl__gc *gc, uint32_t domid,
> +                         const libxl_device_dtdev *dtdev)
> +{
> +    LOG(DEBUG, "Assign device \"%s\" to dom%u", dtdev->path, domid);
> +
> +    return xc_assign_dt_device(CTX->xch, domid, dtdev->path);
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index be5ed82..c00516a 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -1179,6 +1179,11 @@ _hidden int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
>                                        libxl_device_pci *pcidev, int num);
>  _hidden int libxl__device_pci_destroy_all(libxl__gc *gc, uint32_t domid);
>  
> +/* from libxl_dtdev */
> +
> +_hidden int libxl__device_dt_add(libxl__gc *gc, uint32_t domid,
> +                                 const libxl_device_dtdev *dtdev);
> +
>  /*----- xswait: wait for a xenstore node to be suitable -----*/
>  
>  typedef struct libxl__xswait_state libxl__xswait_state;
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index 5651110..c10fd2f 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -522,6 +522,10 @@ libxl_device_pci = Struct("device_pci", [
>      ("seize", bool),
>      ])
>  
> +libxl_device_dtdev = Struct("device_dtdev", [
> +    ("path", string),
> +    ])
> +
>  libxl_device_vtpm = Struct("device_vtpm", [
>      ("backend_domid",    libxl_domid),
>      ("backend_domname",  string),
> @@ -548,6 +552,7 @@ libxl_domain_config = Struct("domain_config", [
>      ("disks", Array(libxl_device_disk, "num_disks")),
>      ("nics", Array(libxl_device_nic, "num_nics")),
>      ("pcidevs", Array(libxl_device_pci, "num_pcidevs")),
> +    ("dtdevs", Array(libxl_device_dtdev, "num_dtdevs")),
>      ("vfbs", Array(libxl_device_vfb, "num_vfbs")),
>      ("vkbs", Array(libxl_device_vkb, "num_vkbs")),
>      ("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 24/24] xl: Add new option dtdev
  2015-01-13 14:25 ` [PATCH v3 24/24] xl: Add new option dtdev Julien Grall
@ 2015-01-29 11:18   ` Stefano Stabellini
  2015-01-29 12:09     ` Julien Grall
  2015-02-23 14:45   ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 11:18 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On Tue, 13 Jan 2015, Julien Grall wrote:
> The option "dtdev" will be used to passthrough a non-PCI device described
> in the device tree to a guest.

Actually didn't you add the dtdev option to the idl in the previous
patch?  You should probably move it to this one.


> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> 
> ---
>     Changes in v2:
>         - libxl_device_dt has been rename to libxl_device_dtdev
>         - use xrealloc instead of realloc
> ---
>  docs/man/xl.cfg.pod.5    |  5 +++++
>  tools/libxl/xl_cmdimpl.c | 21 ++++++++++++++++++++-
>  2 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
> index 225b782..cfd3d5f 100644
> --- a/docs/man/xl.cfg.pod.5
> +++ b/docs/man/xl.cfg.pod.5
> @@ -721,6 +721,11 @@ More information about Xen gfx_passthru feature is available
>  on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
>  wiki page.
>  
> +=item B<dtdev=[ "DTDEV_PATH", "DTDEV_PATH", ... ]>
> +
> +Specifies the host device node to passthrough to this guest. Each DTDEV_PATH
> +is the absolute path in the device tree.
> +
>  =item B<ioports=[ "IOPORT_RANGE", "IOPORT_RANGE", ... ]>
>  
>  Allow guest to access specific legacy I/O ports. Each B<IOPORT_RANGE>
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> index 31e89e8..80c9df6 100644
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -986,7 +986,7 @@ static void parse_config_data(const char *config_source,
>      long l;
>      XLU_Config *config;
>      XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms;
> -    XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian;
> +    XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs;
>      int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian;
>      int pci_power_mgmt = 0;
>      int pci_msitranslate = 0;
> @@ -1746,6 +1746,25 @@ skip_vfb:
>              libxl_defbool_set(&b_info->u.pv.e820_host, true);
>      }
>  
> +    if (!xlu_cfg_get_list (config, "dtdev", &dtdevs, 0, 0)) {
> +        d_config->num_dtdevs = 0;
> +        d_config->dtdevs = NULL;
> +        for (i = 0; (buf = xlu_cfg_get_listitem(dtdevs, i)) != NULL; i++) {
> +            libxl_device_dtdev *dtdev;
> +
> +            d_config->dtdevs = (libxl_device_dtdev *) xrealloc(d_config->dtdevs, sizeof (libxl_device_dtdev) * (d_config->num_dtdevs + 1));
> +            dtdev = d_config->dtdevs + d_config->num_dtdevs;
> +            libxl_device_dtdev_init(dtdev);
> +
> +            dtdev->path = strdup(buf);
> +            if (dtdev->path == NULL) {
> +                fprintf(stderr, "unable to duplicate string for dtdevs\n");
> +                exit(-1);
> +            }
> +            d_config->num_dtdevs++;
> +        }
> +    }
> +
>      switch (xlu_cfg_get_list(config, "cpuid", &cpuids, 0, 1)) {
>      case 0:
>          {
> -- 
> 2.1.4
> 

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-29 10:29     ` Stefano Stabellini
  2015-01-29 10:37       ` Jan Beulich
@ 2015-01-29 11:40       ` Julien Grall
  1 sibling, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-29 11:40 UTC (permalink / raw)
  To: Stefano Stabellini, Jan Beulich
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On 29/01/15 10:29, Stefano Stabellini wrote:
>>> -        seg = domctl->u.assign_device.machine_sbdf >> 16;
>>> -        bus = (domctl->u.assign_device.machine_sbdf >> 8) & 0xff;
>>> -        devfn = domctl->u.assign_device.machine_sbdf & 0xff;
>>> +        seg = machine_sbdf >> 16;
>>> +        bus = (machine_sbdf >> 8) & 0xff;
>>> +        devfn = machine_sbdf & 0xff;
>>
>> If you fiddle with these, please make them use at least PCI_BUS()
>> and PCI_DEVFN2() (we don't have a matching macro for retrieving
>> the segment).
> 
> Maybe we should?

I could add one.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 06/24] xen/arm: Map disabled device in DOM0
  2015-01-28 16:23     ` Julien Grall
@ 2015-01-29 11:41       ` Stefano Stabellini
  0 siblings, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 11:41 UTC (permalink / raw)
  To: Julien Grall
  Cc: ian.campbell, Stefano Stabellini, tim, stefano.stabellini,
	xen-devel, Andrii Tseglytskyi

On Wed, 28 Jan 2015, Julien Grall wrote:
> Hi Stefano,
> 
> On 28/01/15 16:18, Stefano Stabellini wrote:
> > On Tue, 13 Jan 2015, Julien Grall wrote:
> >> The check to avoid mapping disabled device in DOM0 was added in the anticipation
> >> of the device passthrough. But, a brand new property will be added later to mark
> >> device which will passthrough. At the same time, remove the memory type
> >> check because those nodes has been blacklisted.
> > 
> > Sorry, I don't understand the explanation on why you removed the check
> > on dt_device_type_is_equal(node, "memory") too.
> 
> The memory nodes has been skipped earlier via the skip_matches variable.
> 
> How about "Also, remove the memory type check as we already skipped them
> earlier in the function"?

"earlier in the function via skip_matches."

With that:

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-01-28 16:53     ` Julien Grall
@ 2015-01-29 11:43       ` Stefano Stabellini
  0 siblings, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 11:43 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, tim, ian.campbell, stefano.stabellini, Stefano Stabellini

On Wed, 28 Jan 2015, Julien Grall wrote:
> On 28/01/15 16:36, Stefano Stabellini wrote:
> > On Tue, 13 Jan 2015, Julien Grall wrote:
> >> When a device is marked for passthrough (via the new property "xen,passthrough"),
> >> dom0 must not access to the device (i.e not loading a driver), but should
> >> be able to manage the MMIO/interrupt of the passthrough device.
> >>
> >> The latter part will allow the toolstack to map MMIO/IRQ when a device
> >> is pass through to a guest.
> >>
> >> The property "xen,passthrough" will be translated as 'status="disabled"'
> >> in the device tree to avoid DOM0 using the device. We assume that DOM0 is
> >> able to cope with this property (already the case for Linux).
> >>
> >> Rework the function map_device (renamed into handle_device) to:
> >>
> >> * For a given device node:
> >>     - Give permission to manage IRQ/MMIO for this device
> >>     - Retrieve the IRQ configuration (i.e edge/level) from the device
> >>     tree
> >> * When the device is not marked for guest passthrough:
> >>     - Assign the device to the guest if it's protected by an IOMMU
> >>     - Map the IRQs and MMIOs regions to the guest
> >>
> >> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >>
> >> ---
> >>     Changes in v3:
> >>         - This patch was formely "xen/arm: Follow-up to allow DOM0
> >>         manage IRQ and MMIO". It has been split in 2 parts [1].
> >>         - Update commit title and improve message
> >>         - Remove spurious change
> >>
> >> [1] https://patches.linaro.org/34669/
> >> ---
> >>  docs/misc/arm/device-tree/passthrough.txt |   7 ++
> >>  xen/arch/arm/device.c                     |   2 +-
> >>  xen/arch/arm/domain_build.c               | 102 ++++++++++++++++++++++--------
> >>  xen/common/device_tree.c                  |   6 ++
> >>  xen/include/xen/device_tree.h             |  11 ++++
> >>  5 files changed, 100 insertions(+), 28 deletions(-)
> >>  create mode 100644 docs/misc/arm/device-tree/passthrough.txt
> >>
> >> diff --git a/docs/misc/arm/device-tree/passthrough.txt b/docs/misc/arm/device-tree/passthrough.txt
> >> new file mode 100644
> >> index 0000000..04645b3
> >> --- /dev/null
> >> +++ b/docs/misc/arm/device-tree/passthrough.txt
> >> @@ -0,0 +1,7 @@
> >> +Device passthrough
> >> +===================
> >> +
> >> +Any device that will be passthrough to a guest should have a property
> >> +"xen,passthrough" in their device tree node.
> >> +
> >> +The device won't be exposed to DOM0 and therefore no driver will be loaded.
> >> diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
> >> index 1993929..1a01793 100644
> >> --- a/xen/arch/arm/device.c
> >> +++ b/xen/arch/arm/device.c
> >> @@ -30,7 +30,7 @@ int __init device_init(struct dt_device_node *dev, enum device_match type,
> >>  
> >>      ASSERT(dev != NULL);
> >>  
> >> -    if ( !dt_device_is_available(dev) )
> >> +    if ( !dt_device_is_available(dev) || dt_device_for_passthrough(dev) )
> >>          return  -ENODEV;
> >>  
> >>      for ( desc = _sdevice; desc != _edevice; desc++ )
> >> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> >> index f68755f..b48b5d0 100644
> >> --- a/xen/arch/arm/domain_build.c
> >> +++ b/xen/arch/arm/domain_build.c
> >> @@ -402,7 +402,7 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
> >>                              const struct dt_device_node *node)
> >>  {
> >>      const char *bootargs = NULL;
> >> -    const struct dt_property *prop;
> >> +    const struct dt_property *prop, *status = NULL;
> >>      int res = 0;
> >>      int had_dom0_bootargs = 0;
> >>  
> >> @@ -457,6 +457,17 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
> >>              }
> >>          }
> >>  
> >> +        /* Don't expose the property "xen,passthrough" to the guest */
> >> +        if ( dt_property_name_is_equal(prop, "xen,passthrough") )
> >> +            continue;
> >> +
> >> +        /* Remember and skip the status property as Xen may modify it later */
> >> +        if ( dt_property_name_is_equal(prop, "status") )
> >> +        {
> >> +            status = prop;
> >> +            continue;
> >> +        }
> >> +
> >>          res = fdt_property(kinfo->fdt, prop->name, prop_data, prop_len);
> >>  
> >>          xfree(new_data);
> >> @@ -465,6 +476,19 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
> >>              return res;
> >>      }
> >>  
> >> +    /*
> >> +     * Override the property "status" to disable the device when it's
> >> +     * marked for passthrough.
> >> +     */
> >> +    if ( dt_device_for_passthrough(node) )
> >> +        res = fdt_property_string(kinfo->fdt, "status", "disabled");
> >> +    else if ( status )
> >> +        res = fdt_property(kinfo->fdt, "status", status->value,
> >> +                           status->length);
> > 
> > Why is the "else" needed? Wouldn't the status property for
> > non-passtrough devices already be covered by the
> > dt_for_each_property_node loop above?
> 
> 
> Because the property "status" is skipped earlier in any case.

I see that now.

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-29 10:29   ` Stefano Stabellini
@ 2015-01-29 11:45     ` Julien Grall
  2015-01-29 12:09       ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-29 11:45 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	Jan Beulich, xen-devel

Hi Stefano,

On 29/01/15 10:29, Stefano Stabellini wrote:
>> +static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev)
>> +{
>> +    bool_t assigned = 0;
>> +
>> +    if ( !dt_device_is_protected(dev) )
>> +        return 1;
> 
> Why return true here?

Because any device not protected cannot be assigned to another guest.

This could be used by the toolstack to know whether the device is
assigned or not. IHMO, returning 0 would be a false negative.

Would a comment in the code suitable?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-01-28 16:56     ` Julien Grall
  2015-01-28 17:00       ` Julien Grall
@ 2015-01-29 11:50       ` Stefano Stabellini
  1 sibling, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 11:50 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, tim, ian.campbell, stefano.stabellini, Stefano Stabellini

On Wed, 28 Jan 2015, Julien Grall wrote:
> On 28/01/15 16:47, Stefano Stabellini wrote:
> >> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> >> index 25ecf1d..830832c 100644
> >> --- a/xen/arch/arm/irq.c
> >> +++ b/xen/arch/arm/irq.c
> >> @@ -31,6 +31,13 @@
> >>  static unsigned int local_irqs_type[NR_LOCAL_IRQS];
> >>  static DEFINE_SPINLOCK(local_irqs_type_lock);
> >>  
> >> +/* Describe an IRQ assigned to a guest */
> >> +struct irq_guest
> >> +{
> >> +    struct domain *d;
> >> +    unsigned int virq;
> >> +};
> > 
> > I would prefer if you didn't use dev_id for this and just added a virq
> > field to irqaction.
> 
> We already talked about it on v2. You were fine with the idea and acked
> the patch. Although, I haven't add your acked-by here because of the new
> changes in the code.

It is good to be consistent :-D


> Here my answer to the same question on v2:
> 
> "I though about it. If we add another field in arch_irq_desc, we will
> likely use more memory than xmalloc. This is because most of the
> platform doesn't use 1024 interrupts but about 256 interrupts.
> 
> As the new field will be a pointer (on ARM64, 8 bytes), that would make
> Xen use statically about 8K more.
> 
> We could allocate irq_desc dynamically during Xen boot."

I remember now. Go ahead and add back my ack.

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

* Re: [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ
  2015-01-28 18:05     ` Julien Grall
@ 2015-01-29 11:52       ` Stefano Stabellini
  0 siblings, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 11:52 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, tim, ian.campbell, stefano.stabellini, Stefano Stabellini

On Wed, 28 Jan 2015, Julien Grall wrote:
> On 28/01/15 17:55, Stefano Stabellini wrote:
> >> ---
> >>  xen/arch/arm/irq.c        | 58 +++++++++++++++++++++++++++++++++++++++++++----
> >>  xen/include/asm-arm/irq.h |  2 ++
> >>  2 files changed, 56 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> >> index 830832c..af408ac 100644
> >> --- a/xen/arch/arm/irq.c
> >> +++ b/xen/arch/arm/irq.c
> >> @@ -379,6 +379,15 @@ err:
> >>      return rc;
> >>  }
> >>  
> >> +bool_t is_assignable_irq(unsigned int irq)
> > 
> > static inline?
> 
> It's exported (will be used later) and not possible to inline in irq.h
> because of interdependency between irq.h and gic.h
> 
> [..]
> 
> >> @@ -418,13 +460,21 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
> >>          struct domain *ad = irq_get_domain(desc);
> >>  
> >>          if ( test_bit(_IRQ_GUEST, &desc->status) && d == ad )
> >> +        {
> >> +            if ( irq_get_guest_info(desc)->virq != virq )
> >> +            {
> >> +                dprintk(XENLOG_G_ERR, "d%u: IRQ %u is already assigned to vIRQ %u\n",
> >> +                        d->domain_id, irq, irq_get_guest_info(desc)->virq);
> >> +                retval = -EPERM;
> > 
> > I don't think that EPERM is the right error for this. Maybe EBUSY?
> 
> Right.
> 
> > 
> >> +            }
> > 
> > Should we return error for this too? Maybe EEXIST?
> 
> No, this is a valid use case especially for DOM0.  The device tree may
> expose twice the same IRQ.

OK

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-01-28 18:58     ` Julien Grall
@ 2015-01-29 12:01       ` Stefano Stabellini
  2015-01-29 12:14         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 12:01 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, Jan Beulich, xen-devel

On Wed, 28 Jan 2015, Julien Grall wrote:
> Hi Stefano,
> 
> On 28/01/15 18:26, Stefano Stabellini wrote:
> > On Tue, 13 Jan 2015, Julien Grall wrote:
> >> Each domain may have a different number of IRQs depending on the devices
> >> assigned to it.
> >>
> >> Rather re-using the number of IRQs used by the hardwared GIC, let the
> >> toolstack specify the number of SPIs when the domain is created. This
> >> will avoid to waste memory.
> >>
> >> To calculate the number of SPIs, we assume that any IRQ given via the option
> >> "irqs=" in xl is mapped 1:1 to the guest.
> >>
> >> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> >> Cc: Jan Beulich <jbeulich@suse.com>
> >> Cc: Wei Liu <wei.liu2@citrix.com>
> >>
> >> ---
> >>     Changes in v3:
> >>         - Fix typoes
> >>         - A separate has been created to extend the DOMCTL create domain
> >>
> >>     Changes in v2:
> >>         - Patch added
> >> ---
> >>  tools/libxc/xc_domain.c       |  1 +
> >>  tools/libxl/libxl_arm.c       | 19 +++++++++++++++++++
> >>  xen/arch/arm/domain.c         |  7 ++++++-
> >>  xen/arch/arm/setup.c          |  1 +
> >>  xen/arch/arm/vgic.c           | 10 +++++-----
> >>  xen/include/asm-arm/domain.h  |  2 ++
> >>  xen/include/asm-arm/setup.h   |  1 +
> >>  xen/include/asm-arm/vgic.h    |  2 +-
> >>  xen/include/public/arch-arm.h |  2 ++
> >>  9 files changed, 38 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
> >> index eebc121..eb066cf 100644
> >> --- a/tools/libxc/xc_domain.c
> >> +++ b/tools/libxc/xc_domain.c
> >> @@ -67,6 +67,7 @@ int xc_domain_create(xc_interface *xch,
> >>      /* No arch-specific configuration for now */
> >>  #elif defined (__arm__) || defined(__aarch64__)
> >>      config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
> >> +    config.nr_spis = 0;
> >>  #else
> >>      errno = ENOSYS;
> >>      return -1;
> >> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> >> index cddce6e..53177eb 100644
> >> --- a/tools/libxl/libxl_arm.c
> >> +++ b/tools/libxl/libxl_arm.c
> >> @@ -39,6 +39,25 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
> >>                                        libxl_domain_config *d_config,
> >>                                        xc_domain_configuration_t *xc_config)
> >>  {
> >> +    uint32_t nr_spis = 0;
> >> +    unsigned int i;
> >> +
> >> +    for (i = 0; i < d_config->b_info.num_irqs; i++) {
> >> +        int irq = d_config->b_info.irqs[i];
> > 
> > unsigned int
> 
> I will use uint32_t.
> 
> >> +        int spi = irq - 32;
> 
> Same here.
> 
> > 
> >> +        if (irq < 32)
> >> +            continue;
> >> +
> >> +        if (nr_spis <= spi)
> >> +            nr_spis = spi + 1;
> > 
> > overflow check?
> 
> If I use unsigned int, the overflow will go back to 0. While it won't
> affect the code, the domain creation will fail later (unable to assign
> the SPI).
> 
> So is it useful to add a check here?

The maximum number of allowed spis has to be lower than UINT_MAX, right?

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-01-29 11:03   ` Stefano Stabellini
@ 2015-01-29 12:02     ` Julien Grall
  2015-01-29 12:26       ` Stefano Stabellini
  2015-02-23 11:31     ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-29 12:02 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On 29/01/15 11:03, Stefano Stabellini wrote:
> On Tue, 13 Jan 2015, Julien Grall wrote:
>> Let the user to pass additional nodes to the guest device tree. For this
>> purpose, everything in the node /passthrough from the partial device tree will
>> be copied into the guest device tree.
>>
>> The node /aliases will be also copied to allow the user to define aliases
>> which can be used by the guest kernel.
>>
>> A simple partial device tree will look like:
>>
>> /dts-v1/;
>>
>> / {
>>         #address-cells = <2>;
>>         #size-cells = <2>;
>>
>>         passthrough {
>>             compatible = "simple-bus";
>>             ranges;
>>             #address-cells = <2>;
>>             #size-cells = <2>;
>>
>>             /* List of your nodes */
>>         }
>> };
> 
> It would be nice to have an example of this under tools/examples.

Ok. I will add one.

[..]

>> +/*
>> + * Check if a string stored the strings block section is correctly
>> + * nul-terminated.
>> + * off_dt_strings and size_dt_strings fields have been validity-check
>> + * earlier, so it's safe to use them here.
>> + */
>> +static bool check_string(void *fdt, int nameoffset)
>> +{
>> +    const char *str = fdt_string(fdt, nameoffset);
>> +
>> +    for (; nameoffset < fdt_size_dt_strings(fdt); nameoffset++, str++) {
>> +        if (*str == '\0')
>> +            return true;
>> +    }
>> +
>> +    return false;
>> +}
> 
> strnlen?

I could but it would not tell us directly if the string is NULL
terminated or not.

What about memchr?


[..]

>> +static int copy_node_by_path(libxl__gc *gc, const char *path,
>> +                             void *fdt, void *pfdt)
>> +{
>> +    int nodeoff, r;
>> +    const char *name = strrchr(path, '/');
>> +
>> +    if (!name)
>> +        return -FDT_ERR_INTERNAL;
>> +
>> +    name++;
>> +
>> +    /* The FDT function to look at node doesn't take into account the
>> +     * unit (i.e anything after @) when search by name. Check if the
>> +     * name exactly match.
>> +     */
>> +    nodeoff = fdt_path_offset(pfdt, path);
>> +    if (nodeoff < 0)
>> +        return nodeoff;
>> +
>> +    if (strcmp(fdt_get_name(pfdt, nodeoff, NULL), name))
>> +        return -FDT_ERR_NOTFOUND;
> 
> Are we sure that the string returned by fdt_get_name is NULL terminated?

Yes, libfdt does some sanity check on it (see fdt_next_tag case
FDT_BEGIN_NODE).

I tried to fix all the possible security flaw in libfdt (and there is
quite a lot). If we don't trust the rest of libfdt, then we have to
import our own and fix it.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-01-29 11:07   ` Stefano Stabellini
@ 2015-01-29 12:05     ` Julien Grall
  2015-01-29 12:28       ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-29 12:05 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On 29/01/15 11:07, Stefano Stabellini wrote:
> On Tue, 13 Jan 2015, Julien Grall wrote:
>> The partial device tree may contains phandle. The Device Tree Compiler
>> tends to allocate the phandle from 1.
>>
>> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
>> that the partial device tree will never contain a such ID.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>>
> 
> Shouldn't we at least check that the partial device tree doesn't contain
> a conflicting phandle?

I don't think so. This will unlikely happen, and if it happens the guest
will crash with an obvious error.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 23/24] libxl: Add support for non-PCI passthrough
  2015-01-29 11:12   ` Stefano Stabellini
@ 2015-01-29 12:08     ` Julien Grall
  2015-01-29 12:31       ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-29 12:08 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

Hi Stefano,

On 29/01/15 11:12, Stefano Stabellini wrote:
>> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
>> index 029d2e2..b7ef528 100644
>> --- a/tools/libxl/libxl_create.c
>> +++ b/tools/libxl/libxl_create.c
>> @@ -1430,6 +1430,16 @@ static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev,
> 
> I think you should at least rename domcreate_attach_pci to something
> more generic, like domcreate_attach_dev.

Actually I was planning to add a domcreate_attach_dtdev but I forgot
about it.

What the best approach for this?


> 
>>          }
>>      }
>>  
>> +    for (i = 0; i < d_config->num_dtdevs; i++) {
>> +
>> +        ret = libxl__device_dt_add(gc, domid, &d_config->dtdevs[i]);
>> +        if (ret < 0) {
>> +            LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
>> +                       "libxl__device_dt_add failed: %d\n", ret);
>> +            goto error_out;
>> +        }
>> +    }
> 
> You are allowed to call xc_* functions from here. The
> libxl__device_dt_add wrapper doesn't add much value.

I would like to keep the wrapper. It's in sync with the PCI solution and
it will avoid refactoring later for add new code.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-29 11:45     ` Julien Grall
@ 2015-01-29 12:09       ` Stefano Stabellini
  2015-01-29 13:09         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 12:09 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, Jan Beulich, xen-devel

On Thu, 29 Jan 2015, Julien Grall wrote:
> Hi Stefano,
> 
> On 29/01/15 10:29, Stefano Stabellini wrote:
> >> +static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev)
> >> +{
> >> +    bool_t assigned = 0;
> >> +
> >> +    if ( !dt_device_is_protected(dev) )
> >> +        return 1;
> > 
> > Why return true here?
> 
> Because any device not protected cannot be assigned to another guest.
> This could be used by the toolstack to know whether the device is
> assigned or not.

I understand that much.


> IHMO, returning 0 would be a false negative.

Why? Returning 0 means that the device is not assigned, that would be
correct. From this statement I think that actually you are thinking as
if this function actually returned whether a given device is assignable.

In that case you should rename the function to

iommu_dt_device_is_assignable


> Would a comment in the code suitable?

I think you should rename the function or be consistent with its name.

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

* Re: [PATCH v3 24/24] xl: Add new option dtdev
  2015-01-29 11:18   ` Stefano Stabellini
@ 2015-01-29 12:09     ` Julien Grall
  2015-01-29 12:32       ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-29 12:09 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

Hi Stefano,

On 29/01/15 11:18, Stefano Stabellini wrote:
> On Tue, 13 Jan 2015, Julien Grall wrote:
>> The option "dtdev" will be used to passthrough a non-PCI device described
>> in the device tree to a guest.
> 
> Actually didn't you add the dtdev option to the idl in the previous
> patch?  You should probably move it to this one.

The IDL is part of libxl, and the change is required by the previous patch.

This patch is only adding the option in xl.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-01-29 12:01       ` Stefano Stabellini
@ 2015-01-29 12:14         ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-29 12:14 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	Jan Beulich, xen-devel

On 29/01/15 12:01, Stefano Stabellini wrote:
> On Wed, 28 Jan 2015, Julien Grall wrote:
>> Hi Stefano,
>>
>> On 28/01/15 18:26, Stefano Stabellini wrote:
>>> On Tue, 13 Jan 2015, Julien Grall wrote:
>>>> Each domain may have a different number of IRQs depending on the devices
>>>> assigned to it.
>>>>
>>>> Rather re-using the number of IRQs used by the hardwared GIC, let the
>>>> toolstack specify the number of SPIs when the domain is created. This
>>>> will avoid to waste memory.
>>>>
>>>> To calculate the number of SPIs, we assume that any IRQ given via the option
>>>> "irqs=" in xl is mapped 1:1 to the guest.
>>>>
>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>>>
>>>> ---
>>>>     Changes in v3:
>>>>         - Fix typoes
>>>>         - A separate has been created to extend the DOMCTL create domain
>>>>
>>>>     Changes in v2:
>>>>         - Patch added
>>>> ---
>>>>  tools/libxc/xc_domain.c       |  1 +
>>>>  tools/libxl/libxl_arm.c       | 19 +++++++++++++++++++
>>>>  xen/arch/arm/domain.c         |  7 ++++++-
>>>>  xen/arch/arm/setup.c          |  1 +
>>>>  xen/arch/arm/vgic.c           | 10 +++++-----
>>>>  xen/include/asm-arm/domain.h  |  2 ++
>>>>  xen/include/asm-arm/setup.h   |  1 +
>>>>  xen/include/asm-arm/vgic.h    |  2 +-
>>>>  xen/include/public/arch-arm.h |  2 ++
>>>>  9 files changed, 38 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
>>>> index eebc121..eb066cf 100644
>>>> --- a/tools/libxc/xc_domain.c
>>>> +++ b/tools/libxc/xc_domain.c
>>>> @@ -67,6 +67,7 @@ int xc_domain_create(xc_interface *xch,
>>>>      /* No arch-specific configuration for now */
>>>>  #elif defined (__arm__) || defined(__aarch64__)
>>>>      config.gic_version = XEN_DOMCTL_CONFIG_GIC_DEFAULT;
>>>> +    config.nr_spis = 0;
>>>>  #else
>>>>      errno = ENOSYS;
>>>>      return -1;
>>>> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
>>>> index cddce6e..53177eb 100644
>>>> --- a/tools/libxl/libxl_arm.c
>>>> +++ b/tools/libxl/libxl_arm.c
>>>> @@ -39,6 +39,25 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
>>>>                                        libxl_domain_config *d_config,
>>>>                                        xc_domain_configuration_t *xc_config)
>>>>  {
>>>> +    uint32_t nr_spis = 0;
>>>> +    unsigned int i;
>>>> +
>>>> +    for (i = 0; i < d_config->b_info.num_irqs; i++) {
>>>> +        int irq = d_config->b_info.irqs[i];
>>>
>>> unsigned int
>>
>> I will use uint32_t.
>>
>>>> +        int spi = irq - 32;
>>
>> Same here.
>>
>>>
>>>> +        if (irq < 32)
>>>> +            continue;
>>>> +
>>>> +        if (nr_spis <= spi)
>>>> +            nr_spis = spi + 1;
>>>
>>> overflow check?
>>
>> If I use unsigned int, the overflow will go back to 0. While it won't
>> affect the code, the domain creation will fail later (unable to assign
>> the SPI).
>>
>> So is it useful to add a check here?
> 
> The maximum number of allowed spis has to be lower than UINT_MAX, right?

UINT_MAX + 1 would give 0. So it's still < UINT_MAX. When the toolstack
will try to assign the IRQ. The hypervisor will see the SPI is too high
for the vGIC. So it will reject.

Anyway, technically it's even 1024. I forgot to add this check in the
vgic code. I will do it in the next version.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-01-28 19:04     ` Julien Grall
@ 2015-01-29 12:17       ` Stefano Stabellini
  2015-01-29 12:26         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 12:17 UTC (permalink / raw)
  To: Julien Grall
  Cc: ian.campbell, Stefano Stabellini, tim, stefano.stabellini,
	Jan Beulich, xen-devel

On Wed, 28 Jan 2015, Julien Grall wrote:
> Hi Stefano,
> 
> On 28/01/15 18:52, Stefano Stabellini wrote:
> > On Tue, 13 Jan 2015, Julien Grall wrote:
> >> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
> >> assign/deassign a physical IRQ to the guest (via the config options "irqs"
> >> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
> >> channel). As ARM doesn't have a such concept, we could reuse it to bound
> >> a physical IRQ to a virtual IRQ.
> >>
> >> For now, we allow only SPIs to be mapped to the guest.
> >> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
> >>
> >> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >> Cc: Jan Beulich <jbeulich@suse.com>
> >>
> >> ---
> >>     I'm not sure it's the best solution to reuse hypercalls for a
> >>     different purpose. If x86 plan to have a such concept (i.e binding a
> >>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
> >>     Any thoughs?
> > 
> > I think it is OK, as long as we write down very clearly what we are
> > doing.
> > 
> > 
> >>     TODO: This patch is lacking of support of vIRQ != IRQ. I plan to
> >>     handle it correctly on the next version.
> > 
> > Why do you say that? From the code in this patch it looks like it
> > supports vIRQ != IRQ already.
> 
> Because PHYSDEV_map_pirq is taking a vIRQ number in parameter. This vIRQ
> is only valid for the domain which issue the hypercall.

That's not very useful. I think that the vIRQ passed to PHYSDEV_map_pirq
should be a vIRQ in the destination domain, not the source domain.

In fact on x86 the pirq parameter to PHYSDEV_map_pirq is interpreted as
pirq in the destination domain too.


> In our use case, it's DOM0. DOM0 may not have all the time vIRQ == IRQ.
> 
> Futhermore, on PHYSDEV_unmap_pirq I assume the DOM0 virq == guest virq.

That's bad.


> > 
> >>     Changes in v3:
> >>         - Functions to allocate/release/reserved a VIRQ has been moved
> >>         in a separate patch
> > 
> > That might be a good idea, but then you need to move that patch before
> > this one, otherwise it won't compile. As is it would break the build.
> 
> This patch belongs to a separate patch series. FIY, on the cover letter
> I explicitly wrote the dependency in other to apply this series.
 
OK

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-01-29 12:02     ` Julien Grall
@ 2015-01-29 12:26       ` Stefano Stabellini
  0 siblings, 0 replies; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 12:26 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, xen-devel

On Thu, 29 Jan 2015, Julien Grall wrote:
> On 29/01/15 11:03, Stefano Stabellini wrote:
> > On Tue, 13 Jan 2015, Julien Grall wrote:
> >> Let the user to pass additional nodes to the guest device tree. For this
> >> purpose, everything in the node /passthrough from the partial device tree will
> >> be copied into the guest device tree.
> >>
> >> The node /aliases will be also copied to allow the user to define aliases
> >> which can be used by the guest kernel.
> >>
> >> A simple partial device tree will look like:
> >>
> >> /dts-v1/;
> >>
> >> / {
> >>         #address-cells = <2>;
> >>         #size-cells = <2>;
> >>
> >>         passthrough {
> >>             compatible = "simple-bus";
> >>             ranges;
> >>             #address-cells = <2>;
> >>             #size-cells = <2>;
> >>
> >>             /* List of your nodes */
> >>         }
> >> };
> > 
> > It would be nice to have an example of this under tools/examples.
> 
> Ok. I will add one.
> 
> [..]
> 
> >> +/*
> >> + * Check if a string stored the strings block section is correctly
> >> + * nul-terminated.
> >> + * off_dt_strings and size_dt_strings fields have been validity-check
> >> + * earlier, so it's safe to use them here.
> >> + */
> >> +static bool check_string(void *fdt, int nameoffset)
> >> +{
> >> +    const char *str = fdt_string(fdt, nameoffset);
> >> +
> >> +    for (; nameoffset < fdt_size_dt_strings(fdt); nameoffset++, str++) {
> >> +        if (*str == '\0')
> >> +            return true;
> >> +    }
> >> +
> >> +    return false;
> >> +}
> > 
> > strnlen?
> 
> I could but it would not tell us directly if the string is NULL
> terminated or not.

you can use it to find if it is NULL terminated because it returns
maxlen in that case:

       The strnlen() function returns strlen(s), if that is less than maxlen, or maxlen if there is no null byte ('\0') among  the
       first maxlen bytes pointed to by s.


> What about memchr?
> 
> 
> [..]
> 
> >> +static int copy_node_by_path(libxl__gc *gc, const char *path,
> >> +                             void *fdt, void *pfdt)
> >> +{
> >> +    int nodeoff, r;
> >> +    const char *name = strrchr(path, '/');
> >> +
> >> +    if (!name)
> >> +        return -FDT_ERR_INTERNAL;
> >> +
> >> +    name++;
> >> +
> >> +    /* The FDT function to look at node doesn't take into account the
> >> +     * unit (i.e anything after @) when search by name. Check if the
> >> +     * name exactly match.
> >> +     */
> >> +    nodeoff = fdt_path_offset(pfdt, path);
> >> +    if (nodeoff < 0)
> >> +        return nodeoff;
> >> +
> >> +    if (strcmp(fdt_get_name(pfdt, nodeoff, NULL), name))
> >> +        return -FDT_ERR_NOTFOUND;
> > 
> > Are we sure that the string returned by fdt_get_name is NULL terminated?
> 
> Yes, libfdt does some sanity check on it (see fdt_next_tag case
> FDT_BEGIN_NODE).
> 
> I tried to fix all the possible security flaw in libfdt (and there is
> quite a lot). If we don't trust the rest of libfdt, then we have to
> import our own and fix it.
 
I was just asking because you clearly didn't trust its output earlier
but you did in this case. That's OK for me.

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-01-29 12:17       ` Stefano Stabellini
@ 2015-01-29 12:26         ` Julien Grall
  2015-01-29 12:33           ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-29 12:26 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: xen-devel, Jan Beulich, tim, ian.campbell, stefano.stabellini

On 29/01/15 12:17, Stefano Stabellini wrote:
> On Wed, 28 Jan 2015, Julien Grall wrote:
>> Hi Stefano,
>>
>> On 28/01/15 18:52, Stefano Stabellini wrote:
>>> On Tue, 13 Jan 2015, Julien Grall wrote:
>>>> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
>>>> assign/deassign a physical IRQ to the guest (via the config options "irqs"
>>>> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
>>>> channel). As ARM doesn't have a such concept, we could reuse it to bound
>>>> a physical IRQ to a virtual IRQ.
>>>>
>>>> For now, we allow only SPIs to be mapped to the guest.
>>>> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
>>>>
>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>
>>>> ---
>>>>     I'm not sure it's the best solution to reuse hypercalls for a
>>>>     different purpose. If x86 plan to have a such concept (i.e binding a
>>>>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
>>>>     Any thoughs?
>>>
>>> I think it is OK, as long as we write down very clearly what we are
>>> doing.
>>>
>>>
>>>>     TODO: This patch is lacking of support of vIRQ != IRQ. I plan to
>>>>     handle it correctly on the next version.
>>>
>>> Why do you say that? From the code in this patch it looks like it
>>> supports vIRQ != IRQ already.
>>
>> Because PHYSDEV_map_pirq is taking a vIRQ number in parameter. This vIRQ
>> is only valid for the domain which issue the hypercall.
> 
> That's not very useful. I think that the vIRQ passed to PHYSDEV_map_pirq
> should be a vIRQ in the destination domain, not the source domain.
> 
> In fact on x86 the pirq parameter to PHYSDEV_map_pirq is interpreted as
> pirq in the destination domain too.

I'm talking about the index parameter. It's a vIRQ in the domain issue
the hypercall not the real IRQ.

>> In our use case, it's DOM0. DOM0 may not have all the time vIRQ == IRQ.
>>
>> Futhermore, on PHYSDEV_unmap_pirq I assume the DOM0 virq == guest virq.
> 
> That's bad.

I plan to support it for the next series. This change shouldn't impact
the other patches of the series, so I decided to send a new version to
gather some comments.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-01-29 12:05     ` Julien Grall
@ 2015-01-29 12:28       ` Stefano Stabellini
  2015-01-29 13:48         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 12:28 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, xen-devel

On Thu, 29 Jan 2015, Julien Grall wrote:
> On 29/01/15 11:07, Stefano Stabellini wrote:
> > On Tue, 13 Jan 2015, Julien Grall wrote:
> >> The partial device tree may contains phandle. The Device Tree Compiler
> >> tends to allocate the phandle from 1.
> >>
> >> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
> >> that the partial device tree will never contain a such ID.
> >>
> >> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> >> Cc: Wei Liu <wei.liu2@citrix.com>
> >>
> > 
> > Shouldn't we at least check that the partial device tree doesn't contain
> > a conflicting phandle?
> 
> I don't think so. This will unlikely happen, and if it happens the guest
> will crash with an obvious error.

It is good that the error is obvious.

But how expensive is to check for it?
Think about the poor user that ends up in this situation: the fact that
is unlikely only makes it harder for a user to figure out what to do to
fix it.

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

* Re: [PATCH v3 23/24] libxl: Add support for non-PCI passthrough
  2015-01-29 12:08     ` Julien Grall
@ 2015-01-29 12:31       ` Stefano Stabellini
  2015-01-29 13:51         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 12:31 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, xen-devel

On Thu, 29 Jan 2015, Julien Grall wrote:
> Hi Stefano,
> 
> On 29/01/15 11:12, Stefano Stabellini wrote:
> >> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> >> index 029d2e2..b7ef528 100644
> >> --- a/tools/libxl/libxl_create.c
> >> +++ b/tools/libxl/libxl_create.c
> >> @@ -1430,6 +1430,16 @@ static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev,
> > 
> > I think you should at least rename domcreate_attach_pci to something
> > more generic, like domcreate_attach_dev.
> 
> Actually I was planning to add a domcreate_attach_dtdev but I forgot
> about it.
> 
> What the best approach for this?

Either one would work. But don't add non-PCI passthrough code to a
function named domcreate_attach_pci :-)


> > 
> >>          }
> >>      }
> >>  
> >> +    for (i = 0; i < d_config->num_dtdevs; i++) {
> >> +
> >> +        ret = libxl__device_dt_add(gc, domid, &d_config->dtdevs[i]);
> >> +        if (ret < 0) {
> >> +            LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
> >> +                       "libxl__device_dt_add failed: %d\n", ret);
> >> +            goto error_out;
> >> +        }
> >> +    }
> > 
> > You are allowed to call xc_* functions from here. The
> > libxl__device_dt_add wrapper doesn't add much value.
> 
> I would like to keep the wrapper. It's in sync with the PCI solution and
> it will avoid refactoring later for add new code.

But in the PCI case there is a lot of code in the function.
Regardless if you think it is useful, keep it.

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

* Re: [PATCH v3 24/24] xl: Add new option dtdev
  2015-01-29 12:09     ` Julien Grall
@ 2015-01-29 12:32       ` Stefano Stabellini
  2015-01-29 13:51         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 12:32 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, xen-devel

On Thu, 29 Jan 2015, Julien Grall wrote:
> Hi Stefano,
> 
> On 29/01/15 11:18, Stefano Stabellini wrote:
> > On Tue, 13 Jan 2015, Julien Grall wrote:
> >> The option "dtdev" will be used to passthrough a non-PCI device described
> >> in the device tree to a guest.
> > 
> > Actually didn't you add the dtdev option to the idl in the previous
> > patch?  You should probably move it to this one.
> 
> The IDL is part of libxl, and the change is required by the previous patch.
> 
> This patch is only adding the option in xl.

Fair enough

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-01-29 12:26         ` Julien Grall
@ 2015-01-29 12:33           ` Stefano Stabellini
  2015-02-20 16:53             ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 12:33 UTC (permalink / raw)
  To: Julien Grall
  Cc: ian.campbell, Stefano Stabellini, tim, stefano.stabellini,
	Jan Beulich, xen-devel

On Thu, 29 Jan 2015, Julien Grall wrote:
> On 29/01/15 12:17, Stefano Stabellini wrote:
> > On Wed, 28 Jan 2015, Julien Grall wrote:
> >> Hi Stefano,
> >>
> >> On 28/01/15 18:52, Stefano Stabellini wrote:
> >>> On Tue, 13 Jan 2015, Julien Grall wrote:
> >>>> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
> >>>> assign/deassign a physical IRQ to the guest (via the config options "irqs"
> >>>> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
> >>>> channel). As ARM doesn't have a such concept, we could reuse it to bound
> >>>> a physical IRQ to a virtual IRQ.
> >>>>
> >>>> For now, we allow only SPIs to be mapped to the guest.
> >>>> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
> >>>>
> >>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >>>> Cc: Jan Beulich <jbeulich@suse.com>
> >>>>
> >>>> ---
> >>>>     I'm not sure it's the best solution to reuse hypercalls for a
> >>>>     different purpose. If x86 plan to have a such concept (i.e binding a
> >>>>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
> >>>>     Any thoughs?
> >>>
> >>> I think it is OK, as long as we write down very clearly what we are
> >>> doing.
> >>>
> >>>
> >>>>     TODO: This patch is lacking of support of vIRQ != IRQ. I plan to
> >>>>     handle it correctly on the next version.
> >>>
> >>> Why do you say that? From the code in this patch it looks like it
> >>> supports vIRQ != IRQ already.
> >>
> >> Because PHYSDEV_map_pirq is taking a vIRQ number in parameter. This vIRQ
> >> is only valid for the domain which issue the hypercall.
> > 
> > That's not very useful. I think that the vIRQ passed to PHYSDEV_map_pirq
> > should be a vIRQ in the destination domain, not the source domain.
> > 
> > In fact on x86 the pirq parameter to PHYSDEV_map_pirq is interpreted as
> > pirq in the destination domain too.
> 
> I'm talking about the index parameter. It's a vIRQ in the domain issue
> the hypercall not the real IRQ.

I see.  OK.


> >> In our use case, it's DOM0. DOM0 may not have all the time vIRQ == IRQ.
> >>
> >> Futhermore, on PHYSDEV_unmap_pirq I assume the DOM0 virq == guest virq.
> > 
> > That's bad.
> 
> I plan to support it for the next series. This change shouldn't impact
> the other patches of the series, so I decided to send a new version to
> gather some comments.
> 
> Regards,
> 
> -- 
> Julien Grall
> 

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-29 12:09       ` Stefano Stabellini
@ 2015-01-29 13:09         ` Julien Grall
  2015-01-29 15:03           ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-29 13:09 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	Jan Beulich, xen-devel

On 29/01/15 12:09, Stefano Stabellini wrote:
> On Thu, 29 Jan 2015, Julien Grall wrote:
>> Hi Stefano,
>>
>> On 29/01/15 10:29, Stefano Stabellini wrote:
>>>> +static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev)
>>>> +{
>>>> +    bool_t assigned = 0;
>>>> +
>>>> +    if ( !dt_device_is_protected(dev) )
>>>> +        return 1;
>>>
>>> Why return true here?
>>
>> Because any device not protected cannot be assigned to another guest.
>> This could be used by the toolstack to know whether the device is
>> assigned or not.
> 
> I understand that much.
> 
> 
>> IHMO, returning 0 would be a false negative.
> 
> Why? Returning 0 means that the device is not assigned, that would be
> correct. From this statement I think that actually you are thinking as
> if this function actually returned whether a given device is assignable.

0 means the device is not assigned and therefore can be used for
passthrough.

This function is used in the DOMCTL test_assign_device. That would mean
we will return 0 for non-protected device. That doesn't sound right as a
such device can never be assigned.

> In that case you should rename the function to
> 
> iommu_dt_device_is_assignable

dt_device_is_assignable is not more clear. Return 0 here would mean the
device cannot be assigned in the sense it's not protected.

Moreover, this name would not be in sync with the DOMCTL test_assign_device.


Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-01-29 12:28       ` Stefano Stabellini
@ 2015-01-29 13:48         ` Julien Grall
  2015-01-29 15:04           ` Stefano Stabellini
  2015-02-23 14:36           ` Ian Campbell
  0 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-29 13:48 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On 29/01/15 12:28, Stefano Stabellini wrote:
> On Thu, 29 Jan 2015, Julien Grall wrote:
>> On 29/01/15 11:07, Stefano Stabellini wrote:
>>> On Tue, 13 Jan 2015, Julien Grall wrote:
>>>> The partial device tree may contains phandle. The Device Tree Compiler
>>>> tends to allocate the phandle from 1.
>>>>
>>>> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
>>>> that the partial device tree will never contain a such ID.
>>>>
>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>>>
>>>
>>> Shouldn't we at least check that the partial device tree doesn't contain
>>> a conflicting phandle?
>>
>> I don't think so. This will unlikely happen, and if it happens the guest
>> will crash with an obvious error.
> 
> It is good that the error is obvious.
> 
> But how expensive is to check for it?

I would have to check the validity of the properties (name + value
size). At least the properties "linux,phandle" and "phandle" should be
checked.

Though I could do in copy_properties but I find it hackish.

> Think about the poor user that ends up in this situation: the fact that
> is unlikely only makes it harder for a user to figure out what to do to
> fix it.

The poor use will have to write his device tree by hand to hit this
error ;).

So using the right phandle is not a huge drawback.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 23/24] libxl: Add support for non-PCI passthrough
  2015-01-29 12:31       ` Stefano Stabellini
@ 2015-01-29 13:51         ` Julien Grall
  2015-02-23 14:41           ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-29 13:51 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On 29/01/15 12:31, Stefano Stabellini wrote:
> On Thu, 29 Jan 2015, Julien Grall wrote:
>> Hi Stefano,
>>
>> On 29/01/15 11:12, Stefano Stabellini wrote:
>>>> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
>>>> index 029d2e2..b7ef528 100644
>>>> --- a/tools/libxl/libxl_create.c
>>>> +++ b/tools/libxl/libxl_create.c
>>>> @@ -1430,6 +1430,16 @@ static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev,
>>>
>>> I think you should at least rename domcreate_attach_pci to something
>>> more generic, like domcreate_attach_dev.
>>
>> Actually I was planning to add a domcreate_attach_dtdev but I forgot
>> about it.
>>
>> What the best approach for this?
> 
> Either one would work. But don't add non-PCI passthrough code to a
> function named domcreate_attach_pci :-)

Right, it was a quick & dirty implementation which I forgot to clean up.

>>>
>>>>          }
>>>>      }
>>>>  
>>>> +    for (i = 0; i < d_config->num_dtdevs; i++) {
>>>> +
>>>> +        ret = libxl__device_dt_add(gc, domid, &d_config->dtdevs[i]);
>>>> +        if (ret < 0) {
>>>> +            LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
>>>> +                       "libxl__device_dt_add failed: %d\n", ret);
>>>> +            goto error_out;
>>>> +        }
>>>> +    }
>>>
>>> You are allowed to call xc_* functions from here. The
>>> libxl__device_dt_add wrapper doesn't add much value.
>>
>> I would like to keep the wrapper. It's in sync with the PCI solution and
>> it will avoid refactoring later for add new code.
> 
> But in the PCI case there is a lot of code in the function.
> Regardless if you think it is useful, keep it.

If we plan to implement a proper platform device pass-through we will
have to add lots of code.

Wei, Ian & Ian, do you have any opinions?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 24/24] xl: Add new option dtdev
  2015-01-29 12:32       ` Stefano Stabellini
@ 2015-01-29 13:51         ` Julien Grall
  2015-01-29 15:06           ` Stefano Stabellini
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-01-29 13:51 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On 29/01/15 12:32, Stefano Stabellini wrote:
> On Thu, 29 Jan 2015, Julien Grall wrote:
>> Hi Stefano,
>>
>> On 29/01/15 11:18, Stefano Stabellini wrote:
>>> On Tue, 13 Jan 2015, Julien Grall wrote:
>>>> The option "dtdev" will be used to passthrough a non-PCI device described
>>>> in the device tree to a guest.
>>>
>>> Actually didn't you add the dtdev option to the idl in the previous
>>> patch?  You should probably move it to this one.
>>
>> The IDL is part of libxl, and the change is required by the previous patch.
>>
>> This patch is only adding the option in xl.
> 
> Fair enough

I can merge it in the previous patch if you feel it's not necessary to
have a separate one.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-29 13:09         ` Julien Grall
@ 2015-01-29 15:03           ` Stefano Stabellini
  2015-01-29 15:14             ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 15:03 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, Jan Beulich, xen-devel

On Thu, 29 Jan 2015, Julien Grall wrote:
> On 29/01/15 12:09, Stefano Stabellini wrote:
> > On Thu, 29 Jan 2015, Julien Grall wrote:
> >> Hi Stefano,
> >>
> >> On 29/01/15 10:29, Stefano Stabellini wrote:
> >>>> +static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev)
> >>>> +{
> >>>> +    bool_t assigned = 0;
> >>>> +
> >>>> +    if ( !dt_device_is_protected(dev) )
> >>>> +        return 1;
> >>>
> >>> Why return true here?
> >>
> >> Because any device not protected cannot be assigned to another guest.
> >> This could be used by the toolstack to know whether the device is
> >> assigned or not.
> > 
> > I understand that much.
> > 
> > 
> >> IHMO, returning 0 would be a false negative.
> > 
> > Why? Returning 0 means that the device is not assigned, that would be
> > correct. From this statement I think that actually you are thinking as
> > if this function actually returned whether a given device is assignable.
> 
> 0 means the device is not assigned and therefore can be used for
> passthrough.

I disagree on the "therefore".
0 means (or should mean that) the device is not assigned and stop there.


> This function is used in the DOMCTL test_assign_device. That would mean
> we will return 0 for non-protected device. That doesn't sound right as a
> such device can never be assigned.

assigned -> passed through to a VM
assignable -> can potentially be assigned

A non-assignable device cannot be assigned by definition. It does not
make sense to returned true for it, if the question is "is it
assigned?".


> > In that case you should rename the function to
> > 
> > iommu_dt_device_is_assignable
> 
> dt_device_is_assignable is not more clear.

I disagree.


> Return 0 here would mean the
> device cannot be assigned in the sense it's not protected.
> 
> Moreover, this name would not be in sync with the DOMCTL test_assign_device.

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-01-29 13:48         ` Julien Grall
@ 2015-01-29 15:04           ` Stefano Stabellini
  2015-01-29 15:12             ` Julien Grall
  2015-02-23 14:36           ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 15:04 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, xen-devel

On Thu, 29 Jan 2015, Julien Grall wrote:
> On 29/01/15 12:28, Stefano Stabellini wrote:
> > On Thu, 29 Jan 2015, Julien Grall wrote:
> >> On 29/01/15 11:07, Stefano Stabellini wrote:
> >>> On Tue, 13 Jan 2015, Julien Grall wrote:
> >>>> The partial device tree may contains phandle. The Device Tree Compiler
> >>>> tends to allocate the phandle from 1.
> >>>>
> >>>> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
> >>>> that the partial device tree will never contain a such ID.
> >>>>
> >>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> >>>> Cc: Wei Liu <wei.liu2@citrix.com>
> >>>>
> >>>
> >>> Shouldn't we at least check that the partial device tree doesn't contain
> >>> a conflicting phandle?
> >>
> >> I don't think so. This will unlikely happen, and if it happens the guest
> >> will crash with an obvious error.
> > 
> > It is good that the error is obvious.
> > 
> > But how expensive is to check for it?
> 
> I would have to check the validity of the properties (name + value
> size). At least the properties "linux,phandle" and "phandle" should be
> checked.
> 
> Though I could do in copy_properties but I find it hackish.
> 
> > Think about the poor user that ends up in this situation: the fact that
> > is unlikely only makes it harder for a user to figure out what to do to
> > fix it.
> 
> The poor use will have to write his device tree by hand to hit this
> error ;).
> 
> So using the right phandle is not a huge drawback.

Fair enough.  Please document this limitation in the docs and/or manuals.

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

* Re: [PATCH v3 24/24] xl: Add new option dtdev
  2015-01-29 13:51         ` Julien Grall
@ 2015-01-29 15:06           ` Stefano Stabellini
  2015-02-23 14:44             ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Stefano Stabellini @ 2015-01-29 15:06 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, ian.campbell, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, xen-devel

On Thu, 29 Jan 2015, Julien Grall wrote:
> On 29/01/15 12:32, Stefano Stabellini wrote:
> > On Thu, 29 Jan 2015, Julien Grall wrote:
> >> Hi Stefano,
> >>
> >> On 29/01/15 11:18, Stefano Stabellini wrote:
> >>> On Tue, 13 Jan 2015, Julien Grall wrote:
> >>>> The option "dtdev" will be used to passthrough a non-PCI device described
> >>>> in the device tree to a guest.
> >>>
> >>> Actually didn't you add the dtdev option to the idl in the previous
> >>> patch?  You should probably move it to this one.
> >>
> >> The IDL is part of libxl, and the change is required by the previous patch.
> >>
> >> This patch is only adding the option in xl.
> > 
> > Fair enough
> 
> I can merge it in the previous patch if you feel it's not necessary to
> have a separate one.

I don't think it is necessary to have two separate patches, but let's
see what the libxl maintainers have to say.

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-01-29 15:04           ` Stefano Stabellini
@ 2015-01-29 15:12             ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-29 15:12 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini, xen-devel

On 29/01/15 15:04, Stefano Stabellini wrote:
> On Thu, 29 Jan 2015, Julien Grall wrote:
>> On 29/01/15 12:28, Stefano Stabellini wrote:
>>> On Thu, 29 Jan 2015, Julien Grall wrote:
>>>> On 29/01/15 11:07, Stefano Stabellini wrote:
>>>>> On Tue, 13 Jan 2015, Julien Grall wrote:
>>>>>> The partial device tree may contains phandle. The Device Tree Compiler
>>>>>> tends to allocate the phandle from 1.
>>>>>>
>>>>>> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
>>>>>> that the partial device tree will never contain a such ID.
>>>>>>
>>>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>>>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>>>>>
>>>>>
>>>>> Shouldn't we at least check that the partial device tree doesn't contain
>>>>> a conflicting phandle?
>>>>
>>>> I don't think so. This will unlikely happen, and if it happens the guest
>>>> will crash with an obvious error.
>>>
>>> It is good that the error is obvious.
>>>
>>> But how expensive is to check for it?
>>
>> I would have to check the validity of the properties (name + value
>> size). At least the properties "linux,phandle" and "phandle" should be
>> checked.
>>
>> Though I could do in copy_properties but I find it hackish.
>>
>>> Think about the poor user that ends up in this situation: the fact that
>>> is unlikely only makes it harder for a user to figure out what to do to
>>> fix it.
>>
>> The poor use will have to write his device tree by hand to hit this
>> error ;).
>>
>> So using the right phandle is not a huge drawback.
> 
> Fair enough.  Please document this limitation in the docs and/or manuals.

I will do.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-29 15:03           ` Stefano Stabellini
@ 2015-01-29 15:14             ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-01-29 15:14 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, ian.campbell, tim, Ian Jackson, stefano.stabellini,
	Jan Beulich, xen-devel

On 29/01/15 15:03, Stefano Stabellini wrote:
> On Thu, 29 Jan 2015, Julien Grall wrote:
>> On 29/01/15 12:09, Stefano Stabellini wrote:
>>> On Thu, 29 Jan 2015, Julien Grall wrote:
>>>> Hi Stefano,
>>>>
>>>> On 29/01/15 10:29, Stefano Stabellini wrote:
>>>>>> +static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev)
>>>>>> +{
>>>>>> +    bool_t assigned = 0;
>>>>>> +
>>>>>> +    if ( !dt_device_is_protected(dev) )
>>>>>> +        return 1;
>>>>>
>>>>> Why return true here?
>>>>
>>>> Because any device not protected cannot be assigned to another guest.
>>>> This could be used by the toolstack to know whether the device is
>>>> assigned or not.
>>>
>>> I understand that much.
>>>
>>>
>>>> IHMO, returning 0 would be a false negative.
>>>
>>> Why? Returning 0 means that the device is not assigned, that would be
>>> correct. From this statement I think that actually you are thinking as
>>> if this function actually returned whether a given device is assignable.
>>
>> 0 means the device is not assigned and therefore can be used for
>> passthrough.
> 
> I disagree on the "therefore".
> 0 means (or should mean that) the device is not assigned and stop there.
> 
> 
>> This function is used in the DOMCTL test_assign_device. That would mean
>> we will return 0 for non-protected device. That doesn't sound right as a
>> such device can never be assigned.
> 
> assigned -> passed through to a VM
> assignable -> can potentially be assigned
> 
> A non-assignable device cannot be assigned by definition. It does not
> make sense to returned true for it, if the question is "is it
> assigned?".

Ok. I will return 0 in when the device is not protected.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-01-13 14:25 ` [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration Julien Grall
                     ` (2 preceding siblings ...)
  2015-01-28 15:50   ` Stefano Stabellini
@ 2015-02-20 15:15   ` Ian Campbell
  2015-02-20 16:09     ` Julien Grall
                       ` (2 more replies)
  3 siblings, 3 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:15 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, George Dunlap, Ian Jackson, tim, stefano.stabellini,
	Jan Beulich, Andrew Cooper, xen-devel, Daniel De Graaf,
	Keir Fraser

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> On ARM the virtual GIC may differ between each guest (emulated GIC version,
> number of SPIs...). Those informations are already known at the domain creation

"This information is already known at domain creation..."

> and can never change.
> 
> For now only the gic_version is set. In long run, there will be more parameters

"In the long run".

> such as the number of SPIs. All will be required to be set at the same time.
> 
> A new arch-specific structure arch_domainconfig has been created, the x86
> one doesn't have any specific configuration, a dummy structure
> (C-spec compliant) has been created to factorize the code on the toolstack.

I'm not sure what you mean by factorize here.

> Some external tools (qemu, xenstore) may require to create a domain. Rather

"may be required" perhaps? I'm not 100% sure what you are trying to say.

> than asking them to take care of the arch-specific domain configuration, let
> the current function (xc_domain_create) to chose a default configuration and

s/to//

> introduce a new one (xc_domain_create_config).
> 
> This patch also drop the previously DOMCTL arm_configure_domain introduced

"drops the previously introduced DOMCTL arm...".

> in Xen 4.5, as it has been made useless.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: George Dunlap <george.dunlap@eu.citrix.com>
> 
> ---
>     This is a follow-up of http://lists.xen.org/archives/html/xen-devel/2014-11/msg00522.html
> 
>     TODO: What about migration? For now the configuration lives in internal
>     libxl structure. We need a way to pass the domain configuration to the
>     other end.

Things like the GIC version and number of SPIs would normally end up
being encoded in the hvm save records, i.e. the blob which Xen provides
to the toolstack to be included in the save stream. That would then be
alongside the actual related interrupt architectural state etc (e.g.
pending, active, masked etc).

That's problematic here because you can't pass that blob to the create
function and the toolstack cannot really parse the blob to figure out
the details to pass.

Looking back at msg00522.html it does seem like migration is a good
motivation for doing it as a separate hypercall as you originally did,
so initial create would be
	DOMCTL_create
	DOMCTL_set_the_variables
and restore would be
	DOMCTL_create
	DOMCTL_restore_from_blob

In both cases this needn't preclude requiring the call to be made before
unpause or that it is only called exactly once.

Write once HVM params would be another option here.

Jan, do you find any of that convincing as to the need for doing this
outside the the create domctl? Based on msg00522 is seems you would
prefer some HVM params over a new domctl?

>     I'm not sure if we should care of this right now as migration doesn't
>     yet exists on ARM.

It's a domctl so we aren't exactly painting ourselves into a corner, but
it would be good to have some idea that we aren't going down a blind
alley at least. Especially if the way out of the alley is to come back
to where we are now...

(There doesn't seem much point in looking at the code until we conclude
the approach is correct, so I haven't)

Ian.

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

* Re: [PATCH v3 02/24] xen/arm: Divide GIC initialization in 2 parts
  2015-01-28 16:09   ` Stefano Stabellini
@ 2015-02-20 15:19     ` Ian Campbell
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:19 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: xen-devel, Julien Grall, tim, stefano.stabellini

On Wed, 2015-01-28 at 16:09 +0000, Stefano Stabellini wrote:
> On Tue, 13 Jan 2015, Julien Grall wrote:
> > Currently the function to translate IRQ from the device tree is set
> > unconditionally  to be able to be able to retrieve serial/timer IRQ before the
> > GIC has been initialized.
> > 
> > It assumes that the xlate function won't never changed. We may also need to
> > have the primary interrupt controller very early.
> > 
> > Rework the gic initialization in 2 parts:
> >     - gic_preinit: Get the interrupt controller device tree node and set
> > up GIC and xlate callbacks
> >     - gic_init: Initialize the interrupt controller and the boot CPU
> >     interrupts.
> > 
> > The former function will be called just after the IRQ subsystem as been
> > initialized.
> > 
> > Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

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

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

* Re: [PATCH v3 02/24] xen/arm: Divide GIC initialization in 2 parts
  2015-01-13 14:25 ` [PATCH v3 02/24] xen/arm: Divide GIC initialization in 2 parts Julien Grall
  2015-01-28 16:09   ` Stefano Stabellini
@ 2015-02-20 15:19   ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:19 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Currently the function to translate IRQ from the device tree is set
> unconditionally  to be able to be able to retrieve serial/timer IRQ before the
> GIC has been initialized.
> 
> It assumes that the xlate function won't never changed. We may also need to

Forgot to say: either "will never change" or "won't ever change" here

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

* Re: [PATCH v3 03/24] xen/dts: Allow only IRQ translation that are mapped to main GIC
  2015-01-13 14:25 ` [PATCH v3 03/24] xen/dts: Allow only IRQ translation that are mapped to main GIC Julien Grall
  2015-01-28 16:11   ` Stefano Stabellini
@ 2015-02-20 15:20   ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:20 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Xen is only able to handle one GIC controller. Some platform may contain
> other interrupt controller.

"platforms" and "controllers"

> Make sure to only translate IRQ mapped into the GIC handled by Xen.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>

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

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

* Re: [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest
  2015-01-13 14:25 ` [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest Julien Grall
  2015-01-13 15:10   ` Daniel De Graaf
  2015-01-19 16:51   ` Jan Beulich
@ 2015-02-20 15:22   ` Ian Campbell
  2 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:22 UTC (permalink / raw)
  To: Julien Grall
  Cc: Keir Fraser, Ian Jackson, tim, stefano.stabellini, Jan Beulich,
	xen-devel, Daniel De Graaf

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Flask code already provides an helper to copy a string from guest. In a later

"a helper".

> patch, the new DT hypercalls will need a similar function.
> 
> To avoid code duplication, copy the flask helper (flask_copying_string) to
> common code:
>     - Rename into safe_copy_string_from_guest
>     - Add comment to explain the extra +1
>     - Return directly the buffer and use the macros provided by

"Return the buffer directly and...".

>     xen/err.h to return an error code if necessary.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Keir Fraser <keir@xen.org>

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

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

* Re: [PATCH v3 05/24] xen/arm: vgic: Introduce a function to initialize pending_irq
  2015-01-13 14:25 ` [PATCH v3 05/24] xen/arm: vgic: Introduce a function to initialize pending_irq Julien Grall
@ 2015-02-20 15:24   ` Ian Campbell
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:24 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> The structure pending_irq is initialized on the same way in 2 differents

"in the same way in 2 different places".

> place. Introduce vgic_init_pending_irq to avoid code duplication.
> 
> Also move the setting of the irq field in this function as we need to

"...into this function..."

> initialize it once rather than every time an IRQ is injected to the guest.
> 
> Finally, use unsigned int for the "irq" field to be consistent with the
> virq variable
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

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

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

* Re: [PATCH v3 06/24] xen/arm: Map disabled device in DOM0
  2015-01-13 14:25 ` [PATCH v3 06/24] xen/arm: Map disabled device in DOM0 Julien Grall
  2015-01-28 16:18   ` Stefano Stabellini
@ 2015-02-20 15:27   ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:27 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini, Andrii Tseglytskyi

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> The check to avoid mapping disabled device in DOM0 was added in the anticipation

"disabled devices" and "in anticipation of device passthrough"

> of the device passthrough. But, a brand new property will be added later to mark
> device which will passthrough. At the same time, remove the memory type

"which will be passedthrough" or maybe "which will be passthrough"?
(It's hard to say because passthrough isn't really a word...)

> check because those nodes has been blacklisted.
> 
> Futhermore, some platform (such as the OMAP) may try to poke device even

"Furthermore".

> if the property "status" is set to "disabled".
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Andrii Tseglytskyi <andrii.tseglytskyi@globallogic.com>

With that and the change Stefano requested:
Acked-by: Ian Campbell <ian.campbell@citrix.com>

> 
> ---
> 
>     Changes in v3:
>         - Patch added
>         - "xen/arm: follow-up to allow DOM0 manage IRQ and MMIO" has
>         been split in 2 patch [1]
>         - Drop the check for memory type. Thoses nodes have been
>         blacklisted.
> 
> [1] https://patches.linaro.org/34669/
> ---
>  xen/arch/arm/domain_build.c    | 19 +++----------------
>  xen/arch/arm/platforms/omap5.c | 12 ------------
>  2 files changed, 3 insertions(+), 28 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 8f1b48e..f68755f 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1104,22 +1104,9 @@ static int handle_node(struct domain *d, struct kernel_info *kinfo,
>          return 0;
>      }
>  
> -    /*
> -     * Some device doesn't need to be mapped in Xen:
> -     *  - Memory: the guest will see a different view of memory. It will
> -     *  be allocated later.
> -     *  - Disabled device: Linux is able to cope with status="disabled"
> -     *  property. Therefore these device doesn't need to be mapped. This
> -     *  solution can be use later for pass through.
> -     */
> -    if ( !dt_device_type_is_equal(node, "memory") &&
> -         dt_device_is_available(node) )
> -    {
> -        res = map_device(d, node);
> -
> -        if ( res )
> -            return res;
> -    }
> +    res = map_device(d, node);
> +    if ( res)
> +        return res;
>  
>      /*
>       * The property "name" is used to have a different name on older FDT
> diff --git a/xen/arch/arm/platforms/omap5.c b/xen/arch/arm/platforms/omap5.c
> index 9d6e504..e7bf30d 100644
> --- a/xen/arch/arm/platforms/omap5.c
> +++ b/xen/arch/arm/platforms/omap5.c
> @@ -155,17 +155,6 @@ static const char * const dra7_dt_compat[] __initconst =
>      NULL
>  };
>  
> -static const struct dt_device_match dra7_blacklist_dev[] __initconst =
> -{
> -    /* OMAP Linux kernel handles devices with status "disabled" in a
> -     * weird manner - tries to reset them. While their memory ranges
> -     * are not mapped, this leads to data aborts, so skip these devices
> -     * from DT for dom0.
> -     */
> -    DT_MATCH_NOT_AVAILABLE(),
> -    { /* sentinel */ },
> -};
> -
>  PLATFORM_START(omap5, "TI OMAP5")
>      .compatible = omap5_dt_compat,
>      .init_time = omap5_init_time,
> @@ -185,7 +174,6 @@ PLATFORM_START(dra7, "TI DRA7")
>  
>      .dom0_gnttab_start = 0x4b000000,
>      .dom0_gnttab_size = 0x20000,
> -    .blacklist_dev = dra7_blacklist_dev,
>  PLATFORM_END
>  
>  /*

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-01-13 14:25 ` [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property Julien Grall
  2015-01-28 16:36   ` Stefano Stabellini
@ 2015-02-20 15:38   ` Ian Campbell
  2015-02-20 17:01     ` Julien Grall
  2015-02-20 15:42   ` Ian Campbell
  2 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:38 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> When a device is marked for passthrough (via the new property "xen,passthrough"),
> dom0 must not access to the device (i.e not loading a driver), but should

"must not access the device (i.e. not load a driver)"

perhaps "should still be able"

> be able to manage the MMIO/interrupt of the passthrough device.
> 
> The latter part will allow the toolstack to map MMIO/IRQ when a device
> is pass through to a guest.
> 
> The property "xen,passthrough" will be translated as 'status="disabled"'
> in the device tree to avoid DOM0 using the device. We assume that DOM0 is
> able to cope with this property (already the case for Linux).

Is it true to say "already the case for Linux, and required by ePAPR"?
Or are we relying on a Linux implementation detail here?

> diff --git a/docs/misc/arm/device-tree/passthrough.txt b/docs/misc/arm/device-tree/passthrough.txt
> new file mode 100644
> index 0000000..04645b3
> --- /dev/null
> +++ b/docs/misc/arm/device-tree/passthrough.txt
> @@ -0,0 +1,7 @@
> +Device passthrough
> +===================
> +
> +Any device that will be passthrough to a guest should have a property
> +"xen,passthrough" in their device tree node.
> +
> +The device won't be exposed to DOM0 and therefore no driver will be loaded.

This (and the commit message to some extent) seem stricter than what I
think is actually required here.

I understand that it is a very good idea for any sort of passthrough to
prevent dom0 from messing with a device before it gets assigned to the
eventual guest domain.

But AIUI it is not strictly speaking a hard requirement that dom0 does
not do this and depending on the device it may be perfectly acceptable
for dom0 to drive a device for a bit and then give it to a guest and
then have it back again etc.

So I would suggest to invert the wording a bit, currently it reads
something like "if a device is to be passed through then it must have
this property set, then dom0 will not touch".

So I'd suggest something weaker like:

        Devices with this property set will not be exposed to dom0 and
        therefore no driver will be loaded.
        
        It is highly recommended to set this property on devices which
        are to be passed through since many devices will not cope with
        being accessed by dom0 and then handed over to another domain.

(second half of the second paragraph could be clearer though I think)

(I'll hit send now and then review the code itself)

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-01-13 14:25 ` [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property Julien Grall
  2015-01-28 16:36   ` Stefano Stabellini
  2015-02-20 15:38   ` Ian Campbell
@ 2015-02-20 15:42   ` Ian Campbell
  2015-02-20 17:03     ` Julien Grall
  2 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:42 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> @@ -919,8 +943,14 @@ static int make_timer_node(const struct domain *d, void *fdt,
>      return res;
>  }
>  
> -/* Map the device in the domain */
> -static int map_device(struct domain *d, struct dt_device_node *dev)
> +/* For a given device node:

Strictly speaking should be:
 /*
  * For a given...

(I don't care all that much, but since I'm commenting elsewhere)

> @@ -947,7 +979,7 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
>          }
>      }
>  
> -    /* Map IRQs */
> +    /* Give permission and  map IRQs */

Another Nit: "  " -> " ".

> +        if ( need_mapping )
> +        {
> +            /*
> +             * Checking the return of vgic_reserve_virq is not
> +             * necessary. It should not fail except when we try to map
> +             * twice the IRQ. This can happen if the IRQ is shared

"when we try to map the IRQ twice"

Other than those nits the code itself looks good, will ack once we've
agreed on the bindings wording.

Ian.

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-01-13 14:25 ` [PATCH v3 08/24] xen/arm: Allow virq != irq Julien Grall
  2015-01-28 16:47   ` Stefano Stabellini
@ 2015-02-20 15:52   ` Ian Campbell
  2015-02-20 17:09     ` Julien Grall
  2015-02-27 14:25     ` Julien Grall
  1 sibling, 2 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 15:52 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Actually Xen is assuming that the virtual IRQ will always be the same as IRQ.

s/Actually/Currently/?

> Modify route_guest_irq to take the virtual IRQ in parameter and let Xen
> assign a different IRQ number.

I think I must be misunderstanding this, but if route_guest_irq is
taking the vIRQ as a parameter then why does it then need to assign a
different IRQ number?

Oh, did you mean allowing the *caller* to setup a non-1:1 mapping
perhaps? I think s/and let Xen assign/which allows Xen to.../ might be
closer to that meaning if that's the intention?

>  Also store the vIRQ in the desc action to
> easily retrieve easily the IRQ target when we need to inject the interrupt.

-ETooManyEasilys ;-)

(I think you want to drop the second one)

> As DOM0 will get most the devices, the vIRQ is equal to the IRQ in that case.

Am I correct that after this patch all callers still pass irq==virq to
the new function?

> At the same time modify the behavior of irq_get_domain. The function now
> assumes that the irq_desc belongs to an IRQ assigned to a guest.

s/assumes/requires/?

>  
>      action = xmalloc(struct irqaction);
> -    if (!action)
> +    if ( !action )
> +        return -ENOMEM;
> +
> +    info = xmalloc(struct irq_guest);

FWIW you might (subject to sizing/alignment needs) be able to do
	action = _xmalloc(sizeof(struct irqaction) + sizeof(struct irq_guest);
	info = (sturct irq_guest *)(action + 1);

which would save some memory overhead for free pointers etc and allow
you to avoid manually managing the info.

You probably won't like that though, so feel free to ignore.

Ian.

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

* Re: [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ
  2015-01-13 14:25 ` [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ Julien Grall
  2015-01-28 17:55   ` Stefano Stabellini
@ 2015-02-20 16:00   ` Ian Campbell
  2015-02-20 17:21     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 16:00 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Currently Xen only supports SPIs routing for guest, add a function
> is_assignable_irq to check if we can assign a given IRQ to the guest.
> 
> Secondly, make sure the vIRQ is not the greater that the number of IRQs handle
> to the vGIC and it's an SPIs.

I think you mean the "number of IRQs handled by the vGIC" (or configured
in?) and it would just be "an SPI".

> Thirdly, when the IRQ is already assigned to the domain, check the user
> is not asking to use a different vIRQ than the one already bound.
> 
> Finally, desc->arch.type which contains the IRQ type (i.e level/edge) must
> be correctly configured before. The IRQ type won't be configure when:
                                ^routing?

>     - the device has been blacklist for the current platform

"blacklisted".

>     - the IRQ has not been describe in the device tree

"described".

> I think we can safely assume that a user won't never ask to route
> as such IRQ to the guest.

Can we now ;-) Does this mean the code doesn't check for and abort on
these cases?

<later>Having read further I think you do catch it, so I think you can
remove that sentence, or at least append "...but we check for this
anyway"</later>.

> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> index 830832c..af408ac 100644
> --- a/xen/arch/arm/irq.c
> +++ b/xen/arch/arm/irq.c
> @@ -379,6 +379,15 @@ err:
>      return rc;
>  }
>  
> +bool_t is_assignable_irq(unsigned int irq)
> +{
> +    /* For now, we can only route SPIs to the guest */
> +    return ((irq >= NR_LOCAL_IRQS) && (irq < gic_number_lines()));
> +}
> +
> +/* Route an IRQ to a specific guest.
> + * For now only SPIs are assignabled to the guest.

"assignable"

> + */
>  int route_irq_to_guest(struct domain *d, unsigned int virq,
>                         unsigned int irq, const char * devname)
>  {
> @@ -388,6 +397,29 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
>      unsigned long flags;
>      int retval = 0;
>  
> +    if ( !is_assignable_irq(irq) )
> +    {
> +        dprintk(XENLOG_G_ERR, "the IRQ%u is not routable\n", irq);
> +        return -EINVAL;
> +    }
> +
> +    desc = irq_to_desc(irq);

I can't remember if this is expensive, but you could safely do it
further down after more of the sanity checks.

> +
> +    if ( virq >= vgic_num_irqs(d) )
> +    {
> +        dprintk(XENLOG_G_ERR,
> +                "the vIRQ number %u is too high for domain %u (max = %u)\n",
> +                irq, d->domain_id, vgic_num_irqs(d));
> +        return -EINVAL;
> +    }
> +
> +    /* Only routing to virtual SPIs is supported */
> +    if ( virq < 32 )

NR_LOCAL_IRQS?

> +    {
> +        dprintk(XENLOG_G_ERR, "IRQ can only be routed to a virtual SPIs");

Just "SPI".

> -            printk(XENLOG_ERR "ERROR: IRQ %u is already used by domain %u\n",
> -                   irq, ad->domain_id);
> +            dprintk(XENLOG_G_ERR, "IRQ %u is already used by domain %u\n",
> +                    irq, ad->domain_id);
>          else
> -            printk(XENLOG_ERR "ERROR: IRQ %u is already used by Xen\n", irq);
> +            dprintk(XENLOG_G_ERR, "IRQ %u is already used by Xen\n", irq);

Is the file/line really needed here? The messages seem reasonably unique
already.

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

* Re: [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  2015-01-13 14:25 ` [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest Julien Grall
  2015-01-28 18:15   ` Stefano Stabellini
@ 2015-02-20 16:07   ` Ian Campbell
  2015-02-20 17:28     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 16:07 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> With the addition of interrupt assignment to guest, we need to make sure
> the guest don't blow up the interrupt management in Xen.

s/don't/can't/

> 
> Before associating the IRQ to a vIRQ we need to make sure:
>     - the vIRQ is not already associated to another IRQ
>     - the guest didn't enable the vIRQ
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> ---
>     Changes in v3:
>         - Patch added
> ---
>  xen/arch/arm/gic.c        | 34 ++++++++++++++++++++++++++--------
>  xen/arch/arm/irq.c        | 12 ++++++++++--
>  xen/include/asm-arm/gic.h |  7 +++----
>  3 files changed, 39 insertions(+), 14 deletions(-)
> 
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 15de283..240870f 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -126,22 +126,40 @@ void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask,
>  /* Program the GIC to route an interrupt to a guest
>   *   - desc.lock must be held
>   */
> -void gic_route_irq_to_guest(struct domain *d, unsigned int virq,
> -                            struct irq_desc *desc,
> -                            const cpumask_t *cpu_mask, unsigned int priority)
> +int gic_route_irq_to_guest(struct domain *d, unsigned int virq,
> +                           struct irq_desc *desc, unsigned int priority)
>  {
> -    struct pending_irq *p;
> +    unsigned long flags;
> +    /* Use vcpu0 to retrieve the pending_irq struct. Given that we only
> +     * route SPIs to guests, it doesn't make any difference. */
> +    struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq);
> +    struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq);
> +    struct pending_irq *p = irq_to_pending(v_target, virq);
> +    int res = -EBUSY;
> +
>      ASSERT(spin_is_locked(&desc->lock));
> +    /* We only support SPIs */

More importantly: We have (hopefully) guaranteed elsewhere that an PPI
or SGI can never make it here, I take it. If that's the case then either
the comment should say that, or more likely, the comment is redundently
restating the assert's condition.

> +    ASSERT(virq >= 32 && virq < vgic_num_irqs(d));

NR_LOCAL_IRQS?

Also splitting the two conditions into two asserts will make it more
obvious which one failed if we hit it.

> +
> +    vgic_lock_rank(v_target, rank, flags);
> +
> +    if ( p->desc ||
> +         /* The VIRQ should not be already enabled by the guest */
> +         test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) )
> +        goto out;
>  
>      desc->handler = gic_hw_ops->gic_guest_irq_type;
>      set_bit(_IRQ_GUEST, &desc->status);
>  
> -    gic_set_irq_properties(desc, cpumask_of(smp_processor_id()), GIC_PRI_IRQ);
> +    gic_set_irq_properties(desc, cpumask_of(v_target->processor), priority);

This smells like a functional change, not a sanity check, what is it
for?

Is v_target->processor always configured, even for the first routing of
an IRQ to dom0?

Care needs to be taken here that priority is not under unfettered guest
control -- since this configures the physical GIC we need to e.g. ensure
that Xen's own IPIs have higher priority than anything a guest can ever
set. (Realistically this probably means we want to constrain guests to
the bottom half of the priority range and expose different BPR etc in
the vgic, out of scope here though)

Ian.

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-01-28 18:26   ` Stefano Stabellini
  2015-01-28 18:58     ` Julien Grall
@ 2015-02-20 16:08     ` Ian Campbell
  2015-02-20 17:29       ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 16:08 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, Ian Jackson, Julien Grall, tim, stefano.stabellini,
	Jan Beulich, xen-devel

On Wed, 2015-01-28 at 18:26 +0000, Stefano Stabellini wrote:

> > +        int spi = irq - 32;
> 
> unsigned int

and underflow?

Ian.

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-02-20 15:15   ` Ian Campbell
@ 2015-02-20 16:09     ` Julien Grall
  2015-02-20 16:37       ` Jan Beulich
  2015-02-23 15:09       ` Ian Campbell
  2015-02-20 16:35     ` Jan Beulich
  2015-02-23 15:48     ` Andrew Cooper
  2 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-20 16:09 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Wei Liu, George Dunlap, Ian Jackson, tim, stefano.stabellini,
	Jan Beulich, Andrew Cooper, xen-devel, Daniel De Graaf,
	Keir Fraser

Hi Ian,

On 20/02/15 15:15, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> On ARM the virtual GIC may differ between each guest (emulated GIC version,
>> number of SPIs...). Those informations are already known at the domain creation
> 
> "This information is already known at domain creation..."
> 
>> and can never change.
>>
>> For now only the gic_version is set. In long run, there will be more parameters
> 
> "In the long run".
> 
>> such as the number of SPIs. All will be required to be set at the same time.
>>
>> A new arch-specific structure arch_domainconfig has been created, the x86
>> one doesn't have any specific configuration, a dummy structure
>> (C-spec compliant) has been created to factorize the code on the toolstack.
> 
> I'm not sure what you mean by factorize here.

There is an arch-specific function where

> 
>> Some external tools (qemu, xenstore) may require to create a domain. Rather
> 
> "may be required" perhaps? I'm not 100% sure what you are trying to say.

I meant some external tools (such as qemu, xenstore) needs to create
domain. So we have to keep the old xc_domain_create.

I will use "may be required".

> 
>> than asking them to take care of the arch-specific domain configuration, let
>> the current function (xc_domain_create) to chose a default configuration and
> 
> s/to//
> 
>> introduce a new one (xc_domain_create_config).
>>
>> This patch also drop the previously DOMCTL arm_configure_domain introduced
> 
> "drops the previously introduced DOMCTL arm...".
> 
>> in Xen 4.5, as it has been made useless.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>> Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
>> Cc: Keir Fraser <keir@xen.org>
>> Cc: Jan Beulich <jbeulich@suse.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>> Cc: George Dunlap <george.dunlap@eu.citrix.com>
>>
>> ---
>>     This is a follow-up of http://lists.xen.org/archives/html/xen-devel/2014-11/msg00522.html
>>
>>     TODO: What about migration? For now the configuration lives in internal
>>     libxl structure. We need a way to pass the domain configuration to the
>>     other end.
> 
> Things like the GIC version and number of SPIs would normally end up
> being encoded in the hvm save records, i.e. the blob which Xen provides
> to the toolstack to be included in the save stream. That would then be
> alongside the actual related interrupt architectural state etc (e.g.
> pending, active, masked etc).
> 
> That's problematic here because you can't pass that blob to the create
> function and the toolstack cannot really parse the blob to figure out
> the details to pass.

I was thinking to pass those information the same way we do to know the
domain is a PVH/HVM...

AFAICT they are required in order to create the domain.


> Looking back at msg00522.html it does seem like migration is a good
> motivation for doing it as a separate hypercall as you originally did,
> so initial create would be
> 	DOMCTL_create
> 	DOMCTL_set_the_variables
> and restore would be
> 	DOMCTL_create
> 	DOMCTL_restore_from_blob
> 
> In both cases this needn't preclude requiring the call to be made before
> unpause or that it is only called exactly once.
> 
> Write once HVM params would be another option here.
> 
> Jan, do you find any of that convincing as to the need for doing this
> outside the the create domctl? Based on msg00522 is seems you would
> prefer some HVM params over a new domctl?

The problem with HVM params is we need to wait until every HVM
parameters is set and we have to do it before vCPU are initialized.

The problem with a new DOMCTL is it make the code more complicate in the
hypervisor as it require some kind of synchronization to know if
everything as been correctly initialized.

> 
>>     I'm not sure if we should care of this right now as migration doesn't
>>     yet exists on ARM.
> 
> It's a domctl so we aren't exactly painting ourselves into a corner, but
> it would be good to have some idea that we aren't going down a blind
> alley at least. Especially if the way out of the alley is to come back
> to where we are now...
> 
> (There doesn't seem much point in looking at the code until we conclude
> the approach is correct, so I haven't)

I believe that the migration can be taken in different way without
modifying the current approach.

What we have to do is moving this internal information to the global
structure... That wouldn't be too bad because sooner or later we will
have to let the user choose between vGICv2 and vGICv3.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-01-13 14:25 ` [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs Julien Grall
  2015-01-28 18:26   ` Stefano Stabellini
@ 2015-02-20 16:23   ` Ian Campbell
  2015-02-20 17:31     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 16:23 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich, xen-devel

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Each domain may have a different number of IRQs depending on the devices
> assigned to it.
> 
> Rather re-using the number of IRQs used by the hardwared GIC, let the
        ^than and "hardware" (although "physical" might be better)

> toolstack specify the number of SPIs when the domain is created. This
> will avoid to waste memory.

"will avoid wasting memory".

> To calculate the number of SPIs, we assume that any IRQ given via the option
> "irqs=" in xl is mapped 1:1 to the guest.

I don't see any xl changes here, and I think all that really matters is
the semantics of the libxl_domain_build_info.irqs[] array, which
currently I think can only express 1:1 mappings anyway.

So:

"To calculate the number of SPIs, we take advantage of the fact that the
libxl interface can only expose a 1:1 mapping and look for the largest
SPI in the list" or something.

Ian.

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

* Re: [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying
  2015-01-13 14:25 ` [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying Julien Grall
  2015-01-28 18:38   ` Stefano Stabellini
@ 2015-02-20 16:31   ` Ian Campbell
  2015-02-20 17:41     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 16:31 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:

> Futhermore, a guest can crash and let the IRQ in an incorrect state (i.e has

"Furthermore" (I think your finger macros have this one wrong, you might
want to grep the series ;-))

> +    /* TODO: Handle eviction from LRs. For now, deny remove if the IRQ
> +     * is inflight and not disabled.

If we are ungracefully killing a guest doesn't this risk ending up with
an undestroyable domain? i.e. if the guest is paused with an inflight
IRQ and then destroyed, how does the inflight IRQ ever become
not-inflight again? A similar argument could apply if the guest has e.g.
crashed, paniced or is otherwise not processing any more interrupts or
generating EOIs for existing ones.

We need to be able to kill a guest in such a state somehow.

(BTW, I notice the comment style is consistently wrong through the
series)

> +    /* Only SPIs are supported */
> +    if ( virq < 32 || virq >= vgic_num_irqs(d) )
> +        return -EINVAL;
> +
> +    p = irq_to_pending(d->vcpu[0], virq);
> +    if ( !p->desc )
> +        return -EINVAL;

Are we seeing this pattern a lot? It seems so, I wonder if a helper
could be useful:
       p = spi_to_pending(d, virq);
       if ( !p->desc )
           return -EINVAL;

with the < 32 check etc in the helper where it only needs commenting on
once.

> +
> +    desc = p->desc;
> +
> +    spin_lock_irqsave(&desc->lock, flags);
> +
> +    ret = -EINVAL;
> +    if ( !test_bit(_IRQ_GUEST, &desc->status) )
> +        goto unlock;
> +
> +    ret = -EINVAL;

A bit redundant, or should nestle the info = like you did above with the
test_bit.

> +    info = irq_get_guest_info(desc);
> +    if ( d != info->d )
> +        goto unlock;
> +
> +    ret = gic_remove_irq_from_guest(d, virq, desc);
> +
> +    spin_unlock_irqrestore(&desc->lock, flags);
> +
> +    if ( !ret )

This is a bit unconventional (it looks essentially like you have three
exit paths, with this extra special success case and two error cases).

It would better if the gic_remove_irq_from_guest failure case went to
unlock like all the other failure cases, then the success path would be
a straight line.

(yes, that would mean a goto unlock right before the first spin_unlock,
but the code flow would be clearer).

> +    {
> +        release_irq(desc->irq, info);
> +        xfree(info);
> +    }
> +
> +    return ret;
> +
> +unlock:
> +    spin_unlock_irqrestore(&desc->lock, flags);
> +
> +    return ret;
> +}
> +
>  /*
>   * pirq event channels. We don't use these on ARM, instead we use the
>   * features of the GIC to inject virtualised normal interrupts.
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index fc8a270..4ddfd73 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -133,6 +133,22 @@ void register_vgic_ops(struct domain *d, const struct vgic_ops *ops)
>  
>  void domain_vgic_free(struct domain *d)
>  {
> +    int i;
> +    int ret;
> +
> +    for ( i = 0; i < (d->arch.vgic.nr_spis); i++ )
> +    {
> +        struct pending_irq *p = &d->arch.vgic.pending_irqs[i];

Is there not a helper for this lookup? If so it should be used.

Ian.

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-02-20 15:15   ` Ian Campbell
  2015-02-20 16:09     ` Julien Grall
@ 2015-02-20 16:35     ` Jan Beulich
  2015-02-23 15:48     ` Andrew Cooper
  2 siblings, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-02-20 16:35 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall
  Cc: Wei Liu, George Dunlap, Andrew Cooper, IanJackson, tim,
	stefano.stabellini, xen-devel, Daniel De Graaf, KeirFraser

>>> On 20.02.15 at 16:15, <ian.campbell@citrix.com> wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>     This is a follow-up of 
> http://lists.xen.org/archives/html/xen-devel/2014-11/msg00522.html 
>> 
>>     TODO: What about migration? For now the configuration lives in internal
>>     libxl structure. We need a way to pass the domain configuration to the
>>     other end.
> 
> Things like the GIC version and number of SPIs would normally end up
> being encoded in the hvm save records, i.e. the blob which Xen provides
> to the toolstack to be included in the save stream. That would then be
> alongside the actual related interrupt architectural state etc (e.g.
> pending, active, masked etc).
> 
> That's problematic here because you can't pass that blob to the create
> function and the toolstack cannot really parse the blob to figure out
> the details to pass.
> 
> Looking back at msg00522.html it does seem like migration is a good
> motivation for doing it as a separate hypercall as you originally did,
> so initial create would be
> 	DOMCTL_create
> 	DOMCTL_set_the_variables
> and restore would be
> 	DOMCTL_create
> 	DOMCTL_restore_from_blob
> 
> In both cases this needn't preclude requiring the call to be made before
> unpause or that it is only called exactly once.
> 
> Write once HVM params would be another option here.
> 
> Jan, do you find any of that convincing as to the need for doing this
> outside the the create domctl? Based on msg00522 is seems you would
> prefer some HVM params over a new domctl?

Not really (HVM params are already being dealt with for migration
iirc, i.e. one wouldn't even need to think about that aspect), but
considering the other domctl-vs-HVM-param discussion we're having
I suppose at least Andrew might be of a different opinion. My main
reservation against domctl-s is (more there than here) that HVM
params scale better (there it's domain creation flag being defined,
of which we have only so many), along with said "built-in" migration.

But then again - if everyone else thinks domctl-s are the mechanism
to use (here and there), I don#t want to stand in the way...

Jan

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-02-20 16:09     ` Julien Grall
@ 2015-02-20 16:37       ` Jan Beulich
  2015-02-23 15:09       ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-02-20 16:37 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall
  Cc: Wei Liu, George Dunlap, Andrew Cooper, Ian Jackson, tim,
	stefano.stabellini, xen-devel, Daniel De Graaf, Keir Fraser

>>> On 20.02.15 at 17:09, <julien.grall@linaro.org> wrote:
> On 20/02/15 15:15, Ian Campbell wrote:
>> Jan, do you find any of that convincing as to the need for doing this
>> outside the the create domctl? Based on msg00522 is seems you would
>> prefer some HVM params over a new domctl?
> 
> The problem with HVM params is we need to wait until every HVM
> parameters is set and we have to do it before vCPU are initialized.

vCPU initialization could simply fail is certain params didn't get set yet.

Jan

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-01-29 12:33           ` Stefano Stabellini
@ 2015-02-20 16:53             ` Ian Campbell
  2015-02-23  9:33               ` Jan Beulich
  2015-02-23 15:51               ` Julien Grall
  0 siblings, 2 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 16:53 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: xen-devel, Julien Grall, tim, Jan Beulich, stefano.stabellini

On Thu, 2015-01-29 at 12:33 +0000, Stefano Stabellini wrote:
> On Thu, 29 Jan 2015, Julien Grall wrote:
> > On 29/01/15 12:17, Stefano Stabellini wrote:
> > > On Wed, 28 Jan 2015, Julien Grall wrote:
> > >> Hi Stefano,
> > >>
> > >> On 28/01/15 18:52, Stefano Stabellini wrote:
> > >>> On Tue, 13 Jan 2015, Julien Grall wrote:
> > >>>> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
> > >>>> assign/deassign a physical IRQ to the guest (via the config options "irqs"
> > >>>> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
> > >>>> channel). As ARM doesn't have a such concept, we could reuse it to bound
> > >>>> a physical IRQ to a virtual IRQ.
> > >>>>
> > >>>> For now, we allow only SPIs to be mapped to the guest.
> > >>>> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
> > >>>>
> > >>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> > >>>> Cc: Jan Beulich <jbeulich@suse.com>
> > >>>>
> > >>>> ---
> > >>>>     I'm not sure it's the best solution to reuse hypercalls for a
> > >>>>     different purpose. If x86 plan to have a such concept (i.e binding a
> > >>>>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
> > >>>>     Any thoughs?
> > >>>
> > >>> I think it is OK, as long as we write down very clearly what we are
> > >>> doing.

Would adding MAP_PIRQ_TYPE_PPI (even as an alias for TYPE_GSI) be
helpful?

I have a feeling not, since type is, I think, declaring the "namespace"
of the index parameter, whereas the pirq is the one containing the vGIC
provided virq (or the pirq-type evtchn on x86). Does that make sense?

Are we absolutely 100% sure that we will never ever want to map hardware
IRQs to guests on ARMs using pirq-type event channels? Because that is
what we are essentially ruling out here.

x86 is, I think, in the process of gaining vapic support and things like
direct irq injection -- essentially the same as what we are doing here.
In that case they clearly won't be able to use the same interfaces.

The main issue is that physdevop is a stable ABI interface, once we use
it one way we are stuck with it. Is there actually any need for this
"map a physical irq to a hardware virtualised guest irq" to be a stable
API (i.e. used from the dom0 kernel)? If not then I'm inclined to
suggest that we can skirt all of these concerns by just adding a new
domctl and be done with it. Internally it would perhaps share a lot of
code with the map_pirq call, but externally it would give us more
flexibility...

Jan, do you have any feeling for how this is going to play out on x86
with the vapic stuff?

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

* Re: [PATCH v3 14/24] xen/dts: Use unsigned int for MMIO and IRQ index
  2015-01-13 14:25 ` [PATCH v3 14/24] xen/dts: Use unsigned int for MMIO and IRQ index Julien Grall
@ 2015-02-20 16:55   ` Ian Campbell
  2015-02-23 15:57     ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 16:55 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> There is no reason to use signed integer for an index.

Did you check for now pointless "if ( uthing < 0 ) which a picky
compiler might whinge about?

> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

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

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

* Re: [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-01-13 14:25 ` [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest Julien Grall
@ 2015-02-20 16:56   ` Ian Campbell
  2015-02-20 17:43     ` Julien Grall
  2015-02-23 15:30   ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 16:56 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Signed-off-by: Julien Grall <julien.grall@linaro.org>

Is this function still needed in the new model which doesn't do
automatic mappings etc?

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-01-13 14:25 ` [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct Julien Grall
  2015-01-19 17:02   ` Jan Beulich
@ 2015-02-20 16:58   ` Ian Campbell
  2015-02-20 17:45     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 16:58 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Jan Beulich, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> This new function will correctly initialize the IOMMU page table for the
> current domain.
> 
> Also use it in iommu_assign_dt_device even though the current IOMMU
> implementation on ARM shares P2M with the processor.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Jan Beulich <jbeulich@suse.com>

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

Although I'm not actually sure what it is going to be used for.

Also, needs Jan to ack I think.

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-02-20 15:38   ` Ian Campbell
@ 2015-02-20 17:01     ` Julien Grall
  2015-02-23 15:12       ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:01 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 20/02/15 15:38, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> When a device is marked for passthrough (via the new property "xen,passthrough"),
>> dom0 must not access to the device (i.e not loading a driver), but should
> 
> "must not access the device (i.e. not load a driver)"
> 
> perhaps "should still be able"
> 
>> be able to manage the MMIO/interrupt of the passthrough device.
>>
>> The latter part will allow the toolstack to map MMIO/IRQ when a device
>> is pass through to a guest.
>>
>> The property "xen,passthrough" will be translated as 'status="disabled"'
>> in the device tree to avoid DOM0 using the device. We assume that DOM0 is
>> able to cope with this property (already the case for Linux).
> 
> Is it true to say "already the case for Linux, and required by ePAPR"?
> Or are we relying on a Linux implementation detail here?

The ePAPR says:

"Indicates that the device is not presently operational, but it might
become operational in the future (for example, something is not plugged
in, or switched off).
Refer to the device binding for details on what disabled means for a
given device."

So I think we can say "required by ePAPR".

>> diff --git a/docs/misc/arm/device-tree/passthrough.txt b/docs/misc/arm/device-tree/passthrough.txt
>> new file mode 100644
>> index 0000000..04645b3
>> --- /dev/null
>> +++ b/docs/misc/arm/device-tree/passthrough.txt
>> @@ -0,0 +1,7 @@
>> +Device passthrough
>> +===================
>> +
>> +Any device that will be passthrough to a guest should have a property
>> +"xen,passthrough" in their device tree node.
>> +
>> +The device won't be exposed to DOM0 and therefore no driver will be loaded.
> 
> This (and the commit message to some extent) seem stricter than what I
> think is actually required here.
> 
> I understand that it is a very good idea for any sort of passthrough to
> prevent dom0 from messing with a device before it gets assigned to the
> eventual guest domain.
> 
> But AIUI it is not strictly speaking a hard requirement that dom0 does
> not do this and depending on the device it may be perfectly acceptable
> for dom0 to drive a device for a bit and then give it to a guest and
> then have it back again etc.

When the device has the property "xen,passthrough", Xen won't map the
MMIO and IRQ to DOM0. So it's an hard requirement.

We may want to be less strict if we decide to let DOM0 cope with
platform device passthrough (as it's done for PCI).

But this is more complicate than the current use case for this type of
passthrough.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-01-13 14:25 ` [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest Julien Grall
  2015-01-20  9:19   ` Jan Beulich
  2015-01-28 18:59   ` Stefano Stabellini
@ 2015-02-20 17:03   ` Ian Campbell
  2015-02-20 17:46     ` Julien Grall
  2 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 17:03 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Jan Beulich, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:

Subject: "release the DT devices assigned to a guest earlier"

> The toolstack may not have deassign every device used by a guest.

"deassigned"

> Therefore we have to go through the device list and removing them before

"and remove them"

> asking the IOMMU drivers to release memory for this domain.
> 
> This can be done by moving the call to the release function when we
> relinquish the resources. The IOMMU part will be destroyed later when
> the domain is freed.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Jan Beulich <jbeulich@suse.com>

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

I'd like to hear Jan's opinion though.

> 
> ---
>     Changes in v3:
>         - Patch added. Superseed the patch "xen/passthrough: call
>         arch_iommu_domain_destroy before calling iommu teardown" in
>         the previous patch series.
> ---
>  xen/arch/arm/domain.c                 | 4 ++++
>  xen/drivers/passthrough/arm/iommu.c   | 1 -
>  xen/drivers/passthrough/device_tree.c | 5 ++++-
>  xen/include/xen/iommu.h               | 2 +-
>  4 files changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 6e56665..d85748a 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -772,6 +772,10 @@ int domain_relinquish_resources(struct domain *d)
>      switch ( d->arch.relmem )
>      {
>      case RELMEM_not_started:
> +        ret = iommu_release_dt_devices(d);
> +        if ( ret )
> +            return ret;
> +
>          d->arch.relmem = RELMEM_xen;
>          /* Falltrough */
>  
> diff --git a/xen/drivers/passthrough/arm/iommu.c b/xen/drivers/passthrough/arm/iommu.c
> index 5870aef..8223a39 100644
> --- a/xen/drivers/passthrough/arm/iommu.c
> +++ b/xen/drivers/passthrough/arm/iommu.c
> @@ -66,7 +66,6 @@ int arch_iommu_domain_init(struct domain *d)
>  
>  void arch_iommu_domain_destroy(struct domain *d)
>  {
> -    iommu_dt_domain_destroy(d);
>  }
>  
>  int arch_iommu_populate_page_table(struct domain *d)
> diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
> index 88e496e..e7eb34f 100644
> --- a/xen/drivers/passthrough/device_tree.c
> +++ b/xen/drivers/passthrough/device_tree.c
> @@ -97,7 +97,7 @@ int iommu_dt_domain_init(struct domain *d)
>      return 0;
>  }
>  
> -void iommu_dt_domain_destroy(struct domain *d)
> +int iommu_release_dt_devices(struct domain *d)
>  {
>      struct hvm_iommu *hd = domain_hvm_iommu(d);
>      struct dt_device_node *dev, *_dev;
> @@ -109,5 +109,8 @@ void iommu_dt_domain_destroy(struct domain *d)
>          if ( rc )
>              dprintk(XENLOG_ERR, "Failed to deassign %s in domain %u\n",
>                      dt_node_full_name(dev), d->domain_id);
> +        return rc;
>      }
> +
> +    return 0;
>  }
> diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
> index c146ee4..d03df14 100644
> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -117,7 +117,7 @@ void iommu_read_msi_from_ire(struct msi_desc *msi_desc, struct msi_msg *msg);
>  int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev);
>  int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev);
>  int iommu_dt_domain_init(struct domain *d);
> -void iommu_dt_domain_destroy(struct domain *d);
> +int iommu_release_dt_devices(struct domain *d);
>  
>  #endif /* HAS_DEVICE_TREE */
>  

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-02-20 15:42   ` Ian Campbell
@ 2015-02-20 17:03     ` Julien Grall
  2015-02-23 15:15       ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:03 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

On 20/02/15 15:42, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> @@ -919,8 +943,14 @@ static int make_timer_node(const struct domain *d, void *fdt,
>>      return res;
>>  }
>>  
>> -/* Map the device in the domain */
>> -static int map_device(struct domain *d, struct dt_device_node *dev)
>> +/* For a given device node:
> 
> Strictly speaking should be:
>  /*
>   * For a given...
> 
> (I don't care all that much, but since I'm commenting elsewhere)

Hmmm right. I will change it.

>> @@ -947,7 +979,7 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
>>          }
>>      }
>>  
>> -    /* Map IRQs */
>> +    /* Give permission and  map IRQs */
> 
> Another Nit: "  " -> " ".
> 
>> +        if ( need_mapping )
>> +        {
>> +            /*
>> +             * Checking the return of vgic_reserve_virq is not
>> +             * necessary. It should not fail except when we try to map
>> +             * twice the IRQ. This can happen if the IRQ is shared
> 
> "when we try to map the IRQ twice"
> 
> Other than those nits the code itself looks good, will ack once we've
> agreed on the bindings wording.

BTW, should we upstream the bindings to device tree git?

Thanks,

-- 
Julien Grall

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-01-13 14:25 ` [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody Julien Grall
  2015-01-20  9:21   ` Jan Beulich
  2015-01-29 10:20   ` Stefano Stabellini
@ 2015-02-20 17:04   ` Ian Campbell
  2015-02-23  9:40     ` Jan Beulich
  2015-02-23 10:10     ` Julien Grall
  2 siblings, 2 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 17:04 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Jan Beulich, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Currently, when the device is deassigned from a domain, we directly reassign
> to DOM0.
> 
> As the device may not have been correctly reset, this may lead to corruption or
> expose some part of DOM0 memory. Also, we may have no way to reset some
> platform devices.
> 
> If Xen reassigns the device to "nobody", it may receive some global/context
> fault because the transaction has failed (indeed the context has been
> marked invalid). Unfortunately there is no simple way to quiesce a buggy
> hardware. I think we could live with that for a first version of platform
> device passthrough.
> 
> DOM0 will have to issue an hypercall to assign the device to itself if it
> wants to use it.

Does this behaviour differ from x86? If so then it is worth calling that
out explicitly (even if not, good to know I think!)

> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> 
> ---
>     Changes in v3:
>         - Use the coding style of the new SMMU drivers
> 
>     Changes in v2:
>         - Fix typoes in the commit message
>         - Update commit message
> ---
>  xen/drivers/passthrough/arm/smmu.c    | 8 +++++++-
>  xen/drivers/passthrough/device_tree.c | 9 +++------
>  2 files changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
> index 3cf1773..45a2db8 100644
> --- a/xen/drivers/passthrough/arm/smmu.c
> +++ b/xen/drivers/passthrough/arm/smmu.c
> @@ -2774,7 +2774,7 @@ static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
>  	int ret = 0;
>  
>  	/* Don't allow remapping on other domain than hwdom */
> -	if (t != hardware_domain)
> +	if (t && t != hardware_domain)
>  		return -EPERM;
>  
>  	if (t == s)
> @@ -2784,6 +2784,12 @@ static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
>  	if (ret)
>  		return ret;
>  
> +	if (t) {
> +		ret = arm_smmu_assign_dev(t, devfn, dev);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
> index e7eb34f..d9b486e 100644
> --- a/xen/drivers/passthrough/device_tree.c
> +++ b/xen/drivers/passthrough/device_tree.c
> @@ -72,15 +72,12 @@ int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev)
>  
>      spin_lock(&dtdevs_lock);
>  
> -    rc = hd->platform_ops->reassign_device(d, hardware_domain,
> -                                           0, dt_to_dev(dev));
> +    rc = hd->platform_ops->reassign_device(d, NULL, 0, dt_to_dev(dev));
>      if ( rc )
>          goto fail;
>  
> -    list_del(&dev->domain_list);
> -
> -    dt_device_set_used_by(dev, hardware_domain->domain_id);
> -    list_add(&dev->domain_list, &domain_hvm_iommu(hardware_domain)->dt_devices);
> +    list_del_init(&dev->domain_list);
> +    dt_device_set_used_by(dev, DOMID_IO);
>  
>  fail:
>      spin_unlock(&dtdevs_lock);

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

* Re: [PATCH v3 19/24] xen/iommu: arm: Wire iommu DOMCTL for ARM
  2015-01-13 14:25 ` [PATCH v3 19/24] xen/iommu: arm: Wire iommu DOMCTL for ARM Julien Grall
  2015-01-20  9:22   ` Jan Beulich
@ 2015-02-20 17:06   ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 17:06 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Jan Beulich, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

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

(although this does seem to suggest that my decision to use
subarch_do_domctl was flawed -- I should just have inlined
XEN_DOMCTL_set_address_size with a call to a subarch helper)

> Cc: Jan Beulich <jbeulich@suse.com>
> 
> ---
>     Changes in v3:
>         - Add Stefano's ack
> 
>     Changes in v2:
>         - Don't move the call in common code.
> ---
>  xen/arch/arm/domctl.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
> index 485d3aa..cc4894e 100644
> --- a/xen/arch/arm/domctl.c
> +++ b/xen/arch/arm/domctl.c
> @@ -33,7 +33,16 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
>          return p2m_cache_flush(d, s, e);
>      }
>      default:
> -        return subarch_do_domctl(domctl, d, u_domctl);
> +    {
> +        int rc;
> +
> +        rc = subarch_do_domctl(domctl, d, u_domctl);
> +
> +        if ( rc == -ENOSYS )
> +            rc = iommu_do_domctl(domctl, d, u_domctl);
> +
> +        return rc;
> +    }
>      }
>  }
>  

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-02-20 15:52   ` Ian Campbell
@ 2015-02-20 17:09     ` Julien Grall
  2015-02-27 14:33       ` Julien Grall
  2015-02-27 14:25     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:09 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

On 20/02/15 15:52, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> Actually Xen is assuming that the virtual IRQ will always be the same as IRQ.
> 
> s/Actually/Currently/?

Yes, I always mix both because the former is close to the french word.

>> Modify route_guest_irq to take the virtual IRQ in parameter and let Xen
>> assign a different IRQ number.
> 
> I think I must be misunderstanding this, but if route_guest_irq is
> taking the vIRQ as a parameter then why does it then need to assign a
> different IRQ number?
> 
> Oh, did you mean allowing the *caller* to setup a non-1:1 mapping
> perhaps? I think s/and let Xen assign/which allows Xen to.../ might be
> closer to that meaning if that's the intention?

Yes, the IRQ is not mapped 1:1 to the guest. I will replace by "which
allows Xen to...".

>>  Also store the vIRQ in the desc action to
>> easily retrieve easily the IRQ target when we need to inject the interrupt.
> 
> -ETooManyEasilys ;-)
> 
> (I think you want to drop the second one)

Will fix it.

> 
>> As DOM0 will get most the devices, the vIRQ is equal to the IRQ in that case.
> 
> Am I correct that after this patch all callers still pass irq==virq to
> the new function?
> 
>> At the same time modify the behavior of irq_get_domain. The function now
>> assumes that the irq_desc belongs to an IRQ assigned to a guest.
> 
> s/assumes/requires/?

Will fix it.

>>  
>>      action = xmalloc(struct irqaction);
>> -    if (!action)
>> +    if ( !action )
>> +        return -ENOMEM;
>> +
>> +    info = xmalloc(struct irq_guest);
> 
> FWIW you might (subject to sizing/alignment needs) be able to do
> 	action = _xmalloc(sizeof(struct irqaction) + sizeof(struct irq_guest);
> 	info = (sturct irq_guest *)(action + 1);
> 
> which would save some memory overhead for free pointers etc and allow
> you to avoid manually managing the info.
> 
> You probably won't like that though, so feel free to ignore.

Actually it's a good idea :). I haven't though about it.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-01-13 14:25 ` [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device Julien Grall
  2015-01-20  9:34   ` Jan Beulich
  2015-01-29 10:29   ` Stefano Stabellini
@ 2015-02-20 17:17   ` Ian Campbell
  2015-02-23 16:25     ` Daniel De Graaf
  2015-03-10 16:33     ` Julien Grall
  2 siblings, 2 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 17:17 UTC (permalink / raw)
  To: Julien Grall, Daniel De Graaf
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich, xen-devel

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> TODO: Update the commit message
> 
> A device node is described by a path. It will be used to retrieved the
> node in the device tree and assign the related device to the domain.
> 
> Only device protected by an IOMMU can be assigned to a guest.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> 
> ---
>     Changes in v2:
>         - Use a different number for XEN_DOMCTL_assign_dt_device
> ---
>  tools/libxc/include/xenctrl.h         | 10 ++++
>  tools/libxc/xc_domain.c               | 95 ++++++++++++++++++++++++++++++++--

These bits all look fine.

> +int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
> +                       XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
> +{
> +    int ret;
> +    struct dt_device_node *dev;
> +
> +    /* TODO: How to deal with XSM? */

Adding Daniel.

It seems the PCI ones are protected by 
        xsm_test_assign_device(XSM_HOOK, domctl->u.assign_device.machine_sbdf);

So it seem that either this needs to become "test_assign_pci_device" and
a similar "test_assign_dt_device" needs to be added and plumbed through
or it needs to grow a type parameter and take the union for the
identifier.

The code to apply an XSM context to a DT node would need consideration
too I suppose?

> +    /* TODO: Do we need to check is_dying? Mostly to protect against
> +     * hypercall trying to passthrough a device while we are
> +     * dying.

FWIW the PCI case appears not to care...

> +     */
> +
> +    switch ( domctl->cmd )
> +    {
> +    case XEN_DOMCTL_assign_device:
> +        ret = -ENOSYS;
> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
> +            break;

You added something similar to iommu_do_pci_domctl, would it not be
preferable for the caller to switch on domctl->u.assign_device.dev and
call the correct iommu_do_*_domctl?

Ian.

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

* Re: [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough
  2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
                   ` (24 preceding siblings ...)
  2015-01-13 17:56 ` [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
@ 2015-02-20 17:18 ` Ian Campbell
  2015-02-20 17:47   ` Julien Grall
  25 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-20 17:18 UTC (permalink / raw)
  To: Julien Grall
  Cc: manish.jaggi, tim, stefano.stabellini, suravee.suthikulpanit,
	xen-devel, andrii.tseglytskyi

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:

I've gotten as far as patch #20 but I've run out of time (and it seems
like a good breaking point). I'll look at the last 4 next week.

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

* Re: [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ
  2015-02-20 16:00   ` Ian Campbell
@ 2015-02-20 17:21     ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:21 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 20/02/15 16:00, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> Currently Xen only supports SPIs routing for guest, add a function
>> is_assignable_irq to check if we can assign a given IRQ to the guest.
>>
>> Secondly, make sure the vIRQ is not the greater that the number of IRQs handle
>> to the vGIC and it's an SPIs.
> 
> I think you mean the "number of IRQs handled by the vGIC" (or configured
> in?) and it would just be "an SPI".

I think "configured in" is better here. I will change to "number of IRQs
configured in the vGIC".

>> Thirdly, when the IRQ is already assigned to the domain, check the user
>> is not asking to use a different vIRQ than the one already bound.
>>
>> Finally, desc->arch.type which contains the IRQ type (i.e level/edge) must
>> be correctly configured before. The IRQ type won't be configure when:
>                                 ^routing?

No, I wanted to mean when a IRQ type is not set.

I will replace the last sentence by "This can happen when:"

> 
>>     - the device has been blacklist for the current platform
> 
> "blacklisted".
> 
>>     - the IRQ has not been describe in the device tree
> 
> "described".
> 
>> I think we can safely assume that a user won't never ask to route
>> as such IRQ to the guest.
> 
> Can we now ;-) Does this mean the code doesn't check for and abort on
> these cases?
> <later>Having read further I think you do catch it, so I think you can
> remove that sentence, or at least append "...but we check for this
> anyway"</later>.

Right, this sentence is not clear. What I wanted to mean is we won't
support any IRQ not described in the DT or which belong to a specific
domain.

But with an upcoming patch from Parth, the IRQ configuration
(edge/level) will be deferred until the guest has enabled this IRQ.

>> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
>> index 830832c..af408ac 100644
>> --- a/xen/arch/arm/irq.c
>> +++ b/xen/arch/arm/irq.c
>> @@ -379,6 +379,15 @@ err:
>>      return rc;
>>  }
>>  
>> +bool_t is_assignable_irq(unsigned int irq)
>> +{
>> +    /* For now, we can only route SPIs to the guest */
>> +    return ((irq >= NR_LOCAL_IRQS) && (irq < gic_number_lines()));
>> +}
>> +
>> +/* Route an IRQ to a specific guest.
>> + * For now only SPIs are assignabled to the guest.
> 
> "assignable"
> 
>> + */
>>  int route_irq_to_guest(struct domain *d, unsigned int virq,
>>                         unsigned int irq, const char * devname)
>>  {
>> @@ -388,6 +397,29 @@ int route_irq_to_guest(struct domain *d, unsigned int virq,
>>      unsigned long flags;
>>      int retval = 0;
>>  
>> +    if ( !is_assignable_irq(irq) )
>> +    {
>> +        dprintk(XENLOG_G_ERR, "the IRQ%u is not routable\n", irq);
>> +        return -EINVAL;
>> +    }
>> +
>> +    desc = irq_to_desc(irq);
> 
> I can't remember if this is expensive, but you could safely do it
> further down after more of the sanity checks.

For now we retrieve it from an array. But Vijay's plan to replace the
array by a radix tree.

I will move the whole block (if () ... desc = ) after the vGIC because I
think they should be tight.

> 
>> +
>> +    if ( virq >= vgic_num_irqs(d) )
>> +    {
>> +        dprintk(XENLOG_G_ERR,
>> +                "the vIRQ number %u is too high for domain %u (max = %u)\n",
>> +                irq, d->domain_id, vgic_num_irqs(d));
>> +        return -EINVAL;
>> +    }
>> +
>> +    /* Only routing to virtual SPIs is supported */
>> +    if ( virq < 32 )
> 
> NR_LOCAL_IRQS?

Yes. I think I have multiple place where 32 is open-coded. I will
replace them.

> 
>> +    {
>> +        dprintk(XENLOG_G_ERR, "IRQ can only be routed to a virtual SPIs");
> 
> Just "SPI".
> 
>> -            printk(XENLOG_ERR "ERROR: IRQ %u is already used by domain %u\n",
>> -                   irq, ad->domain_id);
>> +            dprintk(XENLOG_G_ERR, "IRQ %u is already used by domain %u\n",
>> +                    irq, ad->domain_id);
>>          else
>> -            printk(XENLOG_ERR "ERROR: IRQ %u is already used by Xen\n", irq);
>> +            dprintk(XENLOG_G_ERR, "IRQ %u is already used by Xen\n", irq);
> 
> Is the file/line really needed here? The messages seem reasonably unique
> already.

I don't remember why I made this change. I will drop it.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  2015-02-20 16:07   ` Ian Campbell
@ 2015-02-20 17:28     ` Julien Grall
  2015-02-23 15:20       ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:28 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 20/02/15 16:07, Ian Campbell wrote:
> More importantly: We have (hopefully) guaranteed elsewhere that an PPI
> or SGI can never make it here, I take it. If that's the case then either
> the comment should say that, or more likely, the comment is redundently
> restating the assert's condition.

I will update the comment to /* Caller has already checked that the IRQ
is an SPIs */

>> +    ASSERT(virq >= 32 && virq < vgic_num_irqs(d));
> 
> NR_LOCAL_IRQS?

Yes.

> Also splitting the two conditions into two asserts will make it more
> obvious which one failed if we hit it.

Will do.

>> +
>> +    vgic_lock_rank(v_target, rank, flags);
>> +
>> +    if ( p->desc ||
>> +         /* The VIRQ should not be already enabled by the guest */
>> +         test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) )
>> +        goto out;
>>  
>>      desc->handler = gic_hw_ops->gic_guest_irq_type;
>>      set_bit(_IRQ_GUEST, &desc->status);
>>  
>> -    gic_set_irq_properties(desc, cpumask_of(smp_processor_id()), GIC_PRI_IRQ);
>> +    gic_set_irq_properties(desc, cpumask_of(v_target->processor), priority);
> 
> This smells like a functional change, not a sanity check, what is it
> for?

Hmmm right. I will move it to a separate patch.

> Is v_target->processor always configured, even for the first routing of
> an IRQ to dom0?

Yes, IRQ are routed to CPU0 by default.

> 
> Care needs to be taken here that priority is not under unfettered guest
> control -- since this configures the physical GIC we need to e.g. ensure
> that Xen's own IPIs have higher priority than anything a guest can ever
> set. (Realistically this probably means we want to constrain guests to
> the bottom half of the priority range and expose different BPR etc in
> the vgic, out of scope here though)

The priority is controlled by route_irq_to_guest and set statically
using GIC_PRI_IRQ.

If we decide to hardcoded the priority here, we should drop the
parameter on gic_route_irq_guest. But not keeping both.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-02-20 16:08     ` Ian Campbell
@ 2015-02-20 17:29       ` Julien Grall
  2015-02-23 15:22         ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:29 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich, xen-devel

On 20/02/15 16:08, Ian Campbell wrote:
> On Wed, 2015-01-28 at 18:26 +0000, Stefano Stabellini wrote:
> 
>>> +        int spi = irq - 32;
>>
>> unsigned int
> 
> and underflow?

No because there is a check (irq < 32) before using the variable spi.
It was more convenient to initialize it directly.


Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-02-20 16:23   ` Ian Campbell
@ 2015-02-20 17:31     ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:31 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich, xen-devel

Hi Ian,

On 20/02/15 16:23, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> Each domain may have a different number of IRQs depending on the devices
>> assigned to it.
>>
>> Rather re-using the number of IRQs used by the hardwared GIC, let the
>         ^than and "hardware" (although "physical" might be better)
> 
>> toolstack specify the number of SPIs when the domain is created. This
>> will avoid to waste memory.
> 
> "will avoid wasting memory".
> 
>> To calculate the number of SPIs, we assume that any IRQ given via the option
>> "irqs=" in xl is mapped 1:1 to the guest.
> 
> I don't see any xl changes here, and I think all that really matters is
> the semantics of the libxl_domain_build_info.irqs[] array, which
> currently I think can only express 1:1 mappings anyway.
> So:
> 
> "To calculate the number of SPIs, we take advantage of the fact that the
> libxl interface can only expose a 1:1 mapping and look for the largest
> SPI in the list" or something.

I will use this.

Regards,


-- 
Julien Grall

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

* Re: [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying
  2015-02-20 16:31   ` Ian Campbell
@ 2015-02-20 17:41     ` Julien Grall
  2015-02-23 15:25       ` Ian Campbell
  2015-03-03 12:50       ` Julien Grall
  0 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:41 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 20/02/15 16:31, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> 
>> Futhermore, a guest can crash and let the IRQ in an incorrect state (i.e has
> 
> "Furthermore" (I think your finger macros have this one wrong, you might
> want to grep the series ;-))

I do this mistake every-time. I will check this series (and upcoming series)

> 
>> +    /* TODO: Handle eviction from LRs. For now, deny remove if the IRQ
>> +     * is inflight and not disabled.
> 
> If we are ungracefully killing a guest doesn't this risk ending up with
> an undestroyable domain? i.e. if the guest is paused with an inflight
> IRQ and then destroyed, how does the inflight IRQ ever become
> not-inflight again? A similar argument could apply if the guest has e.g.
> crashed, paniced or is otherwise not processing any more interrupts or
> generating EOIs for existing ones.

No, this will fall on the "is_dying" part. During domain destruction,
the hypervisor will release all the IRQ still assigned to the guest one
by one.

> We need to be able to kill a guest in such a state somehow.

The TODO is here for running domain where we try to deassign an inflight
IRQ.

> (BTW, I notice the comment style is consistently wrong through the
> series)

I will check all the patches.

>> +    /* Only SPIs are supported */
>> +    if ( virq < 32 || virq >= vgic_num_irqs(d) )
>> +        return -EINVAL;
>> +
>> +    p = irq_to_pending(d->vcpu[0], virq);
>> +    if ( !p->desc )
>> +        return -EINVAL;
> 
> Are we seeing this pattern a lot? It seems so, I wonder if a helper
> could be useful:
>        p = spi_to_pending(d, virq);
>        if ( !p->desc )
>            return -EINVAL;
> 
> with the < 32 check etc in the helper where it only needs commenting on
> once.

IIRC, there is only 2 places. I will replace it by an helper.

>> +
>> +    desc = p->desc;
>> +
>> +    spin_lock_irqsave(&desc->lock, flags);
>> +
>> +    ret = -EINVAL;
>> +    if ( !test_bit(_IRQ_GUEST, &desc->status) )
>> +        goto unlock;
>> +
>> +    ret = -EINVAL;
> 
> A bit redundant, or should nestle the info = like you did above with the
> test_bit.

I will invert it.

>> +    info = irq_get_guest_info(desc);
>> +    if ( d != info->d )
>> +        goto unlock;
>> +
>> +    ret = gic_remove_irq_from_guest(d, virq, desc);
>> +
>> +    spin_unlock_irqrestore(&desc->lock, flags);
>> +
>> +    if ( !ret )
> 
> This is a bit unconventional (it looks essentially like you have three
> exit paths, with this extra special success case and two error cases).
> 
> It would better if the gic_remove_irq_from_guest failure case went to
> unlock like all the other failure cases, then the success path would be
> a straight line.
> 
> (yes, that would mean a goto unlock right before the first spin_unlock,
> but the code flow would be clearer).

I will do.

> 
>> +    {
>> +        release_irq(desc->irq, info);
>> +        xfree(info);
>> +    }
>> +
>> +    return ret;
>> +
>> +unlock:
>> +    spin_unlock_irqrestore(&desc->lock, flags);
>> +
>> +    return ret;
>> +}
>> +
>>  /*
>>   * pirq event channels. We don't use these on ARM, instead we use the
>>   * features of the GIC to inject virtualised normal interrupts.
>> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
>> index fc8a270..4ddfd73 100644
>> --- a/xen/arch/arm/vgic.c
>> +++ b/xen/arch/arm/vgic.c
>> @@ -133,6 +133,22 @@ void register_vgic_ops(struct domain *d, const struct vgic_ops *ops)
>>  
>>  void domain_vgic_free(struct domain *d)
>>  {
>> +    int i;
>> +    int ret;
>> +
>> +    for ( i = 0; i < (d->arch.vgic.nr_spis); i++ )
>> +    {
>> +        struct pending_irq *p = &d->arch.vgic.pending_irqs[i];
> 
> Is there not a helper for this lookup? If so it should be used.

The irq_pending code is adding extra-check. But I guess we don't care
for domain destruction?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-02-20 16:56   ` Ian Campbell
@ 2015-02-20 17:43     ` Julien Grall
  2015-02-23 15:29       ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:43 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

On 20/02/15 16:56, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> Is this function still needed in the new model which doesn't do
> automatic mappings etc?

It's used is the pass-through DOMCTL code.

Regards,


-- 
Julien Grall

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-02-20 16:58   ` Ian Campbell
@ 2015-02-20 17:45     ` Julien Grall
  2015-02-23 15:31       ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:45 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, Jan Beulich, stefano.stabellini

On 20/02/15 16:58, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> This new function will correctly initialize the IOMMU page table for the
>> current domain.
>>
>> Also use it in iommu_assign_dt_device even though the current IOMMU
>> implementation on ARM shares P2M with the processor.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Jan Beulich <jbeulich@suse.com>
> 
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
> 
> Although I'm not actually sure what it is going to be used for.

The caller are in this patch too :) (see pci.c and device_tree.c changes).

> Also, needs Jan to ack I think.

I have some comments from Jan which I need to address in the next series.

Regards,


-- 
Julien Grall

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

* Re: [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-02-20 17:03   ` Ian Campbell
@ 2015-02-20 17:46     ` Julien Grall
  2015-02-23  9:37       ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:46 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, Jan Beulich, stefano.stabellini

On 20/02/15 17:03, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> 
> Subject: "release the DT devices assigned to a guest earlier"
> 
>> The toolstack may not have deassign every device used by a guest.
> 
> "deassigned"
> 
>> Therefore we have to go through the device list and removing them before
> 
> "and remove them"
> 
>> asking the IOMMU drivers to release memory for this domain.
>>
>> This can be done by moving the call to the release function when we
>> relinquish the resources. The IOMMU part will be destroyed later when
>> the domain is freed.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Jan Beulich <jbeulich@suse.com>
> 
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
> 
> I'd like to hear Jan's opinion though.

FWIW, this is how it's done for PCI.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough
  2015-02-20 17:18 ` Ian Campbell
@ 2015-02-20 17:47   ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-20 17:47 UTC (permalink / raw)
  To: Ian Campbell
  Cc: manish.jaggi, tim, stefano.stabellini, suravee.suthikulpanit,
	xen-devel, andrii.tseglytskyi

On 20/02/15 17:18, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> 
> I've gotten as far as patch #20 but I've run out of time (and it seems
> like a good breaking point). I'll look at the last 4 next week.

Thanks for the review! I will address all the comments next week.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-20 16:53             ` Ian Campbell
@ 2015-02-23  9:33               ` Jan Beulich
  2015-02-23 15:28                 ` Ian Campbell
  2015-02-23 15:51               ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-02-23  9:33 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini
  Cc: xen-devel, Julien Grall, stefano.stabellini, tim

>>> On 20.02.15 at 17:53, <ian.campbell@citrix.com> wrote:
> Jan, do you have any feeling for how this is going to play out on x86
> with the vapic stuff?

The vapic logic shouldn't require any physdevop involvement, so if
I read right what you propose (not having such a requirement /
connection on ARM) either, I agree that a new domctl should be all
that's needed (if XEN_DOMCTL_{,un}bind_pt_irq can't be re-used).

Jan

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

* Re: [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-02-20 17:46     ` Julien Grall
@ 2015-02-23  9:37       ` Jan Beulich
  2015-02-23 15:33         ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-02-23  9:37 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall; +Cc: xen-devel, stefano.stabellini, tim

>>> On 20.02.15 at 18:46, <julien.grall@linaro.org> wrote:
> On 20/02/15 17:03, Ian Campbell wrote:
>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> 
>> Subject: "release the DT devices assigned to a guest earlier"
>> 
>>> The toolstack may not have deassign every device used by a guest.
>> 
>> "deassigned"
>> 
>>> Therefore we have to go through the device list and removing them before
>> 
>> "and remove them"
>> 
>>> asking the IOMMU drivers to release memory for this domain.
>>>
>>> This can be done by moving the call to the release function when we
>>> relinquish the resources. The IOMMU part will be destroyed later when
>>> the domain is freed.
>>>
>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>> Cc: Jan Beulich <jbeulich@suse.com>
>> 
>> Acked-by: Ian Campbell <ian.campbell@citrix.com>
>> 
>> I'd like to hear Jan's opinion though.
> 
> FWIW, this is how it's done for PCI.

Right, IOW I agree to the idea of the patch.

Jan

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-20 17:04   ` Ian Campbell
@ 2015-02-23  9:40     ` Jan Beulich
  2015-02-23 10:10       ` Julien Grall
  2015-02-23 10:10     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-02-23  9:40 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall; +Cc: xen-devel, stefano.stabellini, tim

>>> On 20.02.15 at 18:04, <ian.campbell@citrix.com> wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> Currently, when the device is deassigned from a domain, we directly reassign
>> to DOM0.
>> 
>> As the device may not have been correctly reset, this may lead to corruption 
> or
>> expose some part of DOM0 memory. Also, we may have no way to reset some
>> platform devices.
>> 
>> If Xen reassigns the device to "nobody", it may receive some global/context
>> fault because the transaction has failed (indeed the context has been
>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
>> hardware. I think we could live with that for a first version of platform
>> device passthrough.
>> 
>> DOM0 will have to issue an hypercall to assign the device to itself if it
>> wants to use it.
> 
> Does this behaviour differ from x86? If so then it is worth calling that
> out explicitly (even if not, good to know I think!)

Indeed this is different from x86, and I think such behavior should
be consistent across architectures. If Dom0 isn't handed back the
device, who's going to do the supposedly prerequisite reset? On
x86/PCI that's pciback's job, and it would be illegitimate for the
driver to do _anything_ with the device if it wasn't owned by Dom0.

Jan

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23  9:40     ` Jan Beulich
@ 2015-02-23 10:10       ` Julien Grall
  2015-02-23 10:20         ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 10:10 UTC (permalink / raw)
  To: Jan Beulich, Ian Campbell; +Cc: xen-devel, stefano.stabellini, tim

Hi Jan,

On 23/02/2015 09:40, Jan Beulich wrote:
>>>> On 20.02.15 at 18:04, <ian.campbell@citrix.com> wrote:
>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>> Currently, when the device is deassigned from a domain, we directly reassign
>>> to DOM0.
>>>
>>> As the device may not have been correctly reset, this may lead to corruption
>> or
>>> expose some part of DOM0 memory. Also, we may have no way to reset some
>>> platform devices.
>>>
>>> If Xen reassigns the device to "nobody", it may receive some global/context
>>> fault because the transaction has failed (indeed the context has been
>>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
>>> hardware. I think we could live with that for a first version of platform
>>> device passthrough.
>>>
>>> DOM0 will have to issue an hypercall to assign the device to itself if it
>>> wants to use it.
>>
>> Does this behaviour differ from x86? If so then it is worth calling that
>> out explicitly (even if not, good to know I think!)
> Indeed this is different from x86, and I think such behavior should
> be consistent across architectures. If Dom0 isn't handed back the
> device, who's going to do the supposedly prerequisite reset? On
> x86/PCI that's pciback's job, and it would be illegitimate for the
> driver to do _anything_ with the device if it wasn't owned by Dom0.

I think we already had this discussion on a previous version...

Right now, there is no possibility to reset a platform device in the 
kernel. There is some discussion about it but nothing more.

This series doesn't intend to have a generic solution for platform 
device pass-through. It's target embedded people who will always 
passthrough the same device to the same guest.

As DOM0 *should not* use the device (no reset driver, and no possibility 
to unbind), the safest way is to reassign the device to nobody.

So if the device is not quiescent it may mess up DOM0.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-20 17:04   ` Ian Campbell
  2015-02-23  9:40     ` Jan Beulich
@ 2015-02-23 10:10     ` Julien Grall
  2015-02-23 15:34       ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 10:10 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, Jan Beulich, stefano.stabellini



On 20/02/2015 17:04, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> Currently, when the device is deassigned from a domain, we directly reassign
>> to DOM0.
>>
>> As the device may not have been correctly reset, this may lead to corruption or
>> expose some part of DOM0 memory. Also, we may have no way to reset some
>> platform devices.
>>
>> If Xen reassigns the device to "nobody", it may receive some global/context
>> fault because the transaction has failed (indeed the context has been
>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
>> hardware. I think we could live with that for a first version of platform
>> device passthrough.
>>
>> DOM0 will have to issue an hypercall to assign the device to itself if it
>> wants to use it.
>
> Does this behaviour differ from x86? If so then it is worth calling that
> out explicitly (even if not, good to know I think!)

What do you mean by "calling that out explicitly"?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23 10:10       ` Julien Grall
@ 2015-02-23 10:20         ` Jan Beulich
  2015-02-23 15:39           ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-02-23 10:20 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall; +Cc: xen-devel, stefano.stabellini, tim

>>> On 23.02.15 at 11:10, <julien.grall@linaro.org> wrote:
> Hi Jan,
> 
> On 23/02/2015 09:40, Jan Beulich wrote:
>>>>> On 20.02.15 at 18:04, <ian.campbell@citrix.com> wrote:
>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>> Currently, when the device is deassigned from a domain, we directly reassign
>>>> to DOM0.
>>>>
>>>> As the device may not have been correctly reset, this may lead to corruption
>>> or
>>>> expose some part of DOM0 memory. Also, we may have no way to reset some
>>>> platform devices.
>>>>
>>>> If Xen reassigns the device to "nobody", it may receive some global/context
>>>> fault because the transaction has failed (indeed the context has been
>>>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
>>>> hardware. I think we could live with that for a first version of platform
>>>> device passthrough.
>>>>
>>>> DOM0 will have to issue an hypercall to assign the device to itself if it
>>>> wants to use it.
>>>
>>> Does this behaviour differ from x86? If so then it is worth calling that
>>> out explicitly (even if not, good to know I think!)
>> Indeed this is different from x86, and I think such behavior should
>> be consistent across architectures. If Dom0 isn't handed back the
>> device, who's going to do the supposedly prerequisite reset? On
>> x86/PCI that's pciback's job, and it would be illegitimate for the
>> driver to do _anything_ with the device if it wasn't owned by Dom0.
> 
> I think we already had this discussion on a previous version...
> 
> Right now, there is no possibility to reset a platform device in the 
> kernel. There is some discussion about it but nothing more.
> 
> This series doesn't intend to have a generic solution for platform 
> device pass-through. It's target embedded people who will always 
> passthrough the same device to the same guest.
> 
> As DOM0 *should not* use the device (no reset driver, and no possibility 
> to unbind), the safest way is to reassign the device to nobody.
> 
> So if the device is not quiescent it may mess up DOM0.

And I think spelling this out in the description is what Ian is
asking for.

Jan

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-01-29 11:03   ` Stefano Stabellini
  2015-01-29 12:02     ` Julien Grall
@ 2015-02-23 11:31     ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 11:31 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, Ian Jackson, Julien Grall, tim, stefano.stabellini, xen-devel

On Thu, 2015-01-29 at 11:03 +0000, Stefano Stabellini wrote:
> On Tue, 13 Jan 2015, Julien Grall wrote:
> > Let the user to pass additional nodes to the guest device tree. For this
> > purpose, everything in the node /passthrough from the partial device tree will
> > be copied into the guest device tree.
> > 
> > The node /aliases will be also copied to allow the user to define aliases
> > which can be used by the guest kernel.
> > 
> > A simple partial device tree will look like:
> > 
> > /dts-v1/;
> > 
> > / {
> >         #address-cells = <2>;
> >         #size-cells = <2>;
> > 
> >         passthrough {
> >             compatible = "simple-bus";
> >             ranges;
> >             #address-cells = <2>;
> >             #size-cells = <2>;
> > 
> >             /* List of your nodes */
> >         }
> > };
> 
> It would be nice to have an example of this under tools/examples.

docs/misc/arm-passthrough.{markdown,txt,something} might be better...

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-01-13 14:25 ` [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM Julien Grall
  2015-01-29 11:03   ` Stefano Stabellini
@ 2015-02-23 11:46   ` Ian Campbell
  2015-02-23 17:06     ` Julien Grall
  2015-02-23 12:03   ` Ian Jackson
  2 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 11:46 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Ian Jackson, stefano.stabellini, Wei Liu

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> Let the user to pass additional nodes to the guest device tree. For this
> purpose, everything in the node /passthrough from the partial device tree will
> be copied into the guest device tree.
> 
> The node /aliases will be also copied to allow the user to define aliases
> which can be used by the guest kernel.
> 
> A simple partial device tree will look like:
> 
> /dts-v1/;
> 
> / {
>         #address-cells = <2>;
>         #size-cells = <2>;

Are these mandatory/required as implied below, or only the ones inside
the passthrough node (which is what I would expect).

> 
>         passthrough {
>             compatible = "simple-bus";
>             ranges;
>             #address-cells = <2>;
>             #size-cells = <2>;
> 
>             /* List of your nodes */
>         }
> };
> 
> Note that:
>     * The interrupt-parent proporties will be added by the toolstack in

"properties"

>     the root node
>     * The properties compatible, ranges, #address-cells and #size-cells
>     in /passthrough are mandatory.

Does ranges need to be the empty form? I think ranges = <stuff stuff>
would be illegal?

> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> 
> ---
>     Changes in v3:
>         - Patch added
> ---
>  docs/man/xl.cfg.pod.5       |   7 ++
>  tools/libxl/libxl_arm.c     | 253 ++++++++++++++++++++++++++++++++++++++++++++
>  tools/libxl/libxl_types.idl |   1 +
>  tools/libxl/xl_cmdimpl.c    |   1 +
>  4 files changed, 262 insertions(+)
> 
> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
> index e2f91fc..225b782 100644
> --- a/docs/man/xl.cfg.pod.5
> +++ b/docs/man/xl.cfg.pod.5
> @@ -398,6 +398,13 @@ not emulated.
>  Specify that this domain is a driver domain. This enables certain
>  features needed in order to run a driver domain.
>  
> +=item B<device_tree=PATH>
> +
> +Specify a partial device tree (compiled via the Device Tree Compiler).
> +Everything under the node "/passthrough" will be copied into the guest
> +device tree. For convenience, the node "/aliases" is also copied to allow
> +the user to defined aliases which can be used by the guest kernel.
> +
>  =back
>  
>  =head2 Devices
> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> index 53177eb..619458b 100644
> --- a/tools/libxl/libxl_arm.c
> +++ b/tools/libxl/libxl_arm.c
> @@ -540,6 +540,238 @@ out:
>      }
>  }
>  
> +static bool check_overrun(uint64_t a, uint64_t b, uint32_t max)
> +{
> +    return ((a + b) > UINT_MAX || (a + b) > max);

Both halves here will fail if e.g. a == UINT64_MAX-1 and b == 2, so e..g
a+b <= UINT_MAX and < max.

To avoid this you should check that a and b are both less than some
fraction of UINT64_MAX before the other checks, which would ensure the
overflow can't happen, perhaps even UINT32_MAX would be acceptable for
this use, depending on the input types involved.


> +/*
> + * Based on fdt_first_subnode and fdt_next_subnode.
> + * We can't use the one helpers provided by libfdt because:
> + *      - It has been introduced in 2013 => Doesn't work on wheezy
> + *      - The prototypes exist but the functions are not exported. Don't
> + *      ask why...
> + *      - There is no version in the header (might be better to use
> + *      configure for this purpose?)
> + */
> +static int _fdt_first_subnode(const void *fdt, int offset)

The _ namespace is for something other than applications (POSIX or the
compiler, I forget which is _ and which __)

Using configure to conditionally compile our own versions with the usual
names would be better I think.

The copyright and licensing of these functions should be included
somewhere either just above their definitions, or maybe you want to put
these into a separate .c file for convenience.

> +{
> +    int depth = 0;
> +
> +    offset = fdt_next_node(fdt, offset, &depth);
> +    if (offset < 0 || depth != 1)
> +        return -FDT_ERR_NOTFOUND;
> +
> +    return offset;
> +}
> +
> +static int _fdt_next_subnode(const void *fdt, int offset)
> +{
> +    int depth = 1;
> +
> +    /*
> +     * With respect to the parent, the depth of the next subnode will be
> +     * the same as the last.
> +     */
> +    do {
> +        offset = fdt_next_node(fdt, offset, &depth);
> +        if (offset < 0 || depth < 1)
> +            return -FDT_ERR_NOTFOUND;
> +    } while (depth > 1);
> +
> +    return offset;
> +}
> +
> +/* Limit the maxixum depth of a node because of the recursion */

"maximum".

> +#define MAX_DEPTH   8

This restriction ought to be in the docs I think.
> +static int copy_node_by_path(libxl__gc *gc, const char *path,
> +                             void *fdt, void *pfdt)
> +{
> +    int nodeoff, r;
> +    const char *name = strrchr(path, '/');
> +
> +    if (!name)
> +        return -FDT_ERR_INTERNAL;
> +
> +    name++;
> +
> +    /* The FDT function to look at node doesn't take into account the
                                      ^a 

> +     * unit (i.e anything after @) when search by name. Check if the
> +     * name exactly match.

"exactly matches" or "names exactly match" (I think the second?)

> +/*
> + * The partial device tree is not copied entirely. Only the relevant bits are
> + * copied to the guest device tree:
> + *  - /passthrough node
> + *  - /aliases node

Would it be easy to add a check for other top-level nodes and
error/warn?

> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index 1214d2e..5651110 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -399,6 +399,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
>      ("kernel",           string),
>      ("cmdline",          string),
>      ("ramdisk",          string),
> +    ("device_tree",      string),

Needs a #define LIBXL_HAVE... in libxl.h

Ian.

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-01-13 14:25 ` [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM Julien Grall
  2015-01-29 11:03   ` Stefano Stabellini
  2015-02-23 11:46   ` Ian Campbell
@ 2015-02-23 12:03   ` Ian Jackson
  2015-02-23 12:44     ` Ian Jackson
  2015-02-23 18:43     ` Julien Grall
  2 siblings, 2 replies; 251+ messages in thread
From: Ian Jackson @ 2015-02-23 12:03 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini, Wei Liu

Julien Grall writes ("[PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM"):
> Let the user to pass additional nodes to the guest device tree. For this
> purpose, everything in the node /passthrough from the partial device tree \
will
> be copied into the guest device tree.

Please wrap your commit messages to 70, not 80.

> +=item B<device_tree=PATH>
> +
> +Specify a partial device tree (compiled via the Device Tree Compiler).
> +Everything under the node "/passthrough" will be copied into the guest
> +device tree. For convenience, the node "/aliases" is also copied to allow
> +the user to defined aliases which can be used by the guest kernel.

This is rather odd.  The config option is `device_tree' but apparently
it is only relevant for passthrough and nothing else can be set with
it.

> +static int check_partial_fdt(libxl__gc *gc, void *fdt, size_t size)
> +{
...
> +    /* Check if the *size and off* fields doesn't overrun the totalsize
> +     * of the partial FDT.
> +     */
> +    if (fdt_totalsize(fdt) > size) {
> +        LOG(ERROR, "Partial FDT totalsize is too big");
> +        return ERROR_FAIL;
> +    }

There's lots and lots of this very fragile binary parsing code.

Is this facility supposed to take untrusted or partially-trusted
partial device trees ?

If so then I suspect we need a different approach.  It might be easer
to rewrite this whole functionality in a programming language which is
less fragile in the face of programming errors, than to try to make
this whole thing secure (and review it).

I'm definitely having XSA-55 flashbacks.

Ian.

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-02-23 12:03   ` Ian Jackson
@ 2015-02-23 12:44     ` Ian Jackson
  2015-02-23 18:43     ` Julien Grall
  1 sibling, 0 replies; 251+ messages in thread
From: Ian Jackson @ 2015-02-23 12:44 UTC (permalink / raw)
  To: Julien Grall, xen-devel, ian.campbell, tim, stefano.stabellini, Wei Liu

Ian Jackson writes ("Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM"):
> Is this facility supposed to take untrusted or partially-trusted
> partial device trees ?

Also, is libfdt intended (and safe) for use with untrusted fdt blobs ?

Ian.

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-01-29 13:48         ` Julien Grall
  2015-01-29 15:04           ` Stefano Stabellini
@ 2015-02-23 14:36           ` Ian Campbell
  2015-02-23 22:02             ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 14:36 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, tim,
	stefano.stabellini, xen-devel

On Thu, 2015-01-29 at 13:48 +0000, Julien Grall wrote:
> On 29/01/15 12:28, Stefano Stabellini wrote:
> > On Thu, 29 Jan 2015, Julien Grall wrote:
> >> On 29/01/15 11:07, Stefano Stabellini wrote:
> >>> On Tue, 13 Jan 2015, Julien Grall wrote:
> >>>> The partial device tree may contains phandle. The Device Tree Compiler
> >>>> tends to allocate the phandle from 1.
> >>>>
> >>>> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
> >>>> that the partial device tree will never contain a such ID.
> >>>>
> >>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> >>>> Cc: Wei Liu <wei.liu2@citrix.com>
> >>>>
> >>>
> >>> Shouldn't we at least check that the partial device tree doesn't contain
> >>> a conflicting phandle?
> >>
> >> I don't think so. This will unlikely happen, and if it happens the guest
> >> will crash with an obvious error.
> > 
> > It is good that the error is obvious.
> > 
> > But how expensive is to check for it?
> 
> I would have to check the validity of the properties (name + value
> size). At least the properties "linux,phandle" and "phandle" should be
> checked.
> 
> Though I could do in copy_properties but I find it hackish.

Can't you just track the largest phandle ever seen during
copy_properties and then use N+1 for the GIC?

> > Think about the poor user that ends up in this situation: the fact that
> > is unlikely only makes it harder for a user to figure out what to do to
> > fix it.
> 
> The poor use will have to write his device tree by hand to hit this
> error ;).

Or use a new version of dtc which does things differently for some
reason.

> So using the right phandle is not a huge drawback.
> 
> Regards,
> 

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

* Re: [PATCH v3 23/24] libxl: Add support for non-PCI passthrough
  2015-01-29 13:51         ` Julien Grall
@ 2015-02-23 14:41           ` Ian Campbell
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 14:41 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, tim,
	stefano.stabellini, xen-devel

On Thu, 2015-01-29 at 13:51 +0000, Julien Grall wrote:
> On 29/01/15 12:31, Stefano Stabellini wrote:
> > On Thu, 29 Jan 2015, Julien Grall wrote:
> >> Hi Stefano,
> >>
> >> On 29/01/15 11:12, Stefano Stabellini wrote:
> >>>> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> >>>> index 029d2e2..b7ef528 100644
> >>>> --- a/tools/libxl/libxl_create.c
> >>>> +++ b/tools/libxl/libxl_create.c
> >>>> @@ -1430,6 +1430,16 @@ static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev,
> >>>
> >>> I think you should at least rename domcreate_attach_pci to something
> >>> more generic, like domcreate_attach_dev.
> >>
> >> Actually I was planning to add a domcreate_attach_dtdev but I forgot
> >> about it.
> >>
> >> What the best approach for this?
> > 
> > Either one would work. But don't add non-PCI passthrough code to a
> > function named domcreate_attach_pci :-)
> 
> Right, it was a quick & dirty implementation which I forgot to clean up.
> 
> >>>
> >>>>          }
> >>>>      }
> >>>>  
> >>>> +    for (i = 0; i < d_config->num_dtdevs; i++) {
> >>>> +
> >>>> +        ret = libxl__device_dt_add(gc, domid, &d_config->dtdevs[i]);
> >>>> +        if (ret < 0) {
> >>>> +            LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
> >>>> +                       "libxl__device_dt_add failed: %d\n", ret);
> >>>> +            goto error_out;
> >>>> +        }
> >>>> +    }
> >>>
> >>> You are allowed to call xc_* functions from here. The
> >>> libxl__device_dt_add wrapper doesn't add much value.
> >>
> >> I would like to keep the wrapper. It's in sync with the PCI solution and
> >> it will avoid refactoring later for add new code.
> > 
> > But in the PCI case there is a lot of code in the function.
> > Regardless if you think it is useful, keep it.
> 
> If we plan to implement a proper platform device pass-through we will
> have to add lots of code.
> 
> Wei, Ian & Ian, do you have any opinions?

A new function (e.g. domcreate_attach_dtdev) between
domcreate_attach_pci and domcreate_console_available in the callback
chain is the right answer, I think.

Unless there is a lot more code to come then I'm not sure adding
libxl_dtdev.c or the function in there is necessary -- just call
xc_assign... from the new domcreate_attach function. It's up to you
though.

Ian.

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

* Re: [PATCH v3 23/24] libxl: Add support for non-PCI passthrough
  2015-01-13 14:25 ` [PATCH v3 23/24] libxl: Add support for non-PCI passthrough Julien Grall
  2015-01-29 11:12   ` Stefano Stabellini
@ 2015-02-23 14:42   ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 14:42 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Ian Jackson, stefano.stabellini, Wei Liu

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index 5651110..c10fd2f 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl

Need a new LIBXL_HAVE here. Perhaps combined into an umbrella one with
the device tree one.

> @@ -522,6 +522,10 @@ libxl_device_pci = Struct("device_pci", [
>      ("seize", bool),
>      ])
>  
> +libxl_device_dtdev = Struct("device_dtdev", [
> +    ("path", string),
> +    ])
> +
>  libxl_device_vtpm = Struct("device_vtpm", [
>      ("backend_domid",    libxl_domid),
>      ("backend_domname",  string),
> @@ -548,6 +552,7 @@ libxl_domain_config = Struct("domain_config", [
>      ("disks", Array(libxl_device_disk, "num_disks")),
>      ("nics", Array(libxl_device_nic, "num_nics")),
>      ("pcidevs", Array(libxl_device_pci, "num_pcidevs")),
> +    ("dtdevs", Array(libxl_device_dtdev, "num_dtdevs")),
>      ("vfbs", Array(libxl_device_vfb, "num_vfbs")),
>      ("vkbs", Array(libxl_device_vkb, "num_vkbs")),
>      ("vtpms", Array(libxl_device_vtpm, "num_vtpms")),

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

* Re: [PATCH v3 24/24] xl: Add new option dtdev
  2015-01-29 15:06           ` Stefano Stabellini
@ 2015-02-23 14:44             ` Ian Campbell
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 14:44 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, Ian Jackson, Julien Grall, tim, stefano.stabellini, xen-devel

On Thu, 2015-01-29 at 15:06 +0000, Stefano Stabellini wrote:
> I don't think it is necessary to have two separate patches, but let's
> see what the libxl maintainers have to say.

For large changes having the split between introducing libxl side and
then using it can be useful, but this change is so small I really don't
think it matters if it is 1 or 2 patches, as long as the series bisects.

Given that it is written as two patches now I see no compelling reason
to change it.

Ian.

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

* Re: [PATCH v3 24/24] xl: Add new option dtdev
  2015-01-13 14:25 ` [PATCH v3 24/24] xl: Add new option dtdev Julien Grall
  2015-01-29 11:18   ` Stefano Stabellini
@ 2015-02-23 14:45   ` Ian Campbell
  2015-02-23 22:03     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 14:45 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Ian Jackson, stefano.stabellini, Wei Liu

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> The option "dtdev" will be used to passthrough a non-PCI device described
> in the device tree to a guest.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> 
> ---
>     Changes in v2:
>         - libxl_device_dt has been rename to libxl_device_dtdev
>         - use xrealloc instead of realloc
> ---
>  docs/man/xl.cfg.pod.5    |  5 +++++
>  tools/libxl/xl_cmdimpl.c | 21 ++++++++++++++++++++-
>  2 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
> index 225b782..cfd3d5f 100644
> --- a/docs/man/xl.cfg.pod.5
> +++ b/docs/man/xl.cfg.pod.5
> @@ -721,6 +721,11 @@ More information about Xen gfx_passthru feature is available
>  on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
>  wiki page.
>  
> +=item B<dtdev=[ "DTDEV_PATH", "DTDEV_PATH", ... ]>
> +
> +Specifies the host device node to passthrough to this guest. Each DTDEV_PATH
                            ^tree?

s/node/nodes/ either way.
 
> +is the absolute path in the device tree.

Can it be an alias?

>  =item B<ioports=[ "IOPORT_RANGE", "IOPORT_RANGE", ... ]>
>  
>  Allow guest to access specific legacy I/O ports. Each B<IOPORT_RANGE>
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> index 31e89e8..80c9df6 100644
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -986,7 +986,7 @@ static void parse_config_data(const char *config_source,
>      long l;
>      XLU_Config *config;
>      XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms;
> -    XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian;
> +    XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs;
>      int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian;
>      int pci_power_mgmt = 0;
>      int pci_msitranslate = 0;
> @@ -1746,6 +1746,25 @@ skip_vfb:
>              libxl_defbool_set(&b_info->u.pv.e820_host, true);
>      }
>  
> +    if (!xlu_cfg_get_list (config, "dtdev", &dtdevs, 0, 0)) {
> +        d_config->num_dtdevs = 0;
> +        d_config->dtdevs = NULL;
> +        for (i = 0; (buf = xlu_cfg_get_listitem(dtdevs, i)) != NULL; i++) {
> +            libxl_device_dtdev *dtdev;
> +
> +            d_config->dtdevs = (libxl_device_dtdev *) xrealloc(d_config->dtdevs, sizeof (libxl_device_dtdev) * (d_config->num_dtdevs + 1));

Please wrap the long line.

(I know there is some bad precedent in this file...)

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-02-20 16:09     ` Julien Grall
  2015-02-20 16:37       ` Jan Beulich
@ 2015-02-23 15:09       ` Ian Campbell
  1 sibling, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:09 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, George Dunlap, tim, Ian Jackson, stefano.stabellini,
	Jan Beulich, Andrew Cooper, xen-devel, Daniel De Graaf,
	Keir Fraser

On Fri, 2015-02-20 at 16:09 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 20/02/15 15:15, Ian Campbell wrote:
> > On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >> On ARM the virtual GIC may differ between each guest (emulated GIC version,
> >> number of SPIs...). Those informations are already known at the domain creation
> > 
> > "This information is already known at domain creation..."
> > 
> >> and can never change.
> >>
> >> For now only the gic_version is set. In long run, there will be more parameters
> > 
> > "In the long run".
> > 
> >> such as the number of SPIs. All will be required to be set at the same time.
> >>
> >> A new arch-specific structure arch_domainconfig has been created, the x86
> >> one doesn't have any specific configuration, a dummy structure
> >> (C-spec compliant) has been created to factorize the code on the toolstack.
> > 
> > I'm not sure what you mean by factorize here.
> 
> There is an arch-specific function where

... truncated sentence?

> 
> > 
> >> Some external tools (qemu, xenstore) may require to create a domain. Rather
> > 
> > "may be required" perhaps? I'm not 100% sure what you are trying to say.
> 
> I meant some external tools (such as qemu, xenstore) needs to create
> domain. So we have to keep the old xc_domain_create.

FWIW libxc does not have a stable interface...

xenstore we could just update in lockstep since it is in the same tree.
(I suppose you are thinking of the stubdom launcher helper).

qemu -- well, I suppose if it is easy to keep it working we might as
well, although I'm not sure it's actually used/maintained (maybe this is
a good way to find out :-P).

> >>     TODO: What about migration? For now the configuration lives in internal
> >>     libxl structure. We need a way to pass the domain configuration to the
> >>     other end.
> > 
> > Things like the GIC version and number of SPIs would normally end up
> > being encoded in the hvm save records, i.e. the blob which Xen provides
> > to the toolstack to be included in the save stream. That would then be
> > alongside the actual related interrupt architectural state etc (e.g.
> > pending, active, masked etc).
> > 
> > That's problematic here because you can't pass that blob to the create
> > function and the toolstack cannot really parse the blob to figure out
> > the details to pass.
> 
> I was thinking to pass those information the same way we do to know the
> domain is a PVH/HVM...
> 
> AFAICT they are required in order to create the domain.

IIRC you said on Friday that you spoke with Andy Cooper and thought
about adding new records to the migration v2 format to allow such things
to be part of the migration stream (with requirements on the ordering).

> > Looking back at msg00522.html it does seem like migration is a good
> > motivation for doing it as a separate hypercall as you originally did,
> > so initial create would be
> > 	DOMCTL_create
> > 	DOMCTL_set_the_variables
> > and restore would be
> > 	DOMCTL_create
> > 	DOMCTL_restore_from_blob
> > 
> > In both cases this needn't preclude requiring the call to be made before
> > unpause or that it is only called exactly once.
> > 
> > Write once HVM params would be another option here.
> > 
> > Jan, do you find any of that convincing as to the need for doing this
> > outside the the create domctl? Based on msg00522 is seems you would
> > prefer some HVM params over a new domctl?
> 
> The problem with HVM params is we need to wait until every HVM
> parameters is set and we have to do it before vCPU are initialized.
> 
> The problem with a new DOMCTL is it make the code more complicate in the
> hypervisor as it require some kind of synchronization to know if
> everything as been correctly initialized.
> 
> > 
> >>     I'm not sure if we should care of this right now as migration doesn't
> >>     yet exists on ARM.
> > 
> > It's a domctl so we aren't exactly painting ourselves into a corner, but
> > it would be good to have some idea that we aren't going down a blind
> > alley at least. Especially if the way out of the alley is to come back
> > to where we are now...
> > 
> > (There doesn't seem much point in looking at the code until we conclude
> > the approach is correct, so I haven't)
> 
> I believe that the migration can be taken in different way without
> modifying the current approach.

What I meant was if that when implementing migration we end up back
where we started before this patch, because that approach turns out to
be the right one, then it's all a bit of a waste of time, so we should
try and understand at least to the level required to have a good feeling
we won't be doing that.

Ian.

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-02-20 17:01     ` Julien Grall
@ 2015-02-23 15:12       ` Ian Campbell
  2015-02-23 15:43         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:12 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Fri, 2015-02-20 at 17:01 +0000, Julien Grall wrote:
> >> diff --git a/docs/misc/arm/device-tree/passthrough.txt b/docs/misc/arm/device-tree/passthrough.txt
> >> new file mode 100644
> >> index 0000000..04645b3
> >> --- /dev/null
> >> +++ b/docs/misc/arm/device-tree/passthrough.txt
> >> @@ -0,0 +1,7 @@
> >> +Device passthrough
> >> +===================
> >> +
> >> +Any device that will be passthrough to a guest should have a property
> >> +"xen,passthrough" in their device tree node.
> >> +
> >> +The device won't be exposed to DOM0 and therefore no driver will be loaded.
> > 
> > This (and the commit message to some extent) seem stricter than what I
> > think is actually required here.
> > 
> > I understand that it is a very good idea for any sort of passthrough to
> > prevent dom0 from messing with a device before it gets assigned to the
> > eventual guest domain.
> > 
> > But AIUI it is not strictly speaking a hard requirement that dom0 does
> > not do this and depending on the device it may be perfectly acceptable
> > for dom0 to drive a device for a bit and then give it to a guest and
> > then have it back again etc.
> 
> When the device has the property "xen,passthrough", Xen won't map the
> MMIO and IRQ to DOM0. So it's an hard requirement.

That's not what I meant.

What I was getting at is that it's not 100% mandatory for a device you
want to pass through to have the "xen,passthrough" property at all, but
the wording of the binding implies otherwise..

There will be at least some devices in the world (even if only trivial
ones) where you can pass them through even if dom0 has been touching
them before. Or dom0 might choose to implement a reset helper for some
device or other.

Ian.

> We may want to be less strict if we decide to let DOM0 cope with
> platform device passthrough (as it's done for PCI).
> 
> But this is more complicate than the current use case for this type of
> passthrough.
> 
> Regards,
> 

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-02-20 17:03     ` Julien Grall
@ 2015-02-23 15:15       ` Ian Campbell
  2015-02-23 15:44         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:15 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Fri, 2015-02-20 at 17:03 +0000, Julien Grall wrote:
> On 20/02/15 15:42, Ian Campbell wrote:
> > On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >> @@ -919,8 +943,14 @@ static int make_timer_node(const struct domain *d, void *fdt,
> >>      return res;
> >>  }
> >>  
> >> -/* Map the device in the domain */
> >> -static int map_device(struct domain *d, struct dt_device_node *dev)
> >> +/* For a given device node:
> > 
> > Strictly speaking should be:
> >  /*
> >   * For a given...
> > 
> > (I don't care all that much, but since I'm commenting elsewhere)
> 
> Hmmm right. I will change it.

FWIW I noticed this pattern a lot in this series.

> >> @@ -947,7 +979,7 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
> >>          }
> >>      }
> >>  
> >> -    /* Map IRQs */
> >> +    /* Give permission and  map IRQs */
> > 
> > Another Nit: "  " -> " ".
> > 
> >> +        if ( need_mapping )
> >> +        {
> >> +            /*
> >> +             * Checking the return of vgic_reserve_virq is not
> >> +             * necessary. It should not fail except when we try to map
> >> +             * twice the IRQ. This can happen if the IRQ is shared
> > 
> > "when we try to map the IRQ twice"
> > 
> > Other than those nits the code itself looks good, will ack once we've
> > agreed on the bindings wording.
> 
> BTW, should we upstream the bindings to device tree git?

Arguably we should upstream all of our bindings (e.g.
docs/misc/arm/device-tree/*, admittedly a single file right now) but
doing just one/some seems worse than keeping them in tree.

IOW it should be all or nothing, and I have no problem with you deciding
that nothing is easier for you here...

Ian.

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

* Re: [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  2015-02-20 17:28     ` Julien Grall
@ 2015-02-23 15:20       ` Ian Campbell
  2015-02-23 15:47         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:20 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Fri, 2015-02-20 at 17:28 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 20/02/15 16:07, Ian Campbell wrote:
> > More importantly: We have (hopefully) guaranteed elsewhere that an PPI
> > or SGI can never make it here, I take it. If that's the case then either
> > the comment should say that, or more likely, the comment is redundently
> > restating the assert's condition.
> 
> I will update the comment to /* Caller has already checked that the IRQ
> is an SPIs */

Just "SPI", but otherwise sounds good.

> > Care needs to be taken here that priority is not under unfettered guest
> > control -- since this configures the physical GIC we need to e.g. ensure
> > that Xen's own IPIs have higher priority than anything a guest can ever
> > set. (Realistically this probably means we want to constrain guests to
> > the bottom half of the priority range and expose different BPR etc in
> > the vgic, out of scope here though)
> 
> The priority is controlled by route_irq_to_guest and set statically
> using GIC_PRI_IRQ.
> 
> If we decide to hardcoded the priority here, we should drop the
> parameter on gic_route_irq_guest. But not keeping both.

There is a middle ground, which is for guest-routed IRQs to be allowed a
subset of the real priorities, but until those associated checks are in
place I think hardcoding in gic_route_irq_to_guest leaves less scope for
mistakes.

Ian.

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-02-20 17:29       ` Julien Grall
@ 2015-02-23 15:22         ` Ian Campbell
  2015-02-23 15:48           ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:22 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, Jan Beulich, xen-devel

On Fri, 2015-02-20 at 17:29 +0000, Julien Grall wrote:
> On 20/02/15 16:08, Ian Campbell wrote:
> > On Wed, 2015-01-28 at 18:26 +0000, Stefano Stabellini wrote:
> > 
> >>> +        int spi = irq - 32;
> >>
> >> unsigned int
> > 
> > and underflow?
> 
> No because there is a check (irq < 32) before using the variable spi.
> It was more convenient to initialize it directly.

You'd have to be sure that "irq - 32" wasn't undefined behaviour then,
or the compiler can decide to omit the rest of the function, or perhaps
just that second check, because things are undefined from the
initialiser onwards.

I think with unsigned you are probably ok.

Ian.

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

* Re: [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying
  2015-02-20 17:41     ` Julien Grall
@ 2015-02-23 15:25       ` Ian Campbell
  2015-02-23 15:49         ` Julien Grall
  2015-03-03 12:50       ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:25 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Fri, 2015-02-20 at 17:41 +0000, Julien Grall wrote:

> >> +    /* TODO: Handle eviction from LRs. For now, deny remove if the IRQ
> >> +     * is inflight and not disabled.
> > 
> > If we are ungracefully killing a guest doesn't this risk ending up with
> > an undestroyable domain? i.e. if the guest is paused with an inflight
> > IRQ and then destroyed, how does the inflight IRQ ever become
> > not-inflight again? A similar argument could apply if the guest has e.g.
> > crashed, paniced or is otherwise not processing any more interrupts or
> > generating EOIs for existing ones.
> 
> No, this will fall on the "is_dying" part. During domain destruction,
> the hypervisor will release all the IRQ still assigned to the guest one
> by one.
> 
> > We need to be able to kill a guest in such a state somehow.
> 
> The TODO is here for running domain where we try to deassign an inflight
> IRQ.

I see. I think either expand the comment to say "for a running domain"
or, probably better, put this bit of code (and the comment) in an else
of the is_dying and get rid of the goto in the is_dying==true case.

> >> +    for ( i = 0; i < (d->arch.vgic.nr_spis); i++ )
> >> +    {
> >> +        struct pending_irq *p = &d->arch.vgic.pending_irqs[i];
> > 
> > Is there not a helper for this lookup? If so it should be used.
> 
> The irq_pending code is adding extra-check. But I guess we don't care
> for domain destruction?

I don't think so.

Ian.

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-23  9:33               ` Jan Beulich
@ 2015-02-23 15:28                 ` Ian Campbell
  2015-02-23 15:53                   ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:28 UTC (permalink / raw)
  To: Jan Beulich
  Cc: xen-devel, tim, Julien Grall, stefano.stabellini, Stefano Stabellini

On Mon, 2015-02-23 at 09:33 +0000, Jan Beulich wrote:
> >>> On 20.02.15 at 17:53, <ian.campbell@citrix.com> wrote:
> > Jan, do you have any feeling for how this is going to play out on x86
> > with the vapic stuff?
> 
> The vapic logic shouldn't require any physdevop involvement, so if
> I read right what you propose (not having such a requirement /
> connection on ARM) either, I agree that a new domctl should be all
> that's needed (if XEN_DOMCTL_{,un}bind_pt_irq can't be re-used).

Actually, I think bind_pt_irq with a new PT_IRQ_TYPE_* would be a good
option.

An ARM SPI is a bit like an ISA IRQ, but not close enough to reuse IMHO
(and the datatype would need widening).

Ian.

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

* Re: [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-02-20 17:43     ` Julien Grall
@ 2015-02-23 15:29       ` Ian Campbell
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:29 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Fri, 2015-02-20 at 17:43 +0000, Julien Grall wrote:
> On 20/02/15 16:56, Ian Campbell wrote:
> > On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> > 
> > Is this function still needed in the new model which doesn't do
> > automatic mappings etc?
> 
> It's used is the pass-through DOMCTL code.

Yeah, I realised that later, sorry.

Ian.

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

* Re: [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-01-13 14:25 ` [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest Julien Grall
  2015-02-20 16:56   ` Ian Campbell
@ 2015-02-23 15:30   ` Ian Campbell
  2015-02-23 16:01     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:30 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:

> +/* This limit is used by the hypercalls to restrict the size of the path */
> +#define DEVICE_TREE_MAX_PATHLEN 1024

Is this something you've made up or derived from the DT spec/ePAPR etc?

Apart from this the patch seems fine, clarifying the genesis of that
number in the commit log would be sufficient for me.

Ian.

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-02-20 17:45     ` Julien Grall
@ 2015-02-23 15:31       ` Ian Campbell
  2015-02-23 16:04         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:31 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, tim, Jan Beulich

On Fri, 2015-02-20 at 17:45 +0000, Julien Grall wrote:
> On 20/02/15 16:58, Ian Campbell wrote:
> > On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >> This new function will correctly initialize the IOMMU page table for the
> >> current domain.
> >>
> >> Also use it in iommu_assign_dt_device even though the current IOMMU
> >> implementation on ARM shares P2M with the processor.
> >>
> >> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >> Cc: Jan Beulich <jbeulich@suse.com>
> > 
> > Acked-by: Ian Campbell <ian.campbell@citrix.com>
> > 
> > Although I'm not actually sure what it is going to be used for.
> 
> The caller are in this patch too :) (see pci.c and device_tree.c changes).

Right, I meant "what non-trivial functionality is going to land here"
i..e what the grandparent callers etc will eventually expect from it.

Ian

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

* Re: [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-02-23  9:37       ` Jan Beulich
@ 2015-02-23 15:33         ` Ian Campbell
  2015-02-23 16:22           ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:33 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, Julien Grall, stefano.stabellini, tim

On Mon, 2015-02-23 at 09:37 +0000, Jan Beulich wrote:
> >>> On 20.02.15 at 18:46, <julien.grall@linaro.org> wrote:
> > On 20/02/15 17:03, Ian Campbell wrote:
> >> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >> 
> >> Subject: "release the DT devices assigned to a guest earlier"
> >> 
> >>> The toolstack may not have deassign every device used by a guest.
> >> 
> >> "deassigned"
> >> 
> >>> Therefore we have to go through the device list and removing them before
> >> 
> >> "and remove them"
> >> 
> >>> asking the IOMMU drivers to release memory for this domain.
> >>>
> >>> This can be done by moving the call to the release function when we
> >>> relinquish the resources. The IOMMU part will be destroyed later when
> >>> the domain is freed.
> >>>
> >>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >>> Cc: Jan Beulich <jbeulich@suse.com>
> >> 
> >> Acked-by: Ian Campbell <ian.campbell@citrix.com>
> >> 
> >> I'd like to hear Jan's opinion though.
> > 
> > FWIW, this is how it's done for PCI.
> 
> Right, IOW I agree to the idea of the patch.

Thanks. If Julien could record this in the form of an ack that would
save me remembering you've said so (otherwise it could just go as a
comment after the --- I suppose).

Ian.

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23 10:10     ` Julien Grall
@ 2015-02-23 15:34       ` Ian Campbell
  2015-03-10 15:29         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:34 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Jan Beulich, stefano.stabellini

On Mon, 2015-02-23 at 10:10 +0000, Julien Grall wrote:
> 
> On 20/02/2015 17:04, Ian Campbell wrote:
> > On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >> Currently, when the device is deassigned from a domain, we directly reassign
> >> to DOM0.
> >>
> >> As the device may not have been correctly reset, this may lead to corruption or
> >> expose some part of DOM0 memory. Also, we may have no way to reset some
> >> platform devices.
> >>
> >> If Xen reassigns the device to "nobody", it may receive some global/context
> >> fault because the transaction has failed (indeed the context has been
> >> marked invalid). Unfortunately there is no simple way to quiesce a buggy
> >> hardware. I think we could live with that for a first version of platform
> >> device passthrough.
> >>
> >> DOM0 will have to issue an hypercall to assign the device to itself if it
> >> wants to use it.
> >
> > Does this behaviour differ from x86?

I realise now that x86 is a red-herring, what I really meant was differ
from other types of device (specifically PCI ones).

>  If so then it is worth calling that
> > out explicitly (even if not, good to know I think!)
> 
> What do you mean by "calling that out explicitly"?

Stating in the commit log or a suitably placed comment (at least under
xen/include/public hopefully) that deassignment of dt devices behaves
differently to deassignment of other types of devices.

Ian.

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23 10:20         ` Jan Beulich
@ 2015-02-23 15:39           ` Ian Campbell
  2015-02-23 16:24             ` Jan Beulich
  2015-02-23 16:37             ` Julien Grall
  0 siblings, 2 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:39 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, Julien Grall, stefano.stabellini, tim

On Mon, 2015-02-23 at 10:20 +0000, Jan Beulich wrote:
> >>> On 23.02.15 at 11:10, <julien.grall@linaro.org> wrote:
> > Hi Jan,
> > 
> > On 23/02/2015 09:40, Jan Beulich wrote:
> >>>>> On 20.02.15 at 18:04, <ian.campbell@citrix.com> wrote:
> >>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >>>> Currently, when the device is deassigned from a domain, we directly reassign
> >>>> to DOM0.
> >>>>
> >>>> As the device may not have been correctly reset, this may lead to corruption
> >>> or
> >>>> expose some part of DOM0 memory. Also, we may have no way to reset some
> >>>> platform devices.
> >>>>
> >>>> If Xen reassigns the device to "nobody", it may receive some global/context
> >>>> fault because the transaction has failed (indeed the context has been
> >>>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
> >>>> hardware. I think we could live with that for a first version of platform
> >>>> device passthrough.
> >>>>
> >>>> DOM0 will have to issue an hypercall to assign the device to itself if it
> >>>> wants to use it.
> >>>
> >>> Does this behaviour differ from x86? If so then it is worth calling that
> >>> out explicitly (even if not, good to know I think!)
> >> Indeed this is different from x86, and I think such behavior should
> >> be consistent across architectures. If Dom0 isn't handed back the
> >> device, who's going to do the supposedly prerequisite reset? On
> >> x86/PCI that's pciback's job, and it would be illegitimate for the
> >> driver to do _anything_ with the device if it wasn't owned by Dom0.
> > 
> > I think we already had this discussion on a previous version...
> > 
> > Right now, there is no possibility to reset a platform device in the 
> > kernel. There is some discussion about it but nothing more.

"there is no possibility to reset a platform device" isn't quite true,
there is certainly a theoretical possibility (i.e. it is obviously the
case that a dom0 could be written to do so for at least some devices).

So what happens if such a dom0 arises in the future? I suppose the
intention is that the user would having deassigned from domU and
determined that there kernel has the necessary feature would do some
sort of xl command to assign to dom0?

> > This series doesn't intend to have a generic solution for platform 
> > device pass-through. It's target embedded people who will always 
> > passthrough the same device to the same guest.
> > 
> > As DOM0 *should not* use the device (no reset driver, and no possibility 
> > to unbind), the safest way is to reassign the device to nobody.
> > 
> > So if the device is not quiescent it may mess up DOM0.
> 
> And I think spelling this out in the description is what Ian is
> asking for.

Yes.

I think it probably ought to be mentioned in the docs surrounding the
hypercalls in question, for both PCI, DT and any other device type
whether or not there is some implicit rebinding or not.

Ian.

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-02-23 15:12       ` Ian Campbell
@ 2015-02-23 15:43         ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-23 15:43 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 23/02/15 15:12, Ian Campbell wrote:
> On Fri, 2015-02-20 at 17:01 +0000, Julien Grall wrote:
>>>> diff --git a/docs/misc/arm/device-tree/passthrough.txt b/docs/misc/arm/device-tree/passthrough.txt
>>>> new file mode 100644
>>>> index 0000000..04645b3
>>>> --- /dev/null
>>>> +++ b/docs/misc/arm/device-tree/passthrough.txt
>>>> @@ -0,0 +1,7 @@
>>>> +Device passthrough
>>>> +===================
>>>> +
>>>> +Any device that will be passthrough to a guest should have a property
>>>> +"xen,passthrough" in their device tree node.
>>>> +
>>>> +The device won't be exposed to DOM0 and therefore no driver will be loaded.
>>>
>>> This (and the commit message to some extent) seem stricter than what I
>>> think is actually required here.
>>>
>>> I understand that it is a very good idea for any sort of passthrough to
>>> prevent dom0 from messing with a device before it gets assigned to the
>>> eventual guest domain.
>>>
>>> But AIUI it is not strictly speaking a hard requirement that dom0 does
>>> not do this and depending on the device it may be perfectly acceptable
>>> for dom0 to drive a device for a bit and then give it to a guest and
>>> then have it back again etc.
>>
>> When the device has the property "xen,passthrough", Xen won't map the
>> MMIO and IRQ to DOM0. So it's an hard requirement.
> 
> That's not what I meant.
> 
> What I was getting at is that it's not 100% mandatory for a device you
> want to pass through to have the "xen,passthrough" property at all, but
> the wording of the binding implies otherwise..
> 
> There will be at least some devices in the world (even if only trivial
> ones) where you can pass them through even if dom0 has been touching
> them before. Or dom0 might choose to implement a reset helper for some
> device or other.

Hmmm right... I will update the binding.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property
  2015-02-23 15:15       ` Ian Campbell
@ 2015-02-23 15:44         ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-23 15:44 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

On 23/02/15 15:15, Ian Campbell wrote:
> On Fri, 2015-02-20 at 17:03 +0000, Julien Grall wrote:
>> On 20/02/15 15:42, Ian Campbell wrote:
>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>> @@ -919,8 +943,14 @@ static int make_timer_node(const struct domain *d, void *fdt,
>>>>      return res;
>>>>  }
>>>>  
>>>> -/* Map the device in the domain */
>>>> -static int map_device(struct domain *d, struct dt_device_node *dev)
>>>> +/* For a given device node:
>>>
>>> Strictly speaking should be:
>>>  /*
>>>   * For a given...
>>>
>>> (I don't care all that much, but since I'm commenting elsewhere)
>>
>> Hmmm right. I will change it.
> 
> FWIW I noticed this pattern a lot in this series.
> 
>>>> @@ -947,7 +979,7 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
>>>>          }
>>>>      }
>>>>  
>>>> -    /* Map IRQs */
>>>> +    /* Give permission and  map IRQs */
>>>
>>> Another Nit: "  " -> " ".
>>>
>>>> +        if ( need_mapping )
>>>> +        {
>>>> +            /*
>>>> +             * Checking the return of vgic_reserve_virq is not
>>>> +             * necessary. It should not fail except when we try to map
>>>> +             * twice the IRQ. This can happen if the IRQ is shared
>>>
>>> "when we try to map the IRQ twice"
>>>
>>> Other than those nits the code itself looks good, will ack once we've
>>> agreed on the bindings wording.
>>
>> BTW, should we upstream the bindings to device tree git?
> 
> Arguably we should upstream all of our bindings (e.g.
> docs/misc/arm/device-tree/*, admittedly a single file right now) but
> doing just one/some seems worse than keeping them in tree.
> 
> IOW it should be all or nothing, and I have no problem with you deciding
> that nothing is easier for you here...

For now, I will stick for nothing :).

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  2015-02-23 15:20       ` Ian Campbell
@ 2015-02-23 15:47         ` Julien Grall
  2015-02-23 15:52           ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 15:47 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 23/02/15 15:20, Ian Campbell wrote:
> On Fri, 2015-02-20 at 17:28 +0000, Julien Grall wrote:
>> The priority is controlled by route_irq_to_guest and set statically
>> using GIC_PRI_IRQ.
>>
>> If we decide to hardcoded the priority here, we should drop the
>> parameter on gic_route_irq_guest. But not keeping both.
> 
> There is a middle ground, which is for guest-routed IRQs to be allowed a
> subset of the real priorities, but until those associated checks are in
> place I think hardcoding in gic_route_irq_to_guest leaves less scope for
> mistakes.

The interface for routing an IRQ to xen (gic_route_irq_to_xen) is taking
the priority in parameter.

I would prefer if we keep the same interface for guest and then hardcode
the value in route_irq_to_guest.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs
  2015-02-23 15:22         ` Ian Campbell
@ 2015-02-23 15:48           ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-23 15:48 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Wei Liu, Stefano Stabellini, tim, Ian Jackson,
	stefano.stabellini, Jan Beulich, xen-devel

Hi Ian,

On 23/02/15 15:22, Ian Campbell wrote:
> On Fri, 2015-02-20 at 17:29 +0000, Julien Grall wrote:
>> On 20/02/15 16:08, Ian Campbell wrote:
>>> On Wed, 2015-01-28 at 18:26 +0000, Stefano Stabellini wrote:
>>>
>>>>> +        int spi = irq - 32;
>>>>
>>>> unsigned int
>>>
>>> and underflow?
>>
>> No because there is a check (irq < 32) before using the variable spi.
>> It was more convenient to initialize it directly.
> 
> You'd have to be sure that "irq - 32" wasn't undefined behaviour then,
> or the compiler can decide to omit the rest of the function, or perhaps
> just that second check, because things are undefined from the
> initialiser onwards.
> 
> I think with unsigned you are probably ok.

I will move the (irq - 32) after the check for safety.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-02-20 15:15   ` Ian Campbell
  2015-02-20 16:09     ` Julien Grall
  2015-02-20 16:35     ` Jan Beulich
@ 2015-02-23 15:48     ` Andrew Cooper
  2015-02-23 16:00       ` Ian Campbell
  2 siblings, 1 reply; 251+ messages in thread
From: Andrew Cooper @ 2015-02-23 15:48 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall
  Cc: Wei Liu, George Dunlap, Ian Jackson, tim, stefano.stabellini,
	Jan Beulich, xen-devel, Daniel De Graaf, Keir Fraser

On 20/02/15 15:15, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> On ARM the virtual GIC may differ between each guest (emulated GIC version,
>> number of SPIs...). Those informations are already known at the domain creation
> "This information is already known at domain creation..."
>
>> and can never change.
>>
>> For now only the gic_version is set. In long run, there will be more parameters
> "In the long run".
>
>> such as the number of SPIs. All will be required to be set at the same time.
>>
>> A new arch-specific structure arch_domainconfig has been created, the x86
>> one doesn't have any specific configuration, a dummy structure
>> (C-spec compliant) has been created to factorize the code on the toolstack.
> I'm not sure what you mean by factorize here.
>
>> Some external tools (qemu, xenstore) may require to create a domain. Rather
> "may be required" perhaps? I'm not 100% sure what you are trying to say.
>
>> than asking them to take care of the arch-specific domain configuration, let
>> the current function (xc_domain_create) to chose a default configuration and
> s/to//
>
>> introduce a new one (xc_domain_create_config).
>>
>> This patch also drop the previously DOMCTL arm_configure_domain introduced
> "drops the previously introduced DOMCTL arm...".
>
>> in Xen 4.5, as it has been made useless.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>> Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
>> Cc: Keir Fraser <keir@xen.org>
>> Cc: Jan Beulich <jbeulich@suse.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>> Cc: George Dunlap <george.dunlap@eu.citrix.com>
>>
>> ---
>>     This is a follow-up of http://lists.xen.org/archives/html/xen-devel/2014-11/msg00522.html
>>
>>     TODO: What about migration? For now the configuration lives in internal
>>     libxl structure. We need a way to pass the domain configuration to the
>>     other end.
> Things like the GIC version and number of SPIs would normally end up
> being encoded in the hvm save records, i.e. the blob which Xen provides
> to the toolstack to be included in the save stream. That would then be
> alongside the actual related interrupt architectural state etc (e.g.
> pending, active, masked etc).
>
> That's problematic here because you can't pass that blob to the create
> function and the toolstack cannot really parse the blob to figure out
> the details to pass.
>
> Looking back at msg00522.html it does seem like migration is a good
> motivation for doing it as a separate hypercall as you originally did,
> so initial create would be
> 	DOMCTL_create
> 	DOMCTL_set_the_variables
> and restore would be
> 	DOMCTL_create
> 	DOMCTL_restore_from_blob
>
> In both cases this needn't preclude requiring the call to be made before
> unpause or that it is only called exactly once.
>
> Write once HVM params would be another option here.
>
> Jan, do you find any of that convincing as to the need for doing this
> outside the the create domctl? Based on msg00522 is seems you would
> prefer some HVM params over a new domctl?
>
>>     I'm not sure if we should care of this right now as migration doesn't
>>     yet exists on ARM.
> It's a domctl so we aren't exactly painting ourselves into a corner, but
> it would be good to have some idea that we aren't going down a blind
> alley at least. Especially if the way out of the alley is to come back
> to where we are now...
>
> (There doesn't seem much point in looking at the code until we conclude
> the approach is correct, so I haven't)

GIC version and SPIs should absolutely be part of the migration stream. 
They are domain architectural state.

I have a similar issue with my plans for cpuid improvements in x86, and
was going to introduce a domain architectural state near the head of the
migration stream.  (There is currently a chicken & egg problem in x86
with the hvm params, the cpu state and the cpuid policy.  In Xen, we
currently check the cpu state for plausibility because it is not
currently possible to load the policy before xc_domain_restore() is
complete.)


At first glance, extending createdomian would look like a sensible
action to ensure that these bits of state get set appropriately.  A
consequence would be that the createdomain hypercall must move down into
xc_domain_restore(), which causes problems in the XSM case (where the
permissions are along the lines of "sub builder $X is permitted to issue
hypercalls on domid $Y).

An alternative is instead to move more of domain construction into the
xc_domain_restore(), so architectural state from the stream can be used
to construct the domain.  (For x86 cpuid, I believe I need to set part
of the architectural state before the set_max_vcpus hypercall, and I
certainly need to propagate maxphysaddr from the source before I can
validate any memory frames in the stream.)

This would result in a leaning towards separate hypercalls.

~Andrew

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

* Re: [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying
  2015-02-23 15:25       ` Ian Campbell
@ 2015-02-23 15:49         ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-23 15:49 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 23/02/15 15:25, Ian Campbell wrote:
> On Fri, 2015-02-20 at 17:41 +0000, Julien Grall wrote:
> 
>>>> +    /* TODO: Handle eviction from LRs. For now, deny remove if the IRQ
>>>> +     * is inflight and not disabled.
>>>
>>> If we are ungracefully killing a guest doesn't this risk ending up with
>>> an undestroyable domain? i.e. if the guest is paused with an inflight
>>> IRQ and then destroyed, how does the inflight IRQ ever become
>>> not-inflight again? A similar argument could apply if the guest has e.g.
>>> crashed, paniced or is otherwise not processing any more interrupts or
>>> generating EOIs for existing ones.
>>
>> No, this will fall on the "is_dying" part. During domain destruction,
>> the hypervisor will release all the IRQ still assigned to the guest one
>> by one.
>>
>>> We need to be able to kill a guest in such a state somehow.
>>
>> The TODO is here for running domain where we try to deassign an inflight
>> IRQ.
> 
> I see. I think either expand the comment to say "for a running domain"
> or, probably better, put this bit of code (and the comment) in an else
> of the is_dying and get rid of the goto in the is_dying==true case.

I will do.

>>>> +    for ( i = 0; i < (d->arch.vgic.nr_spis); i++ )
>>>> +    {
>>>> +        struct pending_irq *p = &d->arch.vgic.pending_irqs[i];
>>>
>>> Is there not a helper for this lookup? If so it should be used.
>>
>> The irq_pending code is adding extra-check. But I guess we don't care
>> for domain destruction?
> 
> I don't think so.

Ok.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-20 16:53             ` Ian Campbell
  2015-02-23  9:33               ` Jan Beulich
@ 2015-02-23 15:51               ` Julien Grall
  2015-02-23 16:02                 ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 15:51 UTC (permalink / raw)
  To: Ian Campbell, Stefano Stabellini
  Cc: xen-devel, tim, Jan Beulich, stefano.stabellini

Hi Ian,

On 20/02/15 16:53, Ian Campbell wrote:
> On Thu, 2015-01-29 at 12:33 +0000, Stefano Stabellini wrote:
>> On Thu, 29 Jan 2015, Julien Grall wrote:
>>> On 29/01/15 12:17, Stefano Stabellini wrote:
>>>> On Wed, 28 Jan 2015, Julien Grall wrote:
>>>>> Hi Stefano,
>>>>>
>>>>> On 28/01/15 18:52, Stefano Stabellini wrote:
>>>>>> On Tue, 13 Jan 2015, Julien Grall wrote:
>>>>>>> The physdev sub-hypercalls PHYSDEVOP_{,map}_pirq allow the toolstack to
>>>>>>> assign/deassign a physical IRQ to the guest (via the config options "irqs"
>>>>>>> for xl). The x86 version is using them with PIRQ (IRQ bound to an event
>>>>>>> channel). As ARM doesn't have a such concept, we could reuse it to bound
>>>>>>> a physical IRQ to a virtual IRQ.
>>>>>>>
>>>>>>> For now, we allow only SPIs to be mapped to the guest.
>>>>>>> The type MAP_PIRQ_TYPE_GSI is used for this purpose.
>>>>>>>
>>>>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>>>>
>>>>>>> ---
>>>>>>>     I'm not sure it's the best solution to reuse hypercalls for a
>>>>>>>     different purpose. If x86 plan to have a such concept (i.e binding a
>>>>>>>     physical IRQ to a virtual IRQ), we could introduce new hypercalls.
>>>>>>>     Any thoughs?
>>>>>>
>>>>>> I think it is OK, as long as we write down very clearly what we are
>>>>>> doing.
> 
> Would adding MAP_PIRQ_TYPE_PPI (even as an alias for TYPE_GSI) be
> helpful?
> 
> I have a feeling not, since type is, I think, declaring the "namespace"
> of the index parameter, whereas the pirq is the one containing the vGIC
> provided virq (or the pirq-type evtchn on x86). Does that make sense?
> 
> Are we absolutely 100% sure that we will never ever want to map hardware
> IRQs to guests on ARMs using pirq-type event channels? Because that is
> what we are essentially ruling out here.

That would happen if we decide to implement an interrupt controller
which doesn't support virtualization.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  2015-02-23 15:47         ` Julien Grall
@ 2015-02-23 15:52           ` Ian Campbell
  2015-02-23 15:54             ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 15:52 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Mon, 2015-02-23 at 15:47 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 23/02/15 15:20, Ian Campbell wrote:
> > On Fri, 2015-02-20 at 17:28 +0000, Julien Grall wrote:
> >> The priority is controlled by route_irq_to_guest and set statically
> >> using GIC_PRI_IRQ.
> >>
> >> If we decide to hardcoded the priority here, we should drop the
> >> parameter on gic_route_irq_guest. But not keeping both.
> > 
> > There is a middle ground, which is for guest-routed IRQs to be allowed a
> > subset of the real priorities, but until those associated checks are in
> > place I think hardcoding in gic_route_irq_to_guest leaves less scope for
> > mistakes.
> 
> The interface for routing an IRQ to xen (gic_route_irq_to_xen) is taking
> the priority in parameter.

It's useful and safe in the route to xen case.

> I would prefer if we keep the same interface for guest and then hardcode
> the value in route_irq_to_guest.

In which case I think route_irq_to_guest should complain/error-out if
the priority given is not the default one until such a time as it
understands which inputs are safe.

Ian.

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-23 15:28                 ` Ian Campbell
@ 2015-02-23 15:53                   ` Julien Grall
  2015-02-23 16:04                     ` Ian Campbell
  2015-02-23 16:22                     ` Jan Beulich
  0 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-23 15:53 UTC (permalink / raw)
  To: Ian Campbell, Jan Beulich
  Cc: xen-devel, tim, stefano.stabellini, Stefano Stabellini

Hi Ian,

On 23/02/15 15:28, Ian Campbell wrote:
> On Mon, 2015-02-23 at 09:33 +0000, Jan Beulich wrote:
>>>>> On 20.02.15 at 17:53, <ian.campbell@citrix.com> wrote:
>>> Jan, do you have any feeling for how this is going to play out on x86
>>> with the vapic stuff?
>>
>> The vapic logic shouldn't require any physdevop involvement, so if
>> I read right what you propose (not having such a requirement /
>> connection on ARM) either, I agree that a new domctl should be all
>> that's needed (if XEN_DOMCTL_{,un}bind_pt_irq can't be re-used).
> 
> Actually, I think bind_pt_irq with a new PT_IRQ_TYPE_* would be a good
> option.
> 
> An ARM SPI is a bit like an ISA IRQ, but not close enough to reuse IMHO
> (and the datatype would need widening).

We have to think about MSI and other type too...

In any case a DOMCTL is not suitable here because a guest kernel may
need to map/unmap IRQ too (think about ACPI or device passthrough).

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  2015-02-23 15:52           ` Ian Campbell
@ 2015-02-23 15:54             ` Julien Grall
  2015-02-23 16:04               ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 15:54 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

On 23/02/15 15:52, Ian Campbell wrote:
> On Mon, 2015-02-23 at 15:47 +0000, Julien Grall wrote:
>> Hi Ian,
>>
>> On 23/02/15 15:20, Ian Campbell wrote:
>>> On Fri, 2015-02-20 at 17:28 +0000, Julien Grall wrote:
>>>> The priority is controlled by route_irq_to_guest and set statically
>>>> using GIC_PRI_IRQ.
>>>>
>>>> If we decide to hardcoded the priority here, we should drop the
>>>> parameter on gic_route_irq_guest. But not keeping both.
>>>
>>> There is a middle ground, which is for guest-routed IRQs to be allowed a
>>> subset of the real priorities, but until those associated checks are in
>>> place I think hardcoding in gic_route_irq_to_guest leaves less scope for
>>> mistakes.
>>
>> The interface for routing an IRQ to xen (gic_route_irq_to_xen) is taking
>> the priority in parameter.
> 
> It's useful and safe in the route to xen case.
> 
>> I would prefer if we keep the same interface for guest and then hardcode
>> the value in route_irq_to_guest.
> 
> In which case I think route_irq_to_guest should complain/error-out if
> the priority given is not the default one until such a time as it
> understands which inputs are safe.

I guess you mean gic_route_irq_to_guest?

I could add a check and error-out for this case.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 14/24] xen/dts: Use unsigned int for MMIO and IRQ index
  2015-02-20 16:55   ` Ian Campbell
@ 2015-02-23 15:57     ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-23 15:57 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 20/02/15 16:55, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> There is no reason to use signed integer for an index.
> 
> Did you check for now pointless "if ( uthing < 0 ) which a picky
> compiler might whinge about?

I just checked and we don't have a such test in those function.

BTW, I think clang is picky on pointless if ( ufoo < 0 ) but we don't
support it on ARM right now.

>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> 
> Acked-by: Ian Campbell <ian.campbell@citrix.com>

Thanks,

-- 
Julien Grall

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-02-23 15:48     ` Andrew Cooper
@ 2015-02-23 16:00       ` Ian Campbell
  2015-02-23 21:48         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 16:00 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Wei Liu, George Dunlap, Ian Jackson, Julien Grall, tim,
	stefano.stabellini, Jan Beulich, xen-devel, Daniel De Graaf,
	Keir Fraser

On Mon, 2015-02-23 at 15:48 +0000, Andrew Cooper wrote:
> GIC version and SPIs should absolutely be part of the migration stream. 
> They are domain architectural state.

Of course, the question is where.

They could be part of the Xen hvmsave blob for the GIC (i.e. along with
the other GIC architectural state such as which interrupts are currently
active,pending,masked etc).

Or they could be part of a new migration v2 record for such things.

Or they could be part of the hvm params migration record.

Or they could be part of the libxl json cfg blob, (but I think that
option is a bad one).

> I have a similar issue with my plans for cpuid improvements in x86, and
> was going to introduce a domain architectural state near the head of the
> migration stream.  (There is currently a chicken & egg problem in x86
> with the hvm params, the cpu state and the cpuid policy.  In Xen, we
> currently check the cpu state for plausibility because it is not
> currently possible to load the policy before xc_domain_restore() is
> complete.)
> 
> 
> At first glance, extending createdomian would look like a sensible
> action to ensure that these bits of state get set appropriately.  A
> consequence would be that the createdomain hypercall must move down into
> xc_domain_restore(), which causes problems in the XSM case (where the
> permissions are along the lines of "sub builder $X is permitted to issue
> hypercalls on domid $Y).
> 
> An alternative is instead to move more of domain construction into the
> xc_domain_restore(), so architectural state from the stream can be used
> to construct the domain.  (For x86 cpuid, I believe I need to set part
> of the architectural state before the set_max_vcpus hypercall, and I
> certainly need to propagate maxphysaddr from the source before I can
> validate any memory frames in the stream.)
> 
> This would result in a leaning towards separate hypercalls.
> 
> ~Andrew
> _

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

* Re: [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-02-23 15:30   ` Ian Campbell
@ 2015-02-23 16:01     ` Julien Grall
  2015-02-23 16:27       ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 16:01 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 23/02/15 15:30, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> 
>> +/* This limit is used by the hypercalls to restrict the size of the path */
>> +#define DEVICE_TREE_MAX_PATHLEN 1024
> 
> Is this something you've made up or derived from the DT spec/ePAPR etc?

I didn't find a such requirements on the spec.

I chose this number based on the linux pathlen because the path is also
used in the sysfs (/sys/firmware/devicetree).

> Apart from this the patch seems fine, clarifying the genesis of that
> number in the commit log would be sufficient for me.

I will update the commit message.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-23 15:51               ` Julien Grall
@ 2015-02-23 16:02                 ` Ian Campbell
  2015-03-04 14:37                   ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 16:02 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, tim, Jan Beulich, stefano.stabellini, Stefano Stabellini

On Mon, 2015-02-23 at 15:51 +0000, Julien Grall wrote:
> On 20/02/15 16:53, Ian Campbell wrote:

> > Are we absolutely 100% sure that we will never ever want to map hardware
> > IRQs to guests on ARMs using pirq-type event channels? Because that is
> > what we are essentially ruling out here.
> 
> That would happen if we decide to implement an interrupt controller
> which doesn't support virtualization.

Good point. It's pretty unlikely but not absolutely impossible. So we
should avoid reusing the pirq evtchn type for this. Jan suggested
XENDOMCTL_bind_pt_irq which is looking better and better...

Ian.

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-23 15:53                   ` Julien Grall
@ 2015-02-23 16:04                     ` Ian Campbell
  2015-02-23 16:11                       ` Julien Grall
  2015-02-23 16:22                     ` Jan Beulich
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 16:04 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, stefano.stabellini, tim, Jan Beulich, Stefano Stabellini

On Mon, 2015-02-23 at 15:53 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 23/02/15 15:28, Ian Campbell wrote:
> > On Mon, 2015-02-23 at 09:33 +0000, Jan Beulich wrote:
> >>>>> On 20.02.15 at 17:53, <ian.campbell@citrix.com> wrote:
> >>> Jan, do you have any feeling for how this is going to play out on x86
> >>> with the vapic stuff?
> >>
> >> The vapic logic shouldn't require any physdevop involvement, so if
> >> I read right what you propose (not having such a requirement /
> >> connection on ARM) either, I agree that a new domctl should be all
> >> that's needed (if XEN_DOMCTL_{,un}bind_pt_irq can't be re-used).
> > 
> > Actually, I think bind_pt_irq with a new PT_IRQ_TYPE_* would be a good
> > option.
> > 
> > An ARM SPI is a bit like an ISA IRQ, but not close enough to reuse IMHO
> > (and the datatype would need widening).
> 
> We have to think about MSI and other type too...
> 
> In any case a DOMCTL is not suitable here because a guest kernel may
> need to map/unmap IRQ too (think about ACPI or device passthrough).

I don't follow, setting up device passthrough is very much a toolstack
operation, isn't it? Where does the guest kernel get involved?

As for ACPI, I think dom0 propagating ACPI derived platform info to Xen
should be handled differently (at the hypercall interface at least)
separate from passthrough.

Ian.

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

* Re: [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
  2015-02-23 15:54             ` Julien Grall
@ 2015-02-23 16:04               ` Ian Campbell
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 16:04 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Mon, 2015-02-23 at 15:54 +0000, Julien Grall wrote:
> On 23/02/15 15:52, Ian Campbell wrote:
> > On Mon, 2015-02-23 at 15:47 +0000, Julien Grall wrote:
> >> Hi Ian,
> >>
> >> On 23/02/15 15:20, Ian Campbell wrote:
> >>> On Fri, 2015-02-20 at 17:28 +0000, Julien Grall wrote:
> >>>> The priority is controlled by route_irq_to_guest and set statically
> >>>> using GIC_PRI_IRQ.
> >>>>
> >>>> If we decide to hardcoded the priority here, we should drop the
> >>>> parameter on gic_route_irq_guest. But not keeping both.
> >>>
> >>> There is a middle ground, which is for guest-routed IRQs to be allowed a
> >>> subset of the real priorities, but until those associated checks are in
> >>> place I think hardcoding in gic_route_irq_to_guest leaves less scope for
> >>> mistakes.
> >>
> >> The interface for routing an IRQ to xen (gic_route_irq_to_xen) is taking
> >> the priority in parameter.
> > 
> > It's useful and safe in the route to xen case.
> > 
> >> I would prefer if we keep the same interface for guest and then hardcode
> >> the value in route_irq_to_guest.
> > 
> > In which case I think route_irq_to_guest should complain/error-out if
> > the priority given is not the default one until such a time as it
> > understands which inputs are safe.
> 
> I guess you mean gic_route_irq_to_guest?

Whichever function is ignoring its priority argument in favour of a
hardcoded value.

> I could add a check and error-out for this case.
> 
> Regards,
> 

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

* Re: [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct
  2015-02-23 15:31       ` Ian Campbell
@ 2015-02-23 16:04         ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-23 16:04 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, stefano.stabellini, tim, Jan Beulich

Hi Ian,

On 23/02/15 15:31, Ian Campbell wrote:
> On Fri, 2015-02-20 at 17:45 +0000, Julien Grall wrote:
>> On 20/02/15 16:58, Ian Campbell wrote:
>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>> This new function will correctly initialize the IOMMU page table for the
>>>> current domain.
>>>>
>>>> Also use it in iommu_assign_dt_device even though the current IOMMU
>>>> implementation on ARM shares P2M with the processor.
>>>>
>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>
>>> Acked-by: Ian Campbell <ian.campbell@citrix.com>
>>>
>>> Although I'm not actually sure what it is going to be used for.
>>
>> The caller are in this patch too :) (see pci.c and device_tree.c changes).
> 
> Right, I meant "what non-trivial functionality is going to land here"
> i..e what the grandparent callers etc will eventually expect from it.

Oh ok. The function is used to the prepare the IOMMU structure for the
domain. Currently, the steps are:
	- build the page table on platforms which don't share the P2M
	- set need_iommu to 1.

Within this series, this is the only patch who touch this function.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-23 16:04                     ` Ian Campbell
@ 2015-02-23 16:11                       ` Julien Grall
  2015-02-23 16:34                         ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 16:11 UTC (permalink / raw)
  To: Ian Campbell
  Cc: xen-devel, stefano.stabellini, tim, Jan Beulich, Stefano Stabellini

On 23/02/15 16:04, Ian Campbell wrote:
> On Mon, 2015-02-23 at 15:53 +0000, Julien Grall wrote:
>> Hi Ian,
>>
>> On 23/02/15 15:28, Ian Campbell wrote:
>>> On Mon, 2015-02-23 at 09:33 +0000, Jan Beulich wrote:
>>>>>>> On 20.02.15 at 17:53, <ian.campbell@citrix.com> wrote:
>>>>> Jan, do you have any feeling for how this is going to play out on x86
>>>>> with the vapic stuff?
>>>>
>>>> The vapic logic shouldn't require any physdevop involvement, so if
>>>> I read right what you propose (not having such a requirement /
>>>> connection on ARM) either, I agree that a new domctl should be all
>>>> that's needed (if XEN_DOMCTL_{,un}bind_pt_irq can't be re-used).
>>>
>>> Actually, I think bind_pt_irq with a new PT_IRQ_TYPE_* would be a good
>>> option.
>>>
>>> An ARM SPI is a bit like an ISA IRQ, but not close enough to reuse IMHO
>>> (and the datatype would need widening).
>>
>> We have to think about MSI and other type too...
>>
>> In any case a DOMCTL is not suitable here because a guest kernel may
>> need to map/unmap IRQ too (think about ACPI or device passthrough).
> 
> I don't follow, setting up device passthrough is very much a toolstack
> operation, isn't it? Where does the guest kernel get involved?

Sorry I meant the DOM0 kernel.

Not really. On platform device pass-through there is no way to know the
IRQ, so for now the routing is done by the toolstack.

But we could decide to implement a driver in DOM0 which will
unbind/bind/reset device. In this case it will require to
assign/deassign the IRQ from DOM0.

There is also the case of MSI.

> As for ACPI, I think dom0 propagating ACPI derived platform info to Xen
> should be handled differently (at the hypercall interface at least)
> separate from passthrough.

There is no difference between routing because of ACPI and/or because
pass-through. So this should be done the same way.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-23 15:53                   ` Julien Grall
  2015-02-23 16:04                     ` Ian Campbell
@ 2015-02-23 16:22                     ` Jan Beulich
  1 sibling, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-02-23 16:22 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall
  Cc: xen-devel, tim, stefano.stabellini, Stefano Stabellini

>>> On 23.02.15 at 16:53, <julien.grall@linaro.org> wrote:
> Hi Ian,
> 
> On 23/02/15 15:28, Ian Campbell wrote:
>> On Mon, 2015-02-23 at 09:33 +0000, Jan Beulich wrote:
>>>>>> On 20.02.15 at 17:53, <ian.campbell@citrix.com> wrote:
>>>> Jan, do you have any feeling for how this is going to play out on x86
>>>> with the vapic stuff?
>>>
>>> The vapic logic shouldn't require any physdevop involvement, so if
>>> I read right what you propose (not having such a requirement /
>>> connection on ARM) either, I agree that a new domctl should be all
>>> that's needed (if XEN_DOMCTL_{,un}bind_pt_irq can't be re-used).
>> 
>> Actually, I think bind_pt_irq with a new PT_IRQ_TYPE_* would be a good
>> option.
>> 
>> An ARM SPI is a bit like an ISA IRQ, but not close enough to reuse IMHO
>> (and the datatype would need widening).
> 
> We have to think about MSI and other type too...

Which that domctl already provides for.

> In any case a DOMCTL is not suitable here because a guest kernel may
> need to map/unmap IRQ too (think about ACPI or device passthrough).

But not the physical IRQ I suppose. The virtual counterpart is what
should be used there, and that's what said domctl extablishes.

Jan

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

* Re: [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest
  2015-02-23 15:33         ` Ian Campbell
@ 2015-02-23 16:22           ` Jan Beulich
  0 siblings, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-02-23 16:22 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, Julien Grall, stefano.stabellini, tim

>>> On 23.02.15 at 16:33, <ian.campbell@citrix.com> wrote:
> On Mon, 2015-02-23 at 09:37 +0000, Jan Beulich wrote:
>> >>> On 20.02.15 at 18:46, <julien.grall@linaro.org> wrote:
>> > On 20/02/15 17:03, Ian Campbell wrote:
>> >> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> >> 
>> >> Subject: "release the DT devices assigned to a guest earlier"
>> >> 
>> >>> The toolstack may not have deassign every device used by a guest.
>> >> 
>> >> "deassigned"
>> >> 
>> >>> Therefore we have to go through the device list and removing them before
>> >> 
>> >> "and remove them"
>> >> 
>> >>> asking the IOMMU drivers to release memory for this domain.
>> >>>
>> >>> This can be done by moving the call to the release function when we
>> >>> relinquish the resources. The IOMMU part will be destroyed later when
>> >>> the domain is freed.
>> >>>
>> >>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> >>> Cc: Jan Beulich <jbeulich@suse.com>
>> >> 
>> >> Acked-by: Ian Campbell <ian.campbell@citrix.com>
>> >> 
>> >> I'd like to hear Jan's opinion though.
>> > 
>> > FWIW, this is how it's done for PCI.
>> 
>> Right, IOW I agree to the idea of the patch.
> 
> Thanks. If Julien could record this in the form of an ack that would
> save me remembering you've said so (otherwise it could just go as a
> comment after the --- I suppose).

That's fine with me, I just didn't say so because it seemed a bit
odd on an ARM-only change.

Jan

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23 15:39           ` Ian Campbell
@ 2015-02-23 16:24             ` Jan Beulich
  2015-02-23 16:35               ` Ian Campbell
  2015-02-23 16:37             ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-02-23 16:24 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall; +Cc: xen-devel, stefano.stabellini, tim

>>> On 23.02.15 at 16:39, <ian.campbell@citrix.com> wrote:
> On Mon, 2015-02-23 at 10:20 +0000, Jan Beulich wrote:
>> >>> On 23.02.15 at 11:10, <julien.grall@linaro.org> wrote:
>> > Hi Jan,
>> > 
>> > On 23/02/2015 09:40, Jan Beulich wrote:
>> >>>>> On 20.02.15 at 18:04, <ian.campbell@citrix.com> wrote:
>> >>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> >>>> Currently, when the device is deassigned from a domain, we directly 
> reassign
>> >>>> to DOM0.
>> >>>>
>> >>>> As the device may not have been correctly reset, this may lead to 
> corruption
>> >>> or
>> >>>> expose some part of DOM0 memory. Also, we may have no way to reset some
>> >>>> platform devices.
>> >>>>
>> >>>> If Xen reassigns the device to "nobody", it may receive some global/context
>> >>>> fault because the transaction has failed (indeed the context has been
>> >>>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
>> >>>> hardware. I think we could live with that for a first version of platform
>> >>>> device passthrough.
>> >>>>
>> >>>> DOM0 will have to issue an hypercall to assign the device to itself if it
>> >>>> wants to use it.
>> >>>
>> >>> Does this behaviour differ from x86? If so then it is worth calling that
>> >>> out explicitly (even if not, good to know I think!)
>> >> Indeed this is different from x86, and I think such behavior should
>> >> be consistent across architectures. If Dom0 isn't handed back the
>> >> device, who's going to do the supposedly prerequisite reset? On
>> >> x86/PCI that's pciback's job, and it would be illegitimate for the
>> >> driver to do _anything_ with the device if it wasn't owned by Dom0.
>> > 
>> > I think we already had this discussion on a previous version...
>> > 
>> > Right now, there is no possibility to reset a platform device in the 
>> > kernel. There is some discussion about it but nothing more.
> 
> "there is no possibility to reset a platform device" isn't quite true,
> there is certainly a theoretical possibility (i.e. it is obviously the
> case that a dom0 could be written to do so for at least some devices).
> 
> So what happens if such a dom0 arises in the future? I suppose the
> intention is that the user would having deassigned from domU and
> determined that there kernel has the necessary feature would do some
> sort of xl command to assign to dom0?

I suppose this was really targeted at Julien...

Jan

>> > This series doesn't intend to have a generic solution for platform 
>> > device pass-through. It's target embedded people who will always 
>> > passthrough the same device to the same guest.
>> > 
>> > As DOM0 *should not* use the device (no reset driver, and no possibility 
>> > to unbind), the safest way is to reassign the device to nobody.
>> > 
>> > So if the device is not quiescent it may mess up DOM0.
>> 
>> And I think spelling this out in the description is what Ian is
>> asking for.
> 
> Yes.
> 
> I think it probably ought to be mentioned in the docs surrounding the
> hypercalls in question, for both PCI, DT and any other device type
> whether or not there is some implicit rebinding or not.
> 
> Ian.

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-02-20 17:17   ` Ian Campbell
@ 2015-02-23 16:25     ` Daniel De Graaf
  2015-03-10 16:52       ` Julien Grall
  2015-03-10 16:33     ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Daniel De Graaf @ 2015-02-23 16:25 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich,
	Machon Gregory, xen-devel

On 02/20/2015 12:17 PM, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> TODO: Update the commit message
>>
>> A device node is described by a path. It will be used to retrieved the
>> node in the device tree and assign the related device to the domain.
>>
>> Only device protected by an IOMMU can be assigned to a guest.
>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>> Cc: Jan Beulich <jbeulich@suse.com>
>>
>> ---
>>      Changes in v2:
>>          - Use a different number for XEN_DOMCTL_assign_dt_device
>> ---
>>   tools/libxc/include/xenctrl.h         | 10 ++++
>>   tools/libxc/xc_domain.c               | 95 ++++++++++++++++++++++++++++++++--
>
> These bits all look fine.
>
>> +int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
>> +                       XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>> +{
>> +    int ret;
>> +    struct dt_device_node *dev;
>> +
>> +    /* TODO: How to deal with XSM? */
>
> Adding Daniel.
>
> It seems the PCI ones are protected by
>          xsm_test_assign_device(XSM_HOOK, domctl->u.assign_device.machine_sbdf);
>
> So it seem that either this needs to become "test_assign_pci_device" and
> a similar "test_assign_dt_device" needs to be added and plumbed through
> or it needs to grow a type parameter and take the union for the
> identifier.

Either would work, but a distinct hook seems simpler to me, especially as
the call sites are distinct and the hook would process them differently.

> The code to apply an XSM context to a DT node would need consideration
> too I suppose?

This may require a bit more thought.  At first glance, the dt_phandle
field seems to be an identifier that could be used by FLASK to identify a
device using an ocontext lookup.  Labeling would then be done in the same
way as PCI devices and x86 legacy I/O ports.

-- 
Daniel De Graaf
National Security Agency

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

* Re: [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-02-23 16:01     ` Julien Grall
@ 2015-02-23 16:27       ` Ian Campbell
  2015-03-10 13:58         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 16:27 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Mon, 2015-02-23 at 16:01 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 23/02/15 15:30, Ian Campbell wrote:
> > On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> > 
> >> +/* This limit is used by the hypercalls to restrict the size of the path */
> >> +#define DEVICE_TREE_MAX_PATHLEN 1024
> > 
> > Is this something you've made up or derived from the DT spec/ePAPR etc?
> 
> I didn't find a such requirements on the spec.

I vaguely recall a limit on the length of a single node name, and a
limit on the depth which they may nest, which can be multiplied. It's
probably an unhelpfully large number though, so...

> I chose this number based on the linux pathlen because the path is also
> used in the sysfs (/sys/firmware/devicetree).

...that's a good as anything I suppose!

> > Apart from this the patch seems fine, clarifying the genesis of that
> > number in the commit log would be sufficient for me.
> 
> I will update the commit message.

Ian.

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-23 16:11                       ` Julien Grall
@ 2015-02-23 16:34                         ` Ian Campbell
  2015-02-23 21:54                           ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 16:34 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, Stefano Stabellini, stefano.stabellini, Jan Beulich, tim

On Mon, 2015-02-23 at 16:11 +0000, Julien Grall wrote:
> On 23/02/15 16:04, Ian Campbell wrote:
> > On Mon, 2015-02-23 at 15:53 +0000, Julien Grall wrote:
> >> Hi Ian,
> >>
> >> On 23/02/15 15:28, Ian Campbell wrote:
> >>> On Mon, 2015-02-23 at 09:33 +0000, Jan Beulich wrote:
> >>>>>>> On 20.02.15 at 17:53, <ian.campbell@citrix.com> wrote:
> >>>>> Jan, do you have any feeling for how this is going to play out on x86
> >>>>> with the vapic stuff?
> >>>>
> >>>> The vapic logic shouldn't require any physdevop involvement, so if
> >>>> I read right what you propose (not having such a requirement /
> >>>> connection on ARM) either, I agree that a new domctl should be all
> >>>> that's needed (if XEN_DOMCTL_{,un}bind_pt_irq can't be re-used).
> >>>
> >>> Actually, I think bind_pt_irq with a new PT_IRQ_TYPE_* would be a good
> >>> option.
> >>>
> >>> An ARM SPI is a bit like an ISA IRQ, but not close enough to reuse IMHO
> >>> (and the datatype would need widening).
> >>
> >> We have to think about MSI and other type too...
> >>
> >> In any case a DOMCTL is not suitable here because a guest kernel may
> >> need to map/unmap IRQ too (think about ACPI or device passthrough).
> > 
> > I don't follow, setting up device passthrough is very much a toolstack
> > operation, isn't it? Where does the guest kernel get involved?
> 
> Sorry I meant the DOM0 kernel.
> 
> Not really. On platform device pass-through there is no way to know the
> IRQ, so for now the routing is done by the toolstack.
> 
> But we could decide to implement a driver in DOM0 which will
> unbind/bind/reset device.

Sure, but...

>  In this case it will require to
> assign/deassign the IRQ from DOM0.

...why does that follow?

> There is also the case of MSI.

Handled via XEN_DOMCTL_bind_pt_irq for the toolstack configuration
angle, the actual guest usage of them is a separate interface which
doesn't yet concern us, at least not in this series.

> > As for ACPI, I think dom0 propagating ACPI derived platform info to Xen
> > should be handled differently (at the hypercall interface at least)
> > separate from passthrough.
> 
> There is no difference between routing because of ACPI and/or because
> pass-through. So this should be done the same way.

I'm not convinced. Routing all the IRQs is only one aspect of dom0
propagating ACPI derived platform info to Xen.

I suppose we will see once I look at the ACPI series. In the meantime I
think XEN_DOMCTL_bind_pt_irq matches your requirements in for this
series (and is a domctl so we aren't tied to it once we have a better
understanding of the other stuff).

Ian.

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23 16:24             ` Jan Beulich
@ 2015-02-23 16:35               ` Ian Campbell
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 16:35 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, Julien Grall, stefano.stabellini, tim

On Mon, 2015-02-23 at 16:24 +0000, Jan Beulich wrote:
> >>> On 23.02.15 at 16:39, <ian.campbell@citrix.com> wrote:
> > On Mon, 2015-02-23 at 10:20 +0000, Jan Beulich wrote:
> >> >>> On 23.02.15 at 11:10, <julien.grall@linaro.org> wrote:
> >> > Hi Jan,
> >> > 
> >> > On 23/02/2015 09:40, Jan Beulich wrote:
> >> >>>>> On 20.02.15 at 18:04, <ian.campbell@citrix.com> wrote:
> >> >>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >> >>>> Currently, when the device is deassigned from a domain, we directly 
> > reassign
> >> >>>> to DOM0.
> >> >>>>
> >> >>>> As the device may not have been correctly reset, this may lead to 
> > corruption
> >> >>> or
> >> >>>> expose some part of DOM0 memory. Also, we may have no way to reset some
> >> >>>> platform devices.
> >> >>>>
> >> >>>> If Xen reassigns the device to "nobody", it may receive some global/context
> >> >>>> fault because the transaction has failed (indeed the context has been
> >> >>>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
> >> >>>> hardware. I think we could live with that for a first version of platform
> >> >>>> device passthrough.
> >> >>>>
> >> >>>> DOM0 will have to issue an hypercall to assign the device to itself if it
> >> >>>> wants to use it.
> >> >>>
> >> >>> Does this behaviour differ from x86? If so then it is worth calling that
> >> >>> out explicitly (even if not, good to know I think!)
> >> >> Indeed this is different from x86, and I think such behavior should
> >> >> be consistent across architectures. If Dom0 isn't handed back the
> >> >> device, who's going to do the supposedly prerequisite reset? On
> >> >> x86/PCI that's pciback's job, and it would be illegitimate for the
> >> >> driver to do _anything_ with the device if it wasn't owned by Dom0.
> >> > 
> >> > I think we already had this discussion on a previous version...
> >> > 
> >> > Right now, there is no possibility to reset a platform device in the 
> >> > kernel. There is some discussion about it but nothing more.
> > 
> > "there is no possibility to reset a platform device" isn't quite true,
> > there is certainly a theoretical possibility (i.e. it is obviously the
> > case that a dom0 could be written to do so for at least some devices).
> > 
> > So what happens if such a dom0 arises in the future? I suppose the
> > intention is that the user would having deassigned from domU and
> > determined that there kernel has the necessary feature would do some
> > sort of xl command to assign to dom0?
> 
> I suppose this was really targeted at Julien...

Right, sorry that wasn't very clear of me.

> 
> Jan
> 
> >> > This series doesn't intend to have a generic solution for platform 
> >> > device pass-through. It's target embedded people who will always 
> >> > passthrough the same device to the same guest.
> >> > 
> >> > As DOM0 *should not* use the device (no reset driver, and no possibility 
> >> > to unbind), the safest way is to reassign the device to nobody.
> >> > 
> >> > So if the device is not quiescent it may mess up DOM0.
> >> 
> >> And I think spelling this out in the description is what Ian is
> >> asking for.
> > 
> > Yes.
> > 
> > I think it probably ought to be mentioned in the docs surrounding the
> > hypercalls in question, for both PCI, DT and any other device type
> > whether or not there is some implicit rebinding or not.
> > 
> > Ian.
> 
> 
> 

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23 15:39           ` Ian Campbell
  2015-02-23 16:24             ` Jan Beulich
@ 2015-02-23 16:37             ` Julien Grall
  2015-02-23 16:47               ` Jan Beulich
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 16:37 UTC (permalink / raw)
  To: Ian Campbell, Jan Beulich; +Cc: xen-devel, stefano.stabellini, tim

On 23/02/15 15:39, Ian Campbell wrote:
> On Mon, 2015-02-23 at 10:20 +0000, Jan Beulich wrote:
>>>>> On 23.02.15 at 11:10, <julien.grall@linaro.org> wrote:
>>> Hi Jan,
>>>
>>> On 23/02/2015 09:40, Jan Beulich wrote:
>>>>>>> On 20.02.15 at 18:04, <ian.campbell@citrix.com> wrote:
>>>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>>>> Currently, when the device is deassigned from a domain, we directly reassign
>>>>>> to DOM0.
>>>>>>
>>>>>> As the device may not have been correctly reset, this may lead to corruption
>>>>> or
>>>>>> expose some part of DOM0 memory. Also, we may have no way to reset some
>>>>>> platform devices.
>>>>>>
>>>>>> If Xen reassigns the device to "nobody", it may receive some global/context
>>>>>> fault because the transaction has failed (indeed the context has been
>>>>>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
>>>>>> hardware. I think we could live with that for a first version of platform
>>>>>> device passthrough.
>>>>>>
>>>>>> DOM0 will have to issue an hypercall to assign the device to itself if it
>>>>>> wants to use it.
>>>>>
>>>>> Does this behaviour differ from x86? If so then it is worth calling that
>>>>> out explicitly (even if not, good to know I think!)
>>>> Indeed this is different from x86, and I think such behavior should
>>>> be consistent across architectures. If Dom0 isn't handed back the
>>>> device, who's going to do the supposedly prerequisite reset? On
>>>> x86/PCI that's pciback's job, and it would be illegitimate for the
>>>> driver to do _anything_ with the device if it wasn't owned by Dom0.
>>>
>>> I think we already had this discussion on a previous version...
>>>
>>> Right now, there is no possibility to reset a platform device in the 
>>> kernel. There is some discussion about it but nothing more.
> 
> "there is no possibility to reset a platform device" isn't quite true,
> there is certainly a theoretical possibility (i.e. it is obviously the
> case that a dom0 could be written to do so for at least some devices).

> So what happens if such a dom0 arises in the future? I suppose the
> intention is that the user would having deassigned from domU and
> determined that there kernel has the necessary feature would do some
> sort of xl command to assign to dom0?

The list of things to do for resetting a device would be:
	- Deassign device from DOMU (though it's done during destruction)
	- Assign the device to DOM0 and map MMIO
	- Reset the device

But that not my concern right now. As we agreed, this feature (i.e reset
a device) is not in the scope of this series.

So assigning the device to DOM0 is not safe at all.

>>> This series doesn't intend to have a generic solution for platform 
>>> device pass-through. It's target embedded people who will always 
>>> passthrough the same device to the same guest.
>>>
>>> As DOM0 *should not* use the device (no reset driver, and no possibility 
>>> to unbind), the safest way is to reassign the device to nobody.
>>>
>>> So if the device is not quiescent it may mess up DOM0.
>>
>> And I think spelling this out in the description is what Ian is
>> asking for.
> 
> Yes.
> 
> I think it probably ought to be mentioned in the docs surrounding the
> hypercalls in question, for both PCI, DT and any other device type
> whether or not there is some implicit rebinding or not.

Ok.

-- 
Julien Grall

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23 16:37             ` Julien Grall
@ 2015-02-23 16:47               ` Jan Beulich
  2015-02-23 16:54                 ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-02-23 16:47 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, Ian Campbell, tim

>>> On 23.02.15 at 17:37, <julien.grall@linaro.org> wrote:
> On 23/02/15 15:39, Ian Campbell wrote:
>> On Mon, 2015-02-23 at 10:20 +0000, Jan Beulich wrote:
>>>>>> On 23.02.15 at 11:10, <julien.grall@linaro.org> wrote:
>>>> Right now, there is no possibility to reset a platform device in the 
>>>> kernel. There is some discussion about it but nothing more.
>> 
>> "there is no possibility to reset a platform device" isn't quite true,
>> there is certainly a theoretical possibility (i.e. it is obviously the
>> case that a dom0 could be written to do so for at least some devices).
> 
>> So what happens if such a dom0 arises in the future? I suppose the
>> intention is that the user would having deassigned from domU and
>> determined that there kernel has the necessary feature would do some
>> sort of xl command to assign to dom0?
> 
> The list of things to do for resetting a device would be:
> 	- Deassign device from DOMU (though it's done during destruction)
> 	- Assign the device to DOM0 and map MMIO
> 	- Reset the device
> 
> But that not my concern right now. As we agreed, this feature (i.e reset
> a device) is not in the scope of this series.
> 
> So assigning the device to DOM0 is not safe at all.

Kind of confusing - above you state "assign the device to DOM0
and map MMIO" as a prereq step for resetting the device, yet
then you state assigning it back to Dom0 is not safe. Which of the
two do you mean after all?

Jan

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23 16:47               ` Jan Beulich
@ 2015-02-23 16:54                 ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-23 16:54 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, stefano.stabellini, Ian Campbell, tim

On 23/02/15 16:47, Jan Beulich wrote:
>>>> On 23.02.15 at 17:37, <julien.grall@linaro.org> wrote:
>> On 23/02/15 15:39, Ian Campbell wrote:
>>> On Mon, 2015-02-23 at 10:20 +0000, Jan Beulich wrote:
>>>>>>> On 23.02.15 at 11:10, <julien.grall@linaro.org> wrote:
>>>>> Right now, there is no possibility to reset a platform device in the 
>>>>> kernel. There is some discussion about it but nothing more.
>>>
>>> "there is no possibility to reset a platform device" isn't quite true,
>>> there is certainly a theoretical possibility (i.e. it is obviously the
>>> case that a dom0 could be written to do so for at least some devices).
>>
>>> So what happens if such a dom0 arises in the future? I suppose the
>>> intention is that the user would having deassigned from domU and
>>> determined that there kernel has the necessary feature would do some
>>> sort of xl command to assign to dom0?
>>
>> The list of things to do for resetting a device would be:
>> 	- Deassign device from DOMU (though it's done during destruction)
>> 	- Assign the device to DOM0 and map MMIO
>> 	- Reset the device
>>
>> But that not my concern right now. As we agreed, this feature (i.e reset
>> a device) is not in the scope of this series.
>>
>> So assigning the device to DOM0 is not safe at all.
> 
> Kind of confusing - above you state "assign the device to DOM0
> and map MMIO" as a prereq step for resetting the device, yet
> then you state assigning it back to Dom0 is not safe. Which of the
> two do you mean after all?

Ian was asking how would it be possible to reset the device and I gave
him a list of things to do.

Reassigning the device to DOM0 is not safe if there is no reset driver
in the DOM0 kernel. Unlike PCI, there is no generic way to reset a
platform device.

As for now, there is no reset driver at all in DOM0. Not reassign the
device is the better thing to do.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-02-23 11:46   ` Ian Campbell
@ 2015-02-23 17:06     ` Julien Grall
  2015-02-23 17:22       ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 17:06 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, Ian Jackson, stefano.stabellini, Wei Liu

On 23/02/15 11:46, Ian Campbell wrote:
> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>> Let the user to pass additional nodes to the guest device tree. For this
>> purpose, everything in the node /passthrough from the partial device tree will
>> be copied into the guest device tree.
>>
>> The node /aliases will be also copied to allow the user to define aliases
>> which can be used by the guest kernel.
>>
>> A simple partial device tree will look like:
>>
>> /dts-v1/;
>>
>> / {
>>         #address-cells = <2>;
>>         #size-cells = <2>;
> 
> Are these mandatory/required as implied below, or only the ones inside
> the passthrough node (which is what I would expect).

It's to make DTC quiet.

>>
>>         passthrough {
>>             compatible = "simple-bus";
>>             ranges;
>>             #address-cells = <2>;
>>             #size-cells = <2>;
>>
>>             /* List of your nodes */
>>         }
>> };
>>
>> Note that:
>>     * The interrupt-parent proporties will be added by the toolstack in
> 
> "properties"
> 
>>     the root node
>>     * The properties compatible, ranges, #address-cells and #size-cells
>>     in /passthrough are mandatory.
> 
> Does ranges need to be the empty form? I think ranges = <stuff stuff>
> would be illegal?

It's not illegal as long as you correctly use it in the inner "reg".

Also, I admit that the "ranges" is confusing to read.

>>
>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>> Cc: Wei Liu <wei.liu2@citrix.com>
>>
>> ---
>>     Changes in v3:
>>         - Patch added
>> ---
>>  docs/man/xl.cfg.pod.5       |   7 ++
>>  tools/libxl/libxl_arm.c     | 253 ++++++++++++++++++++++++++++++++++++++++++++
>>  tools/libxl/libxl_types.idl |   1 +
>>  tools/libxl/xl_cmdimpl.c    |   1 +
>>  4 files changed, 262 insertions(+)
>>
>> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
>> index e2f91fc..225b782 100644
>> --- a/docs/man/xl.cfg.pod.5
>> +++ b/docs/man/xl.cfg.pod.5
>> @@ -398,6 +398,13 @@ not emulated.
>>  Specify that this domain is a driver domain. This enables certain
>>  features needed in order to run a driver domain.
>>  
>> +=item B<device_tree=PATH>
>> +
>> +Specify a partial device tree (compiled via the Device Tree Compiler).
>> +Everything under the node "/passthrough" will be copied into the guest
>> +device tree. For convenience, the node "/aliases" is also copied to allow
>> +the user to defined aliases which can be used by the guest kernel.
>> +
>>  =back
>>  
>>  =head2 Devices
>> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
>> index 53177eb..619458b 100644
>> --- a/tools/libxl/libxl_arm.c
>> +++ b/tools/libxl/libxl_arm.c
>> @@ -540,6 +540,238 @@ out:
>>      }
>>  }
>>  
>> +static bool check_overrun(uint64_t a, uint64_t b, uint32_t max)
>> +{
>> +    return ((a + b) > UINT_MAX || (a + b) > max);
> 
> Both halves here will fail if e.g. a == UINT64_MAX-1 and b == 2, so e..g
> a+b <= UINT_MAX and < max.

Oops right.

> To avoid this you should check that a and b are both less than some
> fraction of UINT64_MAX before the other checks, which would ensure the
> overflow can't happen, perhaps even UINT32_MAX would be acceptable for
> this use, depending on the input types involved.

max is an uint32_t so a and b should be inferior to UINT32_MAX.

What about

a < UINT_MAX && b < UINT_MAX && (a + b) < UINT_MAX

> 
>> +/*
>> + * Based on fdt_first_subnode and fdt_next_subnode.
>> + * We can't use the one helpers provided by libfdt because:
>> + *      - It has been introduced in 2013 => Doesn't work on wheezy
>> + *      - The prototypes exist but the functions are not exported. Don't
>> + *      ask why...
>> + *      - There is no version in the header (might be better to use
>> + *      configure for this purpose?)
>> + */
>> +static int _fdt_first_subnode(const void *fdt, int offset)
> 
> The _ namespace is for something other than applications (POSIX or the
> compiler, I forget which is _ and which __)
> 
> Using configure to conditionally compile our own versions with the usual
> names would be better I think.

I will give a look.


> The copyright and licensing of these functions should be included
> somewhere either just above their definitions, or maybe you want to put
> these into a separate .c file for convenience.

Ok.


>> +{
>> +    int depth = 0;
>> +
>> +    offset = fdt_next_node(fdt, offset, &depth);
>> +    if (offset < 0 || depth != 1)
>> +        return -FDT_ERR_NOTFOUND;
>> +
>> +    return offset;
>> +}
>> +
>> +static int _fdt_next_subnode(const void *fdt, int offset)
>> +{
>> +    int depth = 1;
>> +
>> +    /*
>> +     * With respect to the parent, the depth of the next subnode will be
>> +     * the same as the last.
>> +     */
>> +    do {
>> +        offset = fdt_next_node(fdt, offset, &depth);
>> +        if (offset < 0 || depth < 1)
>> +            return -FDT_ERR_NOTFOUND;
>> +    } while (depth > 1);
>> +
>> +    return offset;
>> +}
>> +
>> +/* Limit the maxixum depth of a node because of the recursion */
> 
> "maximum".
> 
>> +#define MAX_DEPTH   8
> 
> This restriction ought to be in the docs I think.

ok.

>> +static int copy_node_by_path(libxl__gc *gc, const char *path,
>> +                             void *fdt, void *pfdt)
>> +{
>> +    int nodeoff, r;
>> +    const char *name = strrchr(path, '/');
>> +
>> +    if (!name)
>> +        return -FDT_ERR_INTERNAL;
>> +
>> +    name++;
>> +
>> +    /* The FDT function to look at node doesn't take into account the
>                                       ^a 
> 
>> +     * unit (i.e anything after @) when search by name. Check if the
>> +     * name exactly match.
> 
> "exactly matches" or "names exactly match" (I think the second?)

We check only one name at the time. So "exactly matches" seems better.

>> +/*
>> + * The partial device tree is not copied entirely. Only the relevant bits are
>> + * copied to the guest device tree:
>> + *  - /passthrough node
>> + *  - /aliases node
> 
> Would it be easy to add a check for other top-level nodes and
> error/warn?

That would require to browse the device tree entirely, which is not done
there.

>> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
>> index 1214d2e..5651110 100644
>> --- a/tools/libxl/libxl_types.idl
>> +++ b/tools/libxl/libxl_types.idl
>> @@ -399,6 +399,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
>>      ("kernel",           string),
>>      ("cmdline",          string),
>>      ("ramdisk",          string),
>> +    ("device_tree",      string),
> 
> Needs a #define LIBXL_HAVE... in libxl.h

Hmmm why? This will be set to empty when libxl_domain_build_info is
initialized.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-02-23 17:06     ` Julien Grall
@ 2015-02-23 17:22       ` Ian Campbell
  2015-03-17 13:32         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-23 17:22 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Ian Jackson, stefano.stabellini, Wei Liu

On Mon, 2015-02-23 at 17:06 +0000, Julien Grall wrote:
> On 23/02/15 11:46, Ian Campbell wrote:
> > On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >> Let the user to pass additional nodes to the guest device tree. For this
> >> purpose, everything in the node /passthrough from the partial device tree will
> >> be copied into the guest device tree.
> >>
> >> The node /aliases will be also copied to allow the user to define aliases
> >> which can be used by the guest kernel.
> >>
> >> A simple partial device tree will look like:
> >>
> >> /dts-v1/;
> >>
> >> / {
> >>         #address-cells = <2>;
> >>         #size-cells = <2>;
> > 
> > Are these mandatory/required as implied below, or only the ones inside
> > the passthrough node (which is what I would expect).
> 
> It's to make DTC quiet.

Maybe add /* Keep DTC happy */ to both lines?

> 
> >>
> >>         passthrough {
> >>             compatible = "simple-bus";
> >>             ranges;
> >>             #address-cells = <2>;
> >>             #size-cells = <2>;
> >>
> >>             /* List of your nodes */
> >>         }
> >> };
> >>
> >> Note that:
> >>     * The interrupt-parent proporties will be added by the toolstack in
> > 
> > "properties"
> > 
> >>     the root node
> >>     * The properties compatible, ranges, #address-cells and #size-cells
> >>     in /passthrough are mandatory.
> > 
> > Does ranges need to be the empty form? I think ranges = <stuff stuff>
> > would be illegal?
> 
> It's not illegal as long as you correctly use it in the inner "reg".

OK. This could be explained in some more complete documentaiton I think.
(It's a doc day on Wednesday ;-))

> 
> Also, I admit that the "ranges" is confusing to read.
> 
> >>
> >> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> >> Cc: Wei Liu <wei.liu2@citrix.com>
> >>
> >> ---
> >>     Changes in v3:
> >>         - Patch added
> >> ---
> >>  docs/man/xl.cfg.pod.5       |   7 ++
> >>  tools/libxl/libxl_arm.c     | 253 ++++++++++++++++++++++++++++++++++++++++++++
> >>  tools/libxl/libxl_types.idl |   1 +
> >>  tools/libxl/xl_cmdimpl.c    |   1 +
> >>  4 files changed, 262 insertions(+)
> >>
> >> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
> >> index e2f91fc..225b782 100644
> >> --- a/docs/man/xl.cfg.pod.5
> >> +++ b/docs/man/xl.cfg.pod.5
> >> @@ -398,6 +398,13 @@ not emulated.
> >>  Specify that this domain is a driver domain. This enables certain
> >>  features needed in order to run a driver domain.
> >>  
> >> +=item B<device_tree=PATH>
> >> +
> >> +Specify a partial device tree (compiled via the Device Tree Compiler).
> >> +Everything under the node "/passthrough" will be copied into the guest
> >> +device tree. For convenience, the node "/aliases" is also copied to allow
> >> +the user to defined aliases which can be used by the guest kernel.
> >> +
> >>  =back
> >>  
> >>  =head2 Devices
> >> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> >> index 53177eb..619458b 100644
> >> --- a/tools/libxl/libxl_arm.c
> >> +++ b/tools/libxl/libxl_arm.c
> >> @@ -540,6 +540,238 @@ out:
> >>      }
> >>  }
> >>  
> >> +static bool check_overrun(uint64_t a, uint64_t b, uint32_t max)
> >> +{
> >> +    return ((a + b) > UINT_MAX || (a + b) > max);
> > 
> > Both halves here will fail if e.g. a == UINT64_MAX-1 and b == 2, so e..g
> > a+b <= UINT_MAX and < max.
> 
> Oops right.
> 
> > To avoid this you should check that a and b are both less than some
> > fraction of UINT64_MAX before the other checks, which would ensure the
> > overflow can't happen, perhaps even UINT32_MAX would be acceptable for
> > this use, depending on the input types involved.
> 
> max is an uint32_t so a and b should be inferior to UINT32_MAX.

by "inferior to" do you mean less than? Or something to do with type
promotion/demotion rules?

> 
> What about
> 
> a < UINT_MAX && b < UINT_MAX && (a + b) < UINT_MAX

Isn't that inverted from the sense which the function name requires?

Given the complexity in reasoning about this I think a series of
individual if and return statements which check each precondition one at
a time and return failure if necessary wuold be clearer to read and
reason about than trying to encode it all in one expression.

> >> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> >> index 1214d2e..5651110 100644
> >> --- a/tools/libxl/libxl_types.idl
> >> +++ b/tools/libxl/libxl_types.idl
> >> @@ -399,6 +399,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
> >>      ("kernel",           string),
> >>      ("cmdline",          string),
> >>      ("ramdisk",          string),
> >> +    ("device_tree",      string),
> > 
> > Needs a #define LIBXL_HAVE... in libxl.h
> 
> Hmmm why? This will be set to empty when libxl_domain_build_info is
> initialized.

So that applications which use libxl can take advantage of the new
feature when built against versions of the library which support it,
without breaking when built against versions which do not.

See the comments near the top of libxl.h

Ian.

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-02-23 12:03   ` Ian Jackson
  2015-02-23 12:44     ` Ian Jackson
@ 2015-02-23 18:43     ` Julien Grall
  2015-02-23 19:12       ` Ian Jackson
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 18:43 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini, Wei Liu

Hi Ian,

On 23/02/15 12:03, Ian Jackson wrote:
> Julien Grall writes ("[PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM"):
>> Let the user to pass additional nodes to the guest device tree. For this
>> purpose, everything in the node /passthrough from the partial device tree \
> will
>> be copied into the guest device tree.
> 
> Please wrap your commit messages to 70, not 80.

I though commit message has to be wrapped to 80. I will change it.

> 
>> +=item B<device_tree=PATH>
>> +
>> +Specify a partial device tree (compiled via the Device Tree Compiler).
>> +Everything under the node "/passthrough" will be copied into the guest
>> +device tree. For convenience, the node "/aliases" is also copied to allow
>> +the user to defined aliases which can be used by the guest kernel.
> 
> This is rather odd.  The config option is `device_tree' but apparently
> it is only relevant for passthrough and nothing else can be set with
> it.

I had to chose a name for the node and "/passthrough" was the best one
and it won't collapse with the device tree generated by the toolstack.

Although, you can put pretty much everything in the "/passthrough" node.

>> +static int check_partial_fdt(libxl__gc *gc, void *fdt, size_t size)
>> +{
> ...
>> +    /* Check if the *size and off* fields doesn't overrun the totalsize
>> +     * of the partial FDT.
>> +     */
>> +    if (fdt_totalsize(fdt) > size) {
>> +        LOG(ERROR, "Partial FDT totalsize is too big");
>> +        return ERROR_FAIL;
>> +    }
> 
> There's lots and lots of this very fragile binary parsing code.
> 
> Is this facility supposed to take untrusted or partially-trusted
> partial device trees ?

It may take untrusted device tree. I review the libfdt code and try to
fix all possible security issue in the toolstack.

> If so then I suspect we need a different approach.  It might be easer
> to rewrite this whole functionality in a programming language which is
> less fragile in the face of programming errors, than to try to make
> this whole thing secure (and review it).
> 
> I'm definitely having XSA-55 flashbacks.

It's not my plan to have an XSA-55 like :).

As discussed IRL, we can mark this option "unsafe". So any device tree
pass to libxl should be trusted.

I will add an item in the description.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-02-23 18:43     ` Julien Grall
@ 2015-02-23 19:12       ` Ian Jackson
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Jackson @ 2015-02-23 19:12 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, ian.campbell, stefano.stabellini, Wei Liu

Julien Grall writes ("Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM"):
> On 23/02/15 12:03, Ian Jackson wrote:
> > Please wrap your commit messages to 70, not 80.
> 
> I though commit message has to be wrapped to 80. I will change it.

Thanks.  `git log' adds 4 spaces, and email quoting adds varying
numbers of `> ', so the original has to be significantly less than 80
to stop quoted emails and git log from being too wide (by which I mean
more than 79).

> > This is rather odd.  The config option is `device_tree' but apparently
> > it is only relevant for passthrough and nothing else can be set with
> > it.
> 
> I had to chose a name for the node and "/passthrough" was the best one
> and it won't collapse with the device tree generated by the toolstack.
> 
> Although, you can put pretty much everything in the "/passthrough" node.

Perhaps the config option should be renamed so that it's less
general.  Maybe in future people will want a more general dtb-editing
facility and then this would be in the way.

> It's not my plan to have an XSA-55 like :).

:-).

> As discussed IRL, we can mark this option "unsafe". So any device tree
> pass to libxl should be trusted.

Yes.

> I will add an item in the description.

Thanks,
Ian.

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-02-23 16:00       ` Ian Campbell
@ 2015-02-23 21:48         ` Julien Grall
  2015-02-24 10:06           ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 21:48 UTC (permalink / raw)
  To: Ian Campbell, Andrew Cooper
  Cc: Wei Liu, George Dunlap, Ian Jackson, tim, stefano.stabellini,
	Jan Beulich, xen-devel, Daniel De Graaf, Keir Fraser

Hi Ian,

On 23/02/2015 16:00, Ian Campbell wrote:
> On Mon, 2015-02-23 at 15:48 +0000, Andrew Cooper wrote:
>> GIC version and SPIs should absolutely be part of the migration stream.
>> They are domain architectural state.
>
> Of course, the question is where.
>
> They could be part of the Xen hvmsave blob for the GIC (i.e. along with
> the other GIC architectural state such as which interrupts are currently
> active,pending,masked etc).
>
> Or they could be part of a new migration v2 record for such things.

With the extension of the DOMCTL createdomain, this would be the best 
solution. The implementation would be cleaner.

> Or they could be part of the hvm params migration record.

And how do you restore? As we may have some default value (such as 
choosing the default GIC version), how do you know that all the 
parameters is correctly given?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-23 16:34                         ` Ian Campbell
@ 2015-02-23 21:54                           ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-23 21:54 UTC (permalink / raw)
  To: Ian Campbell
  Cc: xen-devel, Stefano Stabellini, stefano.stabellini, Jan Beulich, tim

Hi Ian,

On 23/02/2015 16:34, Ian Campbell wrote:
> On Mon, 2015-02-23 at 16:11 +0000, Julien Grall wrote:
>> On 23/02/15 16:04, Ian Campbell wrote:
>>> On Mon, 2015-02-23 at 15:53 +0000, Julien Grall wrote:
>>>> Hi Ian,
>>>>
>>>> On 23/02/15 15:28, Ian Campbell wrote:
>>>>> On Mon, 2015-02-23 at 09:33 +0000, Jan Beulich wrote:
>>>>>>>>> On 20.02.15 at 17:53, <ian.campbell@citrix.com> wrote:
>>>>>>> Jan, do you have any feeling for how this is going to play out on x86
>>>>>>> with the vapic stuff?
>>>>>>
>>>>>> The vapic logic shouldn't require any physdevop involvement, so if
>>>>>> I read right what you propose (not having such a requirement /
>>>>>> connection on ARM) either, I agree that a new domctl should be all
>>>>>> that's needed (if XEN_DOMCTL_{,un}bind_pt_irq can't be re-used).
>>>>>
>>>>> Actually, I think bind_pt_irq with a new PT_IRQ_TYPE_* would be a good
>>>>> option.
>>>>>
>>>>> An ARM SPI is a bit like an ISA IRQ, but not close enough to reuse IMHO
>>>>> (and the datatype would need widening).
>>>>
>>>> We have to think about MSI and other type too...
>>>>
>>>> In any case a DOMCTL is not suitable here because a guest kernel may
>>>> need to map/unmap IRQ too (think about ACPI or device passthrough).
>>>
>>> I don't follow, setting up device passthrough is very much a toolstack
>>> operation, isn't it? Where does the guest kernel get involved?
>>
>> Sorry I meant the DOM0 kernel.
>>
>> Not really. On platform device pass-through there is no way to know the
>> IRQ, so for now the routing is done by the toolstack.
>>
>> But we could decide to implement a driver in DOM0 which will
>> unbind/bind/reset device.
>
> Sure, but...
>
>>   In this case it will require to
>> assign/deassign the IRQ from DOM0.
>
> ...why does that follow?

Because we may decide to re-use the device to DOM0.

In the case of the DOMCTL, it's not possible to do it.

>> There is also the case of MSI.
>
> Handled via XEN_DOMCTL_bind_pt_irq for the toolstack configuration
> angle, the actual guest usage of them is a separate interface which
> doesn't yet concern us, at least not in this series.

That would require some rework in the toolstack to make the IRQ routing 
(xc_physdev...) per architecture.

Also what about IRQ permission? Should we just ignore it and not give 
permission to the guest domain?

>>> As for ACPI, I think dom0 propagating ACPI derived platform info to Xen
>>> should be handled differently (at the hypercall interface at least)
>>> separate from passthrough.
>>
>> There is no difference between routing because of ACPI and/or because
>> pass-through. So this should be done the same way.
>
> I'm not convinced. Routing all the IRQs is only one aspect of dom0
> propagating ACPI derived platform info to Xen.
>
> I suppose we will see once I look at the ACPI series. In the meantime I
> think XEN_DOMCTL_bind_pt_irq matches your requirements in for this
> series (and is a domctl so we aren't tied to it once we have a better
> understanding of the other stuff).

ACPI is one part of the problem, MSI with PCI is another problem.

Anyway, I suspect we will have the same talk before 4.6 release so we 
just defer the problem.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-02-23 14:36           ` Ian Campbell
@ 2015-02-23 22:02             ` Julien Grall
  2015-02-24 10:08               ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 22:02 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, tim,
	stefano.stabellini, xen-devel



On 23/02/2015 14:36, Ian Campbell wrote:
> On Thu, 2015-01-29 at 13:48 +0000, Julien Grall wrote:
>> On 29/01/15 12:28, Stefano Stabellini wrote:
>>> On Thu, 29 Jan 2015, Julien Grall wrote:
>>>> On 29/01/15 11:07, Stefano Stabellini wrote:
>>>>> On Tue, 13 Jan 2015, Julien Grall wrote:
>>>>>> The partial device tree may contains phandle. The Device Tree Compiler
>>>>>> tends to allocate the phandle from 1.
>>>>>>
>>>>>> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
>>>>>> that the partial device tree will never contain a such ID.
>>>>>>
>>>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>>>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>>>>>
>>>>>
>>>>> Shouldn't we at least check that the partial device tree doesn't contain
>>>>> a conflicting phandle?
>>>>
>>>> I don't think so. This will unlikely happen, and if it happens the guest
>>>> will crash with an obvious error.
>>>
>>> It is good that the error is obvious.
>>>
>>> But how expensive is to check for it?
>>
>> I would have to check the validity of the properties (name + value
>> size). At least the properties "linux,phandle" and "phandle" should be
>> checked.
>>
>> Though I could do in copy_properties but I find it hackish.
>
> Can't you just track the largest phandle ever seen during
> copy_properties and then use N+1 for the GIC?

Now the we decided to trust the input device tree, it would be easier to 
write the code.

I will give a look.

>
>>> Think about the poor user that ends up in this situation: the fact that
>>> is unlikely only makes it harder for a user to figure out what to do to
>>> fix it.
>>
>> The poor use will have to write his device tree by hand to hit this
>> error ;).
>
> Or use a new version of dtc which does things differently for some
> reason.

And you would not be able to get a phandle for the GIC if largest 
phandle is too high.

So the guest won't work correctly.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 24/24] xl: Add new option dtdev
  2015-02-23 14:45   ` Ian Campbell
@ 2015-02-23 22:03     ` Julien Grall
  2015-02-24 10:07       ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-23 22:03 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, Ian Jackson, stefano.stabellini, Wei Liu

Hi Ian,

On 23/02/2015 14:45, Ian Campbell wrote:
>> +is the absolute path in the device tree.
>
> Can it be an alias?

Right now, no. But I can change it if you think it's useful.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration
  2015-02-23 21:48         ` Julien Grall
@ 2015-02-24 10:06           ` Ian Campbell
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-24 10:06 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, George Dunlap, Andrew Cooper, Ian Jackson, tim,
	stefano.stabellini, Jan Beulich, xen-devel, Daniel De Graaf,
	Keir Fraser

On Mon, 2015-02-23 at 21:48 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 23/02/2015 16:00, Ian Campbell wrote:
> > On Mon, 2015-02-23 at 15:48 +0000, Andrew Cooper wrote:
> >> GIC version and SPIs should absolutely be part of the migration stream.
> >> They are domain architectural state.
> >
> > Of course, the question is where.
> >
> > They could be part of the Xen hvmsave blob for the GIC (i.e. along with
> > the other GIC architectural state such as which interrupts are currently
> > active,pending,masked etc).
> >
> > Or they could be part of a new migration v2 record for such things.
> 
> With the extension of the DOMCTL createdomain, this would be the best 
> solution. The implementation would be cleaner.

and this sounds like it fits in with the approach Andrew wants to take
for x86 too.

> > Or they could be part of the hvm params migration record.
> 
> And how do you restore? As we may have some default value (such as 
> choosing the default GIC version), how do you know that all the 
> parameters is correctly given?

IIRC the migration v2 has a list of hvm params to transport in the save
stream (either in a dedicated record or one per param, I don't recall),
i.e. it reads them back on the source and writes them on the target.

The read would presumably have to reflect the actual selection made for
that domain if there was defaulting going on and the write would have to
reject things it couldn't deal with (like GICv2 on v3 only hardware).

Ian.

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

* Re: [PATCH v3 24/24] xl: Add new option dtdev
  2015-02-23 22:03     ` Julien Grall
@ 2015-02-24 10:07       ` Ian Campbell
  0 siblings, 0 replies; 251+ messages in thread
From: Ian Campbell @ 2015-02-24 10:07 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, Ian Jackson, stefano.stabellini, Wei Liu

On Mon, 2015-02-23 at 22:03 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 23/02/2015 14:45, Ian Campbell wrote:
> >> +is the absolute path in the device tree.
> >
> > Can it be an alias?
> 
> Right now, no. But I can change it if you think it's useful.

No need, I was just curious.

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-02-23 22:02             ` Julien Grall
@ 2015-02-24 10:08               ` Ian Campbell
  2015-03-18 14:14                 ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-24 10:08 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, tim,
	stefano.stabellini, xen-devel

On Mon, 2015-02-23 at 22:02 +0000, Julien Grall wrote:
> 
> On 23/02/2015 14:36, Ian Campbell wrote:
> > On Thu, 2015-01-29 at 13:48 +0000, Julien Grall wrote:
> >> On 29/01/15 12:28, Stefano Stabellini wrote:
> >>> On Thu, 29 Jan 2015, Julien Grall wrote:
> >>>> On 29/01/15 11:07, Stefano Stabellini wrote:
> >>>>> On Tue, 13 Jan 2015, Julien Grall wrote:
> >>>>>> The partial device tree may contains phandle. The Device Tree Compiler
> >>>>>> tends to allocate the phandle from 1.
> >>>>>>
> >>>>>> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
> >>>>>> that the partial device tree will never contain a such ID.
> >>>>>>
> >>>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> >>>>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> >>>>>> Cc: Wei Liu <wei.liu2@citrix.com>
> >>>>>>
> >>>>>
> >>>>> Shouldn't we at least check that the partial device tree doesn't contain
> >>>>> a conflicting phandle?
> >>>>
> >>>> I don't think so. This will unlikely happen, and if it happens the guest
> >>>> will crash with an obvious error.
> >>>
> >>> It is good that the error is obvious.
> >>>
> >>> But how expensive is to check for it?
> >>
> >> I would have to check the validity of the properties (name + value
> >> size). At least the properties "linux,phandle" and "phandle" should be
> >> checked.
> >>
> >> Though I could do in copy_properties but I find it hackish.
> >
> > Can't you just track the largest phandle ever seen during
> > copy_properties and then use N+1 for the GIC?
> 
> Now the we decided to trust the input device tree, it would be easier to 
> write the code.
> 
> I will give a look.
> 
> >
> >>> Think about the poor user that ends up in this situation: the fact that
> >>> is unlikely only makes it harder for a user to figure out what to do to
> >>> fix it.
> >>
> >> The poor use will have to write his device tree by hand to hit this
> >> error ;).
> >
> > Or use a new version of dtc which does things differently for some
> > reason.
> 
> And you would not be able to get a phandle for the GIC if largest 
> phandle is too high.
> 
> So the guest won't work correctly.

Indeed, filling in a bitmap as you go might be another option, although
you'd either need an 8k bitmap (not so bad in userspace) or to realloc
as it grows.

Ian.

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-02-20 15:52   ` Ian Campbell
  2015-02-20 17:09     ` Julien Grall
@ 2015-02-27 14:25     ` Julien Grall
  1 sibling, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-27 14:25 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 20/02/15 15:52, Ian Campbell wrote:
>> As DOM0 will get most the devices, the vIRQ is equal to the IRQ in that case.
> 
> Am I correct that after this patch all callers still pass irq==virq to
> the new function?

Sorry, I forgot to answer to this question. Yes, all the callers will
pass irq == virq in case of DOM0.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-02-20 17:09     ` Julien Grall
@ 2015-02-27 14:33       ` Julien Grall
  2015-02-27 14:44         ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-02-27 14:33 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 20/02/15 17:09, Julien Grall wrote:
> On 20/02/15 15:52, Ian Campbell wrote:
>>>  
>>>      action = xmalloc(struct irqaction);
>>> -    if (!action)
>>> +    if ( !action )
>>> +        return -ENOMEM;
>>> +
>>> +    info = xmalloc(struct irq_guest);
>>
>> FWIW you might (subject to sizing/alignment needs) be able to do
>> 	action = _xmalloc(sizeof(struct irqaction) + sizeof(struct irq_guest);
>> 	info = (sturct irq_guest *)(action + 1);
>>
>> which would save some memory overhead for free pointers etc and allow
>> you to avoid manually managing the info.
>>
>> You probably won't like that though, so feel free to ignore.
> 
> Actually it's a good idea :). I haven't though about it.

I though about it. The pointer to irq_guest may not be correctly aligned
with this solution, right?

So I prefer to keep separate the allocation. We can revisit it later.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-02-27 14:33       ` Julien Grall
@ 2015-02-27 14:44         ` Ian Campbell
  2015-02-27 15:55           ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-02-27 14:44 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Fri, 2015-02-27 at 14:33 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 20/02/15 17:09, Julien Grall wrote:
> > On 20/02/15 15:52, Ian Campbell wrote:
> >>>  
> >>>      action = xmalloc(struct irqaction);
> >>> -    if (!action)
> >>> +    if ( !action )
> >>> +        return -ENOMEM;
> >>> +
> >>> +    info = xmalloc(struct irq_guest);
> >>
> >> FWIW you might (subject to sizing/alignment needs) be able to do
> >> 	action = _xmalloc(sizeof(struct irqaction) + sizeof(struct irq_guest);
> >> 	info = (sturct irq_guest *)(action + 1);
> >>
> >> which would save some memory overhead for free pointers etc and allow
> >> you to avoid manually managing the info.
> >>
> >> You probably won't like that though, so feel free to ignore.
> > 
> > Actually it's a good idea :). I haven't though about it.
> 
> I though about it. The pointer to irq_guest may not be correctly aligned
> with this solution, right?

It depends on sizeof(struct irqaction) (which is what I meant by
"subject to..."). t'd probably need a ROUNDUP(sizeof(foo),
pointer-alignement) in there somewhere.

> So I prefer to keep separate the allocation. We can revisit it later.

OK.

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

* Re: [PATCH v3 08/24] xen/arm: Allow virq != irq
  2015-02-27 14:44         ` Ian Campbell
@ 2015-02-27 15:55           ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-02-27 15:55 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

On 27/02/15 14:44, Ian Campbell wrote:
> On Fri, 2015-02-27 at 14:33 +0000, Julien Grall wrote:
>> Hi Ian,
>>
>> On 20/02/15 17:09, Julien Grall wrote:
>>> On 20/02/15 15:52, Ian Campbell wrote:
>>>>>  
>>>>>      action = xmalloc(struct irqaction);
>>>>> -    if (!action)
>>>>> +    if ( !action )
>>>>> +        return -ENOMEM;
>>>>> +
>>>>> +    info = xmalloc(struct irq_guest);
>>>>
>>>> FWIW you might (subject to sizing/alignment needs) be able to do
>>>> 	action = _xmalloc(sizeof(struct irqaction) + sizeof(struct irq_guest);
>>>> 	info = (sturct irq_guest *)(action + 1);
>>>>
>>>> which would save some memory overhead for free pointers etc and allow
>>>> you to avoid manually managing the info.
>>>>
>>>> You probably won't like that though, so feel free to ignore.
>>>
>>> Actually it's a good idea :). I haven't though about it.
>>
>> I though about it. The pointer to irq_guest may not be correctly aligned
>> with this solution, right?
> 
> It depends on sizeof(struct irqaction) (which is what I meant by
> "subject to..."). t'd probably need a ROUNDUP(sizeof(foo),
> pointer-alignement) in there somewhere.

Oh right, I missed the parentheses part.

The pointer alignment is not the same on ARM32 and ARM64, I need to
think more about it.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying
  2015-02-20 17:41     ` Julien Grall
  2015-02-23 15:25       ` Ian Campbell
@ 2015-03-03 12:50       ` Julien Grall
  1 sibling, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-03 12:50 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

Hi Ian,

On 20/02/2015 17:41, Julien Grall wrote:
  >>> +    /* Only SPIs are supported */
>>> +    if ( virq < 32 || virq >= vgic_num_irqs(d) )
>>> +        return -EINVAL;
>>> +
>>> +    p = irq_to_pending(d->vcpu[0], virq);
>>> +    if ( !p->desc )
>>> +        return -EINVAL;
>>
>> Are we seeing this pattern a lot? It seems so, I wonder if a helper
>> could be useful:
>>         p = spi_to_pending(d, virq);
>>         if ( !p->desc )
>>             return -EINVAL;
>>
>> with the < 32 check etc in the helper where it only needs commenting on
>> once.
>
> IIRC, there is only 2 places. I will replace it by an helper.

Hmmmm.... I only found 1 place. So I will keep open-coding in the function.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-02-23 16:02                 ` Ian Campbell
@ 2015-03-04 14:37                   ` Julien Grall
  2015-03-04 14:55                     ` Jan Beulich
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-03-04 14:37 UTC (permalink / raw)
  To: Ian Campbell, Jan Beulich
  Cc: xen-devel, tim, stefano.stabellini, Stefano Stabellini

Hi,

On 23/02/15 16:02, Ian Campbell wrote:
> On Mon, 2015-02-23 at 15:51 +0000, Julien Grall wrote:
>> On 20/02/15 16:53, Ian Campbell wrote:
> 
>>> Are we absolutely 100% sure that we will never ever want to map hardware
>>> IRQs to guests on ARMs using pirq-type event channels? Because that is
>>> what we are essentially ruling out here.
>>
>> That would happen if we decide to implement an interrupt controller
>> which doesn't support virtualization.
> 
> Good point. It's pretty unlikely but not absolutely impossible. So we
> should avoid reusing the pirq evtchn type for this. Jan suggested
> XENDOMCTL_bind_pt_irq which is looking better and better...

I looked to the interface of XENDOMCTL_bind_pt_irq and I'm not sure
about the meaning of machine_irq and isa_irq.

AFAIU the code:
	machine_irq => guest PIRQ
	isa_irq => host IRQ

am I right?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-03-04 14:37                   ` Julien Grall
@ 2015-03-04 14:55                     ` Jan Beulich
  2015-03-04 14:56                       ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-03-04 14:55 UTC (permalink / raw)
  To: Julien Grall
  Cc: xen-devel, tim, stefano.stabellini, Ian Campbell, Stefano Stabellini

>>> On 04.03.15 at 15:37, <julien.grall@linaro.org> wrote:
> I looked to the interface of XENDOMCTL_bind_pt_irq and I'm not sure
> about the meaning of machine_irq and isa_irq.
> 
> AFAIU the code:
> 	machine_irq => guest PIRQ

Yes (i.e. the Xen assigned representation of an IRQ the guest has
been granted access to).

> 	isa_irq => host IRQ

But only for ISA ones, not PCI (i.e. you likely don't care about this
at all).

Note that the PCI case here still lacks a segment number - if you in
the end decided you want/need non-zero segments on ARM, then
this will need extension (which it would need anyway if anyone was
serious about to running Xen on such [x86] hardware).

Jan

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

* Re: [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq
  2015-03-04 14:55                     ` Jan Beulich
@ 2015-03-04 14:56                       ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-04 14:56 UTC (permalink / raw)
  To: Jan Beulich
  Cc: xen-devel, tim, stefano.stabellini, Ian Campbell, Stefano Stabellini

On 04/03/15 14:55, Jan Beulich wrote:
>>>> On 04.03.15 at 15:37, <julien.grall@linaro.org> wrote:
>> I looked to the interface of XENDOMCTL_bind_pt_irq and I'm not sure
>> about the meaning of machine_irq and isa_irq.
>>
>> AFAIU the code:
>> 	machine_irq => guest PIRQ
> 
> Yes (i.e. the Xen assigned representation of an IRQ the guest has
> been granted access to).

Thank you for the confirmation.

>> 	isa_irq => host IRQ
> 
> But only for ISA ones, not PCI (i.e. you likely don't care about this
> at all).
> 
> Note that the PCI case here still lacks a segment number - if you in
> the end decided you want/need non-zero segments on ARM, then
> this will need extension (which it would need anyway if anyone was
> serious about to running Xen on such [x86] hardware).

I don't care about PCI right now. I'm looking for mapping SPI (kind of
ISA) to the guest.

I'm planning to introduce a new type of this purpose.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-02-23 16:27       ` Ian Campbell
@ 2015-03-10 13:58         ` Julien Grall
  2015-03-11 12:34           ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-03-10 13:58 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

On 23/02/15 16:27, Ian Campbell wrote:
> On Mon, 2015-02-23 at 16:01 +0000, Julien Grall wrote:
>> Hi Ian,
>>
>> On 23/02/15 15:30, Ian Campbell wrote:
>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>
>>>> +/* This limit is used by the hypercalls to restrict the size of the path */
>>>> +#define DEVICE_TREE_MAX_PATHLEN 1024
>>>
>>> Is this something you've made up or derived from the DT spec/ePAPR etc?
>>
>> I didn't find a such requirements on the spec.
> 
> I vaguely recall a limit on the length of a single node name, and a
> limit on the depth which they may nest, which can be multiplied. It's
> probably an unhelpfully large number though, so...
> 
>> I chose this number based on the linux pathlen because the path is also
>> used in the sysfs (/sys/firmware/devicetree).
> 
> ...that's a good as anything I suppose!

Hmmm... I'm not so sure about the 1024 limit anymore. Linux is defining
PATH_MAX to 4096 but I don't see many usage in the sysfs code.

And this value may change from one OS to another. Although, 1024 sounds
a very long path to write in the configuration file... Maybe we should
support alias too?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-02-23 15:34       ` Ian Campbell
@ 2015-03-10 15:29         ` Julien Grall
  2015-03-11 12:35           ` Ian Campbell
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-03-10 15:29 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, Jan Beulich, stefano.stabellini

Hi,

On 23/02/15 15:34, Ian Campbell wrote:
> On Mon, 2015-02-23 at 10:10 +0000, Julien Grall wrote:
>>
>> On 20/02/2015 17:04, Ian Campbell wrote:
>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>> Currently, when the device is deassigned from a domain, we directly reassign
>>>> to DOM0.
>>>>
>>>> As the device may not have been correctly reset, this may lead to corruption or
>>>> expose some part of DOM0 memory. Also, we may have no way to reset some
>>>> platform devices.
>>>>
>>>> If Xen reassigns the device to "nobody", it may receive some global/context
>>>> fault because the transaction has failed (indeed the context has been
>>>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
>>>> hardware. I think we could live with that for a first version of platform
>>>> device passthrough.
>>>>
>>>> DOM0 will have to issue an hypercall to assign the device to itself if it
>>>> wants to use it.
>>>
>>> Does this behaviour differ from x86?
> 
> I realise now that x86 is a red-herring, what I really meant was differ
> from other types of device (specifically PCI ones).
> 
>>  If so then it is worth calling that
>>> out explicitly (even if not, good to know I think!)
>>
>> What do you mean by "calling that out explicitly"?
> 
> Stating in the commit log or a suitably placed comment (at least under
> xen/include/public hopefully) that deassignment of dt devices behaves
> differently to deassignment of other types of devices.

I tried to search any documentation explaining the behavior of those
DOMCTL for PCI (mostly the deassign one) but I didn't find any.

By any chance, do you know if there is one? If so where?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-02-20 17:17   ` Ian Campbell
  2015-02-23 16:25     ` Daniel De Graaf
@ 2015-03-10 16:33     ` Julien Grall
  2015-03-11 12:37       ` Ian Campbell
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-03-10 16:33 UTC (permalink / raw)
  To: Ian Campbell, Daniel De Graaf
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich, xen-devel

Hi Ian,

On 20/02/15 17:17, Ian Campbell wrote:
>> +    /* TODO: Do we need to check is_dying? Mostly to protect against
>> +     * hypercall trying to passthrough a device while we are
>> +     * dying.
> 
> FWIW the PCI case appears not to care...

There is one place in XEN_DOMCTL_assign_device...

Although I don't understand much the usage of is_dying.

>> +     */
>> +
>> +    switch ( domctl->cmd )
>> +    {
>> +    case XEN_DOMCTL_assign_device:
>> +        ret = -ENOSYS;
>> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
>> +            break;
> 
> You added something similar to iommu_do_pci_domctl, would it not be
> preferable for the caller to switch on domctl->u.assign_device.dev and
> call the correct iommu_do_*_domctl?

I though about it. It would require to stub iommu_do_*_domctl. So I
preferred to chose the current solution.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-02-23 16:25     ` Daniel De Graaf
@ 2015-03-10 16:52       ` Julien Grall
  2015-03-10 22:45         ` Daniel De Graaf
  0 siblings, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-03-10 16:52 UTC (permalink / raw)
  To: Daniel De Graaf, Ian Campbell
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich,
	Machon Gregory, xen-devel

Hi Daniel,

On 23/02/15 16:25, Daniel De Graaf wrote:
> On 02/20/2015 12:17 PM, Ian Campbell wrote:
>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>> TODO: Update the commit message
>>>
>>> A device node is described by a path. It will be used to retrieved the
>>> node in the device tree and assign the related device to the domain.
>>>
>>> Only device protected by an IOMMU can be assigned to a guest.
>>>
>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>
>>> ---
>>>      Changes in v2:
>>>          - Use a different number for XEN_DOMCTL_assign_dt_device
>>> ---
>>>   tools/libxc/include/xenctrl.h         | 10 ++++
>>>   tools/libxc/xc_domain.c               | 95
>>> ++++++++++++++++++++++++++++++++--
>>
>> These bits all look fine.
>>
>>> +int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
>>> +                       XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>>> +{
>>> +    int ret;
>>> +    struct dt_device_node *dev;
>>> +
>>> +    /* TODO: How to deal with XSM? */
>>
>> Adding Daniel.
>>
>> It seems the PCI ones are protected by
>>          xsm_test_assign_device(XSM_HOOK,
>> domctl->u.assign_device.machine_sbdf);
>>
>> So it seem that either this needs to become "test_assign_pci_device" and
>> a similar "test_assign_dt_device" needs to be added and plumbed through
>> or it needs to grow a type parameter and take the union for the
>> identifier.
> 
> Either would work, but a distinct hook seems simpler to me, especially as
> the call sites are distinct and the hook would process them differently.

Sounds good.

>> The code to apply an XSM context to a DT node would need consideration
>> too I suppose?
> 
> This may require a bit more thought.  At first glance, the dt_phandle
> field seems to be an identifier that could be used by FLASK to identify a
> device using an ocontext lookup.  Labeling would then be done in the same
> way as PCI devices and x86 legacy I/O ports.

We don't always have a dt_phandle in hand. They are mostly used for
referencing a node within another (such as IOMMU, interrupt
controller...). Also, the value is controlled by the compiler.

AFAICT, the only unique value we have in hand is the path of the device.

BTW, do you have any pointer on how to write a policy for device/IRQ
passthrough?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-10 16:52       ` Julien Grall
@ 2015-03-10 22:45         ` Daniel De Graaf
  2015-03-10 23:07           ` Julien Grall
  2015-03-11  8:53           ` Jan Beulich
  0 siblings, 2 replies; 251+ messages in thread
From: Daniel De Graaf @ 2015-03-10 22:45 UTC (permalink / raw)
  To: Julien Grall, Ian Campbell
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich,
	Machon Gregory, xen-devel

On 03/10/2015 12:52 PM, Julien Grall wrote:
> Hi Daniel,
>
> On 23/02/15 16:25, Daniel De Graaf wrote:
>> On 02/20/2015 12:17 PM, Ian Campbell wrote:
>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>> TODO: Update the commit message
>>>>
>>>> A device node is described by a path. It will be used to retrieved the
>>>> node in the device tree and assign the related device to the domain.
>>>>
>>>> Only device protected by an IOMMU can be assigned to a guest.
>>>>
>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>>> Cc: Jan Beulich <jbeulich@suse.com>
>>>>
>>>> ---
>>>>       Changes in v2:
>>>>           - Use a different number for XEN_DOMCTL_assign_dt_device
>>>> ---
>>>>    tools/libxc/include/xenctrl.h         | 10 ++++
>>>>    tools/libxc/xc_domain.c               | 95
>>>> ++++++++++++++++++++++++++++++++--
>>>
>>> These bits all look fine.
>>>
>>>> +int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
>>>> +                       XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>>>> +{
>>>> +    int ret;
>>>> +    struct dt_device_node *dev;
>>>> +
>>>> +    /* TODO: How to deal with XSM? */
>>>
>>> Adding Daniel.
>>>
>>> It seems the PCI ones are protected by
>>>           xsm_test_assign_device(XSM_HOOK,
>>> domctl->u.assign_device.machine_sbdf);
>>>
>>> So it seem that either this needs to become "test_assign_pci_device" and
>>> a similar "test_assign_dt_device" needs to be added and plumbed through
>>> or it needs to grow a type parameter and take the union for the
>>> identifier.
>>
>> Either would work, but a distinct hook seems simpler to me, especially as
>> the call sites are distinct and the hook would process them differently.
>
> Sounds good.
>
>>> The code to apply an XSM context to a DT node would need consideration
>>> too I suppose?
>>
>> This may require a bit more thought.  At first glance, the dt_phandle
>> field seems to be an identifier that could be used by FLASK to identify a
>> device using an ocontext lookup.  Labeling would then be done in the same
>> way as PCI devices and x86 legacy I/O ports.
>
> We don't always have a dt_phandle in hand. They are mostly used for
> referencing a node within another (such as IOMMU, interrupt
> controller...). Also, the value is controlled by the compiler.
>
> AFAICT, the only unique value we have in hand is the path of the device.

OK. I was hoping that there would be a unique numeric identifier.  If
there is not, it may be necessary to either create one or to add a new
field to device nodes (like the one for event channels) so that they
can be labeled.

> BTW, do you have any pointer on how to write a policy for device/IRQ
> passthrough?

There is a bit of documentation in xsm-flask.txt about device labeling,
which is the hard part of making passthrough work.  Labels can be set
either statically in the security policy (as documented in the section
"Device Labeling") or dynamically using a tool like flask-label-pci
as documented in "Resource Policy".  Once that is done, then rules to
allow the passthrough operation can be added, similar to the example
resource nic_dev_t in xen.te.

In order to do static labeling for device passthrough, the nodes in a
device tree need a 32-bit numeric identifier.  IO memory uses the MFN,
PCI devices use SBDF, and IRQs and x86 legacy IOs just use the number.

If device tree nodes can be labeled in this way, they could be added
as another resource type in the policy.  If not, then the label of a
device node will need to be set at boot using the XSM hypercalls;
this label would be stored in a security field added to device tree
nodes.

-- 
Daniel De Graaf
National Security Agency

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-10 22:45         ` Daniel De Graaf
@ 2015-03-10 23:07           ` Julien Grall
  2015-03-10 23:39             ` Daniel De Graaf
  2015-03-11  8:53           ` Jan Beulich
  1 sibling, 1 reply; 251+ messages in thread
From: Julien Grall @ 2015-03-10 23:07 UTC (permalink / raw)
  To: Daniel De Graaf, Ian Campbell
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich,
	Machon Gregory, xen-devel

Hi Daniel,

On 10/03/2015 22:45, Daniel De Graaf wrote:
>> BTW, do you have any pointer on how to write a policy for device/IRQ
>> passthrough?
>
> There is a bit of documentation in xsm-flask.txt about device labeling,
> which is the hard part of making passthrough work.  Labels can be set
> either statically in the security policy (as documented in the section
> "Device Labeling") or dynamically using a tool like flask-label-pci
> as documented in "Resource Policy".  Once that is done, then rules to
> allow the passthrough operation can be added, similar to the example
> resource nic_dev_t in xen.te.

I tried to follow xsm-flask.txt and uncomment one of the pirqcon line in 
the xsm policy.

But I got the following error:

policy/modules/xen/xen.te:199:ERROR 'syntax error' at token 'pirqcon' on 
line 1986:
pirqcon 33 system_u:object_r:nic_dev_t

Did I miss anything?

> In order to do static labeling for device passthrough, the nodes in a
> device tree need a 32-bit numeric identifier.  IO memory uses the MFN,
> PCI devices use SBDF, and IRQs and x86 legacy IOs just use the number.

Why it's restricted to an integer? Would it be possible to use a string 
as it's done for the sid?

Regards,


-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-10 23:07           ` Julien Grall
@ 2015-03-10 23:39             ` Daniel De Graaf
  2015-03-11 12:30               ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Daniel De Graaf @ 2015-03-10 23:39 UTC (permalink / raw)
  To: Julien Grall, Ian Campbell
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich,
	Machon Gregory, xen-devel

On 03/10/2015 07:07 PM, Julien Grall wrote:
> Hi Daniel,
>
> On 10/03/2015 22:45, Daniel De Graaf wrote:
>>> BTW, do you have any pointer on how to write a policy for device/IRQ
>>> passthrough?
>>
>> There is a bit of documentation in xsm-flask.txt about device labeling,
>> which is the hard part of making passthrough work.  Labels can be set
>> either statically in the security policy (as documented in the section
>> "Device Labeling") or dynamically using a tool like flask-label-pci
>> as documented in "Resource Policy".  Once that is done, then rules to
>> allow the passthrough operation can be added, similar to the example
>> resource nic_dev_t in xen.te.
>
> I tried to follow xsm-flask.txt and uncomment one of the pirqcon line in the xsm policy.
>
> But I got the following error:
>
> policy/modules/xen/xen.te:199:ERROR 'syntax error' at token 'pirqcon' on line 1986:
> pirqcon 33 system_u:object_r:nic_dev_t
>
> Did I miss anything?

No, this is an error in either the policy or the parser in checkpolicy.
The parser in checkpolicy is rather inflexible, and it currently requires
that the device labels be specified at the end of the policy.conf instead
of in the middle (as they are now).  You should add the commented out
lines to the end of tools/flask/policy/policy/initial_sids for now; I will
be sending a patch to move them to another file tomorrow.

>> In order to do static labeling for device passthrough, the nodes in a
>> device tree need a 32-bit numeric identifier.  IO memory uses the MFN,
>> PCI devices use SBDF, and IRQs and x86 legacy IOs just use the number.
>
> Why it's restricted to an integer? Would it be possible to use a string as it's done for the sid?

The sid is not actually represented as a string internally: it is mapped
into a set of integers for the user/role/type and MLS range.

-- 
Daniel De Graaf
National Security Agency

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-10 22:45         ` Daniel De Graaf
  2015-03-10 23:07           ` Julien Grall
@ 2015-03-11  8:53           ` Jan Beulich
  2015-03-11 12:15             ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-03-11  8:53 UTC (permalink / raw)
  To: Daniel De Graaf
  Cc: Wei Liu, Ian Campbell, Machon Gregory, Julien Grall, Ian Jackson,
	tim, stefano.stabellini, xen-devel

>>> On 10.03.15 at 23:45, <dgdegra@tycho.nsa.gov> wrote:
> In order to do static labeling for device passthrough, the nodes in a
> device tree need a 32-bit numeric identifier.  IO memory uses the MFN,
> PCI devices use SBDF, and IRQs and x86 legacy IOs just use the number.

A 32-bit number can't uniquely identify an MMIO MFN.

Jan

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-11  8:53           ` Jan Beulich
@ 2015-03-11 12:15             ` Julien Grall
  2015-03-11 12:23               ` Ian Campbell
  2015-03-11 12:45               ` Jan Beulich
  0 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-11 12:15 UTC (permalink / raw)
  To: Jan Beulich, Daniel De Graaf
  Cc: Wei Liu, Ian Campbell, Machon Gregory, Ian Jackson, tim,
	stefano.stabellini, xen-devel

Hi Jan,

On 11/03/2015 08:53, Jan Beulich wrote:
>>>> On 10.03.15 at 23:45, <dgdegra@tycho.nsa.gov> wrote:
>> In order to do static labeling for device passthrough, the nodes in a
>> device tree need a 32-bit numeric identifier.  IO memory uses the MFN,
>> PCI devices use SBDF, and IRQs and x86 legacy IOs just use the number.
>
> A 32-bit number can't uniquely identify an MMIO MFN.

Isn't 32-bit enough to describe an MFN?

Although, MMIO are described with an MFN range.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-11 12:15             ` Julien Grall
@ 2015-03-11 12:23               ` Ian Campbell
  2015-03-11 12:35                 ` Julien Grall
  2015-03-11 12:45               ` Jan Beulich
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-03-11 12:23 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, Machon Gregory, Ian Jackson, tim, stefano.stabellini,
	Jan Beulich, xen-devel, Daniel De Graaf

On Wed, 2015-03-11 at 12:15 +0000, Julien Grall wrote:
> Hi Jan,
> 
> On 11/03/2015 08:53, Jan Beulich wrote:
> >>>> On 10.03.15 at 23:45, <dgdegra@tycho.nsa.gov> wrote:
> >> In order to do static labeling for device passthrough, the nodes in a
> >> device tree need a 32-bit numeric identifier.  IO memory uses the MFN,
> >> PCI devices use SBDF, and IRQs and x86 legacy IOs just use the number.
> >
> > A 32-bit number can't uniquely identify an MMIO MFN.
> 
> Isn't 32-bit enough to describe an MFN?

Up to 32+12== 44 bits, yes, but we know there are ARM systems with 48
bit PA out there.

> 
> Although, MMIO are described with an MFN range.
> 
> Regards,
> 

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-10 23:39             ` Daniel De Graaf
@ 2015-03-11 12:30               ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-11 12:30 UTC (permalink / raw)
  To: Daniel De Graaf, Ian Campbell
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich,
	Machon Gregory, xen-devel

Hi Daniel,

On 10/03/2015 23:39, Daniel De Graaf wrote:
> On 03/10/2015 07:07 PM, Julien Grall wrote:
>> Hi Daniel,
>>
>> On 10/03/2015 22:45, Daniel De Graaf wrote:
>>>> BTW, do you have any pointer on how to write a policy for device/IRQ
>>>> passthrough?
>>>
>>> There is a bit of documentation in xsm-flask.txt about device labeling,
>>> which is the hard part of making passthrough work.  Labels can be set
>>> either statically in the security policy (as documented in the section
>>> "Device Labeling") or dynamically using a tool like flask-label-pci
>>> as documented in "Resource Policy".  Once that is done, then rules to
>>> allow the passthrough operation can be added, similar to the example
>>> resource nic_dev_t in xen.te.
>>
>> I tried to follow xsm-flask.txt and uncomment one of the pirqcon line
>> in the xsm policy.
>>
>> But I got the following error:
>>
>> policy/modules/xen/xen.te:199:ERROR 'syntax error' at token 'pirqcon'
>> on line 1986:
>> pirqcon 33 system_u:object_r:nic_dev_t
>>
>> Did I miss anything?
>
> No, this is an error in either the policy or the parser in checkpolicy.
> The parser in checkpolicy is rather inflexible, and it currently requires
> that the device labels be specified at the end of the policy.conf instead
> of in the middle (as they are now).  You should add the commented out
> lines to the end of tools/flask/policy/policy/initial_sids for now; I will
> be sending a patch to move them to another file tomorrow.

It's working now. Thanks!

>>> In order to do static labeling for device passthrough, the nodes in a
>>> device tree need a 32-bit numeric identifier.  IO memory uses the MFN,
>>> PCI devices use SBDF, and IRQs and x86 legacy IOs just use the number.
>>
>> Why it's restricted to an integer? Would it be possible to use a
>> string as it's done for the sid?
>
> The sid is not actually represented as a string internally: it is mapped
> into a set of integers for the user/role/type and MLS range.

I gave a look to the checkpolicy code and the ocontext can store pretty 
much anything.

Currently for IOMEM, 2 32-bit number is stored to describe the range.

AFAIU, in order to support DT device, I will have to update checkpolicy 
for adding a new token (smth like dtdevicecon). So I don't see why I 
couldn't use a string for purpose.

Or maybe you had in mind to reuse pcidevicecon?

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-03-10 13:58         ` Julien Grall
@ 2015-03-11 12:34           ` Ian Campbell
  2015-03-19 14:53             ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-03-11 12:34 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, tim, stefano.stabellini

On Tue, 2015-03-10 at 13:58 +0000, Julien Grall wrote:
> On 23/02/15 16:27, Ian Campbell wrote:
> > On Mon, 2015-02-23 at 16:01 +0000, Julien Grall wrote:
> >> Hi Ian,
> >>
> >> On 23/02/15 15:30, Ian Campbell wrote:
> >>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >>>
> >>>> +/* This limit is used by the hypercalls to restrict the size of the path */
> >>>> +#define DEVICE_TREE_MAX_PATHLEN 1024
> >>>
> >>> Is this something you've made up or derived from the DT spec/ePAPR etc?
> >>
> >> I didn't find a such requirements on the spec.
> > 
> > I vaguely recall a limit on the length of a single node name, and a
> > limit on the depth which they may nest, which can be multiplied. It's
> > probably an unhelpfully large number though, so...
> > 
> >> I chose this number based on the linux pathlen because the path is also
> >> used in the sysfs (/sys/firmware/devicetree).
> > 
> > ...that's a good as anything I suppose!
> 
> Hmmm... I'm not so sure about the 1024 limit anymore. Linux is defining
> PATH_MAX to 4096 but I don't see many usage in the sysfs code.
> 
> And this value may change from one OS to another. Although, 1024 sounds
> a very long path to write in the configuration file...

I imagine in practice it will be cut-and-pasted, but yes.

>  Maybe we should
> support alias too?

Perhaps 2048 + (optionally, perhaps later) add alias support?

2048 because I assume 4096 being PAGE_SIZE would have some interesting
corner cases, especially for a target buffer on the stack. If not then
why not go straight for 4096?

Ian.

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-11 12:23               ` Ian Campbell
@ 2015-03-11 12:35                 ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-11 12:35 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Wei Liu, Machon Gregory, Ian Jackson, tim, stefano.stabellini,
	Jan Beulich, xen-devel, Daniel De Graaf

On 11/03/2015 12:23, Ian Campbell wrote:
> On Wed, 2015-03-11 at 12:15 +0000, Julien Grall wrote:
>> Hi Jan,
>>
>> On 11/03/2015 08:53, Jan Beulich wrote:
>>>>>> On 10.03.15 at 23:45, <dgdegra@tycho.nsa.gov> wrote:
>>>> In order to do static labeling for device passthrough, the nodes in a
>>>> device tree need a 32-bit numeric identifier.  IO memory uses the MFN,
>>>> PCI devices use SBDF, and IRQs and x86 legacy IOs just use the number.
>>>
>>> A 32-bit number can't uniquely identify an MMIO MFN.
>>
>> Isn't 32-bit enough to describe an MFN?
>
> Up to 32+12== 44 bits, yes, but we know there are ARM systems with 48
> bit PA out there.

Hmmm... checkpolicy and flask will have to be fixed then.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-03-10 15:29         ` Julien Grall
@ 2015-03-11 12:35           ` Ian Campbell
  2015-03-19 15:07             ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-03-11 12:35 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, stefano.stabellini, tim, Jan Beulich

On Tue, 2015-03-10 at 15:29 +0000, Julien Grall wrote:
> Hi,
> 
> On 23/02/15 15:34, Ian Campbell wrote:
> > On Mon, 2015-02-23 at 10:10 +0000, Julien Grall wrote:
> >>
> >> On 20/02/2015 17:04, Ian Campbell wrote:
> >>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
> >>>> Currently, when the device is deassigned from a domain, we directly reassign
> >>>> to DOM0.
> >>>>
> >>>> As the device may not have been correctly reset, this may lead to corruption or
> >>>> expose some part of DOM0 memory. Also, we may have no way to reset some
> >>>> platform devices.
> >>>>
> >>>> If Xen reassigns the device to "nobody", it may receive some global/context
> >>>> fault because the transaction has failed (indeed the context has been
> >>>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
> >>>> hardware. I think we could live with that for a first version of platform
> >>>> device passthrough.
> >>>>
> >>>> DOM0 will have to issue an hypercall to assign the device to itself if it
> >>>> wants to use it.
> >>>
> >>> Does this behaviour differ from x86?
> > 
> > I realise now that x86 is a red-herring, what I really meant was differ
> > from other types of device (specifically PCI ones).
> > 
> >>  If so then it is worth calling that
> >>> out explicitly (even if not, good to know I think!)
> >>
> >> What do you mean by "calling that out explicitly"?
> > 
> > Stating in the commit log or a suitably placed comment (at least under
> > xen/include/public hopefully) that deassignment of dt devices behaves
> > differently to deassignment of other types of devices.
> 
> I tried to search any documentation explaining the behavior of those
> DOMCTL for PCI (mostly the deassign one) but I didn't find any.
> 
> By any chance, do you know if there is one? If so where?

If you didn't find it in the obvious places under xen/include/public
then it probably doesn't exist.

Ian.

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-10 16:33     ` Julien Grall
@ 2015-03-11 12:37       ` Ian Campbell
  2015-03-11 13:50         ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-03-11 12:37 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, tim, Ian Jackson, stefano.stabellini, Jan Beulich,
	xen-devel, Daniel De Graaf

On Tue, 2015-03-10 at 16:33 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 20/02/15 17:17, Ian Campbell wrote:
> >> +    /* TODO: Do we need to check is_dying? Mostly to protect against
> >> +     * hypercall trying to passthrough a device while we are
> >> +     * dying.
> > 
> > FWIW the PCI case appears not to care...
> 
> There is one place in XEN_DOMCTL_assign_device...
> 
> Although I don't understand much the usage of is_dying.
> 
> >> +     */
> >> +
> >> +    switch ( domctl->cmd )
> >> +    {
> >> +    case XEN_DOMCTL_assign_device:
> >> +        ret = -ENOSYS;
> >> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
> >> +            break;
> > 
> > You added something similar to iommu_do_pci_domctl, would it not be
> > preferable for the caller to switch on domctl->u.assign_device.dev and
> > call the correct iommu_do_*_domctl?
> 
> I though about it. It would require to stub iommu_do_*_domctl. So I
> preferred to chose the current solution.

You mean iommu_do_{pci,dt}_domctl?

IIRC you already added suitable #defines for when these features are
present, so reusing them at the call sites wouldn't be too bad, or else
stubs aren't the worst thing either.

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-11 12:15             ` Julien Grall
  2015-03-11 12:23               ` Ian Campbell
@ 2015-03-11 12:45               ` Jan Beulich
  1 sibling, 0 replies; 251+ messages in thread
From: Jan Beulich @ 2015-03-11 12:45 UTC (permalink / raw)
  To: Julien Grall, Daniel De Graaf
  Cc: Wei Liu, Ian Campbell, Machon Gregory, Ian Jackson, tim,
	stefano.stabellini, xen-devel

>>> On 11.03.15 at 13:15, <julien.grall@linaro.org> wrote:
> Hi Jan,
> 
> On 11/03/2015 08:53, Jan Beulich wrote:
>>>>> On 10.03.15 at 23:45, <dgdegra@tycho.nsa.gov> wrote:
>>> In order to do static labeling for device passthrough, the nodes in a
>>> device tree need a 32-bit numeric identifier.  IO memory uses the MFN,
>>> PCI devices use SBDF, and IRQs and x86 legacy IOs just use the number.
>>
>> A 32-bit number can't uniquely identify an MMIO MFN.
> 
> Isn't 32-bit enough to describe an MFN?

No, that only covers up to 1Tb.

Jan

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-11 12:37       ` Ian Campbell
@ 2015-03-11 13:50         ` Julien Grall
  2015-03-11 13:55           ` Ian Campbell
  2015-03-13 16:47           ` Julien Grall
  0 siblings, 2 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-11 13:50 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Wei Liu, tim, Ian Jackson, stefano.stabellini, Jan Beulich,
	xen-devel, Daniel De Graaf

Hi Ian,

On 11/03/2015 12:37, Ian Campbell wrote:
> On Tue, 2015-03-10 at 16:33 +0000, Julien Grall wrote:
>> Hi Ian,
>>
>> On 20/02/15 17:17, Ian Campbell wrote:
>>>> +    /* TODO: Do we need to check is_dying? Mostly to protect against
>>>> +     * hypercall trying to passthrough a device while we are
>>>> +     * dying.
>>>
>>> FWIW the PCI case appears not to care...
>>
>> There is one place in XEN_DOMCTL_assign_device...
>>
>> Although I don't understand much the usage of is_dying.
>>
>>>> +     */
>>>> +
>>>> +    switch ( domctl->cmd )
>>>> +    {
>>>> +    case XEN_DOMCTL_assign_device:
>>>> +        ret = -ENOSYS;
>>>> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
>>>> +            break;
>>>
>>> You added something similar to iommu_do_pci_domctl, would it not be
>>> preferable for the caller to switch on domctl->u.assign_device.dev and
>>> call the correct iommu_do_*_domctl?
>>
>> I though about it. It would require to stub iommu_do_*_domctl. So I
>> preferred to chose the current solution.
>
> You mean iommu_do_{pci,dt}_domctl?
>
> IIRC you already added suitable #defines for when these features are
> present, so reusing them at the call sites wouldn't be too bad, or else
> stubs aren't the worst thing either.

Hmmm I think I got you point now. Do you mean have something like:

switch (domctl->u.assign_device.dev)
{
#ifdef HAS_PCI
case XEN_DOMCTL_DEV_PCI:
     ret = iommu_do_pci_domctl();
     break;
#endif
#ifdef HAS_DEVICE_TREE
case XEN_DOMCTL_DEV_DT:
     ret = iommu_do_dt_domctl()
     break;
#endif

default:
    ret = -ENOSYS;
}

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-11 13:50         ` Julien Grall
@ 2015-03-11 13:55           ` Ian Campbell
  2015-03-11 14:03             ` Jan Beulich
  2015-03-13 16:47           ` Julien Grall
  1 sibling, 1 reply; 251+ messages in thread
From: Ian Campbell @ 2015-03-11 13:55 UTC (permalink / raw)
  To: Julien Grall
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, Jan Beulich,
	xen-devel, Daniel De Graaf

On Wed, 2015-03-11 at 13:50 +0000, Julien Grall wrote:
> Hi Ian,
> 
> On 11/03/2015 12:37, Ian Campbell wrote:
> > On Tue, 2015-03-10 at 16:33 +0000, Julien Grall wrote:
> >> Hi Ian,
> >>
> >> On 20/02/15 17:17, Ian Campbell wrote:
> >>>> +    /* TODO: Do we need to check is_dying? Mostly to protect against
> >>>> +     * hypercall trying to passthrough a device while we are
> >>>> +     * dying.
> >>>
> >>> FWIW the PCI case appears not to care...
> >>
> >> There is one place in XEN_DOMCTL_assign_device...
> >>
> >> Although I don't understand much the usage of is_dying.
> >>
> >>>> +     */
> >>>> +
> >>>> +    switch ( domctl->cmd )
> >>>> +    {
> >>>> +    case XEN_DOMCTL_assign_device:
> >>>> +        ret = -ENOSYS;
> >>>> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
> >>>> +            break;
> >>>
> >>> You added something similar to iommu_do_pci_domctl, would it not be
> >>> preferable for the caller to switch on domctl->u.assign_device.dev and
> >>> call the correct iommu_do_*_domctl?
> >>
> >> I though about it. It would require to stub iommu_do_*_domctl. So I
> >> preferred to chose the current solution.
> >
> > You mean iommu_do_{pci,dt}_domctl?
> >
> > IIRC you already added suitable #defines for when these features are
> > present, so reusing them at the call sites wouldn't be too bad, or else
> > stubs aren't the worst thing either.
> 
> Hmmm I think I got you point now. Do you mean have something like:

That's one option I'd be happy with, yes. Jan might disagree.

> 
> switch (domctl->u.assign_device.dev)
> {
> #ifdef HAS_PCI
> case XEN_DOMCTL_DEV_PCI:
>      ret = iommu_do_pci_domctl();
>      break;
> #endif
> #ifdef HAS_DEVICE_TREE
> case XEN_DOMCTL_DEV_DT:
>      ret = iommu_do_dt_domctl()
>      break;
> #endif
> 
> default:
>     ret = -ENOSYS;
> }
> 
> Regards,
> 

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-11 13:55           ` Ian Campbell
@ 2015-03-11 14:03             ` Jan Beulich
  2015-03-11 14:11               ` Julien Grall
  0 siblings, 1 reply; 251+ messages in thread
From: Jan Beulich @ 2015-03-11 14:03 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, xen-devel,
	Daniel De Graaf

>>> On 11.03.15 at 14:55, <ian.campbell@citrix.com> wrote:
> On Wed, 2015-03-11 at 13:50 +0000, Julien Grall wrote:
>> Hi Ian,
>> 
>> On 11/03/2015 12:37, Ian Campbell wrote:
>> > On Tue, 2015-03-10 at 16:33 +0000, Julien Grall wrote:
>> >> Hi Ian,
>> >>
>> >> On 20/02/15 17:17, Ian Campbell wrote:
>> >>>> +    /* TODO: Do we need to check is_dying? Mostly to protect against
>> >>>> +     * hypercall trying to passthrough a device while we are
>> >>>> +     * dying.
>> >>>
>> >>> FWIW the PCI case appears not to care...
>> >>
>> >> There is one place in XEN_DOMCTL_assign_device...
>> >>
>> >> Although I don't understand much the usage of is_dying.
>> >>
>> >>>> +     */
>> >>>> +
>> >>>> +    switch ( domctl->cmd )
>> >>>> +    {
>> >>>> +    case XEN_DOMCTL_assign_device:
>> >>>> +        ret = -ENOSYS;
>> >>>> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
>> >>>> +            break;
>> >>>
>> >>> You added something similar to iommu_do_pci_domctl, would it not be
>> >>> preferable for the caller to switch on domctl->u.assign_device.dev and
>> >>> call the correct iommu_do_*_domctl?
>> >>
>> >> I though about it. It would require to stub iommu_do_*_domctl. So I
>> >> preferred to chose the current solution.
>> >
>> > You mean iommu_do_{pci,dt}_domctl?
>> >
>> > IIRC you already added suitable #defines for when these features are
>> > present, so reusing them at the call sites wouldn't be too bad, or else
>> > stubs aren't the worst thing either.
>> 
>> Hmmm I think I got you point now. Do you mean have something like:
> 
> That's one option I'd be happy with, yes. Jan might disagree.

Looks quite reasonable to except for ...

>> switch (domctl->u.assign_device.dev)
>> {
>> #ifdef HAS_PCI
>> case XEN_DOMCTL_DEV_PCI:
>>      ret = iommu_do_pci_domctl();
>>      break;
>> #endif
>> #ifdef HAS_DEVICE_TREE
>> case XEN_DOMCTL_DEV_DT:
>>      ret = iommu_do_dt_domctl()
>>      break;
>> #endif
>> 
>> default:
>>     ret = -ENOSYS;

... the -ENOSYS here: We commonly use e.g. -EOPNOTSUPP in
such situations.

Jan

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-11 14:03             ` Jan Beulich
@ 2015-03-11 14:11               ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-11 14:11 UTC (permalink / raw)
  To: Jan Beulich, Ian Campbell
  Cc: Wei Liu, Ian Jackson, tim, stefano.stabellini, xen-devel,
	Daniel De Graaf

Hi Jan,

On 11/03/2015 14:03, Jan Beulich wrote:
>>>> On 11.03.15 at 14:55, <ian.campbell@citrix.com> wrote:
>> On Wed, 2015-03-11 at 13:50 +0000, Julien Grall wrote:
>>> Hmmm I think I got you point now. Do you mean have something like:
>>
>> That's one option I'd be happy with, yes. Jan might disagree.
>
> Looks quite reasonable to except for ...
>
>>> switch (domctl->u.assign_device.dev)
>>> {
>>> #ifdef HAS_PCI
>>> case XEN_DOMCTL_DEV_PCI:
>>>       ret = iommu_do_pci_domctl();
>>>       break;
>>> #endif
>>> #ifdef HAS_DEVICE_TREE
>>> case XEN_DOMCTL_DEV_DT:
>>>       ret = iommu_do_dt_domctl()
>>>       break;
>>> #endif
>>>
>>> default:
>>>      ret = -ENOSYS;
>
> ... the -ENOSYS here: We commonly use e.g. -EOPNOTSUPP in
> such situations.

Ok I will use it.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device
  2015-03-11 13:50         ` Julien Grall
  2015-03-11 13:55           ` Ian Campbell
@ 2015-03-13 16:47           ` Julien Grall
  1 sibling, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-13 16:47 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Wei Liu, tim, Ian Jackson, stefano.stabellini, Jan Beulich,
	xen-devel, Daniel De Graaf

Hi,

On 11/03/2015 13:50, Julien Grall wrote:
> On 11/03/2015 12:37, Ian Campbell wrote:
>> On Tue, 2015-03-10 at 16:33 +0000, Julien Grall wrote:
>>> Hi Ian,
>>>
>>> On 20/02/15 17:17, Ian Campbell wrote:
>>>>> +    /* TODO: Do we need to check is_dying? Mostly to protect against
>>>>> +     * hypercall trying to passthrough a device while we are
>>>>> +     * dying.
>>>>
>>>> FWIW the PCI case appears not to care...
>>>
>>> There is one place in XEN_DOMCTL_assign_device...
>>>
>>> Although I don't understand much the usage of is_dying.
>>>
>>>>> +     */
>>>>> +
>>>>> +    switch ( domctl->cmd )
>>>>> +    {
>>>>> +    case XEN_DOMCTL_assign_device:
>>>>> +        ret = -ENOSYS;
>>>>> +        if ( domctl->u.assign_device.dev != XEN_DOMCTL_DEV_DT )
>>>>> +            break;
>>>>
>>>> You added something similar to iommu_do_pci_domctl, would it not be
>>>> preferable for the caller to switch on domctl->u.assign_device.dev and
>>>> call the correct iommu_do_*_domctl?
>>>
>>> I though about it. It would require to stub iommu_do_*_domctl. So I
>>> preferred to chose the current solution.
>>
>> You mean iommu_do_{pci,dt}_domctl?
>>
>> IIRC you already added suitable #defines for when these features are
>> present, so reusing them at the call sites wouldn't be too bad, or else
>> stubs aren't the worst thing either.
>
> Hmmm I think I got you point now. Do you mean have something like:
>
> switch (domctl->u.assign_device.dev)
> {
> #ifdef HAS_PCI
> case XEN_DOMCTL_DEV_PCI:
>      ret = iommu_do_pci_domctl();
>      break;
> #endif
> #ifdef HAS_DEVICE_TREE
> case XEN_DOMCTL_DEV_DT:
>      ret = iommu_do_dt_domctl()
>      break;
> #endif
>
> default:
>     ret = -ENOSYS;
> }

I though more about it and it won't be possible to do it unless we 
decode DOMCTL too.

This is because the DOMCTL_get_device_group use a different structure 
and is only for PCI.

So unless we decide to consolidate the 2 DOMCTL structures in a single 
one. I would prefer to keep the current solution with the suggestion 
made by Jan earlier.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM
  2015-02-23 17:22       ` Ian Campbell
@ 2015-03-17 13:32         ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-17 13:32 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, Ian Jackson, stefano.stabellini, Wei Liu

Hi Ian,

Sorry for the late answer.

On 23/02/15 17:22, Ian Campbell wrote:
> On Mon, 2015-02-23 at 17:06 +0000, Julien Grall wrote:
>> On 23/02/15 11:46, Ian Campbell wrote:
>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>> Let the user to pass additional nodes to the guest device tree. For this
>>>> purpose, everything in the node /passthrough from the partial device tree will
>>>> be copied into the guest device tree.
>>>>
>>>> The node /aliases will be also copied to allow the user to define aliases
>>>> which can be used by the guest kernel.
>>>>
>>>> A simple partial device tree will look like:
>>>>
>>>> /dts-v1/;
>>>>
>>>> / {
>>>>         #address-cells = <2>;
>>>>         #size-cells = <2>;
>>>
>>> Are these mandatory/required as implied below, or only the ones inside
>>> the passthrough node (which is what I would expect).
>>
>> It's to make DTC quiet.
> 
> Maybe add /* Keep DTC happy */ to both lines?
> 
>>
>>>>
>>>>         passthrough {
>>>>             compatible = "simple-bus";
>>>>             ranges;
>>>>             #address-cells = <2>;
>>>>             #size-cells = <2>;
>>>>
>>>>             /* List of your nodes */
>>>>         }
>>>> };
>>>>
>>>> Note that:
>>>>     * The interrupt-parent proporties will be added by the toolstack in
>>>
>>> "properties"
>>>
>>>>     the root node
>>>>     * The properties compatible, ranges, #address-cells and #size-cells
>>>>     in /passthrough are mandatory.
>>>
>>> Does ranges need to be the empty form? I think ranges = <stuff stuff>
>>> would be illegal?
>>
>> It's not illegal as long as you correctly use it in the inner "reg".
> 
> OK. This could be explained in some more complete documentaiton I think.
> (It's a doc day on Wednesday ;-))
> 
>>
>> Also, I admit that the "ranges" is confusing to read.
>>
>>>>
>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>>>
>>>> ---
>>>>     Changes in v3:
>>>>         - Patch added
>>>> ---
>>>>  docs/man/xl.cfg.pod.5       |   7 ++
>>>>  tools/libxl/libxl_arm.c     | 253 ++++++++++++++++++++++++++++++++++++++++++++
>>>>  tools/libxl/libxl_types.idl |   1 +
>>>>  tools/libxl/xl_cmdimpl.c    |   1 +
>>>>  4 files changed, 262 insertions(+)
>>>>
>>>> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
>>>> index e2f91fc..225b782 100644
>>>> --- a/docs/man/xl.cfg.pod.5
>>>> +++ b/docs/man/xl.cfg.pod.5
>>>> @@ -398,6 +398,13 @@ not emulated.
>>>>  Specify that this domain is a driver domain. This enables certain
>>>>  features needed in order to run a driver domain.
>>>>  
>>>> +=item B<device_tree=PATH>
>>>> +
>>>> +Specify a partial device tree (compiled via the Device Tree Compiler).
>>>> +Everything under the node "/passthrough" will be copied into the guest
>>>> +device tree. For convenience, the node "/aliases" is also copied to allow
>>>> +the user to defined aliases which can be used by the guest kernel.
>>>> +
>>>>  =back
>>>>  
>>>>  =head2 Devices
>>>> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
>>>> index 53177eb..619458b 100644
>>>> --- a/tools/libxl/libxl_arm.c
>>>> +++ b/tools/libxl/libxl_arm.c
>>>> @@ -540,6 +540,238 @@ out:
>>>>      }
>>>>  }
>>>>  
>>>> +static bool check_overrun(uint64_t a, uint64_t b, uint32_t max)
>>>> +{
>>>> +    return ((a + b) > UINT_MAX || (a + b) > max);
>>>
>>> Both halves here will fail if e.g. a == UINT64_MAX-1 and b == 2, so e..g
>>> a+b <= UINT_MAX and < max.
>>
>> Oops right.
>>
>>> To avoid this you should check that a and b are both less than some
>>> fraction of UINT64_MAX before the other checks, which would ensure the
>>> overflow can't happen, perhaps even UINT32_MAX would be acceptable for
>>> this use, depending on the input types involved.
>>
>> max is an uint32_t so a and b should be inferior to UINT32_MAX.
> 
> by "inferior to" do you mean less than? Or something to do with type
> promotion/demotion rules?

I meant less than.

>>
>> What about
>>
>> a < UINT_MAX && b < UINT_MAX && (a + b) < UINT_MAX
> 
> Isn't that inverted from the sense which the function name requires?
> 
> Given the complexity in reasoning about this I think a series of
> individual if and return statements which check each precondition one at
> a time and return failure if necessary wuold be clearer to read and
> reason about than trying to encode it all in one expression.

Given that we will mark the option unsafe. I'm thinking to drop this
check and some others. This would make the code less complex and avoid
to check on half of the FDT.

> 
>>>> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
>>>> index 1214d2e..5651110 100644
>>>> --- a/tools/libxl/libxl_types.idl
>>>> +++ b/tools/libxl/libxl_types.idl
>>>> @@ -399,6 +399,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
>>>>      ("kernel",           string),
>>>>      ("cmdline",          string),
>>>>      ("ramdisk",          string),
>>>> +    ("device_tree",      string),
>>>
>>> Needs a #define LIBXL_HAVE... in libxl.h
>>
>> Hmmm why? This will be set to empty when libxl_domain_build_info is
>> initialized.
> 
> So that applications which use libxl can take advantage of the new
> feature when built against versions of the library which support it,
> without breaking when built against versions which do not.

Hmmm right. I will add the LIBXL_HAVE_PARTIAL_DEVICE_TREE.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle
  2015-02-24 10:08               ` Ian Campbell
@ 2015-03-18 14:14                 ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-18 14:14 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Wei Liu, Stefano Stabellini, Ian Jackson, tim,
	stefano.stabellini, xen-devel

Hi Ian,

On 24/02/2015 10:08, Ian Campbell wrote:
> On Mon, 2015-02-23 at 22:02 +0000, Julien Grall wrote:
>>
>> On 23/02/2015 14:36, Ian Campbell wrote:
>>> On Thu, 2015-01-29 at 13:48 +0000, Julien Grall wrote:
>>>> On 29/01/15 12:28, Stefano Stabellini wrote:
>>>>> On Thu, 29 Jan 2015, Julien Grall wrote:
>>>>>> On 29/01/15 11:07, Stefano Stabellini wrote:
>>>>>>> On Tue, 13 Jan 2015, Julien Grall wrote:
>>>>>>>> The partial device tree may contains phandle. The Device Tree Compiler
>>>>>>>> tends to allocate the phandle from 1.
>>>>>>>>
>>>>>>>> Reserve the ID 65000 for the GIC phandle. I think we can safely assume
>>>>>>>> that the partial device tree will never contain a such ID.
>>>>>>>>
>>>>>>>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
>>>>>>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>>>>>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>>>>>>>
>>>>>>>
>>>>>>> Shouldn't we at least check that the partial device tree doesn't contain
>>>>>>> a conflicting phandle?
>>>>>>
>>>>>> I don't think so. This will unlikely happen, and if it happens the guest
>>>>>> will crash with an obvious error.
>>>>>
>>>>> It is good that the error is obvious.
>>>>>
>>>>> But how expensive is to check for it?
>>>>
>>>> I would have to check the validity of the properties (name + value
>>>> size). At least the properties "linux,phandle" and "phandle" should be
>>>> checked.
>>>>
>>>> Though I could do in copy_properties but I find it hackish.
>>>
>>> Can't you just track the largest phandle ever seen during
>>> copy_properties and then use N+1 for the GIC?
>>
>> Now the we decided to trust the input device tree, it would be easier to
>> write the code.
>>
>> I will give a look.
>>
>>>
>>>>> Think about the poor user that ends up in this situation: the fact that
>>>>> is unlikely only makes it harder for a user to figure out what to do to
>>>>> fix it.
>>>>
>>>> The poor use will have to write his device tree by hand to hit this
>>>> error ;).
>>>
>>> Or use a new version of dtc which does things differently for some
>>> reason.
>>
>> And you would not be able to get a phandle for the GIC if largest
>> phandle is too high.
>>
>> So the guest won't work correctly.
>
> Indeed, filling in a bitmap as you go might be another option, although
> you'd either need an 8k bitmap (not so bad in userspace) or to realloc
> as it grows.

I though about different implementation for tracking the phandle. All 
require to parse the partial device tree twice: one for tracking the 
phandle and the second for copy the nodes.

This is because we need to have the GIC phandle at the time we create 
the root node (properties has to be created before the child nodes).

So I plan to keep this patch as it is and documenting the value of the 
GIC. Would it be fine for you?

Though I could put an higher value too.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest
  2015-03-11 12:34           ` Ian Campbell
@ 2015-03-19 14:53             ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-19 14:53 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, tim, stefano.stabellini

On 11/03/15 12:34, Ian Campbell wrote:
> On Tue, 2015-03-10 at 13:58 +0000, Julien Grall wrote:
>> On 23/02/15 16:27, Ian Campbell wrote:
>>> On Mon, 2015-02-23 at 16:01 +0000, Julien Grall wrote:
>>>> Hi Ian,
>>>>
>>>> On 23/02/15 15:30, Ian Campbell wrote:
>>>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>>>
>>>>>> +/* This limit is used by the hypercalls to restrict the size of the path */
>>>>>> +#define DEVICE_TREE_MAX_PATHLEN 1024
>>>>>
>>>>> Is this something you've made up or derived from the DT spec/ePAPR etc?
>>>>
>>>> I didn't find a such requirements on the spec.
>>>
>>> I vaguely recall a limit on the length of a single node name, and a
>>> limit on the depth which they may nest, which can be multiplied. It's
>>> probably an unhelpfully large number though, so...
>>>
>>>> I chose this number based on the linux pathlen because the path is also
>>>> used in the sysfs (/sys/firmware/devicetree).
>>>
>>> ...that's a good as anything I suppose!
>>
>> Hmmm... I'm not so sure about the 1024 limit anymore. Linux is defining
>> PATH_MAX to 4096 but I don't see many usage in the sysfs code.
>>
>> And this value may change from one OS to another. Although, 1024 sounds
>> a very long path to write in the configuration file...
> 
> I imagine in practice it will be cut-and-pasted, but yes.
> 
>>  Maybe we should
>> support alias too?
> 
> Perhaps 2048 + (optionally, perhaps later) add alias support?
> 
> 2048 because I assume 4096 being PAGE_SIZE would have some interesting
> corner cases, especially for a target buffer on the stack. If not then
> why not go straight for 4096?

XSM seems to use 4096 to copy string for an hypercall buffer. I will use
the same here.

Regards,

-- 
Julien Grall

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

* Re: [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody
  2015-03-11 12:35           ` Ian Campbell
@ 2015-03-19 15:07             ` Julien Grall
  0 siblings, 0 replies; 251+ messages in thread
From: Julien Grall @ 2015-03-19 15:07 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, stefano.stabellini, tim, Jan Beulich

On 11/03/15 12:35, Ian Campbell wrote:
> On Tue, 2015-03-10 at 15:29 +0000, Julien Grall wrote:
>> Hi,
>>
>> On 23/02/15 15:34, Ian Campbell wrote:
>>> On Mon, 2015-02-23 at 10:10 +0000, Julien Grall wrote:
>>>>
>>>> On 20/02/2015 17:04, Ian Campbell wrote:
>>>>> On Tue, 2015-01-13 at 14:25 +0000, Julien Grall wrote:
>>>>>> Currently, when the device is deassigned from a domain, we directly reassign
>>>>>> to DOM0.
>>>>>>
>>>>>> As the device may not have been correctly reset, this may lead to corruption or
>>>>>> expose some part of DOM0 memory. Also, we may have no way to reset some
>>>>>> platform devices.
>>>>>>
>>>>>> If Xen reassigns the device to "nobody", it may receive some global/context
>>>>>> fault because the transaction has failed (indeed the context has been
>>>>>> marked invalid). Unfortunately there is no simple way to quiesce a buggy
>>>>>> hardware. I think we could live with that for a first version of platform
>>>>>> device passthrough.
>>>>>>
>>>>>> DOM0 will have to issue an hypercall to assign the device to itself if it
>>>>>> wants to use it.
>>>>>
>>>>> Does this behaviour differ from x86?
>>>
>>> I realise now that x86 is a red-herring, what I really meant was differ
>>> from other types of device (specifically PCI ones).
>>>
>>>>  If so then it is worth calling that
>>>>> out explicitly (even if not, good to know I think!)
>>>>
>>>> What do you mean by "calling that out explicitly"?
>>>
>>> Stating in the commit log or a suitably placed comment (at least under
>>> xen/include/public hopefully) that deassignment of dt devices behaves
>>> differently to deassignment of other types of devices.
>>
>> I tried to search any documentation explaining the behavior of those
>> DOMCTL for PCI (mostly the deassign one) but I didn't find any.
>>
>> By any chance, do you know if there is one? If so where?
> 
> If you didn't find it in the obvious places under xen/include/public
> then it probably doesn't exist.

Ok. I will add a comment in the patch extending XEN_DOMCTL_assign_device.

Regards,

-- 
Julien Grall

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

end of thread, other threads:[~2015-03-19 15:08 UTC | newest]

Thread overview: 251+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-13 14:25 [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
2015-01-13 14:25 ` [PATCH v3 01/24] xen: Extend DOMCTL createdomain to support arch configuration Julien Grall
2015-01-13 15:08   ` Daniel De Graaf
2015-01-19 16:46   ` Jan Beulich
2015-01-20 12:40     ` Julien Grall
2015-01-28 15:50   ` Stefano Stabellini
2015-02-20 15:15   ` Ian Campbell
2015-02-20 16:09     ` Julien Grall
2015-02-20 16:37       ` Jan Beulich
2015-02-23 15:09       ` Ian Campbell
2015-02-20 16:35     ` Jan Beulich
2015-02-23 15:48     ` Andrew Cooper
2015-02-23 16:00       ` Ian Campbell
2015-02-23 21:48         ` Julien Grall
2015-02-24 10:06           ` Ian Campbell
2015-01-13 14:25 ` [PATCH v3 02/24] xen/arm: Divide GIC initialization in 2 parts Julien Grall
2015-01-28 16:09   ` Stefano Stabellini
2015-02-20 15:19     ` Ian Campbell
2015-02-20 15:19   ` Ian Campbell
2015-01-13 14:25 ` [PATCH v3 03/24] xen/dts: Allow only IRQ translation that are mapped to main GIC Julien Grall
2015-01-28 16:11   ` Stefano Stabellini
2015-02-20 15:20   ` Ian Campbell
2015-01-13 14:25 ` [PATCH v3 04/24] xen: guestcopy: Provide an helper to safely copy string from guest Julien Grall
2015-01-13 15:10   ` Daniel De Graaf
2015-01-19 16:51   ` Jan Beulich
2015-01-20 12:45     ` Julien Grall
2015-01-20 13:16       ` Jan Beulich
2015-02-20 15:22   ` Ian Campbell
2015-01-13 14:25 ` [PATCH v3 05/24] xen/arm: vgic: Introduce a function to initialize pending_irq Julien Grall
2015-02-20 15:24   ` Ian Campbell
2015-01-13 14:25 ` [PATCH v3 06/24] xen/arm: Map disabled device in DOM0 Julien Grall
2015-01-28 16:18   ` Stefano Stabellini
2015-01-28 16:23     ` Julien Grall
2015-01-29 11:41       ` Stefano Stabellini
2015-02-20 15:27   ` Ian Campbell
2015-01-13 14:25 ` [PATCH v3 07/24] xen/arm: Introduce xen, passthrough property Julien Grall
2015-01-28 16:36   ` Stefano Stabellini
2015-01-28 16:53     ` Julien Grall
2015-01-29 11:43       ` Stefano Stabellini
2015-02-20 15:38   ` Ian Campbell
2015-02-20 17:01     ` Julien Grall
2015-02-23 15:12       ` Ian Campbell
2015-02-23 15:43         ` Julien Grall
2015-02-20 15:42   ` Ian Campbell
2015-02-20 17:03     ` Julien Grall
2015-02-23 15:15       ` Ian Campbell
2015-02-23 15:44         ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 08/24] xen/arm: Allow virq != irq Julien Grall
2015-01-28 16:47   ` Stefano Stabellini
2015-01-28 16:56     ` Julien Grall
2015-01-28 17:00       ` Julien Grall
2015-01-29 11:50       ` Stefano Stabellini
2015-02-20 15:52   ` Ian Campbell
2015-02-20 17:09     ` Julien Grall
2015-02-27 14:33       ` Julien Grall
2015-02-27 14:44         ` Ian Campbell
2015-02-27 15:55           ` Julien Grall
2015-02-27 14:25     ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 09/24] xen/arm: route_irq_to_guest: Check validity of the IRQ Julien Grall
2015-01-28 17:55   ` Stefano Stabellini
2015-01-28 18:05     ` Julien Grall
2015-01-29 11:52       ` Stefano Stabellini
2015-02-20 16:00   ` Ian Campbell
2015-02-20 17:21     ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest Julien Grall
2015-01-28 18:15   ` Stefano Stabellini
2015-02-20 16:07   ` Ian Campbell
2015-02-20 17:28     ` Julien Grall
2015-02-23 15:20       ` Ian Campbell
2015-02-23 15:47         ` Julien Grall
2015-02-23 15:52           ` Ian Campbell
2015-02-23 15:54             ` Julien Grall
2015-02-23 16:04               ` Ian Campbell
2015-01-13 14:25 ` [PATCH v3 11/24] xen/arm: Let the toolstack configure the number of SPIs Julien Grall
2015-01-28 18:26   ` Stefano Stabellini
2015-01-28 18:58     ` Julien Grall
2015-01-29 12:01       ` Stefano Stabellini
2015-01-29 12:14         ` Julien Grall
2015-02-20 16:08     ` Ian Campbell
2015-02-20 17:29       ` Julien Grall
2015-02-23 15:22         ` Ian Campbell
2015-02-23 15:48           ` Julien Grall
2015-02-20 16:23   ` Ian Campbell
2015-02-20 17:31     ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying Julien Grall
2015-01-28 18:38   ` Stefano Stabellini
2015-02-20 16:31   ` Ian Campbell
2015-02-20 17:41     ` Julien Grall
2015-02-23 15:25       ` Ian Campbell
2015-02-23 15:49         ` Julien Grall
2015-03-03 12:50       ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 13/24] xen/arm: Implement hypercall PHYSDEVOP_{, un}map_pirq Julien Grall
2015-01-19 16:54   ` Jan Beulich
2015-01-20 14:01     ` Julien Grall
2015-01-28 18:52   ` Stefano Stabellini
2015-01-28 19:04     ` Julien Grall
2015-01-29 12:17       ` Stefano Stabellini
2015-01-29 12:26         ` Julien Grall
2015-01-29 12:33           ` Stefano Stabellini
2015-02-20 16:53             ` Ian Campbell
2015-02-23  9:33               ` Jan Beulich
2015-02-23 15:28                 ` Ian Campbell
2015-02-23 15:53                   ` Julien Grall
2015-02-23 16:04                     ` Ian Campbell
2015-02-23 16:11                       ` Julien Grall
2015-02-23 16:34                         ` Ian Campbell
2015-02-23 21:54                           ` Julien Grall
2015-02-23 16:22                     ` Jan Beulich
2015-02-23 15:51               ` Julien Grall
2015-02-23 16:02                 ` Ian Campbell
2015-03-04 14:37                   ` Julien Grall
2015-03-04 14:55                     ` Jan Beulich
2015-03-04 14:56                       ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 14/24] xen/dts: Use unsigned int for MMIO and IRQ index Julien Grall
2015-02-20 16:55   ` Ian Campbell
2015-02-23 15:57     ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 15/24] xen/dts: Provide an helper to get a DT node from a path provided by a guest Julien Grall
2015-02-20 16:56   ` Ian Campbell
2015-02-20 17:43     ` Julien Grall
2015-02-23 15:29       ` Ian Campbell
2015-02-23 15:30   ` Ian Campbell
2015-02-23 16:01     ` Julien Grall
2015-02-23 16:27       ` Ian Campbell
2015-03-10 13:58         ` Julien Grall
2015-03-11 12:34           ` Ian Campbell
2015-03-19 14:53             ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 16/24] xen/passthrough: Introduce iommu_construct Julien Grall
2015-01-19 17:02   ` Jan Beulich
2015-01-20 14:28     ` Julien Grall
2015-01-20 16:40       ` Jan Beulich
2015-01-20 17:11         ` Julien Grall
2015-01-21 10:23           ` Jan Beulich
2015-01-21 10:37             ` Julien Grall
2015-01-21 10:48               ` Jan Beulich
2015-01-21 12:13                 ` Julien Grall
2015-01-21 14:13                   ` Jan Beulich
2015-01-21 14:22                     ` Julien Grall
2015-01-21 14:29                       ` Jan Beulich
2015-02-20 16:58   ` Ian Campbell
2015-02-20 17:45     ` Julien Grall
2015-02-23 15:31       ` Ian Campbell
2015-02-23 16:04         ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 17/24] xen/passthrough: arm: release earlier the DT devices assigned to a guest Julien Grall
2015-01-20  9:19   ` Jan Beulich
2015-01-20 14:30     ` Julien Grall
2015-01-20 16:42       ` Jan Beulich
2015-01-28 18:59   ` Stefano Stabellini
2015-02-20 17:03   ` Ian Campbell
2015-02-20 17:46     ` Julien Grall
2015-02-23  9:37       ` Jan Beulich
2015-02-23 15:33         ` Ian Campbell
2015-02-23 16:22           ` Jan Beulich
2015-01-13 14:25 ` [PATCH v3 18/24] xen/passthrough: iommu_deassign_device_dt: By default reassign device to nobody Julien Grall
2015-01-20  9:21   ` Jan Beulich
2015-01-20 14:31     ` Julien Grall
2015-01-29 10:20   ` Stefano Stabellini
2015-02-20 17:04   ` Ian Campbell
2015-02-23  9:40     ` Jan Beulich
2015-02-23 10:10       ` Julien Grall
2015-02-23 10:20         ` Jan Beulich
2015-02-23 15:39           ` Ian Campbell
2015-02-23 16:24             ` Jan Beulich
2015-02-23 16:35               ` Ian Campbell
2015-02-23 16:37             ` Julien Grall
2015-02-23 16:47               ` Jan Beulich
2015-02-23 16:54                 ` Julien Grall
2015-02-23 10:10     ` Julien Grall
2015-02-23 15:34       ` Ian Campbell
2015-03-10 15:29         ` Julien Grall
2015-03-11 12:35           ` Ian Campbell
2015-03-19 15:07             ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 19/24] xen/iommu: arm: Wire iommu DOMCTL for ARM Julien Grall
2015-01-20  9:22   ` Jan Beulich
2015-01-20 14:32     ` Julien Grall
2015-02-20 17:06   ` Ian Campbell
2015-01-13 14:25 ` [PATCH v3 20/24] xen/passthrough: Extend XEN_DOMCTL_assign_device to support DT device Julien Grall
2015-01-20  9:34   ` Jan Beulich
2015-01-20 14:37     ` Julien Grall
2015-01-20 16:43       ` Jan Beulich
2015-01-29 10:29     ` Stefano Stabellini
2015-01-29 10:37       ` Jan Beulich
2015-01-29 11:40       ` Julien Grall
2015-01-29 10:29   ` Stefano Stabellini
2015-01-29 11:45     ` Julien Grall
2015-01-29 12:09       ` Stefano Stabellini
2015-01-29 13:09         ` Julien Grall
2015-01-29 15:03           ` Stefano Stabellini
2015-01-29 15:14             ` Julien Grall
2015-02-20 17:17   ` Ian Campbell
2015-02-23 16:25     ` Daniel De Graaf
2015-03-10 16:52       ` Julien Grall
2015-03-10 22:45         ` Daniel De Graaf
2015-03-10 23:07           ` Julien Grall
2015-03-10 23:39             ` Daniel De Graaf
2015-03-11 12:30               ` Julien Grall
2015-03-11  8:53           ` Jan Beulich
2015-03-11 12:15             ` Julien Grall
2015-03-11 12:23               ` Ian Campbell
2015-03-11 12:35                 ` Julien Grall
2015-03-11 12:45               ` Jan Beulich
2015-03-10 16:33     ` Julien Grall
2015-03-11 12:37       ` Ian Campbell
2015-03-11 13:50         ` Julien Grall
2015-03-11 13:55           ` Ian Campbell
2015-03-11 14:03             ` Jan Beulich
2015-03-11 14:11               ` Julien Grall
2015-03-13 16:47           ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 21/24] tools/(lib)xl: Add partial device tree support for ARM Julien Grall
2015-01-29 11:03   ` Stefano Stabellini
2015-01-29 12:02     ` Julien Grall
2015-01-29 12:26       ` Stefano Stabellini
2015-02-23 11:31     ` Ian Campbell
2015-02-23 11:46   ` Ian Campbell
2015-02-23 17:06     ` Julien Grall
2015-02-23 17:22       ` Ian Campbell
2015-03-17 13:32         ` Julien Grall
2015-02-23 12:03   ` Ian Jackson
2015-02-23 12:44     ` Ian Jackson
2015-02-23 18:43     ` Julien Grall
2015-02-23 19:12       ` Ian Jackson
2015-01-13 14:25 ` [PATCH v3 22/24] tools/libxl: arm: Use an higher value for the GIC phandle Julien Grall
2015-01-29 11:07   ` Stefano Stabellini
2015-01-29 12:05     ` Julien Grall
2015-01-29 12:28       ` Stefano Stabellini
2015-01-29 13:48         ` Julien Grall
2015-01-29 15:04           ` Stefano Stabellini
2015-01-29 15:12             ` Julien Grall
2015-02-23 14:36           ` Ian Campbell
2015-02-23 22:02             ` Julien Grall
2015-02-24 10:08               ` Ian Campbell
2015-03-18 14:14                 ` Julien Grall
2015-01-13 14:25 ` [PATCH v3 23/24] libxl: Add support for non-PCI passthrough Julien Grall
2015-01-29 11:12   ` Stefano Stabellini
2015-01-29 12:08     ` Julien Grall
2015-01-29 12:31       ` Stefano Stabellini
2015-01-29 13:51         ` Julien Grall
2015-02-23 14:41           ` Ian Campbell
2015-02-23 14:42   ` Ian Campbell
2015-01-13 14:25 ` [PATCH v3 24/24] xl: Add new option dtdev Julien Grall
2015-01-29 11:18   ` Stefano Stabellini
2015-01-29 12:09     ` Julien Grall
2015-01-29 12:32       ` Stefano Stabellini
2015-01-29 13:51         ` Julien Grall
2015-01-29 15:06           ` Stefano Stabellini
2015-02-23 14:44             ` Ian Campbell
2015-02-23 14:45   ` Ian Campbell
2015-02-23 22:03     ` Julien Grall
2015-02-24 10:07       ` Ian Campbell
2015-01-13 17:56 ` [PATCH v3 00/24] xen/arm: Add support for non-pci passthrough Julien Grall
2015-02-20 17:18 ` Ian Campbell
2015-02-20 17:47   ` Julien Grall

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.