From patchwork Tue Mar 19 15:22:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 10859829 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 2D90215AC for ; Tue, 19 Mar 2019 15:31:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 10EAE28849 for ; Tue, 19 Mar 2019 15:31:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0F352294AB; Tue, 19 Mar 2019 15:31:18 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5981A28849 for ; Tue, 19 Mar 2019 15:31:17 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1h6Gg6-00058x-Op; Tue, 19 Mar 2019 15:29:22 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1h6Gg5-00058s-Sz for xen-devel@lists.xenproject.org; Tue, 19 Mar 2019 15:29:21 +0000 X-Inumbo-ID: c35b3fa7-4a5b-11e9-bc90-bc764e045a96 Received: from SMTP03.CITRIX.COM (unknown [162.221.156.55]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id c35b3fa7-4a5b-11e9-bc90-bc764e045a96; Tue, 19 Mar 2019 15:29:20 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.58,498,1544486400"; d="scan'208";a="81016409" From: Paul Durrant To: Date: Tue, 19 Mar 2019 15:22:54 +0000 Message-ID: <20190319152254.1393-12-paul.durrant@citrix.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190319152254.1393-1-paul.durrant@citrix.com> References: <20190319152254.1393-1-paul.durrant@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v10 11/11] viridian: add implementation of the HvSendSyntheticClusterIpi hypercall X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall , Paul Durrant , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds an implementation of the hypercall as documented in the specification [1], section 10.5.2. This enlightenment, as with others, is advertised by CPUID leaf 0x40000004 and is under control of a new 'hcall_ipi' option in libxl. If used, this enlightenment should mean the guest only takes a single VMEXIT to issue IPIs to multiple vCPUs rather than the multiple VMEXITs that would result from using the emulated local APIC. [1] https://github.com/MicrosoftDocs/Virtualization-Documentation/raw/live/tlfs/Hypervisor%20Top%20Level%20Functional%20Specification%20v5.0C.pdf Signed-off-by: Paul Durrant Acked-by: Wei Liu Reviewed-by: Jan Beulich --- Cc: Ian Jackson Cc: Andrew Cooper Cc: George Dunlap Cc: Julien Grall Cc: Konrad Rzeszutek Wilk Cc: Stefano Stabellini Cc: Tim Deegan Cc: "Roger Pau Monné" v4: - Address comments from Jan v3: - New in v3 --- docs/man/xl.cfg.5.pod.in | 6 +++ tools/libxl/libxl.h | 6 +++ tools/libxl/libxl_dom.c | 3 ++ tools/libxl/libxl_types.idl | 1 + xen/arch/x86/hvm/viridian/viridian.c | 63 ++++++++++++++++++++++++++++ xen/include/public/hvm/params.h | 7 +++- 6 files changed, 85 insertions(+), 1 deletion(-) diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in index 355c654693..c7d70e618b 100644 --- a/docs/man/xl.cfg.5.pod.in +++ b/docs/man/xl.cfg.5.pod.in @@ -2175,6 +2175,12 @@ ticks and hence enabling this group will ensure that ticks will be consistent with use of an enlightened time source (B or B). +=item B + +This set incorporates use of a hypercall for interprocessor interrupts. +This enlightenment may improve performance of Windows guests with multiple +virtual CPUs. + =item B This is a special value that enables the default set of groups, which diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index c8f219b0d3..482499a6c0 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -330,6 +330,12 @@ */ #define LIBXL_HAVE_VIRIDIAN_STIMER 1 +/* + * LIBXL_HAVE_VIRIDIAN_HCALL_IPI indicates that the 'hcall_ipi' value + * is present in the viridian enlightenment enumeration. + */ +#define LIBXL_HAVE_VIRIDIAN_HCALL_IPI 1 + /* * LIBXL_HAVE_BUILDINFO_HVM_ACPI_LAPTOP_SLATE indicates that * libxl_domain_build_info has the u.hvm.acpi_laptop_slate field. diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 2ee0f82ee7..879c806139 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -324,6 +324,9 @@ static int hvm_set_viridian_features(libxl__gc *gc, uint32_t domid, if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_STIMER)) mask |= HVMPV_time_ref_count | HVMPV_synic | HVMPV_stimer; + if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_HCALL_IPI)) + mask |= HVMPV_hcall_ipi; + if (mask != 0 && xc_hvm_param_set(CTX->xch, domid, diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 1cce249de4..cb4702fd7a 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -237,6 +237,7 @@ libxl_viridian_enlightenment = Enumeration("viridian_enlightenment", [ (6, "crash_ctl"), (7, "synic"), (8, "stimer"), + (9, "hcall_ipi"), ]) libxl_hdtype = Enumeration("hdtype", [ diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c index dce648bb4e..4b06b78a27 100644 --- a/xen/arch/x86/hvm/viridian/viridian.c +++ b/xen/arch/x86/hvm/viridian/viridian.c @@ -28,6 +28,7 @@ #define HvFlushVirtualAddressSpace 0x0002 #define HvFlushVirtualAddressList 0x0003 #define HvNotifyLongSpinWait 0x0008 +#define HvSendSyntheticClusterIpi 0x000b #define HvGetPartitionId 0x0046 #define HvExtCallQueryCapabilities 0x8001 @@ -95,6 +96,7 @@ typedef union _HV_CRASH_CTL_REG_CONTENTS #define CPUID4A_HCALL_REMOTE_TLB_FLUSH (1 << 2) #define CPUID4A_MSR_BASED_APIC (1 << 3) #define CPUID4A_RELAX_TIMER_INT (1 << 5) +#define CPUID4A_SYNTHETIC_CLUSTER_IPI (1 << 10) /* Viridian CPUID leaf 6: Implementation HW features detected and in use */ #define CPUID6A_APIC_OVERLAY (1 << 0) @@ -206,6 +208,8 @@ void cpuid_viridian_leaves(const struct vcpu *v, uint32_t leaf, res->a |= CPUID4A_HCALL_REMOTE_TLB_FLUSH; if ( !cpu_has_vmx_apic_reg_virt ) res->a |= CPUID4A_MSR_BASED_APIC; + if ( viridian_feature_mask(d) & HVMPV_hcall_ipi ) + res->a |= CPUID4A_SYNTHETIC_CLUSTER_IPI; /* * This value is the recommended number of attempts to try to @@ -628,6 +632,65 @@ int viridian_hypercall(struct cpu_user_regs *regs) break; } + case HvSendSyntheticClusterIpi: + { + struct vcpu *v; + uint32_t vector; + uint64_t vcpu_mask; + + status = HV_STATUS_INVALID_PARAMETER; + + /* Get input parameters. */ + if ( input.fast ) + { + if ( input_params_gpa >> 32 ) + break; + + vector = input_params_gpa; + vcpu_mask = output_params_gpa; + } + else + { + struct { + uint32_t vector; + uint8_t target_vtl; + uint8_t reserved_zero[3]; + uint64_t vcpu_mask; + } input_params; + + if ( hvm_copy_from_guest_phys(&input_params, input_params_gpa, + sizeof(input_params)) != + HVMTRANS_okay ) + break; + + if ( input_params.target_vtl || + input_params.reserved_zero[0] || + input_params.reserved_zero[1] || + input_params.reserved_zero[2] ) + break; + + vector = input_params.vector; + vcpu_mask = input_params.vcpu_mask; + } + + if ( vector < 0x10 || vector > 0xff ) + break; + + for_each_vcpu ( currd, v ) + { + if ( v->vcpu_id >= (sizeof(vcpu_mask) * 8) ) + break; + + if ( !(vcpu_mask & (1ul << v->vcpu_id)) ) + continue; + + vlapic_set_irq(vcpu_vlapic(v), vector, 0); + } + + status = HV_STATUS_SUCCESS; + break; + } + default: gprintk(XENLOG_WARNING, "unimplemented hypercall %04x\n", input.call_code); diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index e06b0942d0..36832e4b94 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -154,6 +154,10 @@ #define _HVMPV_stimer 8 #define HVMPV_stimer (1 << _HVMPV_stimer) +/* Use Synthetic Cluster IPI Hypercall */ +#define _HVMPV_hcall_ipi 9 +#define HVMPV_hcall_ipi (1 << _HVMPV_hcall_ipi) + #define HVMPV_feature_mask \ (HVMPV_base_freq | \ HVMPV_no_freq | \ @@ -163,7 +167,8 @@ HVMPV_apic_assist | \ HVMPV_crash_ctl | \ HVMPV_synic | \ - HVMPV_stimer) + HVMPV_stimer | \ + HVMPV_hcall_ipi) #endif