diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 7743e8a..5dd5005 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -7,6 +7,7 @@
  * Dave Safford <safford@watson.ibm.com>
  * Reiner Sailer <sailer@watson.ibm.com>
  * Kylene Hall <kjhall@us.ibm.com>
+ * Nayna Jain <nayna@linux.vnet.ibm.com>
  *
  * Maintained by: <tpmdd-devel@lists.sourceforge.net>
  *
@@ -32,6 +33,7 @@
 #include <linux/pm_runtime.h>
 
 #include "tpm.h"
+#include "tpm2.h"
 #include "tpm_eventlog.h"
 
 #define TPM_MAX_ORDINAL 243
@@ -752,7 +754,7 @@ static const struct tpm_input_header pcrextend_header = {
 int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
 {
 	struct tpm_cmd_t cmd;
-	int rc;
+	int i, rc;
 	struct tpm_chip *chip;
 
 	chip = tpm_chip_find_get(chip_num);
@@ -760,7 +762,18 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
 		return -ENODEV;
 
 	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
-		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
+		struct tpml_digest_values d_values;
+
+		memset(&d_values, 0, sizeof(d_values));
+
+		for (i = 0; i < chip->no_of_active_banks; i++) {
+			d_values.digests[i].alg_id =
+				chip->active_banks[i];
+			memcpy(d_values.digests[i].digest, hash,
+			       TPM_DIGEST_SIZE);
+			d_values.count++;
+		}
+		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
 		tpm_put_ops(chip);
 		return rc;
 	}
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index c597cf3c..8ba2992 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -16,6 +16,7 @@
  */
 
 #include "tpm.h"
+#include "tpm2.h"
 #include <crypto/hash_info.h>
 #include <keys/trusted-type.h>
 
@@ -53,22 +54,6 @@ struct tpm2_pcr_read_out {
 	u8	digest[TPM_DIGEST_SIZE];
 } __packed;
 
-struct tpm2_null_auth_area {
-	__be32			handle;
-	__be16			nonce_size;
-	u8			attributes;
-	__be16			auth_size;
-} __packed;
-
-struct tpm2_pcr_extend_in {
-	__be32				pcr_idx;
-	__be32				auth_area_size;
-	struct tpm2_null_auth_area	auth_area;
-	__be32				digest_cnt;
-	__be16				hash_alg;
-	u8				digest[TPM_DIGEST_SIZE];
-} __packed;
-
 struct tpm2_get_tpm_pt_in {
 	__be32	cap_id;
 	__be32	property_id;
@@ -300,38 +285,74 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
 
 static const struct tpm_input_header tpm2_pcrextend_header = {
 	.tag = cpu_to_be16(TPM2_ST_SESSIONS),
-	.length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
 	.ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
 };
 
 /**
  * tpm2_pcr_extend() - extend a PCR value
- * @chip:	TPM chip to use.
- * @pcr_idx:	index of the PCR.
- * @hash:	hash value to use for the extend operation.
+ * @chip:		TPM chip to use.
+ * @pcr_idx:		index of the PCR.
+ * @digest_values:	list of hash values to be extended.
  *
  * 0 is returned when the operation is successful. If a negative number is
  * returned it remarks a POSIX error code. If a positive number is returned
  * it remarks a TPM error.
  */
-int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
+int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
+		    struct tpml_digest_values *digest_list)
 {
 	struct tpm2_cmd cmd;
-	int rc;
+	int i, j, rc;
+	void *marker;
+	size_t size;
+	u32 halg_size;
+	u16 halg;
 
 	cmd.header.in = tpm2_pcrextend_header;
+	size = sizeof(struct tpm_input_header);
+
 	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
+	size = size + sizeof(cmd.params.pcrextend_in.pcr_idx);
+
 	cmd.params.pcrextend_in.auth_area_size =
 		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
+	size = size + sizeof(cmd.params.pcrextend_in.auth_area_size);
+
 	cmd.params.pcrextend_in.auth_area.handle =
 		cpu_to_be32(TPM2_RS_PW);
 	cmd.params.pcrextend_in.auth_area.nonce_size = 0;
 	cmd.params.pcrextend_in.auth_area.attributes = 0;
 	cmd.params.pcrextend_in.auth_area.auth_size = 0;
-	cmd.params.pcrextend_in.digest_cnt = cpu_to_be32(1);
-	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
-	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
+	size = size + sizeof(cmd.params.pcrextend_in.auth_area);
+
+	cmd.params.pcrextend_in.digests.count =
+		cpu_to_be32(digest_list->count);
+	size = size + sizeof(cmd.params.pcrextend_in.digests.count);
+	marker = &cmd.params.pcrextend_in.digests.digests[0];
+
+	for (i = 0; i < digest_list->count; i++) {
+		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
+
+			if (digest_list->digests[i].alg_id !=
+			    tpm2_hash_map[j].tpm_id)
+				continue;
+
+			halg_size = sizeof(digest_list->digests[i].alg_id);
+			halg = cpu_to_be16(digest_list->digests[i].alg_id);
+			memcpy(marker, &halg, halg_size);
+			marker = marker + halg_size;
+			size = size + halg_size;
+
+			memcpy(marker, &digest_list->digests[i].digest,
+			       hash_digest_size[tpm2_hash_map[j].crypto_id]);
+			marker = marker +
+				hash_digest_size[tpm2_hash_map[j].crypto_id];
+			size = size +
+				hash_digest_size[tpm2_hash_map[j].crypto_id];
+		}
+	}
 
+	cmd.header.in.length = cpu_to_be32(size);
 	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
 			      "attempting extend a PCR value");
 
diff --git a/drivers/char/tpm/tpm2.h b/drivers/char/tpm/tpm2.h
index 919fb05..0b1a107 100644
--- a/drivers/char/tpm/tpm2.h
+++ b/drivers/char/tpm/tpm2.h
@@ -74,6 +74,22 @@ struct tcg_pcr_event2 {
 	struct tcg_event_field		event;
 } __packed;
 
+/* Auth Area Structure. */
+struct tpm2_null_auth_area {
+	__be32		handle;
+	__be16		nonce_size;
+	u8		attributes;
+	__be16		auth_size;
+} __packed;
+
+/* Crypto agile extend format. */
+struct tpm2_pcr_extend_in {
+	__be32				pcr_idx;
+	__be32				auth_area_size;
+	struct tpm2_null_auth_area	auth_area;
+	struct tpml_digest_values	digests;
+} __packed;
+
 struct tpm2_get_cap_in {
 	__be32 cap_id;
 	__be32 property_id;
@@ -108,6 +124,8 @@ struct tpm2_get_cap_out {
 extern const struct seq_operations tpm2_binary_b_measurments_seqops;
 
 extern int tpm2_get_active_pcr_banks(struct tpm_chip *chip);
+extern int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
+			   struct tpml_digest_values *digest_values);
 extern int tpm2_get_capability(struct tpm_chip *chip, struct tpm2_get_cap_in
 	*cap_in, struct tpm2_get_cap_out *cap_out);
 
