On 01.11.19 13:25, Janosch Frank wrote: > On 11/1/19 12:26 PM, Christian Borntraeger wrote: >> >> >> 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. > > That's handled by the CC and the return below. > CC == 1 means error > cc == 0 is success, that's why we return erly on cc == 0 Right, uv_call return depends on CC. Nevermind.