[Skiboot] [RFC PATCH 4/7] skiboot: Fetch the IMA dtb

Hemant Kumar hemant at linux.vnet.ibm.com
Tue Oct 25 23:45:45 AEDT 2016


The sub-partition that we obtain from the IMA_CATALOG partition is a
compressed device tree binary. We uncompress it using the libxz's
functions. After uncompressing it, we link the device tree binary to the
system's device tree. The kernel can now access the device tree and get
the IMA PMUs and their events' information.

Signed-off-by: Hemant Kumar <hemant at linux.vnet.ibm.com>
---
 hw/ima.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/hw/ima.c b/hw/ima.c
index 6f447a5..7dd8d8c 100644
--- a/hw/ima.c
+++ b/hw/ima.c
@@ -18,10 +18,71 @@
 #include <xscom.h>
 #include <ima.h>
 #include <chip.h>
+#include <libxz/xz.h>
+
+/*
+ * Decompresses the blob obtained from the IMA catalog sub-partition
+ * in "buf" of size "size", assigns the uncompressed device tree
+ * binary to "fdt" and returns.
+ * Returns 0 on success and -1 on error.
+ */
+static int decompress_subpartition(char *buf, size_t size, void **fdt)
+{
+	struct xz_dec *s;
+	struct xz_buf b;
+	void *data;
+	int ret = 0;
+
+	/* Initialize the xz library first */
+	xz_crc32_init();
+	s = xz_dec_init(XZ_SINGLE, 0);
+	if (s == NULL)
+	{
+		prerror("IMA: initialization error for xz\n");
+		return -1;
+	}
+
+	/* Allocate memory for the uncompressed data */
+	data = malloc(IMA_DTB_SIZE);
+	if (!data) {
+		prerror("IMA: memory allocation error\n");
+		ret = -1;
+		goto err;
+	}
+
+	/*
+	 * Source address : buf
+	 * Source size : size
+	 * Destination address : data
+	 * Destination size : IMA_DTB_SIZE
+	 */
+	b.in = buf;
+	b.in_pos = 0;
+	b.in_size = size;
+	b.out = data;
+	b.out_pos = 0;
+	b.out_size = IMA_DTB_SIZE;
+
+	/* Start decompressing */
+	ret = xz_dec_run(s, &b);
+	if (ret != XZ_STREAM_END) {
+		prerror("IMA: failed to decompress subpartition\n");
+		free(data);
+		ret = -1;
+	}
+	*fdt = data;
+
+err:
+	/* Clean up memory */
+	xz_dec_end(s);
+	return ret;
+}
 
 /*
  * Fetch the IMA Catalog partition and find the appropriate sub-partition
  * based on the platform's PVR.
+ * Decompress the sub-partition and link the ima device tree to the
+ * existing device tree.
  */
 void ima_init(void)
 {
@@ -30,6 +91,8 @@ void ima_init(void)
 	uint32_t pvr = mfspr(SPR_PVR);
 	int ret;
 	struct proc_chip *chip;
+	struct dt_node *dev;
+	void *fdt = NULL;
 
 	/* Disable this for power 8 */
 	chip = get_chip(this_cpu()->chip_id);
@@ -56,6 +119,23 @@ void ima_init(void)
 		goto err;
 	}
 
+	/* Decompress the subpartition now */
+	ret = decompress_subpartition(buf, size, &fdt);
+	if (ret < 0) {
+		goto err;
+	}
+
+	/* Create a device tree entry for ima counters */
+	dev = dt_new(dt_root, "ima-counters");
+	if (!dev) {
+		prerror("IMA: Unable to create device node\n");
+		goto err;
+	}
+
+	/* Attach the new fdt to the ima-counters node */
+	ret = dt_expand_node(dev, fdt, 0);
+	if (ret < 0)
+		prerror("IMA: device tree couldn't be linked\n");
 err:
 	free(buf);
 }
-- 
2.7.4



More information about the Skiboot mailing list