From patchwork Thu Dec 6 22:30:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Collin Walling X-Patchwork-Id: 10717141 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E6D6C13BF for ; Thu, 6 Dec 2018 22:30:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D74202EF96 for ; Thu, 6 Dec 2018 22:30:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CB98D2EFB3; Thu, 6 Dec 2018 22:30:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0634E2EF96 for ; Thu, 6 Dec 2018 22:30:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726039AbeLFWaf (ORCPT ); Thu, 6 Dec 2018 17:30:35 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:50890 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726020AbeLFWae (ORCPT ); Thu, 6 Dec 2018 17:30:34 -0500 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id wB6MNYFo090312 for ; Thu, 6 Dec 2018 17:30:33 -0500 Received: from e12.ny.us.ibm.com (e12.ny.us.ibm.com [129.33.205.202]) by mx0a-001b2d01.pphosted.com with ESMTP id 2p79kx7yxp-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 06 Dec 2018 17:30:32 -0500 Received: from localhost by e12.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 6 Dec 2018 22:30:31 -0000 Received: from b01cxnp23032.gho.pok.ibm.com (9.57.198.27) by e12.ny.us.ibm.com (146.89.104.199) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 6 Dec 2018 22:30:29 -0000 Received: from b01ledav006.gho.pok.ibm.com (b01ledav006.gho.pok.ibm.com [9.57.199.111]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id wB6MUQtG19791886 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 6 Dec 2018 22:30:26 GMT Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2FBE5AC05B; Thu, 6 Dec 2018 22:30:26 +0000 (GMT) Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 189EEAC05F; Thu, 6 Dec 2018 22:30:25 +0000 (GMT) Received: from collin-ThinkPad-W541.pok.ibm.com (unknown [9.56.58.52]) by b01ledav006.gho.pok.ibm.com (Postfix) with ESMTP; Thu, 6 Dec 2018 22:30:25 +0000 (GMT) From: Collin Walling To: linux-s390@vger.kernel.org, kvm@vger.kernel.org, borntraeger@de.ibm.com, david@redhat.com, cohuck@redhat.com, heiko.carstens@de.ibm.com, schwidefsky@de.ibm.com, frankja@linux.ibm.com Subject: [PATCH v2 2/2] s390/kvm: handle diagnose 318 instruction call Date: Thu, 6 Dec 2018 17:30:05 -0500 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1544135405-22385-1-git-send-email-walling@linux.ibm.com> References: <1544135405-22385-1-git-send-email-walling@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18120622-0060-0000-0000-000002E00EA6 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00010184; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000270; SDB=6.01127999; UDB=6.00585945; IPR=6.00908131; MB=3.00024518; MTD=3.00000008; XFM=3.00000015; UTC=2018-12-06 22:30:31 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18120622-0061-0000-0000-000047731192 Message-Id: <1544135405-22385-3-git-send-email-walling@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-12-06_08:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1812060188 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The diagnose 318 instruction is a privileged instruction that must be interpreted by SIE and handled via KVM. The control program name and version codes (CPNC and CPVC) set by this instruction are saved to the kvm->arch struct. The CPNC is also set in the SIE control block of all VCPUs. The new kvm_s390_set_machine interface is introduced for migration. Signed-off-by: Collin Walling Reviewed-by: Janosch Frank --- arch/s390/include/asm/kvm_host.h | 13 +++++- arch/s390/include/uapi/asm/kvm.h | 5 +++ arch/s390/kvm/diag.c | 12 ++++++ arch/s390/kvm/kvm-s390.c | 92 ++++++++++++++++++++++++++++++++++++++++ arch/s390/kvm/kvm-s390.h | 1 + arch/s390/kvm/vsie.c | 7 +++ 6 files changed, 129 insertions(+), 1 deletion(-) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index d5d2488..ad42949 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -229,7 +229,8 @@ struct kvm_s390_sie_block { __u32 scaol; /* 0x0064 */ __u8 reserved68; /* 0x0068 */ __u8 epdx; /* 0x0069 */ - __u8 reserved6a[2]; /* 0x006a */ + __u8 cpnc; /* 0x006a */ + __u8 reserved6b; /* 0x006b */ __u32 todpr; /* 0x006c */ #define GISA_FORMAT1 0x00000001 __u32 gd; /* 0x0070 */ @@ -391,6 +392,7 @@ struct kvm_vcpu_stat { u64 diagnose_9c; u64 diagnose_258; u64 diagnose_308; + u64 diagnose_318; u64 diagnose_500; u64 diagnose_other; }; @@ -804,6 +806,14 @@ struct kvm_s390_vsie { struct page *pages[KVM_MAX_VCPUS]; }; +union kvm_s390_diag318_info { + u64 cpc; + struct { + u64 cpnc : 8; + u64 cpvc : 56; + }; +}; + struct kvm_arch{ void *sca; int use_esca; @@ -838,6 +848,7 @@ struct kvm_arch{ /* subset of available cpu features enabled by user space */ DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS); struct kvm_s390_gisa *gisa; + union kvm_s390_diag318_info diag318_info; }; #define KVM_HVA_ERR_BAD (-1UL) diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 16511d9..6420aad 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h @@ -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_MACHINE 5 /* kvm attributes for mem_ctrl */ #define KVM_S390_VM_MEM_ENABLE_CMMA 0 @@ -130,6 +131,7 @@ struct kvm_s390_vm_cpu_machine { #define KVM_S390_VM_CPU_FEAT_PFMFI 11 #define KVM_S390_VM_CPU_FEAT_SIGPIF 12 #define KVM_S390_VM_CPU_FEAT_KSS 13 +#define KVM_S390_VM_CPU_FEAT_DIAG318 14 struct kvm_s390_vm_cpu_feat { __u64 feat[16]; }; @@ -168,6 +170,9 @@ 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_MACHINE */ +#define KVM_S390_VM_MACHINE_CPC 0 + /* for KVM_GET_REGS and KVM_SET_REGS */ struct kvm_regs { /* general purpose regs for s390 */ diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 45634b3d..b61ffd2 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -235,6 +235,16 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) return ret < 0 ? ret : 0; } +static int __diag_set_control_prog_name(struct kvm_vcpu *vcpu) +{ + unsigned int reg = (vcpu->arch.sie_block->ipa & 0xf0) >> 4; + unsigned long cpc = vcpu->run->s.regs.gprs[reg]; + + vcpu->stat.diagnose_318++; + kvm_s390_set_cpc(vcpu->kvm, cpc); + return 0; +} + int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) { int code = kvm_s390_get_base_disp_rs(vcpu, NULL) & 0xffff; @@ -254,6 +264,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_control_prog_name(vcpu); case 0x500: return __diag_virtio_hypercall(vcpu); default: diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index fe24150..67aa34a 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -157,6 +157,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "instruction_diag_9c", VCPU_STAT(diagnose_9c) }, { "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 } @@ -371,6 +372,10 @@ static void kvm_s390_cpu_feat_init(void) if (MACHINE_HAS_ESOP) allow_cpu_feat(KVM_S390_VM_CPU_FEAT_ESOP); + + /* Enable DIAG318 guest support unconditionally */ + allow_cpu_feat(KVM_S390_VM_CPU_FEAT_DIAG318); + /* * We need SIE support, ESOP (PROT_READ protection for gmap_shadow), * 64bit SCAO (SCA passthrough) and IDTE (for gmap_shadow unshadowing). @@ -1173,6 +1178,75 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) return ret; } +void kvm_s390_set_cpc(struct kvm *kvm, u64 cpc) +{ + struct kvm_vcpu *vcpu; + int i; + + mutex_lock(&kvm->lock); + kvm_s390_vcpu_block_all(kvm); + + kvm->arch.diag318_info.cpc = cpc; + + VM_EVENT(kvm, 3, "SET: cpnc: 0x%x cpvc: 0x%llx", + (u8)kvm->arch.diag318_info.cpnc, (u64)kvm->arch.diag318_info.cpvc); + + kvm_for_each_vcpu(i, vcpu, kvm) { + vcpu->arch.sie_block->cpnc = kvm->arch.diag318_info.cpnc; + } + + kvm_s390_vcpu_unblock_all(kvm); + mutex_unlock(&kvm->lock); +} + +static int kvm_s390_vm_set_machine(struct kvm *kvm, struct kvm_device_attr *attr) +{ + int ret; + u64 cpc; + + switch (attr->attr) { + case KVM_S390_VM_MACHINE_CPC: + ret = -EFAULT; + if (get_user(cpc, (u64 __user *)attr->addr)) + break; + kvm_s390_set_cpc(kvm, cpc); + ret = 0; + break; + default: + ret = -ENXIO; + break; + } + return ret; +} + +static int kvm_s390_get_cpc(struct kvm *kvm, struct kvm_device_attr *attr) +{ + u64 cpc = kvm->arch.diag318_info.cpc; + + if (put_user(cpc, (u64 __user *)attr->addr)) + return -EFAULT; + + VM_EVENT(kvm, 3, "QUERY: cpnc: 0x%x cpvc: 0x%llx", + (u8)kvm->arch.diag318_info.cpnc, (u64)kvm->arch.diag318_info.cpvc); + + return 0; +} + +static int kvm_s390_get_misc(struct kvm *kvm, struct kvm_device_attr *attr) +{ + int ret; + + switch (attr->attr) { + case KVM_S390_VM_MACHINE_CPC: + ret = kvm_s390_get_cpc(kvm, attr); + break; + default: + ret = -ENXIO; + break; + } + return ret; +} + static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) { struct kvm_s390_vm_cpu_processor *proc; @@ -1435,6 +1509,9 @@ static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr) case KVM_S390_VM_MIGRATION: ret = kvm_s390_vm_set_migration(kvm, attr); break; + case KVM_S390_VM_MACHINE: + ret = kvm_s390_vm_set_machine(kvm, attr); + break; default: ret = -ENXIO; break; @@ -1460,6 +1537,9 @@ static int kvm_s390_vm_get_attr(struct kvm *kvm, struct kvm_device_attr *attr) case KVM_S390_VM_MIGRATION: ret = kvm_s390_vm_get_migration(kvm, attr); break; + case KVM_S390_VM_MACHINE: + ret = kvm_s390_get_misc(kvm, attr); + break; default: ret = -ENXIO; break; @@ -1534,6 +1614,16 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr) case KVM_S390_VM_MIGRATION: ret = 0; break; + case KVM_S390_VM_MACHINE: + switch (attr->attr) { + case KVM_S390_VM_MACHINE_CPC: + ret = 0; + break; + default: + ret = -ENXIO; + break; + } + break; default: ret = -ENXIO; break; @@ -2650,7 +2740,9 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) preempt_disable(); vcpu->arch.sie_block->epoch = vcpu->kvm->arch.epoch; vcpu->arch.sie_block->epdx = vcpu->kvm->arch.epdx; + vcpu->arch.sie_block->cpnc = vcpu->kvm->arch.diag318_info.cpnc; preempt_enable(); + mutex_unlock(&vcpu->kvm->lock); if (!kvm_is_ucontrol(vcpu->kvm)) { vcpu->arch.gmap = vcpu->kvm->arch.gmap; diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 1f6e36c..8137f15 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -281,6 +281,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_cpc(struct kvm *kvm, u64 cpc); 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); diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index a153257..1a6a9b6 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -397,6 +397,9 @@ static void unshadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) memcpy(scb_o->gcr, scb_s->gcr, 128); scb_o->pp = scb_s->pp; + /* machine information */ + scb_o->cpnc = scb_s->cpnc; + /* branch prediction */ if (test_kvm_facility(vcpu->kvm, 82)) { scb_o->fpf &= ~FPF_BPBC; @@ -473,6 +476,10 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) scb_s->lctl = scb_o->lctl; scb_s->svcc = scb_o->svcc; scb_s->ictl = scb_o->ictl; + + /* machine information */ + scb_s->cpnc = scb_o->cpnc; + /* * SKEY handling functions can't deal with false setting of PTE invalid * bits. Therefore we cannot provide interpretation and would later