On 24.10.19 13:40, Janosch Frank wrote: > 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; As discussed on the KVM forum. We should also check for uvcb.header.rc != UVC_RC_EXECUTED I know, we cant really do much if this fails, but we certainly want to know. > + 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; again, we should probably check for rc != UVC_RC_EXECUTED to detect any other problem. > + 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) || \ >