diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 229e289..90eaa20 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -306,6 +306,11 @@
 #define LIBXL_HAVE_BUILDINFO_HVM_ACPI_LAPTOP_SLATE 1
 
 /*
+ * LIBXL_HAVE_VUART indicates that the toolstack supports virtual UART.
+ */
+#define LIBXL_HAVE_VUART 1
+
+/*
  * libxl ABI compatibility
  *
  * The only guarantee which libxl makes regarding ABI compatibility
diff --git a/tools/libxl/libxl_console.c b/tools/libxl/libxl_console.c
index 446e766..853be15 100644
--- a/tools/libxl/libxl_console.c
+++ b/tools/libxl/libxl_console.c
@@ -67,6 +67,9 @@ int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num,
     case LIBXL_CONSOLE_TYPE_SERIAL:
         cons_type_s = "serial";
         break;
+    case LIBXL_CONSOLE_TYPE_VUART:
+        cons_type_s = "vuart";
+        break;
     default:
         goto out;
     }
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index f54fd49..e0f0d78 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -803,6 +803,7 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
     if (xc_dom_translated(dom)) {
         state->console_mfn = dom->console_pfn;
         state->store_mfn = dom->xenstore_pfn;
+        state->vuart_gfn = dom->vuart_gfn;
     } else {
         state->console_mfn = xc_dom_p2m(dom, dom->console_pfn);
         state->store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 7247509..6b38453 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1139,6 +1139,9 @@ typedef struct {
     uint32_t num_vmemranges;
 
     xc_domain_configuration_t config;
+
+    xen_pfn_t vuart_gfn;
+    evtchn_port_t vuart_port;
 } libxl__domain_build_state;
 
 _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid,
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 6e80d36..9959efb 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -105,6 +105,7 @@ libxl_console_type = Enumeration("console_type", [
     (0, "UNKNOWN"),
     (1, "SERIAL"),
     (2, "PV"),
+    (3, "VUART"),
     ])
 
 libxl_disk_format = Enumeration("disk_format", [
@@ -240,6 +241,11 @@ libxl_checkpointed_stream = Enumeration("checkpointed_stream", [
     (2, "COLO"),
     ])
 
+libxl_vuart_type = Enumeration("vuart_type", [
+    (0, "unknown"),
+    (1, "sbsa_uart"),
+    ])
+
 #
 # Complex libxl types
 #
@@ -581,6 +587,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
 
 
     ("arch_arm", Struct(None, [("gic_version", libxl_gic_version),
+                               ("vuart", libxl_vuart_type),
                               ])),
     # Alternate p2m is not bound to any architecture or guest type, as it is
     # supported by x86 HVM and ARM support is planned.
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 2c71a9f..3094bce 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -133,7 +133,7 @@ struct cmd_spec cmd_table[] = {
       &main_console, 0, 0,
       "Attach to domain's console",
       "[options] <Domain>\n"
-      "-t <type>       console type, pv or serial\n"
+      "-t <type>       console type, pv , serial or vuart\n"
       "-n <number>     console number"
     },
     { "vncviewer",
diff --git a/tools/xl/xl_console.c b/tools/xl/xl_console.c
index 0508dda..4e65d73 100644
--- a/tools/xl/xl_console.c
+++ b/tools/xl/xl_console.c
@@ -27,6 +27,7 @@ int main_console(int argc, char **argv)
     uint32_t domid;
     int opt = 0, num = 0;
     libxl_console_type type = 0;
+    char *console_names = "pv, serial, vuart";
 
     SWITCH_FOREACH_OPT(opt, "n:t:", NULL, "console", 1) {
     case 't':
@@ -34,8 +35,10 @@ int main_console(int argc, char **argv)
             type = LIBXL_CONSOLE_TYPE_PV;
         else if (!strcmp(optarg, "serial"))
             type = LIBXL_CONSOLE_TYPE_SERIAL;
+        else if (!strcmp(optarg, "vuart"))
+            type = LIBXL_CONSOLE_TYPE_VUART;
         else {
-            fprintf(stderr, "console type supported are: pv, serial\n");
+            fprintf(stderr, "console type supported are: %s\n", console_names);
             return EXIT_FAILURE;
         }
         break;
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 5c2bf17..71588de 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -918,6 +918,14 @@ void parse_config_data(const char *config_source,
     if (!xlu_cfg_get_long (config, "maxvcpus", &l, 0))
         b_info->max_vcpus = l;
 
+    if (!xlu_cfg_get_string(config, "vuart", &buf, 0)) {
+        if (libxl_vuart_type_from_string(buf, &b_info->arch_arm.vuart)) {
+            fprintf(stderr, "ERROR: invalid value \"%s\" for \"vuart\"\n",
+                    buf);
+            exit(1);
+        }
+    }
+
     parse_vnuma_config(config, b_info);
 
     /* Set max_memkb to target_memkb and max_vcpus to avail_vcpus if
