If the host initialized the Ultravisor, we can set stfle bit 161 (protected virtual IPL enhancements facility), which indicates, that the IPL subcodes 8, 9 and are valid. These subcodes are used by a normal guest to set/retrieve a IPIB of type 5 and transition into protected mode. Once in protected mode, the VM will loose the facility bit, as each boot into protected mode has to go through non-protected. There is no secure re-ipl with subcode 10 without a previous subcode 3. In protected mode, there is no subcode 4 available, as the VM has no more access to its memory from non-protected mode. I.e. each IPL clears. Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxx> --- arch/s390/kvm/diag.c | 6 ++++++ arch/s390/kvm/kvm-s390.c | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 3fb54ec2cf3e..b951dbdcb6a0 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -197,6 +197,12 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu) case 4: vcpu->run->s390_reset_flags = 0; break; + case 8: + case 9: + case 10: + if (!test_kvm_facility(vcpu->kvm, 161)) + return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); + /* fall through */ default: return -EOPNOTSUPP; } diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 500972a1f742..8947f1812b12 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -2590,6 +2590,11 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (css_general_characteristics.aiv && test_facility(65)) set_kvm_facility(kvm->arch.model.fac_mask, 65); + if (is_prot_virt_host()) { + set_kvm_facility(kvm->arch.model.fac_mask, 161); + set_kvm_facility(kvm->arch.model.fac_list, 161); + } + kvm->arch.model.cpuid = kvm_s390_get_initial_cpuid(); kvm->arch.model.ibc = sclp.ibc & 0x0fff; -- 2.20.1