@@ -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 )
{
@@ -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 */
@@ -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)
@@ -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;
}