Use DIAG318 to set Control Program Name & Version Codes
Subsystems (4)
v6 cover Use DIAG318 to set Control Program Name & Version Codes
Changelog:
v6
- KVM disables diag318 get/set by default
- added new IOCTL to tell KVM to enable diag318
- removed VCPU event message in favor of VM_EVENT only
v5
- s/cpc/diag318_info in order to make the relevant data more clear
- removed mutex locks for diag318_info get/set
v4
- removed setup.c changes introduced in bullet 1 of v3
- kept diag318_info struct cleanup
- analogous QEMU patches:
https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg00164.html
v3
- kernel patch for diag 0x318 instruction call fixup [removed in v4]
- removed CPU model code
- cleaned up diag318_info struct
- cpnc is no longer unshadowed as it was not needed
- rebased on 5.1.0-rc3
This instruction call is executed once-and-only-once during Kernel setup. The availability of this instruction depends on Read Info byte 134, bit 0.
DIAG 318's functionality is also emulated by KVM, which means we can enable this feature for a guest even if the host kernel cannot support it. This feature is made available starting with the zEC12-full model (see analogous QEMU patches).
The diag318_info is composed of a Control Program Name Code (CPNC) and a Control Program Version Code (CPVC). These values are used for problem diagnosis and allows IBM to identify control program information by answering the following question:
"What environment is this guest running in?" (CPNC) "What are more details regarding the OS?" (CPVC)
In the future, we will implement the CPVC to convey more information about the OS. For now, we set this field to 0 until we come up with a solid plan.
Collin Walling (2):
s390/setup: diag318: refactor struct
s390/kvm: diagnose 318 handling
Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/diag.h | 6 +- arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kernel/setup.c | 3 +- arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 9 files changed, 154 insertions(+), 7 deletions(-)
Signature · 1 line
2.21.3
PATCH v6 1/2 s390/setup: diag318: refactor struct
The diag318 struct introduced in include/asm/diag.h can be reused in KVM, so let's condense the version code fields in the diag318_info struct for easier usage and simplify it until we can determine how the data should be formatted.
--- arch/s390/include/asm/diag.h | 6 ++---- arch/s390/kernel/setup.c | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-)
arch/s390/include/asm/diag.h +2 -4
@@ -298,10 +298,8 @@ struct diag26c_mac_resp {union diag318_info {unsigned long val;struct { -unsigned int cpnc :8 ; -unsigned int cpvc_linux :24 ; -unsigned char cpvc_distro[3 ]; -unsigned char zero; +unsigned long cpnc :8 ; +unsigned long cpvc :56 ; }; };
arch/s390/kernel/setup.c +1 -2
@@ -1028,8 +1028,7 @@ static void __init setup_control_program_code(void) {union diag318_info diag318_info = { .cpnc =CPNC_LINUX , - .cpvc_linux =0 , - .cpvc_distro = {0 }, + .cpvc =0 , };if (!sclp.has_diag318)
Signature · 1 line
2.21.3
PATCH v6 2/2 s390/kvm: diagnose 318 handling
In reply to Collin WallingDIAGNOSE 0x318 (diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.
This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)
Documentation/virt/kvm/devices/vm.rst +29 -0
@@ -314,3 +314,32 @@ Allows userspace to query the status of migration mode. if it is enabled :Returns: -EFAULT if the given address is not accessible from kernel space; 0 in case of success. + +6. GROUP: KVM_S390_VM_MISC +Architectures: s390 + + 6.1. KVM_S390_VM_MISC_ENABLE_DIAG318 + + Allows userspace to enable the DIAGNOSE 0x318 instruction call for a + guest OS. By default, KVM will not allow this instruction to be executed + by a guest, even if support is in place. Userspace must explicitly enable + the instruction handling for DIAGNOSE 0x318 via this call. + + Parameters: none + Returns: 0 after setting a flag telling KVM to enable this feature + + 6.2. KVM_S390_VM_MISC_DIAG318 (r/w) + + Allows userspace to retrieve and set the DIAGNOSE 0x318 information, + which consists of a 1-byte "Control Program Name Code" and a 7-byte + "Control Program Version Code" (a 64 bit value all in all). This + information is set by the guest (usually during IPL). This interface is + intended to allow retrieving and setting it during migration; while no + real harm is done if the information is changed outside of migration, + it is strongly discouraged. + + Parameters: address of a buffer in user space (u64), where the + information is read from or stored into + Returns: -EFAULT if the given address is not accessible from kernel space; + -EOPNOTSUPP if feature has not been requested to be enabled first; + 0 in case of success
arch/s390/include/asm/kvm_host.h +5 -1
@@ -260,7 +260,8 @@ struct kvm_s390_sie_block {__u32 scaol;/* 0x0064 */ __u8 sdf;/* 0x0068 */ __u8 epdx;/* 0x0069 */ -__u8 reserved6a[2 ];/* 0x006a */ +__u8 cpnc;/* 0x006a */ +__u8 reserved6b;/* 0x006b */ __u32 todpr;/* 0x006c */ #define GISA_FORMAT1 0x00000001__u32 gd;/* 0x0070 */
@@ -454,6 +455,7 @@ struct kvm_vcpu_stat {u64 diagnose_9c_ignored;u64 diagnose_258;u64 diagnose_308; +u64 diagnose_318;u64 diagnose_500;u64 diagnose_other; };
@@ -938,6 +940,7 @@ struct kvm_arch{int user_sigp;int user_stsi;int user_instr0; +int use_diag318;struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS ];wait_queue_head_t ipte_wq;int ipte_lock_count;
@@ -956,6 +959,7 @@ struct kvm_arch{DECLARE_BITMAP (idle_mask,KVM_MAX_VCPUS );struct kvm_s390_gisa_interrupt gisa_int;struct kvm_s390_pv pv; +union diag318_info diag318_info; };#define KVM_HVA_ERR_BAD (-1UL)
arch/s390/include/uapi/asm/kvm.h +5 -0
@@ -74,6 +74,7 @@ struct kvm_s390_io_adapter_req {#define KVM_S390_VM_CRYPTO 2#define KVM_S390_VM_CPU_MODEL 3#define KVM_S390_VM_MIGRATION 4 +#define KVM_S390_VM_MISC 5/* kvm attributes for mem_ctrl */ #define KVM_S390_VM_MEM_ENABLE_CMMA 0
@@ -171,6 +172,10 @@ struct kvm_s390_vm_cpu_subfunc {#define KVM_S390_VM_MIGRATION_START 1#define KVM_S390_VM_MIGRATION_STATUS 2 +/* kvm attributes for KVM_S390_VM_MISC */ +#define KVM_S390_VM_MISC_ENABLE_DIAG318 0 +#define KVM_S390_VM_MISC_DIAG318 1 +/* for KVM_GET_REGS and KVM_SET_REGS */ struct kvm_regs {/* general purpose regs for s390 */
arch/s390/kvm/diag.c +20 -0
@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; } +static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318) +return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc); + +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;
@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);default :
arch/s390/kvm/kvm-s390.c +89 -0
125 lines not on this page · raw message
arch/s390/kvm/kvm-s390.h +1 -0
@@ -326,6 +326,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);int kvm_s390_handle_sigp_pei (struct kvm_vcpu *vcpu);/* implemented in kvm-s390.c */ +void kvm_s390_set_diag318_info (struct kvm *kvm,u64 info);void kvm_s390_set_tod_clock (struct kvm *kvm,const struct kvm_s390_vm_tod_clock *gtod);long kvm_arch_fault_in_page (struct kvm_vcpu *vcpu,gpa_t gpa,int writable);
arch/s390/kvm/vsie.c +2 -0
@@ -548,6 +548,8 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) scb_s->ecd |= scb_o->ecd &ECD_ETOKENF ; scb_s->hpid =HPID_VSIE ; +if (sclp.has_diag318) + scb_s->cpnc = scb_o->cpnc;prepare_ibc (vcpu, vsie_page); rc =shadow_crycb (vcpu, vsie_page);
Signature · 1 line
2.21.3
kbuild test robot
build botRe: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
Thank you for the patch! Perhaps something to improve:
Hi Collin,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on kvms390/next]
[also build test WARNING on s390/features v5.7-rc5]
[cannot apply to kvm/linux-next next-20200512]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Collin-Walling/Use-DIAG318-to-set-Control-Program-Name-Version-Codes/20200514-061856 base: https://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git next config: s390-allyesconfig (attached as .config) compiler: s390-linux-gcc (GCC) 9.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day GCC_VERSION=9.3.0 make.cross ARCH=s390
If you fix the issue, kindly add following tag as appropriate
All warnings (new ones prefixed by >>):
In file included from arch/s390/include/asm/kvm_host.h:22, from include/linux/kvm_host.h:36,
from arch/s390/kvm/kvm-s390.c:23:arch/s390/kvm/kvm-s390.c: In function 'kvm_s390_set_diag318_info':
>> arch/s390/kvm/kvm-s390.c:1253:19: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 5 has type 'long unsigned int:56' [-Wformat=] 1253 | VM_EVENT(kvm, 3, "SET: CPNC: 0x%x CPVC: 0x%llx", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1254 | kvm->arch.diag318_info.cpnc, kvm->arch.diag318_info.cpvc); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | long unsigned int:56 arch/s390/include/asm/debug.h:247:12: note: in definition of macro 'debug_sprintf_event' 247 | _fmt, ## __VA_ARGS__); | ^~~~ >> arch/s390/kvm/kvm-s390.c:1253:2: note: in expansion of macro 'VM_EVENT'
1253 | VM_EVENT(kvm, 3, "SET: CPNC: 0x%x CPVC: 0x%llx",
| ^~~~~~~~arch/s390/kvm/kvm-s390.c:1253:47: note: format string is defined here 1253 | VM_EVENT(kvm, 3, "SET: CPNC: 0x%x CPVC: 0x%llx",
| ~~~^ | | | long long unsigned int
vim +1253 arch/s390/kvm/kvm-s390.c
1245
1246 void kvm_s390_set_diag318_info(struct kvm *kvm, u64 info)
1247 {
1248 struct kvm_vcpu *vcpu;
1249 int i;
1250
1251 kvm->arch.diag318_info.val = info;
1252
> 1253 VM_EVENT(kvm, 3, "SET: CPNC: 0x%x CPVC: 0x%llx",
1254 kvm->arch.diag318_info.cpnc, kvm->arch.diag318_info.cpvc);
1255
1256 if (sclp.has_diag318) {
1257 kvm_for_each_vcpu(i, vcpu, kvm) {
1258 vcpu->arch.sie_block->cpnc = kvm->arch.diag318_info.cpnc;
1259 }
1260 }
1261 }
1262
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
Re: [PATCH v6 1/2] s390/setup: diag318: refactor struct
In reply to Collin WallingQuoted 5 lines · Collin Walling
The diag318 struct introduced in
include/asm/diag.hcan be reused in KVM, so let's condense the version code fields in thediag318_infostruct for easier usage and simplify it until we can determine how the data should be formatted.
Quoted 7 lines
Signed-off-by Collin Walling <[email protected]>Reviewed-by David Hildenbrand <[email protected]>Reviewed-by Cornelia Huck <[email protected]>--- arch/s390/include/asm/diag.h | 6 ++---- arch/s390/kernel/setup.c | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-)
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
In reply to Collin WallingQuoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)
[...]
Quoted 30 lines
arch/s390/kvm/diag.c +18
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; } +static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318) +return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc); + +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;
arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);
I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use KVM_S390_VM_MISC_ENABLE_DIAG318 if the guest just executed the diag 318 instruction.
And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
Quoted 34 lines
arch/s390/kvm/diag.c +0
-0default :arch/s390/kvm/kvm-s390.c +18
-0@@ -159,6 +159,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "diag_9c_ignored", VCPU_STAT(diagnose_9c_ignored) }, { "instruction_diag_258", VCPU_STAT(diagnose_258) }, { "instruction_diag_308", VCPU_STAT(diagnose_308) }, + { "instruction_diag_318", VCPU_STAT(diagnose_318) }, { "instruction_diag_500", VCPU_STAT(diagnose_500) }, { "instruction_diag_other", VCPU_STAT(diagnose_other) }, { NULL }@@ -1243,6 +1244,76 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr)return ret; } +void kvm_s390_set_diag318_info (struct kvm *kvm,u64 info) +{ +struct kvm_vcpu *vcpu; +int i; + + kvm->arch.diag318_info.val = info; + +VM_EVENT (kvm,3 ,"SET: CPNC: 0x%x CPVC: 0x%llx" , + kvm->arch.diag318_info.cpnc, kvm->arch.diag318_info.cpvc); + +if (sclp.has_diag318) { +kvm_for_each_vcpu (i, vcpu, kvm) { + vcpu->arch.sie_block->cpnc = kvm->arch.diag318_info.cpnc; + } + } +} +
arch/s390/kvm/kvm-s390.c static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) · line 1273
Quoted 10 lines
arch/s390/kvm/kvm-s390.c +10
-0+static int kvm_s390_vm_set_misc (struct kvm *kvm,struct kvm_device_attr *attr) +{ +int ret; +u64 diag318_info; + +switch (attr->attr) { +case KVM_S390_VM_MISC_ENABLE_DIAG318 : + kvm->arch.use_diag318 =1 ; + ret =0 ; +break ;
Would it make sense to set kvm->arch.use_diag318 = 1 during the first execution of KVM_S390_VM_MISC_DIAG318 instead, so that we could get along without the KVM_S390_VM_MISC_ENABLE_DIAG318 ?
Quoted 5 lines
arch/s390/kvm/kvm-s390.c +5
-0+case KVM_S390_VM_MISC_DIAG318 : + ret = -EFAULT ; +if (!kvm->arch.use_diag318) +return -EOPNOTSUPP ; +if (get_user (diag318_info, (u64 __user *)attr->addr))
arch/s390/kvm/kvm-s390.c static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) · line 1288
Quoted 10 lines
arch/s390/kvm/kvm-s390.c +10
-0+break ; +kvm_s390_set_diag318_info (kvm, diag318_info); + ret =0 ; +break ; +default : + ret = -ENXIO ; +break ; + } +return ret; +}
What about a reset of the guest VM? If a user first boots into a Linux kernel that supports diag 318, then reboots and selects a Linux kernel that does not support diag 318? I'd expect that the cpnc / cpnv values need to be cleared here somewhere? Otherwise the information might not be accurate anymore?
Thomas
Re: [PATCH v6 1/2] s390/setup: diag318: refactor struct
In reply to Collin WallingQuoted 8 lines · Collin Walling
The diag318 struct introduced in
include/asm/diag.hcan be reused in KVM, so let's condense the version code fields in thediag318_infostruct for easier usage and simplify it until we can determine how the data should be formatted.Signed-off-by Collin Walling <[email protected]>Reviewed-by David Hildenbrand <[email protected]>Reviewed-by Cornelia Huck <[email protected]>
Quoted 37 lines
--- arch/s390/include/asm/diag.h | 6 ++---- arch/s390/kernel/setup.c | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-)arch/s390/include/asm/diag.h +2
-4@@ -298,10 +298,8 @@ struct diag26c_mac_resp {union diag318_info {unsigned long val;struct { -unsigned int cpnc :8 ; -unsigned int cpvc_linux :24 ; -unsigned char cpvc_distro[3 ]; -unsigned char zero; +unsigned long cpnc :8 ; +unsigned long cpvc :56 ; }; };arch/s390/kernel/setup.c +1
-2@@ -1028,8 +1028,7 @@ static void __init setup_control_program_code(void) {union diag318_info diag318_info = { .cpnc =CPNC_LINUX , - .cpvc_linux =0 , - .cpvc_distro = {0 }, + .cpvc =0 , };if (!sclp.has_diag318)
Janosch Frank
maintainerRe: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
In reply to Thomas HuthQuoted 117 lines · Thomas Huth
Quoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)[...]
Quoted 30 lines
arch/s390/kvm/diag.c +18
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; } +static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318) +return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc); + +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use
KVM_S390_VM_MISC_ENABLE_DIAG318if the guest just executed the diag 318 instruction.And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
Quoted 40 lines
arch/s390/kvm/diag.c +0
-0default :arch/s390/kvm/kvm-s390.c +24
-0@@ -159,6 +159,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "diag_9c_ignored", VCPU_STAT(diagnose_9c_ignored) }, { "instruction_diag_258", VCPU_STAT(diagnose_258) }, { "instruction_diag_308", VCPU_STAT(diagnose_308) }, + { "instruction_diag_318", VCPU_STAT(diagnose_318) }, { "instruction_diag_500", VCPU_STAT(diagnose_500) }, { "instruction_diag_other", VCPU_STAT(diagnose_other) }, { NULL }@@ -1243,6 +1244,76 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr)return ret; } +void kvm_s390_set_diag318_info (struct kvm *kvm,u64 info) +{ +struct kvm_vcpu *vcpu; +int i; + + kvm->arch.diag318_info.val = info; + +VM_EVENT (kvm,3 ,"SET: CPNC: 0x%x CPVC: 0x%llx" , + kvm->arch.diag318_info.cpnc, kvm->arch.diag318_info.cpvc); + +if (sclp.has_diag318) { +kvm_for_each_vcpu (i, vcpu, kvm) { + vcpu->arch.sie_block->cpnc = kvm->arch.diag318_info.cpnc; + } + } +} + +static int kvm_s390_vm_set_misc (struct kvm *kvm,struct kvm_device_attr *attr) +{ +int ret; +u64 diag318_info; + +switch (attr->attr) {
Quoted 8 lines
arch/s390/kvm/kvm-s390.c static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) · line 1273
Quoted 4 lines
arch/s390/kvm/kvm-s390.c +4
-0+case KVM_S390_VM_MISC_ENABLE_DIAG318 : + kvm->arch.use_diag318 =1 ; + ret =0 ; +break ;Would it make sense to set
kvm->arch.use_diag318= 1 during the first execution ofKVM_S390_VM_MISC_DIAG318instead, so that we could get along without theKVM_S390_VM_MISC_ENABLE_DIAG318?
I'm not an expert in feature negotiation, but why isn't this a cpu feature like sief2 instead of a attribute?
@David?
Quoted 14 lines
Quoted 14 lines
arch/s390/kvm/kvm-s390.c +13
-0+case KVM_S390_VM_MISC_DIAG318 : + ret = -EFAULT ; +if (!kvm->arch.use_diag318) +return -EOPNOTSUPP ; +if (get_user (diag318_info, (u64 __user *)attr->addr)) +break ; +kvm_s390_set_diag318_info (kvm, diag318_info); + ret =0 ; +break ; +default : + ret = -ENXIO ; +break ; + }
Quoted 8 lines
arch/s390/kvm/kvm-s390.c static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) · line 1288
Quoted 2 lines
arch/s390/kvm/kvm-s390.c +2
-0+return ret; +}What about a reset of the guest VM? If a user first boots into a Linux kernel that supports diag 318, then reboots and selects a Linux kernel that does not support diag 318? I'd expect that the cpnc / cpnv values need to be cleared here somewhere? Otherwise the information might not be accurate anymore?
He resets via QEMU on a machine reset.
Quoted 3 lines
Thomas
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
In reply to Collin WallingQuoted 33 lines · On Wed, 13 May 2020 18:15:57 -0400 Collin Walling <[email protected]> wrote:
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)Documentation/virt/kvm/devices/vm.rst +0
-0
Documentation/virt/kvm/devices/vm.rst Allows userspace to query the status of migration mode. · line 318
Quoted 5 lines
Documentation/virt/kvm/devices/vm.rst +2
-0@@ -314,3 +314,32 @@ Allows userspace to query the status of migration mode. if it is enabled :Returns: -EFAULT if the given address is not accessible from kernel space; 0 in case of success. + +6. GROUP: KVM_S390_VM_MISC
This needs to be rstyfied, matching the remainder of the file.
Quoted 11 lines
Documentation/virt/kvm/devices/vm.rst +11
-0+Architectures: s390 + + 6.1. KVM_S390_VM_MISC_ENABLE_DIAG318 + + Allows userspace to enable the DIAGNOSE 0x318 instruction call for a + guest OS. By default, KVM will not allow this instruction to be executed + by a guest, even if support is in place. Userspace must explicitly enable + the instruction handling for DIAGNOSE 0x318 via this call. + + Parameters: none + Returns: 0 after setting a flag telling KVM to enable this feature
Documentation/virt/kvm/devices/vm.rst Allows userspace to query the status of migration mode. · line 339
Quoted 10 lines
Documentation/virt/kvm/devices/vm.rst +10
-0+ + 6.2. KVM_S390_VM_MISC_DIAG318 (r/w) + + Allows userspace to retrieve and set the DIAGNOSE 0x318 information, + which consists of a 1-byte "Control Program Name Code" and a 7-byte + "Control Program Version Code" (a 64 bit value all in all). This + information is set by the guest (usually during IPL). This interface is + intended to allow retrieving and setting it during migration; while no + real harm is done if the information is changed outside of migration, + it is strongly discouraged.
(Sorry if we discussed that already, but that was some time ago and the info has dropped out of my cache...)
Had we considered doing this in userspace only? If QEMU wanted to emulate diag 318 in tcg, it would basically need to mirror what KVM does; diag 318 does not seem like something where we want to optimize for performance, so dropping to userspace seems feasible? We'd just need an interface for userspace to forward anything set by the guest.
Quoted 6 lines
Documentation/virt/kvm/devices/vm.rst +6
-0+ + Parameters: address of a buffer in user space (u64), where the + information is read from or stored into + Returns: -EFAULT if the given address is not accessible from kernel space; + -EOPNOTSUPP if feature has not been requested to be enabled first; + 0 in case of success
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
In reply to Janosch FrankQuoted 127 lines · Janosch Frank
Quoted 117 lines · Thomas Huth
Quoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)[...]
Quoted 30 lines
arch/s390/kvm/diag.c +18
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; } +static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318) +return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc); + +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use
KVM_S390_VM_MISC_ENABLE_DIAG318if the guest just executed the diag 318 instruction.And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
Quoted 40 lines
arch/s390/kvm/diag.c +0
-0default :arch/s390/kvm/kvm-s390.c +24
-0@@ -159,6 +159,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "diag_9c_ignored", VCPU_STAT(diagnose_9c_ignored) }, { "instruction_diag_258", VCPU_STAT(diagnose_258) }, { "instruction_diag_308", VCPU_STAT(diagnose_308) }, + { "instruction_diag_318", VCPU_STAT(diagnose_318) }, { "instruction_diag_500", VCPU_STAT(diagnose_500) }, { "instruction_diag_other", VCPU_STAT(diagnose_other) }, { NULL }@@ -1243,6 +1244,76 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr)return ret; } +void kvm_s390_set_diag318_info (struct kvm *kvm,u64 info) +{ +struct kvm_vcpu *vcpu; +int i; + + kvm->arch.diag318_info.val = info; + +VM_EVENT (kvm,3 ,"SET: CPNC: 0x%x CPVC: 0x%llx" , + kvm->arch.diag318_info.cpnc, kvm->arch.diag318_info.cpvc); + +if (sclp.has_diag318) { +kvm_for_each_vcpu (i, vcpu, kvm) { + vcpu->arch.sie_block->cpnc = kvm->arch.diag318_info.cpnc; + } + } +} + +static int kvm_s390_vm_set_misc (struct kvm *kvm,struct kvm_device_attr *attr) +{ +int ret; +u64 diag318_info; + +switch (attr->attr) {Quoted 8 lines
arch/s390/kvm/kvm-s390.c static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) · line 1273
Quoted 4 lines
arch/s390/kvm/kvm-s390.c +4
-0+case KVM_S390_VM_MISC_ENABLE_DIAG318 : + kvm->arch.use_diag318 =1 ; + ret =0 ; +break ;Would it make sense to set
kvm->arch.use_diag318= 1 during the first execution ofKVM_S390_VM_MISC_DIAG318instead, so that we could get along without theKVM_S390_VM_MISC_ENABLE_DIAG318?
Quoted 4 lines
I'm not an expert in feature negotiation, but why isn't this a cpu feature like sief2 instead of a attribute?
@David?
In the end you want to have it somehow in the CPU model I guess. You cannot glue it to QEMU machines, because availability depends on HW+KVM support.
How does the guest detect that it can use diag318? I assume/hope via a a STFLE feature.
Signature · 3 lines
Thanks, David / dhildenb
Janosch Frank
maintainerRe: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
Quoted 131 lines · David Hildenbrand
Quoted 130 lines · Janosch Frank
Quoted 117 lines · Thomas Huth
Quoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)[...]
Quoted 30 lines
arch/s390/kvm/diag.c +18
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; } +static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318) +return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc); + +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use
KVM_S390_VM_MISC_ENABLE_DIAG318if the guest just executed the diag 318 instruction.And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
Quoted 40 lines
arch/s390/kvm/diag.c +0
-0default :arch/s390/kvm/kvm-s390.c +24
-0@@ -159,6 +159,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "diag_9c_ignored", VCPU_STAT(diagnose_9c_ignored) }, { "instruction_diag_258", VCPU_STAT(diagnose_258) }, { "instruction_diag_308", VCPU_STAT(diagnose_308) }, + { "instruction_diag_318", VCPU_STAT(diagnose_318) }, { "instruction_diag_500", VCPU_STAT(diagnose_500) }, { "instruction_diag_other", VCPU_STAT(diagnose_other) }, { NULL }@@ -1243,6 +1244,76 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr)return ret; } +void kvm_s390_set_diag318_info (struct kvm *kvm,u64 info) +{ +struct kvm_vcpu *vcpu; +int i; + + kvm->arch.diag318_info.val = info; + +VM_EVENT (kvm,3 ,"SET: CPNC: 0x%x CPVC: 0x%llx" , + kvm->arch.diag318_info.cpnc, kvm->arch.diag318_info.cpvc); + +if (sclp.has_diag318) { +kvm_for_each_vcpu (i, vcpu, kvm) { + vcpu->arch.sie_block->cpnc = kvm->arch.diag318_info.cpnc; + } + } +} + +static int kvm_s390_vm_set_misc (struct kvm *kvm,struct kvm_device_attr *attr) +{ +int ret; +u64 diag318_info; + +switch (attr->attr) {Quoted 8 lines
arch/s390/kvm/kvm-s390.c static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) · line 1273
Quoted 4 lines
arch/s390/kvm/kvm-s390.c +4
-0+case KVM_S390_VM_MISC_ENABLE_DIAG318 : + kvm->arch.use_diag318 =1 ; + ret =0 ; +break ;Would it make sense to set
kvm->arch.use_diag318= 1 during the first execution ofKVM_S390_VM_MISC_DIAG318instead, so that we could get along without theKVM_S390_VM_MISC_ENABLE_DIAG318?I'm not an expert in feature negotiation, but why isn't this a cpu feature like sief2 instead of a attribute?
Quoted 9 lines
Quoted 1 line
@David?
In the end you want to have it somehow in the CPU model I guess. You cannot glue it to QEMU machines, because availability depends on HW+KVM support.
How does the guest detect that it can use diag318? I assume/hope via a a STFLE feature.
SCLP
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
Quoted 134 lines · Janosch Frank
Quoted 133 lines · David Hildenbrand
Quoted 131 lines · Janosch Frank
Quoted 117 lines · Thomas Huth
Quoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)[...]
Quoted 30 lines
arch/s390/kvm/diag.c +18
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; } +static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318) +return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc); + +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use
KVM_S390_VM_MISC_ENABLE_DIAG318if the guest just executed the diag 318 instruction.And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
Quoted 40 lines
arch/s390/kvm/diag.c +0
-0default :arch/s390/kvm/kvm-s390.c +24
-0@@ -159,6 +159,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "diag_9c_ignored", VCPU_STAT(diagnose_9c_ignored) }, { "instruction_diag_258", VCPU_STAT(diagnose_258) }, { "instruction_diag_308", VCPU_STAT(diagnose_308) }, + { "instruction_diag_318", VCPU_STAT(diagnose_318) }, { "instruction_diag_500", VCPU_STAT(diagnose_500) }, { "instruction_diag_other", VCPU_STAT(diagnose_other) }, { NULL }@@ -1243,6 +1244,76 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr)return ret; } +void kvm_s390_set_diag318_info (struct kvm *kvm,u64 info) +{ +struct kvm_vcpu *vcpu; +int i; + + kvm->arch.diag318_info.val = info; + +VM_EVENT (kvm,3 ,"SET: CPNC: 0x%x CPVC: 0x%llx" , + kvm->arch.diag318_info.cpnc, kvm->arch.diag318_info.cpvc); + +if (sclp.has_diag318) { +kvm_for_each_vcpu (i, vcpu, kvm) { + vcpu->arch.sie_block->cpnc = kvm->arch.diag318_info.cpnc; + } + } +} + +static int kvm_s390_vm_set_misc (struct kvm *kvm,struct kvm_device_attr *attr) +{ +int ret; +u64 diag318_info; + +switch (attr->attr) {Quoted 8 lines
arch/s390/kvm/kvm-s390.c static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) · line 1273
Quoted 4 lines
arch/s390/kvm/kvm-s390.c +4
-0+case KVM_S390_VM_MISC_ENABLE_DIAG318 : + kvm->arch.use_diag318 =1 ; + ret =0 ; +break ;Would it make sense to set
kvm->arch.use_diag318= 1 during the first execution ofKVM_S390_VM_MISC_DIAG318instead, so that we could get along without theKVM_S390_VM_MISC_ENABLE_DIAG318?I'm not an expert in feature negotiation, but why isn't this a cpu feature like sief2 instead of a attribute?
@David?
Quoted 8 lines
Quoted 7 lines
In the end you want to have it somehow in the CPU model I guess. You cannot glue it to QEMU machines, because availability depends on HW+KVM support.
How does the guest detect that it can use diag318? I assume/hope via a a STFLE feature.
SCLP
Okay, so just another feature flag, which implies it belongs into the CPU model. How we communicate support from kvm to QEMU can be done via features, bot also via attributes. Important part is that we can sense/enable/disable.
Signature · 3 lines
Thanks, David / dhildenb
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
In reply to Cornelia HuckQuoted 69 lines · Cornelia Huck
Quoted 33 lines · On Wed, 13 May 2020 18:15:57 -0400 Collin Walling <[email protected]> wrote:
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)Documentation/virt/kvm/devices/vm.rst +0
-0Documentation/virt/kvm/devices/vm.rst Allows userspace to query the status of migration mode. · line 318
Quoted 5 lines
Documentation/virt/kvm/devices/vm.rst +2
-0@@ -314,3 +314,32 @@ Allows userspace to query the status of migration mode. if it is enabled :Returns: -EFAULT if the given address is not accessible from kernel space; 0 in case of success. + +6. GROUP: KVM_S390_VM_MISCThis needs to be rstyfied, matching the remainder of the file.
Quoted 11 lines
Documentation/virt/kvm/devices/vm.rst +11
-0+Architectures: s390 + + 6.1. KVM_S390_VM_MISC_ENABLE_DIAG318 + + Allows userspace to enable the DIAGNOSE 0x318 instruction call for a + guest OS. By default, KVM will not allow this instruction to be executed + by a guest, even if support is in place. Userspace must explicitly enable + the instruction handling for DIAGNOSE 0x318 via this call. + + Parameters: none + Returns: 0 after setting a flag telling KVM to enable this featureDocumentation/virt/kvm/devices/vm.rst Allows userspace to query the status of migration mode. · line 339
Quoted 10 lines
Documentation/virt/kvm/devices/vm.rst +10
-0+ + 6.2. KVM_S390_VM_MISC_DIAG318 (r/w) + + Allows userspace to retrieve and set the DIAGNOSE 0x318 information, + which consists of a 1-byte "Control Program Name Code" and a 7-byte + "Control Program Version Code" (a 64 bit value all in all). This + information is set by the guest (usually during IPL). This interface is + intended to allow retrieving and setting it during migration; while no + real harm is done if the information is changed outside of migration, + it is strongly discouraged.(Sorry if we discussed that already, but that was some time ago and the info has dropped out of my cache...)
Quoted 6 lines
Had we considered doing this in userspace only? If QEMU wanted to emulate diag 318 in tcg, it would basically need to mirror what KVM does; diag 318 does not seem like something where we want to optimize for performance, so dropping to userspace seems feasible? We'd just need an interface for userspace to forward anything set by the guest.
My reservation with respect to handling this in userspace only is that the data set by the instruction call is relevant to both host-level and guest-level kernels. That data is set during kernel setup.
Right now, the instruction call is used to set a hard-coded "name code" value, but later we want to use this instruction to also set some sort of unique version code. The format of the version code is not yet determined.
If guest support is handled in userspace only, then we'll have to update the version codes in both the Linux kernel /and/ QEMU, which might be a bit messy if things go out of sync.
Quoted 7 lines
Quoted 6 lines
Documentation/virt/kvm/devices/vm.rst +6
-0+ + Parameters: address of a buffer in user space (u64), where the + information is read from or stored into + Returns: -EFAULT if the given address is not accessible from kernel space; + -EOPNOTSUPP if feature has not been requested to be enabled first; + 0 in case of success
Signature · 5 lines
-- Regards, Collin Stay safe and stay healthy
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
Quoted 81 lines · Collin Walling
Quoted 69 lines · Cornelia Huck
Quoted 33 lines · On Wed, 13 May 2020 18:15:57 -0400 Collin Walling <[email protected]> wrote:
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)Documentation/virt/kvm/devices/vm.rst +0
-0Documentation/virt/kvm/devices/vm.rst Allows userspace to query the status of migration mode. · line 318
Quoted 5 lines
Documentation/virt/kvm/devices/vm.rst +2
-0@@ -314,3 +314,32 @@ Allows userspace to query the status of migration mode. if it is enabled :Returns: -EFAULT if the given address is not accessible from kernel space; 0 in case of success. + +6. GROUP: KVM_S390_VM_MISCThis needs to be rstyfied, matching the remainder of the file.
Quoted 11 lines
Documentation/virt/kvm/devices/vm.rst +11
-0+Architectures: s390 + + 6.1. KVM_S390_VM_MISC_ENABLE_DIAG318 + + Allows userspace to enable the DIAGNOSE 0x318 instruction call for a + guest OS. By default, KVM will not allow this instruction to be executed + by a guest, even if support is in place. Userspace must explicitly enable + the instruction handling for DIAGNOSE 0x318 via this call. + + Parameters: none + Returns: 0 after setting a flag telling KVM to enable this featureDocumentation/virt/kvm/devices/vm.rst Allows userspace to query the status of migration mode. · line 339
Quoted 10 lines
Documentation/virt/kvm/devices/vm.rst +10
-0+ + 6.2. KVM_S390_VM_MISC_DIAG318 (r/w) + + Allows userspace to retrieve and set the DIAGNOSE 0x318 information, + which consists of a 1-byte "Control Program Name Code" and a 7-byte + "Control Program Version Code" (a 64 bit value all in all). This + information is set by the guest (usually during IPL). This interface is + intended to allow retrieving and setting it during migration; while no + real harm is done if the information is changed outside of migration, + it is strongly discouraged.(Sorry if we discussed that already, but that was some time ago and the info has dropped out of my cache...)
Quoted 6 lines
Had we considered doing this in userspace only? If QEMU wanted to emulate diag 318 in tcg, it would basically need to mirror what KVM does; diag 318 does not seem like something where we want to optimize for performance, so dropping to userspace seems feasible? We'd just need an interface for userspace to forward anything set by the guest.
My reservation with respect to handling this in userspace only is that the data set by the instruction call is relevant to both host-level and guest-level kernels. That data is set during kernel setup.
Quoted 9 lines
Right now, the instruction call is used to set a hard-coded "name code" value, but later we want to use this instruction to also set some sort of unique version code. The format of the version code is not yet determined.
If guest support is handled in userspace only, then we'll have to update the version codes in both the Linux kernel /and/ QEMU, which might be a bit messy if things go out of sync.
In an attempt to clear up some fogginess with respect to "what" the version code may entail, we're thinking of some sort of 7-byte combination that denotes both the kernel version and a value that denotes the distro + release. We're not 100% solid on exactly what that format will look like just yet, but all of the discussions have revolved around that theme.
Quoted 9 lines
Quoted 7 lines
Quoted 6 lines
Documentation/virt/kvm/devices/vm.rst +6
-0+ + Parameters: address of a buffer in user space (u64), where the + information is read from or stored into + Returns: -EFAULT if the given address is not accessible from kernel space; + -EOPNOTSUPP if feature has not been requested to be enabled first; + 0 in case of success
Signature · 5 lines
-- Regards, Collin Stay safe and stay healthy
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
In reply to David HildenbrandQuoted 41 lines · David Hildenbrand
Quoted 40 lines · Janosch Frank
Quoted 39 lines · David Hildenbrand
Quoted 38 lines · Janosch Frank
Quoted 37 lines · Thomas Huth
Quoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)[...]
Quoted 8 lines
arch/s390/kvm/diag.c +0
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; }
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
arch/s390/kvm/diag.c +6
-0+static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
arch/s390/kvm/diag.c static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) · line 269
Quoted 8 lines
arch/s390/kvm/diag.c +8
-0+return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc);
Errr.. thought I dropped this message. We favored just using the VM_EVENT from last time.
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 8 lines
arch/s390/kvm/diag.c +4
-0+ +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use
KVM_S390_VM_MISC_ENABLE_DIAG318if the guest just executed the diag 318 instruction.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
Pardon my ignorance, but I do not think I fully understand what exactly should be dropped in favor of doing things in userspace.
My assumption: if a diag handler is not found in KVM, then we fallthrough to userspace handling?
Quoted 42 lines
Quoted 42 lines
Quoted 42 lines
Quoted 42 lines
Quoted 42 lines
Quoted 42 lines
arch/s390/kvm/diag.c +0
-0default :arch/s390/kvm/kvm-s390.c +25
-0@@ -159,6 +159,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "diag_9c_ignored", VCPU_STAT(diagnose_9c_ignored) }, { "instruction_diag_258", VCPU_STAT(diagnose_258) }, { "instruction_diag_308", VCPU_STAT(diagnose_308) }, + { "instruction_diag_318", VCPU_STAT(diagnose_318) }, { "instruction_diag_500", VCPU_STAT(diagnose_500) }, { "instruction_diag_other", VCPU_STAT(diagnose_other) }, { NULL }@@ -1243,6 +1244,76 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr)return ret; } +void kvm_s390_set_diag318_info (struct kvm *kvm,u64 info) +{ +struct kvm_vcpu *vcpu; +int i; + + kvm->arch.diag318_info.val = info; + +VM_EVENT (kvm,3 ,"SET: CPNC: 0x%x CPVC: 0x%llx" , + kvm->arch.diag318_info.cpnc, kvm->arch.diag318_info.cpvc); + +if (sclp.has_diag318) { +kvm_for_each_vcpu (i, vcpu, kvm) { + vcpu->arch.sie_block->cpnc = kvm->arch.diag318_info.cpnc; + } + } +} + +static int kvm_s390_vm_set_misc (struct kvm *kvm,struct kvm_device_attr *attr) +{ +int ret; +u64 diag318_info; + +switch (attr->attr) { +case KVM_S390_VM_MISC_ENABLE_DIAG318 :
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
arch/s390/kvm/kvm-s390.c static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) · line 1273
Quoted 3 lines
arch/s390/kvm/kvm-s390.c +3
-0+ kvm->arch.use_diag318 =1 ; + ret =0 ; +break ;Would it make sense to set
kvm->arch.use_diag318= 1 during the first execution ofKVM_S390_VM_MISC_DIAG318instead, so that we could get along without theKVM_S390_VM_MISC_ENABLE_DIAG318?
Hmmm... is your thought set the flag in the diag handler in KVM? That way the get/set functions are only enabled if the instruction was actually called? I like that, actually. I think that makes more sense.
Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
Quoted 4 lines
I'm not an expert in feature negotiation, but why isn't this a cpu feature like sief2 instead of a attribute?
@David?
In the end you want to have it somehow in the CPU model I guess. You cannot glue it to QEMU machines, because availability depends on HW+KVM support.
How does the guest detect that it can use diag318? I assume/hope via a a STFLE feature.
Quoted 8 lines
Quoted 1 line
SCLP
Okay, so just another feature flag, which implies it belongs into the CPU model. How we communicate support from kvm to QEMU can be done via features, bot also via attributes. Important part is that we can sense/enable/disable.
Right. KVM for instruction handling and for get/setting (setting also handles setting the name code in the SIE block), and QEMU for migration / resetting.
There are a lot of moving parts for a simple 8-byte string of data, but its very useful for giving us more information regarding the OS during firmware / service events.
Signature · 5 lines
-- Regards, Collin Stay safe and stay healthy
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
Quoted 83 lines · Collin Walling
Quoted 41 lines · David Hildenbrand
Quoted 40 lines · Janosch Frank
Quoted 39 lines · David Hildenbrand
Quoted 38 lines · Janosch Frank
Quoted 37 lines · Thomas Huth
Quoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)[...]
Quoted 8 lines
arch/s390/kvm/diag.c +0
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; }Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
arch/s390/kvm/diag.c +6
-0+static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
arch/s390/kvm/diag.c static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) · line 269
Quoted 8 lines
arch/s390/kvm/diag.c +8
-0+return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc);Errr.. thought I dropped this message. We favored just using the
VM_EVENTfrom last time.Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 8 lines
arch/s390/kvm/diag.c +4
-0+ +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use
KVM_S390_VM_MISC_ENABLE_DIAG318if the guest just executed the diag 318 instruction.
Quoted 8 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
Pardon my ignorance, but I do not think I fully understand what exactly should be dropped in favor of doing things in userspace.
My assumption: if a diag handler is not found in KVM, then we fallthrough to userspace handling?
Right, if you simply omit this change to diag.c, the default case returns -EOPNOTSUPP which then should cause an exit to userspace. You can then add the code in QEMU to handle_diag() in target/s390x/kvm.c instead.
Thomas
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
In reply to Janosch FrankQuoted 77 lines · Janosch Frank
Quoted 76 lines · Thomas Huth
Quoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)[...]
Quoted 30 lines
arch/s390/kvm/diag.c +18
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; } +static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318) +return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc); + +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use
KVM_S390_VM_MISC_ENABLE_DIAG318if the guest just executed the diag 318 instruction.And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
[...]
Quoted 7 lines
Quoted 5 lines
What about a reset of the guest VM? If a user first boots into a Linux kernel that supports diag 318, then reboots and selects a Linux kernel that does not support diag 318? I'd expect that the cpnc / cpnv values need to be cleared here somewhere? Otherwise the information might not be accurate anymore?
He resets via QEMU on a machine reset.
Ah, thanks for the pointer, makes sense! ... and actually, I think that is another indication that QEMU should rather be in control, thus the kernel code should drop to userspace instead of handling the diag 318 call in diag.c in the kernel above.
Thomas
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
In reply to Thomas HuthQuoted 93 lines · Thomas Huth
Quoted 83 lines · Collin Walling
Quoted 41 lines · David Hildenbrand
Quoted 40 lines · Janosch Frank
Quoted 39 lines · David Hildenbrand
Quoted 38 lines · Janosch Frank
Quoted 37 lines · Thomas Huth
Quoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)[...]
Quoted 8 lines
arch/s390/kvm/diag.c +0
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; }Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
arch/s390/kvm/diag.c +6
-0+static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
arch/s390/kvm/diag.c static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) · line 269
Quoted 8 lines
arch/s390/kvm/diag.c +8
-0+return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc);Errr.. thought I dropped this message. We favored just using the
VM_EVENTfrom last time.Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 8 lines
arch/s390/kvm/diag.c +4
-0+ +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use
KVM_S390_VM_MISC_ENABLE_DIAG318if the guest just executed the diag 318 instruction.Quoted 8 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
Pardon my ignorance, but I do not think I fully understand what exactly should be dropped in favor of doing things in userspace.
My assumption: if a diag handler is not found in KVM, then we fallthrough to userspace handling?
Quoted 7 lines
Right, if you simply omit this change to
diag.c, the default case returns-EOPNOTSUPPwhich then should cause an exit to userspace. You can then add the code in QEMU tohandle_diag()intarget/s390x/kvm.cinstead.Thomas
Very cool! Okay, I think this makes sense, then. I'll look into this. Thanks for the tip.
@Conny, I assume this is what you meant as well? If so, ignore my response I sent earlier :)
Signature · 5 lines
-- Regards, Collin Stay safe and stay healthy
Re: [PATCH v6 2/2] s390/kvm: diagnose 318 handling
Quoted 99 lines · On Thu, 14 May 2020 14:53:24 -0400 Collin Walling <[email protected]> wrote:
Quoted 98 lines · Thomas Huth
Quoted 83 lines · Collin Walling
Quoted 41 lines · David Hildenbrand
Quoted 40 lines · Janosch Frank
Quoted 39 lines · David Hildenbrand
Quoted 38 lines · Janosch Frank
Quoted 37 lines · Thomas Huth
Quoted 27 lines · Collin Walling
DIAGNOSE
0x318(diag318) is a privileged s390x instruction that must be intercepted by SIE and handled via KVM. Let's introduce some functions to communicate between userspace and KVM via ioctls. These will be used to get/set the diag318 related information, as well as check the system if KVM supports handling this instruction.This information can help with diagnosing the environment the VM is running in (Linux, z/VM, etc) if the OS calls this instruction.
By default, this feature is disabled and can only be enabled if a user space program (such as QEMU) explicitly requests it.
The Control Program Name Code (CPNC) is stored in the SIE block and a copy is retained in each VCPU. The Control Program Version Code (CPVC) is not designed to be stored in the SIE block, so we retain a copy in each VCPU next to the CPNC.
Signed-off-by Collin Walling <[email protected]>--- Documentation/virt/kvm/devices/vm.rst | 29 +++++++++ arch/s390/include/asm/kvm_host.h | 6 +- arch/s390/include/uapi/asm/kvm.h | 5 ++ arch/s390/kvm/diag.c | 20 ++++++ arch/s390/kvm/kvm-s390.c | 89 +++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 2 + 7 files changed, 151 insertions(+), 1 deletion(-)[...]
Quoted 8 lines
arch/s390/kvm/diag.c +0
-0@@ -253,6 +253,24 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)return ret <0 ? ret :0 ; }Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
arch/s390/kvm/diag.c +6
-0+static int __diag_set_diag318_info (struct kvm_vcpu *vcpu) +{ +unsigned int reg = (vcpu->arch.sie_block->ipa &0xf0 ) >>4 ; +u64 info = vcpu->run->s.regs.gprs[reg]; + +if (!vcpu->kvm->arch.use_diag318)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
arch/s390/kvm/diag.c static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) · line 269
Quoted 8 lines
arch/s390/kvm/diag.c +8
-0+return -EOPNOTSUPP ; + + vcpu->stat.diagnose_318++; +kvm_s390_set_diag318_info (vcpu->kvm, info); + +VCPU_EVENT (vcpu,3 ,"diag 0x318 cpnc: 0x%x cpvc: 0x%llx" , + vcpu->kvm->arch.diag318_info.cpnc, + (u64 )vcpu->kvm->arch.diag318_info.cpvc);Errr.. thought I dropped this message. We favored just using the
VM_EVENTfrom last time.Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 8 lines
arch/s390/kvm/diag.c +4
-0+ +return 0 ; +} +int kvm_s390_handle_diag (struct kvm_vcpu *vcpu) {int code =kvm_s390_get_base_disp_rs (vcpu,NULL ) &0xffff ;arch/s390/kvm/diag.c int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) · line 296
Quoted 7 lines
arch/s390/kvm/diag.c +2
-0@@ -272,6 +290,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)return __diag_page_ref_service (vcpu);case 0x308 :return __diag_ipl_functions (vcpu); +case 0x318 : +return __diag_set_diag318_info (vcpu);case 0x500 :return __diag_virtio_hypercall (vcpu);I wonder whether it would make more sense to simply drop to userspace and handle the diag 318 call there? That way the userspace would always be up-to-date, and as we've seen in the past (e.g. with the various SIGP handling), it's better if the userspace is in control... e.g. userspace could also decide to only use
KVM_S390_VM_MISC_ENABLE_DIAG318if the guest just executed the diag 318 instruction.Quoted 8 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
And you need the kvm_s390_vm_get/set_misc functions anyway, so these could also be simply used by the diag 318 handler in userspace?
Pardon my ignorance, but I do not think I fully understand what exactly should be dropped in favor of doing things in userspace.
My assumption: if a diag handler is not found in KVM, then we fallthrough to userspace handling?
Right, if you simply omit this change to
diag.c, the default case returns-EOPNOTSUPPwhich then should cause an exit to userspace. You can then add the code in QEMU tohandle_diag()intarget/s390x/kvm.cinstead.
Quoted 9 lines
Quoted 2 lines
Thomas
Very cool! Okay, I think this makes sense, then. I'll look into this. Thanks for the tip.
@Conny, I assume this is what you meant as well? If so, ignore my response I sent earlier :)
Yes; if done correctly, it should be easy to hack something up for tcg as well, if we want it.