diff mbox series

[v2,03/42] s390/protvirt: introduce host side setup

Message ID 20200214222658.12946-4-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. 14, 2020, 10:26 p.m. UTC
From: Vasily Gorbik <gor@linux.ibm.com>

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>
Reviewed-by: Thomas Huth <thuth@redhat.com>
[borntraeger@de.ibm.com: patch merging, splitting, fixing]
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 .../admin-guide/kernel-parameters.txt         |  5 ++
 arch/s390/boot/Makefile                       |  2 +-
 arch/s390/boot/uv.c                           | 21 +++++++-
 arch/s390/include/asm/uv.h                    | 45 +++++++++++++++-
 arch/s390/kernel/Makefile                     |  1 +
 arch/s390/kernel/setup.c                      |  4 --
 arch/s390/kernel/uv.c                         | 52 +++++++++++++++++++
 7 files changed, 122 insertions(+), 8 deletions(-)
 create mode 100644 arch/s390/kernel/uv.c

Comments

David Hildenbrand Feb. 17, 2020, 9:53 a.m. UTC | #1
On 14.02.20 23:26, Christian Borntraeger wrote:
> From: Vasily Gorbik <gor@linux.ibm.com>
> 
> 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>
> Reviewed-by: Thomas Huth <thuth@redhat.com>
> [borntraeger@de.ibm.com: patch merging, splitting, fixing]
> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
> ---
>  .../admin-guide/kernel-parameters.txt         |  5 ++
>  arch/s390/boot/Makefile                       |  2 +-
>  arch/s390/boot/uv.c                           | 21 +++++++-
>  arch/s390/include/asm/uv.h                    | 45 +++++++++++++++-
>  arch/s390/kernel/Makefile                     |  1 +
>  arch/s390/kernel/setup.c                      |  4 --
>  arch/s390/kernel/uv.c                         | 52 +++++++++++++++++++
>  7 files changed, 122 insertions(+), 8 deletions(-)
>  create mode 100644 arch/s390/kernel/uv.c
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index dbc22d684627..b0beae9b9e36 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -3795,6 +3795,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..30f1811540c5 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_PGSTE))	+= 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..af9e1cc93c68 100644
> --- a/arch/s390/boot/uv.c
> +++ b/arch/s390/boot/uv.c
> @@ -3,7 +3,13 @@
>  #include <asm/facility.h>
>  #include <asm/sections.h>
>  
> +/* will be used in arch/s390/kernel/uv.c */
> +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
>  int __bootdata_preserved(prot_virt_guest);
> +#endif
> +#if IS_ENABLED(CONFIG_KVM)
> +struct uv_info __bootdata_preserved(uv_info);
> +#endif
>  
>  void uv_query_info(void)
>  {
> @@ -18,7 +24,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)) {
> +		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..34b1114dcc38 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 reserved70[3];
> +	u32 max_num_sec_conf;
> +	u64 max_guest_stor_addr;
> +	u8  reserved88[158-136];
> +	u16 max_guest_cpus;
> +	u64 reserveda0;
>  } __packed __aligned(8);
>  
>  struct uv_cb_share {
> @@ -69,6 +81,19 @@ static inline int uv_call(unsigned long r1, unsigned long r2)
>  	return cc;
>  }
>  
> +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;
> +
>  #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
>  extern int prot_virt_guest;
>  
> @@ -121,11 +146,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
> +
> +#if IS_ENABLED(CONFIG_KVM)
> +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) ||                          \
> +	IS_ENABLED(CONFIG_KVM)
> +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..22bfb8d5084e 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_PGSTE))	+= uv.o
>  
>  # vdso
>  obj-y				+= vdso64/
> diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
> index b2c2f75860e8..a2496382175e 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..b1f936710360
> --- /dev/null
> +++ b/arch/s390/kernel/uv.c
> @@ -0,0 +1,52 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Common Ultravisor functions and initialization
> + *
> + * Copyright IBM Corp. 2019, 2020
> + */
> +#define KMSG_COMPONENT "prot_virt"
> +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
> +
> +#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>
> +
> +/* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */
> +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
> +int __bootdata_preserved(prot_virt_guest);
> +#endif
> +
> +#if IS_ENABLED(CONFIG_KVM)


Why is that glued to CONFIG_KVM? Can't we glue all that stuff to
CONFIG_PROTECTED_VIRTUALIZATION_GUEST and make in kconfig
CONFIG_PROTECTED_VIRTUALIZATION_GUEST depend on CONFIG_KVM?

IOW, I'd prefer to only have CONFIG_PROTECTED_VIRTUALIZATION_GUEST in
!KVM code and enforce it via kconfig instead.


Anyhow, I remember Conny also having a comment about that previously, so

Acked-by: David Hildenbrand <david@redhat.com>
Christian Borntraeger Feb. 17, 2020, 11:11 a.m. UTC | #2
On 17.02.20 10:53, David Hildenbrand wrote:
> On 14.02.20 23:26, Christian Borntraeger wrote:
>> From: Vasily Gorbik <gor@linux.ibm.com>
>>
>> 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>
>> Reviewed-by: Thomas Huth <thuth@redhat.com>
>> [borntraeger@de.ibm.com: patch merging, splitting, fixing]
>> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
>> ---
>>  .../admin-guide/kernel-parameters.txt         |  5 ++
>>  arch/s390/boot/Makefile                       |  2 +-
>>  arch/s390/boot/uv.c                           | 21 +++++++-
>>  arch/s390/include/asm/uv.h                    | 45 +++++++++++++++-
>>  arch/s390/kernel/Makefile                     |  1 +
>>  arch/s390/kernel/setup.c                      |  4 --
>>  arch/s390/kernel/uv.c                         | 52 +++++++++++++++++++
>>  7 files changed, 122 insertions(+), 8 deletions(-)
>>  create mode 100644 arch/s390/kernel/uv.c
>>
>> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
>> index dbc22d684627..b0beae9b9e36 100644
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -3795,6 +3795,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..30f1811540c5 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_PGSTE))	+= 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..af9e1cc93c68 100644
>> --- a/arch/s390/boot/uv.c
>> +++ b/arch/s390/boot/uv.c
>> @@ -3,7 +3,13 @@
>>  #include <asm/facility.h>
>>  #include <asm/sections.h>
>>  
>> +/* will be used in arch/s390/kernel/uv.c */
>> +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
>>  int __bootdata_preserved(prot_virt_guest);
>> +#endif
>> +#if IS_ENABLED(CONFIG_KVM)
>> +struct uv_info __bootdata_preserved(uv_info);
>> +#endif
>>  
>>  void uv_query_info(void)
>>  {
>> @@ -18,7 +24,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)) {
>> +		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..34b1114dcc38 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 reserved70[3];
>> +	u32 max_num_sec_conf;
>> +	u64 max_guest_stor_addr;
>> +	u8  reserved88[158-136];
>> +	u16 max_guest_cpus;
>> +	u64 reserveda0;
>>  } __packed __aligned(8);
>>  
>>  struct uv_cb_share {
>> @@ -69,6 +81,19 @@ static inline int uv_call(unsigned long r1, unsigned long r2)
>>  	return cc;
>>  }
>>  
>> +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;
>> +
>>  #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
>>  extern int prot_virt_guest;
>>  
>> @@ -121,11 +146,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
>> +
>> +#if IS_ENABLED(CONFIG_KVM)
>> +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) ||                          \
>> +	IS_ENABLED(CONFIG_KVM)
>> +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..22bfb8d5084e 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_PGSTE))	+= uv.o
>>  
>>  # vdso
>>  obj-y				+= vdso64/
>> diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
>> index b2c2f75860e8..a2496382175e 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..b1f936710360
>> --- /dev/null
>> +++ b/arch/s390/kernel/uv.c
>> @@ -0,0 +1,52 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Common Ultravisor functions and initialization
>> + *
>> + * Copyright IBM Corp. 2019, 2020
>> + */
>> +#define KMSG_COMPONENT "prot_virt"
>> +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
>> +
>> +#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>
>> +
>> +/* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */
>> +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
>> +int __bootdata_preserved(prot_virt_guest);
>> +#endif
>> +
>> +#if IS_ENABLED(CONFIG_KVM)
> 
> 
> Why is that glued to CONFIG_KVM? Can't we glue all that stuff to
> CONFIG_PROTECTED_VIRTUALIZATION_GUEST and make in kconfig
> CONFIG_PROTECTED_VIRTUALIZATION_GUEST depend on CONFIG_KVM?


CONFIG_PROTECTED_VIRTUALIZATION_GUEST is for the GUEST part (the virtio-ccw changes
inside the guest). The other thing is for the host and here we bind it
to CONFIG_KVM (or PGSTE for mm code).

> 
> IOW, I'd prefer to only have CONFIG_PROTECTED_VIRTUALIZATION_GUEST in
> !KVM code and enforce it via kconfig instead.
> 
> 
> Anyhow, I remember Conny also having a comment about that previously, so
> 
> Acked-by: David Hildenbrand <david@redhat.com>
> 
>
David Hildenbrand Feb. 17, 2020, 11:13 a.m. UTC | #3
On 17.02.20 12:11, Christian Borntraeger wrote:
> 
> 
> On 17.02.20 10:53, David Hildenbrand wrote:
>> On 14.02.20 23:26, Christian Borntraeger wrote:
>>> From: Vasily Gorbik <gor@linux.ibm.com>
>>>
>>> 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>
>>> Reviewed-by: Thomas Huth <thuth@redhat.com>
>>> [borntraeger@de.ibm.com: patch merging, splitting, fixing]
>>> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
>>> ---
>>>  .../admin-guide/kernel-parameters.txt         |  5 ++
>>>  arch/s390/boot/Makefile                       |  2 +-
>>>  arch/s390/boot/uv.c                           | 21 +++++++-
>>>  arch/s390/include/asm/uv.h                    | 45 +++++++++++++++-
>>>  arch/s390/kernel/Makefile                     |  1 +
>>>  arch/s390/kernel/setup.c                      |  4 --
>>>  arch/s390/kernel/uv.c                         | 52 +++++++++++++++++++
>>>  7 files changed, 122 insertions(+), 8 deletions(-)
>>>  create mode 100644 arch/s390/kernel/uv.c
>>>
>>> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
>>> index dbc22d684627..b0beae9b9e36 100644
>>> --- a/Documentation/admin-guide/kernel-parameters.txt
>>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>>> @@ -3795,6 +3795,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..30f1811540c5 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_PGSTE))	+= 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..af9e1cc93c68 100644
>>> --- a/arch/s390/boot/uv.c
>>> +++ b/arch/s390/boot/uv.c
>>> @@ -3,7 +3,13 @@
>>>  #include <asm/facility.h>
>>>  #include <asm/sections.h>
>>>  
>>> +/* will be used in arch/s390/kernel/uv.c */
>>> +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
>>>  int __bootdata_preserved(prot_virt_guest);
>>> +#endif
>>> +#if IS_ENABLED(CONFIG_KVM)
>>> +struct uv_info __bootdata_preserved(uv_info);
>>> +#endif
>>>  
>>>  void uv_query_info(void)
>>>  {
>>> @@ -18,7 +24,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)) {
>>> +		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..34b1114dcc38 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 reserved70[3];
>>> +	u32 max_num_sec_conf;
>>> +	u64 max_guest_stor_addr;
>>> +	u8  reserved88[158-136];
>>> +	u16 max_guest_cpus;
>>> +	u64 reserveda0;
>>>  } __packed __aligned(8);
>>>  
>>>  struct uv_cb_share {
>>> @@ -69,6 +81,19 @@ static inline int uv_call(unsigned long r1, unsigned long r2)
>>>  	return cc;
>>>  }
>>>  
>>> +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;
>>> +
>>>  #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
>>>  extern int prot_virt_guest;
>>>  
>>> @@ -121,11 +146,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
>>> +
>>> +#if IS_ENABLED(CONFIG_KVM)
>>> +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) ||                          \
>>> +	IS_ENABLED(CONFIG_KVM)
>>> +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..22bfb8d5084e 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_PGSTE))	+= uv.o
>>>  
>>>  # vdso
>>>  obj-y				+= vdso64/
>>> diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
>>> index b2c2f75860e8..a2496382175e 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..b1f936710360
>>> --- /dev/null
>>> +++ b/arch/s390/kernel/uv.c
>>> @@ -0,0 +1,52 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Common Ultravisor functions and initialization
>>> + *
>>> + * Copyright IBM Corp. 2019, 2020
>>> + */
>>> +#define KMSG_COMPONENT "prot_virt"
>>> +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
>>> +
>>> +#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>
>>> +
>>> +/* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */
>>> +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
>>> +int __bootdata_preserved(prot_virt_guest);
>>> +#endif
>>> +
>>> +#if IS_ENABLED(CONFIG_KVM)
>>
>>
>> Why is that glued to CONFIG_KVM? Can't we glue all that stuff to
>> CONFIG_PROTECTED_VIRTUALIZATION_GUEST and make in kconfig
>> CONFIG_PROTECTED_VIRTUALIZATION_GUEST depend on CONFIG_KVM?
> 
> 
> CONFIG_PROTECTED_VIRTUALIZATION_GUEST is for the GUEST part (the virtio-ccw changes
> inside the guest). The other thing is for the host and here we bind it
> to CONFIG_KVM (or PGSTE for mm code).

Ahh, sorry messed that up. Think I had another (in previous versions?)
config option in mind.

Makes sense
diff mbox series

Patch

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index dbc22d684627..b0beae9b9e36 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3795,6 +3795,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..30f1811540c5 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_PGSTE))	+= 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..af9e1cc93c68 100644
--- a/arch/s390/boot/uv.c
+++ b/arch/s390/boot/uv.c
@@ -3,7 +3,13 @@ 
 #include <asm/facility.h>
 #include <asm/sections.h>
 
+/* will be used in arch/s390/kernel/uv.c */
+#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
 int __bootdata_preserved(prot_virt_guest);
+#endif
+#if IS_ENABLED(CONFIG_KVM)
+struct uv_info __bootdata_preserved(uv_info);
+#endif
 
 void uv_query_info(void)
 {
@@ -18,7 +24,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)) {
+		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..34b1114dcc38 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 reserved70[3];
+	u32 max_num_sec_conf;
+	u64 max_guest_stor_addr;
+	u8  reserved88[158-136];
+	u16 max_guest_cpus;
+	u64 reserveda0;
 } __packed __aligned(8);
 
 struct uv_cb_share {
@@ -69,6 +81,19 @@  static inline int uv_call(unsigned long r1, unsigned long r2)
 	return cc;
 }
 
+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;
+
 #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
 extern int prot_virt_guest;
 
@@ -121,11 +146,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
+
+#if IS_ENABLED(CONFIG_KVM)
+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) ||                          \
+	IS_ENABLED(CONFIG_KVM)
+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..22bfb8d5084e 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_PGSTE))	+= uv.o
 
 # vdso
 obj-y				+= vdso64/
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index b2c2f75860e8..a2496382175e 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..b1f936710360
--- /dev/null
+++ b/arch/s390/kernel/uv.c
@@ -0,0 +1,52 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Common Ultravisor functions and initialization
+ *
+ * Copyright IBM Corp. 2019, 2020
+ */
+#define KMSG_COMPONENT "prot_virt"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#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>
+
+/* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */
+#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
+int __bootdata_preserved(prot_virt_guest);
+#endif
+
+#if IS_ENABLED(CONFIG_KVM)
+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_warn("Protected virtualization not available in protected guests.");
+	}
+
+	if (prot_virt_host && !test_facility(158)) {
+		prot_virt_host = 0;
+		pr_warn("Protected virtualization not supported by the hardware.");
+	}
+
+	return rc;
+}
+early_param("prot_virt", prot_virt_setup);
+#endif