diff mbox series

[RFCv2,02/37] s390/protvirt: introduce host side setup

Message ID 20200203131957.383915-3-borntraeger@de.ibm.com (mailing list archive)
State New, archived
Headers show
Series KVM: s390: Add support for protected VMs | expand

Commit Message

Christian Borntraeger Feb. 3, 2020, 1:19 p.m. UTC
From: Vasily Gorbik <gor@linux.ibm.com>

Introduce KVM_S390_PROTECTED_VIRTUALIZATION_HOST kbuild option for
protected virtual machines hosting support code.

Add "prot_virt" command line option which controls if the kernel
protected VMs support is enabled at early boot time. This has to be
done early, because it needs large amounts of memory and will disable
some features like STP time sync for the lpar.

Extend ultravisor info definitions and expose it via uv_info struct
filled in during startup.

Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
---
 .../admin-guide/kernel-parameters.txt         |  5 ++
 arch/s390/boot/Makefile                       |  2 +-
 arch/s390/boot/uv.c                           | 20 +++++++-
 arch/s390/include/asm/uv.h                    | 46 ++++++++++++++++--
 arch/s390/kernel/Makefile                     |  1 +
 arch/s390/kernel/setup.c                      |  4 --
 arch/s390/kernel/uv.c                         | 48 +++++++++++++++++++
 arch/s390/kvm/Kconfig                         | 19 ++++++++
 8 files changed, 136 insertions(+), 9 deletions(-)
 create mode 100644 arch/s390/kernel/uv.c

Comments

Cornelia Huck Feb. 3, 2020, 5:12 p.m. UTC | #1
On Mon,  3 Feb 2020 08:19:22 -0500
Christian Borntraeger <borntraeger@de.ibm.com> wrote:

> From: Vasily Gorbik <gor@linux.ibm.com>
> 
> Introduce KVM_S390_PROTECTED_VIRTUALIZATION_HOST kbuild option for
> protected virtual machines hosting support code.

Hm... I seem to remember that you wanted to drop this config option and
always build the code, in order to reduce complexity. Have you
reconsidered this?

> 
> Add "prot_virt" command line option which controls if the kernel
> protected VMs support is enabled at early boot time. This has to be
> done early, because it needs large amounts of memory and will disable
> some features like STP time sync for the lpar.
> 
> Extend ultravisor info definitions and expose it via uv_info struct
> filled in during startup.
> 
> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
> ---
>  .../admin-guide/kernel-parameters.txt         |  5 ++
>  arch/s390/boot/Makefile                       |  2 +-
>  arch/s390/boot/uv.c                           | 20 +++++++-
>  arch/s390/include/asm/uv.h                    | 46 ++++++++++++++++--
>  arch/s390/kernel/Makefile                     |  1 +
>  arch/s390/kernel/setup.c                      |  4 --
>  arch/s390/kernel/uv.c                         | 48 +++++++++++++++++++
>  arch/s390/kvm/Kconfig                         | 19 ++++++++
>  8 files changed, 136 insertions(+), 9 deletions(-)
>  create mode 100644 arch/s390/kernel/uv.c

(...)

> diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
> new file mode 100644
> index 000000000000..35ce89695509
> --- /dev/null
> +++ b/arch/s390/kernel/uv.c
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Common Ultravisor functions and initialization
> + *
> + * Copyright IBM Corp. 2019

Happy new year?

> + */
> +#include <linux/kernel.h>
> +#include <linux/types.h>
> +#include <linux/sizes.h>
> +#include <linux/bitmap.h>
> +#include <linux/memblock.h>
> +#include <asm/facility.h>
> +#include <asm/sections.h>
> +#include <asm/uv.h>
> +
> +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
> +int __bootdata_preserved(prot_virt_guest);

Confused. You have this and uv_info below both in this file and in
boot/uv.c. Is there some magic happening in __bootdata_preserved()?

> +#endif
> +
> +#ifdef CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST
> +int prot_virt_host;
> +EXPORT_SYMBOL(prot_virt_host);
> +struct uv_info __bootdata_preserved(uv_info);
> +EXPORT_SYMBOL(uv_info);
> +
> +static int __init prot_virt_setup(char *val)
> +{
> +	bool enabled;
> +	int rc;
> +
> +	rc = kstrtobool(val, &enabled);
> +	if (!rc && enabled)
> +		prot_virt_host = 1;
> +
> +	if (is_prot_virt_guest() && prot_virt_host) {
> +		prot_virt_host = 0;
> +		pr_info("Running as protected virtualization guest.");

Trying to disentangle that a bit in my mind...

If we don't have facility 158, is_prot_virt_guest() will return 0. If
protected host support has been requested, we'll print a message below
(and turn it off).

If the hardware provides the facilities for running as a protected virt
guest, we turn off protected virt host support if requested and print a
messages that we're a guest.

Two questions:
- Can the hardware ever provide both host and guest interfaces at the
  same time? I guess not; maybe add a comment?
- Do we also want to print a message that we're running as a guest if
  the user didn't enable host support? If not, maybe prefix the message
  with "Cannot enable support for protected virtualization host:" or
  so? (Maybe also a good idea for the message below.)

> +	}
> +
> +	if (prot_virt_host && !test_facility(158)) {
> +		prot_virt_host = 0;
> +		pr_info("The ultravisor call facility is not available.");
> +	}
> +
> +	return rc;
> +}
> +early_param("prot_virt", prot_virt_setup);
> +#endif

(...)
Christian Borntraeger Feb. 3, 2020, 10:03 p.m. UTC | #2
On 03.02.20 18:12, Cornelia Huck wrote:
> On Mon,  3 Feb 2020 08:19:22 -0500
> Christian Borntraeger <borntraeger@de.ibm.com> wrote:
> 
>> From: Vasily Gorbik <gor@linux.ibm.com>
>>
>> Introduce KVM_S390_PROTECTED_VIRTUALIZATION_HOST kbuild option for
>> protected virtual machines hosting support code.
> 
> Hm... I seem to remember that you wanted to drop this config option and
> always build the code, in order to reduce complexity. Have you
> reconsidered this?

I am still in favour of removing this, but I did not get an "yes, lets do
it" answer. Since removing is easier than re-adding its still in.

 [...]
>> + * Copyright IBM Corp. 2019
> 
> Happy new year?

yep :-)
[..]

>> +
>> +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
>> +int __bootdata_preserved(prot_virt_guest);
> 
> Confused. You have this and uv_info below both in this file and in
> boot/uv.c. Is there some magic happening in __bootdata_preserved()?

Yes, this is information that is transferred from the decompressor
to Linux. 
I think we discussed about this the last time as well?


> 
>> +#endif
>> +
>> +#ifdef CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST
>> +int prot_virt_host;
>> +EXPORT_SYMBOL(prot_virt_host);
>> +struct uv_info __bootdata_preserved(uv_info);
>> +EXPORT_SYMBOL(uv_info);
>> +
>> +static int __init prot_virt_setup(char *val)
>> +{
>> +	bool enabled;
>> +	int rc;
>> +
>> +	rc = kstrtobool(val, &enabled);
>> +	if (!rc && enabled)
>> +		prot_virt_host = 1;
>> +
>> +	if (is_prot_virt_guest() && prot_virt_host) {
>> +		prot_virt_host = 0;
>> +		pr_info("Running as protected virtualization guest.");
> 
> Trying to disentangle that a bit in my mind...
> 
> If we don't have facility 158, is_prot_virt_guest() will return 0. If
> protected host support has been requested, we'll print a message below
> (and turn it off).

yes, a guest cannot be a host. 
> 
> If the hardware provides the facilities for running as a protected virt
> guest, we turn off protected virt host support if requested and print a
> messages that we're a guest.
> 
> Two questions:
> - Can the hardware ever provide both host and guest interfaces at the
>   same time? I guess not; maybe add a comment?

Right, you are either guest or host. 

> - Do we also want to print a message that we're running as a guest if
>   the user didn't enable host support? If not, maybe prefix the message
>   with "Cannot enable support for protected virtualization host:" or
>   so? (Maybe also a good idea for the message below.)

Line too long and I hate breaking string over multiple lines.
I can change if somebody comes up with a proper message that is not too long.
Thomas Huth Feb. 4, 2020, 8:40 a.m. UTC | #3
On 03/02/2020 14.19, Christian Borntraeger wrote:
> From: Vasily Gorbik <gor@linux.ibm.com>
> 
> Introduce KVM_S390_PROTECTED_VIRTUALIZATION_HOST kbuild option for
> protected virtual machines hosting support code.
> 
> Add "prot_virt" command line option which controls if the kernel
> protected VMs support is enabled at early boot time. This has to be
> done early, because it needs large amounts of memory and will disable
> some features like STP time sync for the lpar.
> 
> Extend ultravisor info definitions and expose it via uv_info struct
> filled in during startup.
> 
> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
> ---
[...]
> diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h
> index 4093a2856929..32eac3ab2d3b 100644
> --- a/arch/s390/include/asm/uv.h
> +++ b/arch/s390/include/asm/uv.h
> @@ -44,7 +44,19 @@ struct uv_cb_qui {
>  	struct uv_cb_header header;
>  	u64 reserved08;
>  	u64 inst_calls_list[4];
> -	u64 reserved30[15];
> +	u64 reserved30[2];
> +	u64 uv_base_stor_len;
> +	u64 reserved48;
> +	u64 conf_base_phys_stor_len;
> +	u64 conf_base_virt_stor_len;
> +	u64 conf_virt_var_stor_len;
> +	u64 cpu_stor_len;
> +	u32 reserved68[3];

If I count right, that should be named reserved70 instead?

> +	u32 max_num_sec_conf;
> +	u64 max_guest_stor_addr;
> +	u8  reserved80[150-128];

And this one reserved88[158 - 136] ?

> +	u16 max_guest_cpus;
> +	u64 reserved98;

reservedA0 ?

>  } __packed __aligned(8);
>  

Apart from that, the patch looks ok to me.

 Thomas
Christian Borntraeger Feb. 4, 2020, 9:12 a.m. UTC | #4
On 04.02.20 09:40, Thomas Huth wrote:
> On 03/02/2020 14.19, Christian Borntraeger wrote:
>> From: Vasily Gorbik <gor@linux.ibm.com>
>>
>> Introduce KVM_S390_PROTECTED_VIRTUALIZATION_HOST kbuild option for
>> protected virtual machines hosting support code.
>>
>> Add "prot_virt" command line option which controls if the kernel
>> protected VMs support is enabled at early boot time. This has to be
>> done early, because it needs large amounts of memory and will disable
>> some features like STP time sync for the lpar.
>>
>> Extend ultravisor info definitions and expose it via uv_info struct
>> filled in during startup.
>>
>> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
>> ---
> [...]
>> diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h
>> index 4093a2856929..32eac3ab2d3b 100644
>> --- a/arch/s390/include/asm/uv.h
>> +++ b/arch/s390/include/asm/uv.h
>> @@ -44,7 +44,19 @@ struct uv_cb_qui {
>>  	struct uv_cb_header header;
>>  	u64 reserved08;
>>  	u64 inst_calls_list[4];
>> -	u64 reserved30[15];
>> +	u64 reserved30[2];
>> +	u64 uv_base_stor_len;
>> +	u64 reserved48;
>> +	u64 conf_base_phys_stor_len;
>> +	u64 conf_base_virt_stor_len;
>> +	u64 conf_virt_var_stor_len;
>> +	u64 cpu_stor_len;
>> +	u32 reserved68[3];
> 
> If I count right, that should be named reserved70 instead?

Right. Fixed. 
> 
>> +	u32 max_num_sec_conf;
>> +	u64 max_guest_stor_addr;
>> +	u8  reserved80[150-128];
> 
> And this one reserved88[158 - 136] ?

Right. Fixed
> 
>> +	u16 max_guest_cpus;
>> +	u64 reserved98;
> 
> reservedA0 ?

Fixed. (with lowercase a as in other s390 include files):
> 
>>  } __packed __aligned(8);
>>  
> 
> Apart from that, the patch looks ok to me.

Thanks
Cornelia Huck Feb. 4, 2020, 9:28 a.m. UTC | #5
On Mon, 3 Feb 2020 23:03:42 +0100
Christian Borntraeger <borntraeger@de.ibm.com> wrote:

> On 03.02.20 18:12, Cornelia Huck wrote:
> > On Mon,  3 Feb 2020 08:19:22 -0500
> > Christian Borntraeger <borntraeger@de.ibm.com> wrote:
> >   
> >> From: Vasily Gorbik <gor@linux.ibm.com>
> >>
> >> Introduce KVM_S390_PROTECTED_VIRTUALIZATION_HOST kbuild option for
> >> protected virtual machines hosting support code.  
> > 
> > Hm... I seem to remember that you wanted to drop this config option and
> > always build the code, in order to reduce complexity. Have you
> > reconsidered this?  
> 
> I am still in favour of removing this, but I did not get an "yes, lets do
> it" answer. Since removing is easier than re-adding its still in.

ok

> 
>  [...]
> >> + * Copyright IBM Corp. 2019  
> > 
> > Happy new year?  
> 
> yep :-)
> [..]
> 
> >> +
> >> +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
> >> +int __bootdata_preserved(prot_virt_guest);  
> > 
> > Confused. You have this and uv_info below both in this file and in
> > boot/uv.c. Is there some magic happening in __bootdata_preserved()?  
> 
> Yes, this is information that is transferred from the decompressor
> to Linux. 
> I think we discussed about this the last time as well?

I think I was confused about different things last time...

But that is probably a sign that this wants a comment :)

> 
> 
> >   
> >> +#endif
> >> +
> >> +#ifdef CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST
> >> +int prot_virt_host;
> >> +EXPORT_SYMBOL(prot_virt_host);
> >> +struct uv_info __bootdata_preserved(uv_info);
> >> +EXPORT_SYMBOL(uv_info);
> >> +
> >> +static int __init prot_virt_setup(char *val)
> >> +{
> >> +	bool enabled;
> >> +	int rc;
> >> +
> >> +	rc = kstrtobool(val, &enabled);
> >> +	if (!rc && enabled)
> >> +		prot_virt_host = 1;
> >> +
> >> +	if (is_prot_virt_guest() && prot_virt_host) {
> >> +		prot_virt_host = 0;
> >> +		pr_info("Running as protected virtualization guest.");  
> > 
> > Trying to disentangle that a bit in my mind...
> > 
> > If we don't have facility 158, is_prot_virt_guest() will return 0. If
> > protected host support has been requested, we'll print a message below
> > (and turn it off).  
> 
> yes, a guest cannot be a host. 
> > 
> > If the hardware provides the facilities for running as a protected virt
> > guest, we turn off protected virt host support if requested and print a
> > messages that we're a guest.
> > 
> > Two questions:
> > - Can the hardware ever provide both host and guest interfaces at the
> >   same time? I guess not; maybe add a comment?  
> 
> Right, you are either guest or host. 
> 
> > - Do we also want to print a message that we're running as a guest if
> >   the user didn't enable host support? If not, maybe prefix the message
> >   with "Cannot enable support for protected virtualization host:" or
> >   so? (Maybe also a good idea for the message below.)  
> 
> Line too long and I hate breaking string over multiple lines.
> I can change if somebody comes up with a proper message that is not too long.
> 

Fair enough; it's just that it's not very clear from the messages in
the log what happened. Maybe

"prot_virt: Running as protected virtualization guest."
"prot_virt: The ultravisor call facility is not available."

That at least links back to the kernel parameter.

[Aside: Would prot_virt_host be a better name? But that probably moves
us into bikeshed territory.]
Christian Borntraeger Feb. 4, 2020, 9:38 a.m. UTC | #6
On 04.02.20 10:28, Cornelia Huck wrote:
> On Mon, 3 Feb 2020 23:03:42 +0100
> Christian Borntraeger <borntraeger@de.ibm.com> wrote:
> 
>> On 03.02.20 18:12, Cornelia Huck wrote:
>>> On Mon,  3 Feb 2020 08:19:22 -0500
>>> Christian Borntraeger <borntraeger@de.ibm.com> wrote:
>>>   
>>>> From: Vasily Gorbik <gor@linux.ibm.com>
>>>>
>>>> Introduce KVM_S390_PROTECTED_VIRTUALIZATION_HOST kbuild option for
>>>> protected virtual machines hosting support code.  
>>>
>>> Hm... I seem to remember that you wanted to drop this config option and
>>> always build the code, in order to reduce complexity. Have you
>>> reconsidered this?  
>>
>> I am still in favour of removing this, but I did not get an "yes, lets do
>> it" answer. Since removing is easier than re-adding its still in.
> 
> ok

Any preference from you?

[...]
> 
> I think I was confused about different things last time...
> 
> But that is probably a sign that this wants a comment :)

Will add

to kernel/uv.c
/* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */

to boot/uv.c
/* will be used in arch/s390/kernel/uv.c */


[...]
> Fair enough; it's just that it's not very clear from the messages in
> the log what happened. Maybe
> 
> "prot_virt: Running as protected virtualization guest."
> "prot_virt: The ultravisor call facility is not available."
> 
> That at least links back to the kernel parameter.

I will defer this until the end, in the hope to have a final name by then.
Cornelia Huck Feb. 4, 2020, 9:49 a.m. UTC | #7
On Tue, 4 Feb 2020 10:38:55 +0100
Christian Borntraeger <borntraeger@de.ibm.com> wrote:

> On 04.02.20 10:28, Cornelia Huck wrote:
> > On Mon, 3 Feb 2020 23:03:42 +0100
> > Christian Borntraeger <borntraeger@de.ibm.com> wrote:
> >   
> >> On 03.02.20 18:12, Cornelia Huck wrote:  
> >>> On Mon,  3 Feb 2020 08:19:22 -0500
> >>> Christian Borntraeger <borntraeger@de.ibm.com> wrote:
> >>>     
> >>>> From: Vasily Gorbik <gor@linux.ibm.com>
> >>>>
> >>>> Introduce KVM_S390_PROTECTED_VIRTUALIZATION_HOST kbuild option for
> >>>> protected virtual machines hosting support code.    
> >>>
> >>> Hm... I seem to remember that you wanted to drop this config option and
> >>> always build the code, in order to reduce complexity. Have you
> >>> reconsidered this?    
> >>
> >> I am still in favour of removing this, but I did not get an "yes, lets do
> >> it" answer. Since removing is easier than re-adding its still in.  
> > 
> > ok  
> 
> Any preference from you?

Not at the moment, I still need to look at the following patches.

> 
> [...]
> > 
> > I think I was confused about different things last time...
> > 
> > But that is probably a sign that this wants a comment :)  
> 
> Will add
> 
> to kernel/uv.c
> /* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */
> 
> to boot/uv.c
> /* will be used in arch/s390/kernel/uv.c */

Thanks!

> 
> 
> [...]
> > Fair enough; it's just that it's not very clear from the messages in
> > the log what happened. Maybe
> > 
> > "prot_virt: Running as protected virtualization guest."
> > "prot_virt: The ultravisor call facility is not available."
> > 
> > That at least links back to the kernel parameter.  
> 
> I will defer this until the end, in the hope to have a final name by then.
> 
ok
diff mbox series

Patch

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index ade4e6ec23e0..327af96f9528 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3750,6 +3750,11 @@ 
 			before loading.
 			See Documentation/admin-guide/blockdev/ramdisk.rst.
 
+	prot_virt=	[S390] enable hosting protected virtual machines
+			isolated from the hypervisor (if hardware supports
+			that).
+			Format: <bool>
+
 	psi=		[KNL] Enable or disable pressure stall information
 			tracking.
 			Format: <bool>
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index e2c47d3a1c89..82247e71617a 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -37,7 +37,7 @@  CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
 obj-y	:= head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o
 obj-y	+= string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
 obj-y	+= version.o pgm_check_info.o ctype.o text_dma.o
-obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST)	+= uv.o
+obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST))	+= uv.o
 obj-$(CONFIG_RELOCATABLE)	+= machine_kexec_reloc.o
 obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o
 targets	:= bzImage startup.a section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)
diff --git a/arch/s390/boot/uv.c b/arch/s390/boot/uv.c
index ed007f4a6444..88cf8825d169 100644
--- a/arch/s390/boot/uv.c
+++ b/arch/s390/boot/uv.c
@@ -3,7 +3,12 @@ 
 #include <asm/facility.h>
 #include <asm/sections.h>
 
+#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
 int __bootdata_preserved(prot_virt_guest);
+#endif
+#ifdef CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST
+struct uv_info __bootdata_preserved(uv_info);
+#endif
 
 void uv_query_info(void)
 {
@@ -18,7 +23,20 @@  void uv_query_info(void)
 	if (uv_call(0, (uint64_t)&uvcb))
 		return;
 
-	if (test_bit_inv(BIT_UVC_CMD_SET_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list) &&
+	if (IS_ENABLED(CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST)) {
+		memcpy(uv_info.inst_calls_list, uvcb.inst_calls_list, sizeof(uv_info.inst_calls_list));
+		uv_info.uv_base_stor_len = uvcb.uv_base_stor_len;
+		uv_info.guest_base_stor_len = uvcb.conf_base_phys_stor_len;
+		uv_info.guest_virt_base_stor_len = uvcb.conf_base_virt_stor_len;
+		uv_info.guest_virt_var_stor_len = uvcb.conf_virt_var_stor_len;
+		uv_info.guest_cpu_stor_len = uvcb.cpu_stor_len;
+		uv_info.max_sec_stor_addr = ALIGN(uvcb.max_guest_stor_addr, PAGE_SIZE);
+		uv_info.max_num_sec_conf = uvcb.max_num_sec_conf;
+		uv_info.max_guest_cpus = uvcb.max_guest_cpus;
+	}
+
+	if (IS_ENABLED(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) &&
+	    test_bit_inv(BIT_UVC_CMD_SET_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list) &&
 	    test_bit_inv(BIT_UVC_CMD_REMOVE_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list))
 		prot_virt_guest = 1;
 }
diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h
index 4093a2856929..32eac3ab2d3b 100644
--- a/arch/s390/include/asm/uv.h
+++ b/arch/s390/include/asm/uv.h
@@ -44,7 +44,19 @@  struct uv_cb_qui {
 	struct uv_cb_header header;
 	u64 reserved08;
 	u64 inst_calls_list[4];
-	u64 reserved30[15];
+	u64 reserved30[2];
+	u64 uv_base_stor_len;
+	u64 reserved48;
+	u64 conf_base_phys_stor_len;
+	u64 conf_base_virt_stor_len;
+	u64 conf_virt_var_stor_len;
+	u64 cpu_stor_len;
+	u32 reserved68[3];
+	u32 max_num_sec_conf;
+	u64 max_guest_stor_addr;
+	u8  reserved80[150-128];
+	u16 max_guest_cpus;
+	u64 reserved98;
 } __packed __aligned(8);
 
 struct uv_cb_share {
@@ -69,9 +81,21 @@  static inline int uv_call(unsigned long r1, unsigned long r2)
 	return cc;
 }
 
-#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
+struct uv_info {
+	unsigned long inst_calls_list[4];
+	unsigned long uv_base_stor_len;
+	unsigned long guest_base_stor_len;
+	unsigned long guest_virt_base_stor_len;
+	unsigned long guest_virt_var_stor_len;
+	unsigned long guest_cpu_stor_len;
+	unsigned long max_sec_stor_addr;
+	unsigned int max_num_sec_conf;
+	unsigned short max_guest_cpus;
+};
+extern struct uv_info uv_info;
 extern int prot_virt_guest;
 
+#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
 static inline int is_prot_virt_guest(void)
 {
 	return prot_virt_guest;
@@ -121,11 +145,27 @@  static inline int uv_remove_shared(unsigned long addr)
 	return share(addr, UVC_CMD_REMOVE_SHARED_ACCESS);
 }
 
-void uv_query_info(void);
 #else
 #define is_prot_virt_guest() 0
 static inline int uv_set_shared(unsigned long addr) { return 0; }
 static inline int uv_remove_shared(unsigned long addr) { return 0; }
+#endif
+
+#ifdef CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST
+extern int prot_virt_host;
+
+static inline int is_prot_virt_host(void)
+{
+	return prot_virt_host;
+}
+#else
+#define is_prot_virt_host() 0
+#endif
+
+#if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) ||                          \
+	defined(CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST)
+void uv_query_info(void);
+#else
 static inline void uv_query_info(void) {}
 #endif
 
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 2b1203cf7be6..1b958a453e37 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -78,6 +78,7 @@  obj-$(CONFIG_PERF_EVENTS)	+= perf_cpum_cf_events.o perf_regs.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_cpum_cf_diag.o
 
 obj-$(CONFIG_TRACEPOINTS)	+= trace.o
+obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST))	+= uv.o
 
 # vdso
 obj-y				+= vdso64/
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index d5fbd754f41a..f2ab2528859f 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -92,10 +92,6 @@  char elf_platform[ELF_PLATFORM_SIZE];
 
 unsigned long int_hwcap = 0;
 
-#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
-int __bootdata_preserved(prot_virt_guest);
-#endif
-
 int __bootdata(noexec_disabled);
 int __bootdata(memory_end_set);
 unsigned long __bootdata(memory_end);
diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
new file mode 100644
index 000000000000..35ce89695509
--- /dev/null
+++ b/arch/s390/kernel/uv.c
@@ -0,0 +1,48 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Common Ultravisor functions and initialization
+ *
+ * Copyright IBM Corp. 2019
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sizes.h>
+#include <linux/bitmap.h>
+#include <linux/memblock.h>
+#include <asm/facility.h>
+#include <asm/sections.h>
+#include <asm/uv.h>
+
+#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
+int __bootdata_preserved(prot_virt_guest);
+#endif
+
+#ifdef CONFIG_KVM_S390_PROTECTED_VIRTUALIZATION_HOST
+int prot_virt_host;
+EXPORT_SYMBOL(prot_virt_host);
+struct uv_info __bootdata_preserved(uv_info);
+EXPORT_SYMBOL(uv_info);
+
+static int __init prot_virt_setup(char *val)
+{
+	bool enabled;
+	int rc;
+
+	rc = kstrtobool(val, &enabled);
+	if (!rc && enabled)
+		prot_virt_host = 1;
+
+	if (is_prot_virt_guest() && prot_virt_host) {
+		prot_virt_host = 0;
+		pr_info("Running as protected virtualization guest.");
+	}
+
+	if (prot_virt_host && !test_facility(158)) {
+		prot_virt_host = 0;
+		pr_info("The ultravisor call facility is not available.");
+	}
+
+	return rc;
+}
+early_param("prot_virt", prot_virt_setup);
+#endif
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index d3db3d7ed077..9ce9c7295e16 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -55,6 +55,25 @@  config KVM_S390_UCONTROL
 
 	  If unsure, say N.
 
+config KVM_S390_PROTECTED_VIRTUALIZATION_HOST
+	bool "Protected guests execution support"
+	depends on KVM
+	help
+	Support hosting protected virtual machines in KVM. The state
+	of these machines like memory content or register content is
+	protected from the host or host administrators.
+
+	Enabling this option will enable extra code that allows a
+	Linux hypervisor to talk to a new firmware instance called
+	ultravisor that will take care of protecting the guest while
+	also enabling KVM to run this guest.
+
+	This feature must be enable via the kernel command line option
+	prot_virt.
+
+	If unsure, say Y.
+
+
 # OK, it's a little counter-intuitive to do this, but it puts it neatly under
 # the virtualization menu.
 source "drivers/vhost/Kconfig"