Message ID | 20191024114059.102802-7-frankja@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: s390: Add support for protected VMs | expand |
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. How does paging play along with pinning the pages (from uv_convert_to_secure() -> kvm_s390_pv_pin_page()) in a follow up patch? Can you paint me the bigger picture? Just so I understand: When a page is "secure", it is actually unencrypted but only the guest can access it. If the host accesses it, there is an exception. When a page is "not secure", it is encrypted but only the host can read it. If the guest accesses it, there is an exception. Based on these exceptions, you are able to request to convert back and forth. > > 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@linux.ibm.com> > --- > 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) || \ >
On 10/25/19 10:31 AM, David Hildenbrand 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. > > How does paging play along with pinning the pages (from > uv_convert_to_secure() -> kvm_s390_pv_pin_page()) in a follow up patch? > Can you paint me the bigger picture? That's a stale comment I should have removed before sending... The current patches do not support paging. > > Just so I understand: > > When a page is "secure", it is actually unencrypted but only the guest > can access it. If the host accesses it, there is an exception. > > When a page is "not secure", it is encrypted but only the host can read > it. If the guest accesses it, there is an exception. > > Based on these exceptions, you are able to request to convert back and > forth. Yes Shared pages are the exception, because they are accessible to both parties. > > >> >> 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@linux.ibm.com> >> --- >> 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) || \ >> > >
On 25.10.19 10:39, Janosch Frank wrote: > On 10/25/19 10:31 AM, David Hildenbrand 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. >> >> How does paging play along with pinning the pages (from >> uv_convert_to_secure() -> kvm_s390_pv_pin_page()) in a follow up patch? >> Can you paint me the bigger picture? > > That's a stale comment I should have removed before sending... > The current patches do not support paging. Note that once you pin you really have to disable the balloon in the QEMU (inhibit it).
On 10/25/19 10:40 AM, David Hildenbrand wrote: > On 25.10.19 10:39, Janosch Frank wrote: >> On 10/25/19 10:31 AM, David Hildenbrand 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. >>> >>> How does paging play along with pinning the pages (from >>> uv_convert_to_secure() -> kvm_s390_pv_pin_page()) in a follow up patch? >>> Can you paint me the bigger picture? >> >> That's a stale comment I should have removed before sending... >> The current patches do not support paging. > > Note that once you pin you really have to disable the balloon in the > QEMU (inhibit it). > Yes, and you need the iommu for virtio. We didn't yet fully discuss how to handle that.
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@linux.ibm.com> > --- > 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) || \ >
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@linux.ibm.com> >> --- >> 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 > >> + 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) || \ >>
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@linux.ibm.com> >>> --- >>> 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.
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@linux.ibm.com> After re-reading. Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> > --- > 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) || \ >
On Thu, 24 Oct 2019 07:40:28 -0400 Janosch Frank <frankja@linux.ibm.com> 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@linux.ibm.com> > --- > 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; No possibility for other return codes here (e.g. -EFAULT)? (Asking because you look at a rc in the control block in the reverse function.) > +} > + > +/* > + * 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) || \
On 11/11/19 5:40 PM, Cornelia Huck wrote: > On Thu, 24 Oct 2019 07:40:28 -0400 > Janosch Frank <frankja@linux.ibm.com> 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@linux.ibm.com> >> --- >> 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; > > No possibility for other return codes here (e.g. -EFAULT)? (Asking > because you look at a rc in the control block in the reverse function.) Notice the "paddr" variable? We work on physical memory for this UV call, all error codes that are defined are either input errors (not possible via the exception handlers), a KVM management error or an attack on the VM. > >> +} >> + >> +/* >> + * 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) || \ >
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) || \
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@linux.ibm.com> --- arch/s390/include/asm/uv.h | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)