Iterate through the unclaimed boot modules to see if any are an XSM FLASK
policy. If one is located, mark it as an xsm policy.
To assist with looking up the index of the xsm policy in the boot module array,
an iterator is provided.
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
---
Changes since v6:
- converted boot module walk over to for each helper
- slight reword of commit message
- merged the interator patch with its first usage by XSM
- corrected the short-circuit return value for Xen in the interator
- dropped R-b due to merging with patch not approved.
Changes since v5:
- replaced bootstrap_map with bootstrap_map_bm
- make init function definitions consistent in dropping const on *bi
---
xen/arch/x86/include/asm/bootinfo.h | 30 ++++++++++++++++++++++++++++-
xen/arch/x86/setup.c | 2 +-
xen/include/xsm/xsm.h | 11 +++++++----
xen/xsm/xsm_core.c | 17 ++++++++++++----
xen/xsm/xsm_policy.c | 20 +++++++++----------
5 files changed, 59 insertions(+), 21 deletions(-)
diff --git a/xen/arch/x86/include/asm/bootinfo.h b/xen/arch/x86/include/asm/bootinfo.h
index e470df48700d..3ca56454c4d7 100644
--- a/xen/arch/x86/include/asm/bootinfo.h
+++ b/xen/arch/x86/include/asm/bootinfo.h
@@ -21,6 +21,7 @@ enum bootmod_type {
BOOTMOD_KERNEL,
BOOTMOD_RAMDISK,
BOOTMOD_MICROCODE,
+ BOOTMOD_XSM_POLICY,
};
struct boot_module {
@@ -94,8 +95,35 @@ static inline struct boot_module *__init next_boot_module_by_type(
#define boot_module_index(bi, bm) \
(unsigned int)(bm - &bi->mods[0])
-#endif /* X86_BOOTINFO_H */
+/*
+ * next_boot_module_index:
+ * Finds the next boot module of type t, starting at array index start.
+ *
+ * Returns:
+ * Success - index in boot_module array
+ * Failure - a value greater than MAX_NR_BOOTMODS
+ */
+static inline unsigned int __init next_boot_module_index(
+ const struct boot_info *bi, enum bootmod_type t, unsigned int start)
+{
+ unsigned int i;
+
+ if ( t == BOOTMOD_XEN )
+ return bi->nr_modules;
+
+ for ( i = start; i < bi->nr_modules; i++ )
+ {
+ if ( bi->mods[i].type == t )
+ return i;
+ }
+
+ return MAX_NR_BOOTMODS + 1;
+}
+
+#define first_boot_module_index(bi, t) \
+ next_boot_module_index(bi, t, 0)
+#endif /* X86_BOOTINFO_H */
/*
* Local variables:
* mode: C
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 272d5a725c54..ed1d89ad4bb4 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1882,7 +1882,7 @@ void asmlinkage __init noreturn __start_xen(unsigned long mbi_p)
mmio_ro_ranges = rangeset_new(NULL, "r/o mmio ranges",
RANGESETF_prettyprint_hex);
- xsm_multiboot_init(module_map, mbi);
+ xsm_multiboot_init(module_map, bi);
/*
* IOMMU-related ACPI table parsing may require some of the system domains
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 627c0d2731af..f155d10e718c 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -17,7 +17,10 @@
#include <xen/alternative-call.h>
#include <xen/sched.h>
-#include <xen/multiboot.h>
+
+#ifdef CONFIG_MULTIBOOT
+#include <asm/bootinfo.h>
+#endif
/* policy magic number (defined by XSM_MAGIC) */
typedef uint32_t xsm_magic_t;
@@ -779,9 +782,9 @@ static inline int xsm_argo_send(const struct domain *d, const struct domain *t)
#ifdef CONFIG_MULTIBOOT
int xsm_multiboot_init(
- unsigned long *module_map, const multiboot_info_t *mbi);
+ unsigned long *module_map, struct boot_info *bi);
int xsm_multiboot_policy_init(
- unsigned long *module_map, const multiboot_info_t *mbi,
+ unsigned long *module_map, struct boot_info *bi,
void **policy_buffer, size_t *policy_size);
#endif
@@ -829,7 +832,7 @@ static const inline struct xsm_ops *silo_init(void)
#ifdef CONFIG_MULTIBOOT
static inline int xsm_multiboot_init (
- unsigned long *module_map, const multiboot_info_t *mbi)
+ unsigned long *module_map, struct boot_info *bi)
{
return 0;
}
diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c
index eaa028109bde..234b39de7a1d 100644
--- a/xen/xsm/xsm_core.c
+++ b/xen/xsm/xsm_core.c
@@ -21,6 +21,7 @@
#ifdef CONFIG_XSM
#ifdef CONFIG_MULTIBOOT
+#include <asm/bootinfo.h>
#include <asm/setup.h>
#endif
@@ -140,7 +141,7 @@ static int __init xsm_core_init(const void *policy_buffer, size_t policy_size)
#ifdef CONFIG_MULTIBOOT
int __init xsm_multiboot_init(
- unsigned long *module_map, const multiboot_info_t *mbi)
+ unsigned long *module_map, struct boot_info *bi)
{
int ret = 0;
void *policy_buffer = NULL;
@@ -150,18 +151,26 @@ int __init xsm_multiboot_init(
if ( XSM_MAGIC )
{
- ret = xsm_multiboot_policy_init(module_map, mbi, &policy_buffer,
+ ret = xsm_multiboot_policy_init(module_map, bi, &policy_buffer,
&policy_size);
if ( ret )
{
- bootstrap_map(NULL);
+ bootstrap_map_bm(NULL);
printk(XENLOG_ERR "Error %d initializing XSM policy\n", ret);
return -EINVAL;
}
}
ret = xsm_core_init(policy_buffer, policy_size);
- bootstrap_map(NULL);
+ if ( ret == 0 )
+ {
+ int idx = first_boot_module_index(bi, BOOTMOD_XSM_POLICY);
+
+ /* If the policy was loaded from a boot module, mark it consumed */
+ if ( idx >= 0 )
+ bi->mods[idx].consumed = true;
+ }
+ bootstrap_map_bm(NULL);
return 0;
}
diff --git a/xen/xsm/xsm_policy.c b/xen/xsm/xsm_policy.c
index 8dafbc93810f..9fb8563eb571 100644
--- a/xen/xsm/xsm_policy.c
+++ b/xen/xsm/xsm_policy.c
@@ -21,6 +21,7 @@
#include <xsm/xsm.h>
#ifdef CONFIG_MULTIBOOT
#include <xen/multiboot.h>
+#include <asm/bootinfo.h>
#include <asm/setup.h>
#endif
#include <xen/bitops.h>
@@ -31,26 +32,22 @@
#ifdef CONFIG_MULTIBOOT
int __init xsm_multiboot_policy_init(
- unsigned long *module_map, const multiboot_info_t *mbi,
+ unsigned long *module_map, struct boot_info *bi,
void **policy_buffer, size_t *policy_size)
{
- int i;
- module_t *mod = (module_t *)__va(mbi->mods_addr);
int rc = 0;
u32 *_policy_start;
unsigned long _policy_len;
+ struct boot_module *bm;
/*
* Try all modules and see whichever could be the binary policy.
* Adjust module_map for the module that is the binary policy.
*/
- for ( i = mbi->mods_count-1; i >= 1; i-- )
+ for_each_boot_module(bi, bm, BOOTMOD_UNKNOWN)
{
- if ( !test_bit(i, module_map) )
- continue;
-
- _policy_start = bootstrap_map(mod + i);
- _policy_len = mod[i].mod_end;
+ _policy_start = bootstrap_map_bm(bm);
+ _policy_len = bm->size;
if ( (xsm_magic_t)(*_policy_start) == XSM_MAGIC )
{
@@ -60,12 +57,13 @@ int __init xsm_multiboot_policy_init(
printk("Policy len %#lx, start at %p.\n",
_policy_len,_policy_start);
- __clear_bit(i, module_map);
+ __clear_bit(boot_module_index(bi, bm), module_map);
+ bm->type = BOOTMOD_XSM_POLICY;
break;
}
- bootstrap_map(NULL);
+ bootstrap_map_bm(NULL);
}
return rc;
--
2.30.2