diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index 8a14015..d130633 100644
--- a/xen/arch/arm/bootfdt.c
+++ b/xen/arch/arm/bootfdt.c
@@ -14,6 +14,7 @@
 #include <xen/init.h>
 #include <xen/device_tree.h>
 #include <xen/libfdt/libfdt.h>
+#include <xsm/xsm.h>
 #include <asm/setup.h>
 
 static bool_t __init device_tree_node_matches(const void *fdt, int node,
@@ -175,6 +176,17 @@ static void __init process_multiboot_node(const void *fdt, int node,
     const char *cmdline;
     int len;
 
+    prop = fdt_get_property(fdt, node, "reg", &len);
+    if ( !prop )
+        panic("node %s missing `reg' property\n", name);
+
+    if ( len < dt_cells_to_size(address_cells + size_cells) )
+        panic("fdt: node `%s': `reg` property length is too short\n",
+                    name);
+
+    cell = (const __be32 *)prop->data;
+    device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
+
     if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 ||
          fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
         kind = BOOTMOD_KERNEL;
@@ -186,7 +198,17 @@ static void __init process_multiboot_node(const void *fdt, int node,
     else
         kind = BOOTMOD_UNKNOWN;
 
-    /* Guess that first two unknown are kernel and ramdisk respectively. */
+    /**
+     * Guess the kind of these first two unknowns respectively:
+     * (1) The first unknown must be kernel.
+     * (2) Detect the XSM Magic from the 2nd unknown:
+     *     a. If it's XSM, set the kind as XSM, and that also means we
+     *     won't load ramdisk;
+     *     b. if it's not XSM, set the kind as ramdisk.
+     *     So if user want to load ramdisk, it must be the 2nd unknown.
+     * We also detect the XSM Magic for the following unknowns,
+     * then set its kind according to the return value of has_xsm_magic.
+     */
     if ( kind == BOOTMOD_UNKNOWN )
     {
         switch ( kind_guess++ )
@@ -195,19 +217,10 @@ static void __init process_multiboot_node(const void *fdt, int node,
         case 1: kind = BOOTMOD_RAMDISK; break;
         default: break;
         }
+	if ( kind_guess > 1 && has_xsm_magic(start) )
+            kind = BOOTMOD_XSM;
     }
 
-    prop = fdt_get_property(fdt, node, "reg", &len);
-    if ( !prop )
-        panic("node %s missing `reg' property\n", name);
-
-    if ( len < dt_cells_to_size(address_cells + size_cells) )
-        panic("fdt: node `%s': `reg` property length is too short\n",
-                    name);
-
-    cell = (const __be32 *)prop->data;
-    device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
-
     prop = fdt_get_property(fdt, node, "bootargs", &len);
     if ( prop )
     {
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 3afed70..803c7ea 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -745,6 +745,7 @@ extern int xsm_multiboot_policy_init(unsigned long *module_map,
 #ifdef CONFIG_HAS_DEVICE_TREE
 extern int xsm_dt_init(void);
 extern int xsm_dt_policy_init(void);
+extern bool has_xsm_magic(paddr_t);
 #endif
 
 extern int register_xsm(struct xsm_operations *ops);
@@ -771,7 +772,12 @@ static inline int xsm_dt_init(void)
 {
     return 0;
 }
-#endif
+
+static inline bool has_xsm_magic(paddr_t start)
+{
+    return false;
+}
+#endif /* CONFIG_HAS_DEVICE_TREE */
 
 #endif /* CONFIG_XSM */
 
diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c
index 5e432de..bdb06c5 100644
--- a/xen/xsm/xsm_core.c
+++ b/xen/xsm/xsm_core.c
@@ -19,6 +19,8 @@
 
 #ifdef CONFIG_XSM
 
+#include <asm/setup.h>
+
 #define XSM_FRAMEWORK_VERSION    "1.0.0"
 
 struct xsm_operations *xsm_ops;
@@ -109,6 +111,25 @@ int __init xsm_dt_init(void)
 
     return ret;
 }
+
+/**
+ * has_xsm_magic - Check XSM Magic of the module header by phy address
+ * A XSM module has a special header
+ * ------------------------------------------------
+ * uint magic | uint target_len | uchar target[8] |
+ * 0xf97cff8c |        8        |    "XenFlask"   |
+ * ------------------------------------------------
+ * 0xf97cff8c is policy magic number (XSM_MAGIC).
+ * Here we only check the "magic" of the module.
+ */
+bool __init has_xsm_magic(paddr_t start)
+{
+    xsm_magic_t magic;
+
+    copy_from_paddr(&magic, start, sizeof(magic) );
+
+    return ( XSM_MAGIC && magic == XSM_MAGIC );
+}
 #endif
 
 int register_xsm(struct xsm_operations *ops)
diff --git a/xen/xsm/xsm_policy.c b/xen/xsm/xsm_policy.c
index b60d822..bde8015 100644
--- a/xen/xsm/xsm_policy.c
+++ b/xen/xsm/xsm_policy.c
@@ -79,7 +79,6 @@ int __init xsm_dt_policy_init(void)
 {
     struct bootmodule *mod = boot_module_find_by_kind(BOOTMOD_XSM);
     paddr_t paddr, len;
-    xsm_magic_t magic;
 
     if ( !mod || !mod->size )
         return 0;
@@ -87,12 +86,9 @@ int __init xsm_dt_policy_init(void)
     paddr = mod->start;
     len = mod->size;
 
-    copy_from_paddr(&magic, paddr, sizeof(magic));
-
-    if ( magic != XSM_MAGIC )
+    if ( !has_xsm_magic(paddr) )
     {
-        printk(XENLOG_ERR "xsm: Invalid magic for XSM blob got 0x%x "
-               "expected 0x%x\n", magic, XSM_MAGIC);
+        printk(XENLOG_ERR "xsm: Invalid magic for XSM blob\n");
         return -EINVAL;
     }
 
