diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index f7b9278..f204d71 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1513,6 +1513,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     early_msi_init();
 
     iommu_setup();    /* setup iommu if available */
+    viommu_setup();
 
     smp_prepare_cpus(max_cpus);
 
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index dc8e876..8ba4f5a 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -73,6 +73,18 @@ config TMEM
 
 	  If unsure, say Y.
 
+config VIOMMU
+	def_bool y
+	depends on X86
+	---help---
+	  Virtual IOMMU provides interrupt remapping function for guest and
+	  it allows guest to boot up more than 255 vcpus which requires interrupt
+	  remapping function.
+
+	  You also have to enable it on the Xen commandline by using viommu=1
+
+	  If unsure, say Y.
+
 config XENOPROF
 	def_bool y
 	prompt "Xen Oprofile Support" if EXPERT = "y"
diff --git a/xen/common/Makefile b/xen/common/Makefile
index 26c5a64..852553d 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -56,6 +56,7 @@ obj-y += time.o
 obj-y += timer.o
 obj-y += trace.o
 obj-y += version.o
+obj-$(CONFIG_VIOMMU) += viommu.o
 obj-y += virtual_region.o
 obj-y += vm_event.o
 obj-y += vmap.o
diff --git a/xen/common/domain.c b/xen/common/domain.c
index b22aacc..d1f9b10 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -396,6 +396,9 @@ struct domain *domain_create(domid_t domid, unsigned int domcr_flags,
         spin_unlock(&domlist_update_lock);
     }
 
+    if ( (err = viommu_init_domain(d)) != 0 )
+        goto fail;
+
     return d;
 
  fail:
diff --git a/xen/common/viommu.c b/xen/common/viommu.c
new file mode 100644
index 0000000..19ba529
--- /dev/null
+++ b/xen/common/viommu.c
@@ -0,0 +1,163 @@
+/*
+ * common/viommu.c
+ * 
+ * Copyright (c) 2017 Intel Corporation
+ * Author: Lan Tianyu <tianyu.lan@intel.com> 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/types.h>
+#include <xen/sched.h>
+#include <xen/spinlock.h>
+
+bool_t __read_mostly opt_viommu = 0;
+boolean_param("viommu", opt_viommu);
+
+spinlock_t type_list_lock;
+static struct list_head type_list;
+
+struct viommu_type {
+    u64 type;
+    struct viommu_ops *ops;
+    struct list_head node;
+};
+
+int viommu_init_domain(struct domain *d)
+{
+    d->viommu.nr_viommu = 0;
+    return 0;
+}
+
+static struct viommu_type *viommu_get_type(u64 type)
+{
+    struct viommu_type *viommu_type = NULL;
+
+    spin_lock(&type_list_lock);
+    list_for_each_entry( viommu_type, &type_list, node )
+    {
+        if ( viommu_type->type == type )
+        {
+            spin_unlock(&type_list_lock);
+            return viommu_type;
+        }
+    }
+    spin_unlock(&type_list_lock);
+
+    return NULL;
+}
+
+int viommu_register_type(u64 type, struct viommu_ops * ops)
+{
+    struct viommu_type *viommu_type = NULL;
+
+    if ( !viommu_enabled() )
+        return -EINVAL;
+
+    if ( viommu_get_type(type) )
+        return -EEXIST;
+
+    viommu_type = xzalloc(struct viommu_type);
+    if ( !viommu_type )
+        return -ENOMEM;
+
+    viommu_type->type = type;
+    viommu_type->ops = ops;
+
+    spin_lock(&type_list_lock);
+    list_add_tail(&viommu_type->node, &type_list);
+    spin_unlock(&type_list_lock);
+
+    return 0;
+}
+
+static int viommu_create(struct domain *d, u64 type, u64 base_address,
+                  u64 length, u64 caps)
+{
+    struct viommu_info *info = &d->viommu;
+    struct viommu *viommu;
+    struct viommu_type *viommu_type = NULL;
+    int rc;
+
+    viommu_type = viommu_get_type(type);
+    if ( !viommu_type )
+        return -EINVAL;
+
+    if ( info->nr_viommu >= NR_VIOMMU_PER_DOMAIN
+        || !viommu_type->ops || !viommu_type->ops->create )
+        return -EINVAL;
+
+    viommu = xzalloc(struct viommu);
+    if ( !viommu )
+        return -ENOMEM;
+
+    viommu->base_address = base_address;
+    viommu->length = length;
+    viommu->caps = caps;
+    viommu->ops = viommu_type->ops;
+    viommu->viommu_id = info->nr_viommu;
+
+    info->viommu[info->nr_viommu] = viommu;
+    info->nr_viommu++;
+
+    rc = viommu->ops->create(d, viommu);
+    if ( rc < 0 )
+    {
+        xfree(viommu);
+		info->nr_viommu--;
+		info->viommu[info->nr_viommu] = NULL;
+        return rc;
+    }
+
+    return viommu->viommu_id;
+}
+
+static int viommu_destroy(struct domain *d, u32 viommu_id)
+{
+    struct viommu_info *info = &d->viommu;
+
+    if ( viommu_id > info->nr_viommu || !info->viommu[viommu_id] )
+        return -EINVAL;
+
+    if ( info->viommu[viommu_id]->ops->destroy(info->viommu[viommu_id]) )
+        return -EFAULT;
+
+    info->viommu[viommu_id] = NULL;
+    return 0;
+}
+
+static u64 viommu_query_caps(struct domain *d, u64 type)
+{
+    struct viommu_type *viommu_type = viommu_get_type(type);
+
+    if ( !viommu_type )
+        return -EINVAL;
+
+    return viommu_type->ops->query_caps(d);
+}
+
+int __init viommu_setup(void)
+{
+    INIT_LIST_HEAD(&type_list);
+    spin_lock_init(&type_list_lock);
+    return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/xen/include/public/viommu.h b/xen/include/public/viommu.h
new file mode 100644
index 0000000..d25e3ad
--- /dev/null
+++ b/xen/include/public/viommu.h
@@ -0,0 +1,49 @@
+/*
+ * viommu.h
+ *
+ * Virtual IOMMU information
+ *
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __XEN_PUBLIC_VIOMMU_H__
+#define __XEN_PUBLIC_VIOMMU_H__
+
+/* VIOMMU type */
+#define VIOMMU_TYPE_INTEL_VTD     (1u << 0)
+
+/* VIOMMU capabilities*/
+#define VIOMMU_CAP_IRQ_REMAPPING  (1u << 0)
+
+#endif /* __XEN_PUBLIC_VIOMMU_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 1127ca9..af52ae8 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -21,6 +21,7 @@
 #include <xen/perfc.h>
 #include <asm/atomic.h>
 #include <xen/wait.h>
+#include <xen/viommu.h>
 #include <public/xen.h>
 #include <public/domctl.h>
 #include <public/sysctl.h>
@@ -477,6 +478,7 @@ struct domain
     /* vNUMA topology accesses are protected by rwlock. */
     rwlock_t vnuma_rwlock;
     struct vnuma_info *vnuma;
+    struct viommu_info viommu;
 
     /* Common monitor options */
     struct {
diff --git a/xen/include/xen/viommu.h b/xen/include/xen/viommu.h
new file mode 100644
index 0000000..0a93aa4
--- /dev/null
+++ b/xen/include/xen/viommu.h
@@ -0,0 +1,71 @@
+/*
+ * include/xen/viommu.h
+ *
+ * Copyright (c) 2017, Intel Corporation
+ * Author: Lan Tianyu <tianyu.lan@intel.com> 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#ifndef __XEN_VIOMMU_H__
+#define __XEN_VIOMMU_H__
+
+#define NR_VIOMMU_PER_DOMAIN 1
+
+struct viommu;
+
+struct viommu_ops {
+    u64 (*query_caps)(struct domain *d);
+    int (*create)(struct domain *d, struct viommu *viommu);
+    int (*destroy)(struct viommu *viommu);
+};
+
+struct viommu {
+    u64 base_address;
+    u64 length;
+    u64 caps;
+    u32 viommu_id;
+    const struct viommu_ops *ops;
+    void *priv;
+};
+
+struct viommu_info {
+    u32 nr_viommu;
+    struct viommu *viommu[NR_VIOMMU_PER_DOMAIN]; /* viommu array*/
+};
+
+#ifdef CONFIG_VIOMMU
+extern bool_t opt_viommu;
+static inline bool_t viommu_enabled(void) { return opt_viommu; }
+int viommu_init_domain(struct domain *d);
+int viommu_register_type(u64 type, struct viommu_ops * ops);
+int viommu_setup(void);
+#else
+static inline int viommu_init_domain(struct domain *d) { return 0; }
+static inline int viommu_register_type(u64 type, struct viommu_ops * ops)
+{ return 0; }
+static inline int __init viommu_setup(void) { return 0; }
+static inline bool_t viommu_enabled(void) { return 0; }
+#endif
+
+#endif /* __XEN_VIOMMU_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
