From nobody Tue Feb 10 05:41:59 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1605125266; cv=none; d=zohomail.com; s=zohoarc; b=MxeCPzS4iG+8r4RjLu6uefTGnXYdVXS8FTkcvjOHhJ/wZloCvtNJvLFPBHComPJ5mFqwyJFQUYOWEUVTWelQE7SaY+Yx8XCLuu2t8zzdoBXy8fUZ0qfeHr4Ry3C329G+5yyUB7v+Jl3lKDFYscOjbsj1ANqShkzxZiW3ZpxKda8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605125266; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=KzvkblNZTIan0g0PIlNJgU/4gOw9pc4w+yWFlaLs+3w=; b=XrtPuhMgVTiEF/lpcLWOaBzRMU36MeDtxzBxo7MJAypJUkVoFL6y6a35sQ4fkQV8mQzxtlMRMYVJmzeUNoys5s/RrJAJ1gBfJ+9mk7fEjKwyqZyJQImdTUxiXJ7LMdCJWkOYjKwA9yRU/eRPwV47FbzElzG0sb7oSo4cMdNj+Oc= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1605125266957862.8103616646196; Wed, 11 Nov 2020 12:07:46 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.25211.52872 (Exim 4.92) (envelope-from ) id 1kcwOx-0003QL-Nz; Wed, 11 Nov 2020 20:07:31 +0000 Received: by outflank-mailman (output) from mailman id 25211.52872; Wed, 11 Nov 2020 20:07:31 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kcwOx-0003Q0-I0; Wed, 11 Nov 2020 20:07:31 +0000 Received: by outflank-mailman (input) for mailman id 25211; Wed, 11 Nov 2020 20:07:29 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kcwOv-0003LR-SL for xen-devel@lists.xenproject.org; Wed, 11 Nov 2020 20:07:29 +0000 Received: from host109-146-187-185.range109-146.btcentralplus.com ([109.146.187.185] helo=u2f063a87eabd5f.home) by xenbits.xenproject.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kcwOv-0000pY-KP; Wed, 11 Nov 2020 20:07:29 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1kcwOv-0003LR-SL for xen-devel@lists.xenproject.org; Wed, 11 Nov 2020 20:07:29 +0000 Received: from host109-146-187-185.range109-146.btcentralplus.com ([109.146.187.185] helo=u2f063a87eabd5f.home) by xenbits.xenproject.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kcwOv-0000pY-KP; Wed, 11 Nov 2020 20:07:29 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" From: Paul Durrant To: xen-devel@lists.xenproject.org Cc: Paul Durrant , Wei Liu , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH 06/10] viridian: add ExProcessorMasks variants of the flush hypercalls Date: Wed, 11 Nov 2020 20:07:17 +0000 Message-Id: <20201111200721.30551-7-paul@xen.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20201111200721.30551-1-paul@xen.org> References: <20201111200721.30551-1-paul@xen.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Paul Durrant The Microsoft Hypervisor TLFS specifies variants of the already implemented HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST hypercalls that take a 'Virtual Processor Set' as an argument rather than a simple 64-bit mask. This patch adds a new hvcall_flush_ex() function to implement these (HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE/LIST_EX) hypercalls. This makes use of new helper functions, hv_vpset_nr_banks() and hv_vpset_to_vpmask(), to determine the size of the Virtual Processor Set (so it can be copied from guest memory) and parse it into hypercall_vpmask (respectively). NOTE: A guest should not yet issue these hypercalls as 'ExProcessorMasks' support needs to be advertised via CPUID. This will be done in a subsequent patch. Signed-off-by: Paul Durrant --- Cc: Wei Liu Cc: Jan Beulich Cc: Andrew Cooper Cc: "Roger Pau Monn=C3=A9" --- xen/arch/x86/hvm/viridian/viridian.c | 147 +++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridi= an/viridian.c index 765d53016c02..1226e1596a1c 100644 --- a/xen/arch/x86/hvm/viridian/viridian.c +++ b/xen/arch/x86/hvm/viridian/viridian.c @@ -553,6 +553,83 @@ static unsigned int vpmask_next(struct hypercall_vpmas= k *vpmask, unsigned int vp (vp) < HVM_MAX_VCPUS; \ (vp) =3D vpmask_next(vpmask, vp)) =20 +struct hypercall_vpset { + struct hv_vpset set; + uint64_t __bank_contents[64]; +}; + +static DEFINE_PER_CPU(struct hypercall_vpset, hypercall_vpset); + +static unsigned int hv_vpset_nr_banks(struct hv_vpset *vpset) +{ + uint64_t bank_mask; + unsigned int nr =3D 0; + + for ( bank_mask =3D vpset->valid_bank_mask; bank_mask; bank_mask >>=3D= 1 ) + if ( bank_mask & 1 ) + nr++; + + return nr; +} + +static uint16_t hv_vpset_to_vpmask(struct hv_vpset *set, size_t size, + struct hypercall_vpmask *vpmask) +{ + switch ( set->format ) + { + case HV_GENERIC_SET_ALL: + vpmask_fill(vpmask); + return 0; + + case HV_GENERIC_SET_SPARSE_4K: + { + uint64_t bank_mask; + unsigned int bank =3D 0, vp =3D 0; + + vpmask_empty(vpmask); + for ( bank_mask =3D set->valid_bank_mask; bank_mask; bank_mask >>= =3D 1 ) + { + /* Make sure we won't dereference past the end of the array */ + if ( (void *)(set->bank_contents + bank) >=3D + (void *)set + size ) + { + ASSERT_UNREACHABLE(); + return -EINVAL; + } + + if ( bank_mask & 1 ) + { + uint64_t mask =3D set->bank_contents[bank]; + unsigned int i; + + for ( i =3D 0; i < 64; i++, vp++ ) + { + if ( mask & 1 ) + { + if ( vp >=3D HVM_MAX_VCPUS ) + return -EINVAL; + + vpmask_set(vpmask, vp); + } + + mask >>=3D 1; + } + + bank++; + } + else + vp +=3D 64; + } + return 0; + } + + default: + break; + } + + return -EINVAL; +} + /* * Windows should not issue the hypercalls requiring this callback in the * case where vcpu_id would exceed the size of the mask. @@ -644,6 +721,70 @@ static int hvcall_flush(union hypercall_input *input, return 0; } =20 +static int hvcall_flush_ex(union hypercall_input *input, + union hypercall_output *output, + unsigned long input_params_gpa, + unsigned long output_params_gpa) +{ + struct hypercall_vpmask *vpmask =3D &this_cpu(hypercall_vpmask); + struct { + uint64_t address_space; + uint64_t flags; + struct hv_vpset set; + } input_params; + + /* These hypercalls should never use the fast-call convention. */ + if ( input->fast ) + return -EINVAL; + + /* Get input parameters. */ + if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa, + sizeof(input_params)) !=3D HVMTRANS_okay= ) + return -EINVAL; + + if ( input_params.flags & HV_FLUSH_ALL_PROCESSORS ) + vpmask_fill(vpmask); + else + { + struct hypercall_vpset *vpset =3D &this_cpu(hypercall_vpset); + struct hv_vpset *set =3D &vpset->set; + size_t size; + int rc; + + *set =3D input_params.set; + if ( set->format =3D=3D HV_GENERIC_SET_SPARSE_4K ) + { + unsigned long offset =3D offsetof(typeof(input_params), + set.bank_contents); + + size =3D sizeof(*set->bank_contents) * hv_vpset_nr_banks(set); + if ( hvm_copy_from_guest_phys(&set->bank_contents, + input_params_gpa + offset, + size) !=3D HVMTRANS_okay) + return -EINVAL; + + size +=3D sizeof(*set); + } + else + size =3D sizeof(*set); + + rc =3D hv_vpset_to_vpmask(set, size, vpmask); + if ( rc ) + return rc; + } + + /* + * A false return means that another vcpu is currently trying + * a similar operation, so back off. + */ + if ( !paging_flush_tlb(need_flush, vpmask) ) + return -ERESTART; + + output->rep_complete =3D input->rep_count; + + return 0; +} + static void send_ipi(struct hypercall_vpmask *vpmask, uint8_t vector) { struct domain *currd =3D current->domain; @@ -767,6 +908,12 @@ int viridian_hypercall(struct cpu_user_regs *regs) output_params_gpa); break; =20 + case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX: + case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX: + rc =3D hvcall_flush_ex(&input, &output, input_params_gpa, + output_params_gpa); + break; + case HVCALL_SEND_IPI: rc =3D hvcall_ipi(&input, &output, input_params_gpa, output_params_gpa); --=20 2.20.1