From patchwork Wed Sep 5 16:36:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Khalid Elmously X-Patchwork-Id: 966557 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4258VP5F19z9sCn; Thu, 6 Sep 2018 02:36:45 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1fxanG-0004rI-BZ; Wed, 05 Sep 2018 16:36:38 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1fxanE-0004qc-2u for kernel-team@lists.ubuntu.com; Wed, 05 Sep 2018 16:36:36 +0000 Received: from mail-it0-f70.google.com ([209.85.214.70]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1fxanD-0005h8-Oq for kernel-team@lists.ubuntu.com; Wed, 05 Sep 2018 16:36:35 +0000 Received: by mail-it0-f70.google.com with SMTP id n194-v6so8488897itn.0 for ; Wed, 05 Sep 2018 09:36:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=678PhDN2oTrwzZwW+dEQ89A7sgElf+KmmCyPHGhslHs=; b=KSamuOC4GxnP/uhNTIJfwdmovymci9E5g7FbsFkuTQGT/3JwIKY3vrrP6D0TVWIB1P EJb7MI0SKJfQUFA+WOsGebvoP4qV5ThrQ0Ebl6+nK8Be+wDOaaMvqSTrI/cUtAYgiZbe PPuGPtbcw6nN0MZrN90FTMn7IPN3vgWhH5wklLbRxb3zaRpY1QlU+Rx4rU7vDeRlvIKw mS9kfV+H8jkdNFyJ67nAQ+yIdt53OSPuEy0YcEqMlWJiaUqsVdGM+6qvfoHU86Ynj+L/ x2xAri6gSB5H30W3ihsP6Uv0kzbtx9eYO+1Rl+LZBm9M9vHmhX0WOD3HrrDAaH3Z1W22 mVFA== X-Gm-Message-State: APzg51DAN4Kd7brgDh+jiRPHK980WNrvjBVil8hNOWxSwb8RDt6o3Zil ltFu0/aqORsk4u6teHO87TYw2BAat6EURH5qpLpjKbrJGU+7KIghZDRCLBYEDh5P727LixTRDld IfiWsVILXXVILrrJwzGu2L6DaTzQaDqyYLql0K7Phcw== X-Received: by 2002:a5e:c80b:: with SMTP id y11-v6mr26579934iol.198.1536165394497; Wed, 05 Sep 2018 09:36:34 -0700 (PDT) X-Google-Smtp-Source: ANB0VdbfWNmWaJRWyO3C2PU0dEn6w6LSgARTp5cDdVVKD+DX8BgZUa9LlWmqqlJoB3I86osT6cqfbg== X-Received: by 2002:a5e:c80b:: with SMTP id y11-v6mr26579918iol.198.1536165394279; Wed, 05 Sep 2018 09:36:34 -0700 (PDT) Received: from kbuntu.fuzzbuzz.org (23-233-27-24.cpe.pppoe.ca. [23.233.27.24]) by smtp.gmail.com with ESMTPSA id i5-v6sm744367ioq.5.2018.09.05.09.36.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 05 Sep 2018 09:36:32 -0700 (PDT) From: Khalid Elmously To: kernel-team@lists.ubuntu.com Subject: [SRU][Bionic][v4 1/6] KVM: s390: implement CPU model only facilities Date: Wed, 5 Sep 2018 12:36:16 -0400 Message-Id: <20180905163621.16452-2-khalid.elmously@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180905163621.16452-1-khalid.elmously@canonical.com> References: <20180905163621.16452-1-khalid.elmously@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Christian Borntraeger CVE-2017-5715 (Spectre v2 s390x) Some facilities should only be provided to the guest, if they are enabled by a CPU model. This allows us to avoid capabilities and to simply fall back to the cpumodel for deciding about a facility without enabling it for older QEMUs or QEMUs without a CPU model. Reviewed-by: David Hildenbrand Reviewed-by: Cornelia Huck Signed-off-by: Christian Borntraeger (cherry picked from commit c3b9e3e1ea1c1d1524b56b6734711db2a6fc2163) Signed-off-by: Khalid Elmously --- arch/s390/kvm/kvm-s390.c | 53 ++++++++++++++++++++------------ arch/s390/kvm/kvm-s390.h | 2 -- arch/s390/tools/gen_facilities.c | 20 ++++++++++++ 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 656a3c8dfb50..9629be612304 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -151,13 +151,33 @@ static int nested; module_param(nested, int, S_IRUGO); MODULE_PARM_DESC(nested, "Nested virtualization support"); -/* upper facilities limit for kvm */ -unsigned long kvm_s390_fac_list_mask[16] = { FACILITIES_KVM }; -unsigned long kvm_s390_fac_list_mask_size(void) +/* + * For now we handle at most 16 double words as this is what the s390 base + * kernel handles and stores in the prefix page. If we ever need to go beyond + * this, this requires changes to code, but the external uapi can stay. + */ +#define SIZE_INTERNAL 16 + +/* + * Base feature mask that defines default mask for facilities. Consists of the + * defines in FACILITIES_KVM and the non-hypervisor managed bits. + */ +static unsigned long kvm_s390_fac_base[SIZE_INTERNAL] = { FACILITIES_KVM }; +/* + * Extended feature mask. Consists of the defines in FACILITIES_KVM_CPUMODEL + * and defines the facilities that can be enabled via a cpu model. + */ +static unsigned long kvm_s390_fac_ext[SIZE_INTERNAL] = { FACILITIES_KVM_CPUMODEL }; + +static unsigned long kvm_s390_fac_size(void) { - BUILD_BUG_ON(ARRAY_SIZE(kvm_s390_fac_list_mask) > S390_ARCH_FAC_MASK_SIZE_U64); - return ARRAY_SIZE(kvm_s390_fac_list_mask); + BUILD_BUG_ON(SIZE_INTERNAL > S390_ARCH_FAC_MASK_SIZE_U64); + BUILD_BUG_ON(SIZE_INTERNAL > S390_ARCH_FAC_LIST_SIZE_U64); + BUILD_BUG_ON(SIZE_INTERNAL * sizeof(unsigned long) > + sizeof(S390_lowcore.stfle_fac_list)); + + return SIZE_INTERNAL; } /* available cpu features supported by kvm */ @@ -1953,20 +1973,15 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (!kvm->arch.sie_page2) goto out_err; - /* Populate the facility mask initially. */ - memcpy(kvm->arch.model.fac_mask, S390_lowcore.stfle_fac_list, - sizeof(S390_lowcore.stfle_fac_list)); - for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { - if (i < kvm_s390_fac_list_mask_size()) - kvm->arch.model.fac_mask[i] &= kvm_s390_fac_list_mask[i]; - else - kvm->arch.model.fac_mask[i] = 0UL; - } - - /* Populate the facility list initially. */ kvm->arch.model.fac_list = kvm->arch.sie_page2->fac_list; - memcpy(kvm->arch.model.fac_list, kvm->arch.model.fac_mask, - S390_ARCH_FAC_LIST_SIZE_BYTE); + + for (i = 0; i < kvm_s390_fac_size(); i++) { + kvm->arch.model.fac_mask[i] = S390_lowcore.stfle_fac_list[i] & + (kvm_s390_fac_base[i] | + kvm_s390_fac_ext[i]); + kvm->arch.model.fac_list[i] = S390_lowcore.stfle_fac_list[i] & + kvm_s390_fac_base[i]; + } /* we are always in czam mode - even on pre z14 machines */ set_kvm_facility(kvm->arch.model.fac_mask, 138); @@ -3965,7 +3980,7 @@ static int __init kvm_s390_init(void) } for (i = 0; i < 16; i++) - kvm_s390_fac_list_mask[i] |= + kvm_s390_fac_base[i] |= S390_lowcore.stfle_fac_list[i] & nonhyp_mask(i); return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index efa186f065fb..0f08873937d4 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -281,8 +281,6 @@ void exit_sie(struct kvm_vcpu *vcpu); void kvm_s390_sync_request(int req, struct kvm_vcpu *vcpu); int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu); void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu); -unsigned long kvm_s390_fac_list_mask_size(void); -extern unsigned long kvm_s390_fac_list_mask[]; void kvm_s390_set_cpu_timer(struct kvm_vcpu *vcpu, __u64 cputm); __u64 kvm_s390_get_cpu_timer(struct kvm_vcpu *vcpu); diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c index 0373801d9860..78b7192fc070 100644 --- a/arch/s390/tools/gen_facilities.c +++ b/arch/s390/tools/gen_facilities.c @@ -62,6 +62,13 @@ static struct facility_def facility_defs[] = { } }, { + /* + * FACILITIES_KVM contains the list of facilities that are part + * of the default facility mask and list that are passed to the + * initial CPU model. If no CPU model is used, this, together + * with the non-hypervisor managed bits, is the maximum list of + * guest facilities supported by KVM. + */ .name = "FACILITIES_KVM", .bits = (int[]){ 0, /* N3 instructions */ @@ -89,6 +96,19 @@ static struct facility_def facility_defs[] = { -1 /* END */ } }, + { + /* + * FACILITIES_KVM_CPUMODEL contains the list of facilities + * that can be enabled by CPU model code if the host supports + * it. These facilities are not passed to the guest without + * CPU model support. + */ + + .name = "FACILITIES_KVM_CPUMODEL", + .bits = (int[]){ + -1 /* END */ + } + }, }; static void print_facility_list(struct facility_def *def)