diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1d466addb078..c85d18b1f2fd 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1094,6 +1094,7 @@ config KEXEC
 config KEXEC_FILE
 	bool "kexec file based system call"
 	select KEXEC_CORE
+	select HAVE_IMA_KEXEC
 	help
 	  This is new version of kexec system call. This system call is
 	  file based and takes file descriptors as system call argument
diff --git a/arch/arm64/include/asm/ima.h b/arch/arm64/include/asm/ima.h
new file mode 100644
index 000000000000..8b105157e55f
--- /dev/null
+++ b/arch/arm64/include/asm/ima.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 Microsoft Corporation
+ *
+ * Author: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
+ *
+ */
+#ifndef _ASM_ARCH_IMA_H
+#define _ASM_ARCH_IMA_H
+
+#include <linux/of.h>
+
+#ifdef CONFIG_IMA_KEXEC
+int setup_ima_buffer(const struct kimage *image, void *dtb, int off);
+#else
+static inline int setup_ima_buffer(const struct kimage *image, void *dtb,
+				   int off)
+{
+	remove_ima_buffer(dtb, off);
+	return 0;
+}
+#endif /* CONFIG_IMA_KEXEC */
+
+#endif /* _ASM_ARCH_IMA_H */
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index d24b527e8c00..2bd19ccb6c43 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -100,6 +100,11 @@ struct kimage_arch {
 	void *elf_headers;
 	unsigned long elf_headers_mem;
 	unsigned long elf_headers_sz;
+
+#ifdef CONFIG_IMA_KEXEC
+	phys_addr_t ima_buffer_addr;
+	size_t ima_buffer_size;
+#endif
 };
 
 extern const struct kexec_file_ops kexec_image_ops;
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index bbaf0bc4ad60..da83f1b3367e 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_ARM_SDE_INTERFACE)		+= sdei.o
 obj-$(CONFIG_ARM64_PTR_AUTH)		+= pointer_auth.o
 obj-$(CONFIG_SHADOW_CALL_STACK)		+= scs.o
 obj-$(CONFIG_ARM64_MTE)			+= mte.o
+obj-$(CONFIG_IMA_KEXEC)			+= ima.o
 
 obj-y					+= vdso/ probes/
 obj-$(CONFIG_COMPAT_VDSO)		+= vdso32/
diff --git a/arch/arm64/kernel/ima.c b/arch/arm64/kernel/ima.c
new file mode 100644
index 000000000000..fa7a1dbae183
--- /dev/null
+++ b/arch/arm64/kernel/ima.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 Microsoft Corporation
+ *
+ * Author: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
+ *
+ */
+
+#include <linux/kexec.h>
+#include <linux/of.h>
+#include <linux/libfdt.h>
+#include <asm/ima.h>
+
+/**
+ * setup_ima_buffer - add IMA buffer information to the fdt
+ *
+ * @image:	kexec image being loaded.
+ * @dtb:	Flattened device tree for the next kernel.
+ * @off:	Offset to the chosen node.
+ *
+ * Return: 0 on success, or negative errno on error.
+ */
+int setup_ima_buffer(const struct kimage *image, void *dtb, int off)
+{
+	int ret = 0;
+
+	remove_ima_buffer(dtb, off);
+
+	/* add ima-kexec-buffer */
+	if (image->arch.ima_buffer_size > 0) {
+		ret = fdt_appendprop_addrrange(dtb, 0, off,
+					       "linux,ima-kexec-buffer",
+					       image->arch.ima_buffer_addr,
+					       image->arch.ima_buffer_size);
+		if (ret) {
+			ret = (ret == -FDT_ERR_NOSPACE ? -ENOMEM : -EINVAL);
+			goto out;
+		}
+
+		ret = fdt_add_mem_rsv(dtb, image->arch.ima_buffer_addr,
+				      image->arch.ima_buffer_size);
+	}
+
+out:
+	if (ret)
+		pr_err("Error setting up ima buffer in device tree.\n");
+
+	return ret;
+}
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 3e045cd62451..37a528aca780 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -21,6 +21,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
+#include <asm/ima.h>
 
 const struct kexec_file_ops * const kexec_file_loaders[] = {
 	&kexec_image_ops,
@@ -83,6 +84,13 @@ static int create_dtb(struct kimage *image,
 			}
 		}
 
+		ret = setup_ima_buffer(image, buf,
+				       fdt_path_offset(buf, "/chosen"));
+		if (ret) {
+			vfree(buf);
+			return ret;
+		}
+
 		/* trim it */
 		fdt_pack(buf);
 		*dtb = buf;
