[RFC 06/37] s390: UV: Add import and export to UV library

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The convert to/from secure (or also "import/export") ultravisor calls
are need for page management, i.e. paging, of secure execution VM.

Export encrypts a secure guest's page and makes it accessible to the
guest for paging.

Import makes a page accessible to a secure guest.
On the first import of that page, the page will be cleared by the
Ultravisor before it is given to the guest.

All following imports will decrypt a exported page and verify
integrity before giving the page to the guest.

Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxx>
---
 arch/s390/include/asm/uv.h | 51 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h
index 0bfbafcca136..99cdd2034503 100644
--- a/arch/s390/include/asm/uv.h
+++ b/arch/s390/include/asm/uv.h
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/bug.h>
 #include <asm/page.h>
+#include <asm/gmap.h>
 
 #define UVC_RC_EXECUTED		0x0001
 #define UVC_RC_INV_CMD		0x0002
@@ -279,6 +280,54 @@ static inline int uv_cmd_nodata(u64 handle, u16 cmd, u32 *ret)
 	return rc ? -EINVAL : 0;
 }
 
+/*
+ * Requests the Ultravisor to encrypt a guest page and make it
+ * accessible to the host for paging (export).
+ *
+ * @paddr: Absolute host address of page to be exported
+ */
+static inline int uv_convert_from_secure(unsigned long paddr)
+{
+	struct uv_cb_cfs uvcb = {
+		.header.cmd = UVC_CMD_CONV_FROM_SEC_STOR,
+		.header.len = sizeof(uvcb),
+		.paddr = paddr
+	};
+	if (!uv_call(0, (u64)&uvcb))
+		return 0;
+	return -EINVAL;
+}
+
+/*
+ * Requests the Ultravisor to make a page accessible to a guest
+ * (import). If it's brought in the first time, it will be cleared. If
+ * it has been exported before, it will be decrypted and integrity
+ * checked.
+ *
+ * @handle: Ultravisor guest handle
+ * @gaddr: Guest 2 absolute address to be imported
+ */
+static inline int uv_convert_to_secure(struct gmap *gmap, unsigned long gaddr)
+{
+	int cc;
+	struct uv_cb_cts uvcb = {
+		.header.cmd = UVC_CMD_CONV_TO_SEC_STOR,
+		.header.len = sizeof(uvcb),
+		.guest_handle = gmap->se_handle,
+		.gaddr = gaddr
+	};
+
+	cc = uv_call(0, (u64)&uvcb);
+
+	if (!cc)
+		return 0;
+	if (uvcb.header.rc == 0x104)
+		return -EEXIST;
+	if (uvcb.header.rc == 0x10a)
+		return -EFAULT;
+	return -EINVAL;
+}
+
 void setup_uv(void);
 void adjust_to_uv_max(unsigned long *vmax);
 #else
@@ -286,6 +335,8 @@ void adjust_to_uv_max(unsigned long *vmax);
 static inline void setup_uv(void) {}
 static inline void adjust_to_uv_max(unsigned long *vmax) {}
 static inline int uv_cmd_nodata(u64 handle, u16 cmd, u32 *ret) { return 0; }
+static inline int uv_convert_from_secure(unsigned long paddr) { return 0; }
+static inline int uv_convert_to_secure(unsigned long handle, unsigned long gaddr) { return 0; }
 #endif
 
 #if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) ||                          \
-- 
2.20.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux