Blame SOURCES/librtas-2.0.1-rtas-call.patch

b400a6
From 26970c42bc017ad68b864e7134cf941c07443aa8 Mon Sep 17 00:00:00 2001
b400a6
From: Chris Engel <cengel@linux.vnet.ibm.com>
b400a6
Date: Tue, 22 Aug 2017 14:59:06 -0500
b400a6
Subject: [PATCH] Interface for ibm,physical-attestation rtas call
b400a6
b400a6
The physical attestation interfaces are provided to allow a
b400a6
trusted 3rd party client to retrieve information about the
b400a6
trusted boot state of the target PowerVM system.  This makes
b400a6
use of the systems physical TPM(s).  These TPM(s) are used
b400a6
by system firmware to extend measurements during the
b400a6
boot process.
b400a6
b400a6
Signed-off-by: Chris Engel <cengel@linux.vnet.ibm.com>
b400a6
Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
b400a6
Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
b400a6
---
b400a6
 librtas_src/librtas.h       |  2 ++
b400a6
 librtas_src/syscall_calls.c | 63 +++++++++++++++++++++++++++++++++++++++++++++
b400a6
 2 files changed, 65 insertions(+)
b400a6
b400a6
diff --git a/librtas_src/librtas.h b/librtas_src/librtas.h
b400a6
index ccab3d9..b84fab1 100644
b400a6
--- a/librtas_src/librtas.h
b400a6
+++ b/librtas_src/librtas.h
b400a6
@@ -105,6 +105,8 @@ extern int rtas_set_time(uint32_t year, uint32_t month, uint32_t day,
b400a6
 extern int rtas_suspend_me(uint64_t streamid);
b400a6
 extern int rtas_update_nodes(char *workarea, unsigned int scope);
b400a6
 extern int rtas_update_properties(char *workarea, unsigned int scope);
b400a6
+extern int rtas_physical_attestation(char *workarea, int seq_num,
b400a6
+				     int *next_seq_num, int *work_area_bytes);
b400a6
 
b400a6
 #ifdef __cplusplus
b400a6
 }
b400a6
diff --git a/librtas_src/syscall_calls.c b/librtas_src/syscall_calls.c
b400a6
index a194e4b..35b6d66 100644
b400a6
--- a/librtas_src/syscall_calls.c
b400a6
+++ b/librtas_src/syscall_calls.c
b400a6
@@ -1329,3 +1329,66 @@ int rtas_update_properties(char *workarea, unsigned int scope)
b400a6
 	dbg("(%p) %d = %d\n", workarea, scope, rc ? rc : status);
b400a6
 	return rc ? rc : status;
b400a6
 }
b400a6
+
b400a6
+/**
b400a6
+ * rtas_physical_attestation
b400a6
+ * @brief Interface for ibm,physical-attestation rtas call.
b400a6
+ *
b400a6
+ * @param workarea input/output work area for rtas call
b400a6
+ * @param seq_num sequence number of the rtas call
b400a6
+ * @param next_seq_num next sequence number
b400a6
+ * @param work_area_bytes size of work area
b400a6
+ * @return 0 on success, !0 on failure
b400a6
+ */
b400a6
+int rtas_physical_attestation(char *workarea, int seq_num, int *next_seq_num,
b400a6
+			      int *work_area_bytes)
b400a6
+{
b400a6
+	uint32_t workarea_pa;
b400a6
+	uint64_t elapsed = 0;
b400a6
+	void *kernbuf;
b400a6
+	int kbuf_sz = 4096;
b400a6
+	int rc, status;
b400a6
+	int resp_bytes = *work_area_bytes;
b400a6
+
b400a6
+	rc = sanity_check();
b400a6
+	if (rc)
b400a6
+		return rc;
b400a6
+
b400a6
+	/* Caller provided more data than FW can handle */
b400a6
+	if (*work_area_bytes == 0 ||
b400a6
+	    *work_area_bytes > kbuf_sz)
b400a6
+		return RTAS_IO_ASSERT;
b400a6
+
b400a6
+	rc = rtas_get_rmo_buffer(kbuf_sz, &kernbuf, &workarea_pa);
b400a6
+	if (rc)
b400a6
+		return rc;
b400a6
+	memcpy(kernbuf, workarea, *work_area_bytes);
b400a6
+
b400a6
+	do {
b400a6
+		rc = rtas_call("ibm,physical-attestation", 3, 3,
b400a6
+			       htobe32(workarea_pa), htobe32(kbuf_sz),
b400a6
+			       htobe32(seq_num),
b400a6
+			       &status, next_seq_num, &resp_bytes);
b400a6
+		if (rc < 0)
b400a6
+			break;
b400a6
+
b400a6
+		rc = handle_delay(status, &elapsed);
b400a6
+	} while (rc == CALL_AGAIN);
b400a6
+
b400a6
+	*next_seq_num = be32toh(*next_seq_num);
b400a6
+
b400a6
+	/* FW returned more data than we can handle */
b400a6
+	if (be32toh(resp_bytes) > *work_area_bytes) {
b400a6
+		(void)rtas_free_rmo_buffer(kernbuf, workarea_pa, kbuf_sz);
b400a6
+		return RTAS_IO_ASSERT;
b400a6
+	}
b400a6
+
b400a6
+	*work_area_bytes = be32toh(resp_bytes);
b400a6
+
b400a6
+	if (rc == 0)
b400a6
+		memcpy(workarea, kernbuf, *work_area_bytes);
b400a6
+
b400a6
+	(void)rtas_free_rmo_buffer(kernbuf, workarea_pa, kbuf_sz);
b400a6
+
b400a6
+	return rc ? rc : status;
b400a6
+}
b400a6
-- 
b400a6
2.9.5
b400a6