From nobody Mon May 6 09:17:26 2024 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; dkim=pass; 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; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1613991437; cv=none; d=zohomail.com; s=zohoarc; b=OR8nHU4n0PfVisdL8viu0frqRwIBQUU9ydigU955BDbAyyhuEskry6wfwOuoqmPbiXxnnWhVBJ5sTjEPSbPnERl5zbY5m0Fhs9CRR/Z0LrhJcSqpcrS3AOhBQmF7BUko/6oGlKAS/EtHiiFT0RSV4RtZ78QD/F1g8/zmEVRzH/o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1613991437; 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=8uj5lky+beBmzi1shgy61QnM9D1z2TNAJ5ARxpmCwuk=; b=a6bQ1cPR1F6f9Z+WQ5jNwrvjC/VNptSDWyAJosjvGHuZq/E4jczN2W1sZdK/0kPEUBt4foGjrgx5Hjeh4J7tlLYwcvHmtBi5xWXvwqd41FXDC9LHdZNQIAP6ebHjHbYf4y9VWIey2GMI4ayqv+6qas1ITulttHjhRjeL+GEm02Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=quarantine dis=none) header.from= Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1613991437432309.17606639262783; Mon, 22 Feb 2021 02:57:17 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.87924.165174 (Exim 4.92) (envelope-from ) id 1lE8ti-0004Ax-2s; Mon, 22 Feb 2021 10:57:02 +0000 Received: by outflank-mailman (output) from mailman id 87924.165174; Mon, 22 Feb 2021 10:57:02 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lE8th-0004Aq-Vr; Mon, 22 Feb 2021 10:57:01 +0000 Received: by outflank-mailman (input) for mailman id 87924; Mon, 22 Feb 2021 10:57:01 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lE8tg-0004AA-V7 for xen-devel@lists.xenproject.org; Mon, 22 Feb 2021 10:57:00 +0000 Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 16605c37-2f38-4771-b03e-73c7aa7b963f; Mon, 22 Feb 2021 10:56:59 +0000 (UTC) Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id E2F7FAF23; Mon, 22 Feb 2021 10:56:58 +0000 (UTC) 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" X-Inumbo-ID: 16605c37-2f38-4771-b03e-73c7aa7b963f X-Virus-Scanned: by amavisd-new at test-mx.suse.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1613991419; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8uj5lky+beBmzi1shgy61QnM9D1z2TNAJ5ARxpmCwuk=; b=dETcHXuZtaAQA4Kh8SPgm2s3OPELVTc6arhwtd9UXJ227s7dLkKVrvFg9oHknfWLuUF4b0 TDtPNu47G9x3kHzcdiAoczKUMvc+Lwkq6JZMm2PyyRmBJykVY1PtHNMy6dKnkZwHPlOMyX ydoibrdOJhoaxkXxNhjYCOY9ppJcKIo= Subject: [PATCH v3 1/2][4.15] VMX: delay p2m insertion of APIC access page From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: Andrew Cooper , Wei Liu , =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= , Ian Jackson , George Dunlap , Kevin Tian , Jun Nakajima , Julien Grall References: <4731a3a3-906a-98ac-11ba-6a0723903391@suse.com> Message-ID: <90271e69-c07e-a32c-5531-a79b10ef03dd@suse.com> Date: Mon, 22 Feb 2021 11:56:58 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 MIME-Version: 1.0 In-Reply-To: <4731a3a3-906a-98ac-11ba-6a0723903391@suse.com> Content-Language: en-US Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) Content-Type: text/plain; charset="utf-8" Inserting the mapping at domain creation time leads to a memory leak when the creation fails later on and the domain uses separate CPU and IOMMU page tables - the latter requires intermediate page tables to be allocated, but there's no freeing of them at present in this case. Since we don't need the p2m insertion to happen this early, avoid the problem altogether by deferring it until the last possible point. This comes at the price of not being able to handle an error other than by crashing the domain. Reported-by: Julien Grall Signed-off-by: Jan Beulich Acked-by: Roger Pau Monn=C3=A9 Reviewed-by: Kevin Tian --- v3: New (split out). --- Hooking p2m insertion onto arch_domain_creation_finished() isn't very nice, but I couldn't find any better hook (nor a good place where to introduce a new one). In particular there look to be no hvm_funcs hooks being used on a domain-wide basis (except for init/destroy of course). I did consider connecting this to the setting of HVM_PARAM_IDENT_PT, but considered this no better, the more that the tool stack could be smarter and avoid setting that param when not needed. --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1007,6 +1007,8 @@ int arch_domain_soft_reset(struct domain =20 void arch_domain_creation_finished(struct domain *d) { + if ( is_hvm_domain(d) ) + hvm_domain_creation_finished(d); } =20 #define xen_vcpu_guest_context vcpu_guest_context --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -428,6 +428,14 @@ static void vmx_domain_relinquish_resour vmx_free_vlapic_mapping(d); } =20 +static void domain_creation_finished(struct domain *d) +{ + if ( has_vlapic(d) && !mfn_eq(d->arch.hvm.vmx.apic_access_mfn, _mfn(0)= ) && + set_mmio_p2m_entry(d, gaddr_to_gfn(APIC_DEFAULT_PHYS_BASE), + d->arch.hvm.vmx.apic_access_mfn, PAGE_ORDER_4K= ) ) + domain_crash(d); +} + static void vmx_init_ipt(struct vcpu *v) { unsigned int size =3D v->domain->vmtrace_size; @@ -2408,6 +2416,7 @@ static struct hvm_function_table __initd .cpu_dead =3D vmx_cpu_dead, .domain_initialise =3D vmx_domain_initialise, .domain_relinquish_resources =3D vmx_domain_relinquish_resources, + .domain_creation_finished =3D domain_creation_finished, .vcpu_initialise =3D vmx_vcpu_initialise, .vcpu_destroy =3D vmx_vcpu_destroy, .save_cpu_ctxt =3D vmx_save_vmcs_ctxt, @@ -3234,8 +3243,7 @@ static int vmx_alloc_vlapic_mapping(stru clear_domain_page(mfn); d->arch.hvm.vmx.apic_access_mfn =3D mfn; =20 - return set_mmio_p2m_entry(d, gaddr_to_gfn(APIC_DEFAULT_PHYS_BASE), mfn, - PAGE_ORDER_4K); + return 0; } =20 static void vmx_free_vlapic_mapping(struct domain *d) --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -106,6 +106,7 @@ struct hvm_function_table { * Initialise/destroy HVM domain/vcpu resources */ int (*domain_initialise)(struct domain *d); + void (*domain_creation_finished)(struct domain *d); void (*domain_relinquish_resources)(struct domain *d); void (*domain_destroy)(struct domain *d); int (*vcpu_initialise)(struct vcpu *v); @@ -390,6 +391,12 @@ static inline bool hvm_has_set_descripto return hvm_funcs.set_descriptor_access_exiting; } =20 +static inline void hvm_domain_creation_finished(struct domain *d) +{ + if ( hvm_funcs.domain_creation_finished ) + alternative_vcall(hvm_funcs.domain_creation_finished, d); +} + static inline int hvm_guest_x86_mode(struct vcpu *v) { @@ -765,6 +772,11 @@ static inline void hvm_invlpg(const stru { ASSERT_UNREACHABLE(); } + +static inline void hvm_domain_creation_finished(struct domain *d) +{ + ASSERT_UNREACHABLE(); +} =20 /* * Shadow code needs further cleanup to eliminate some HVM-only paths. For From nobody Mon May 6 09:17:26 2024 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; dkim=pass; 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; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1613991457; cv=none; d=zohomail.com; s=zohoarc; b=S1ZSYAgbYlxd/aqGtw1MaI9PHycDRh7Kwr1Odpw0yjrOCmSc8JlcAdNNmEskyqtEpBZ47jsUER/Yr72UnHj24MEwafQO/BOdF1gVs4FZi995j9m4Z9jsCs7dr662ZRs8YCJeWczKtzOqRVs0TgOX6mPITCXCRNS7rfrYCC2e7r0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1613991457; 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=Qwwk9cXc8T/+fcdIQ8thR6iikFAxZizICApHFhBhDOw=; b=a+bHh5scMUqYurezTKHq39SCae8I77wkVkBKTpEPBacYYtskPvdn9sbjNnOUN4pjTPz05ZNBoYICo4p5i3qbLphysq4g+c2DMa1+u9c24uY+hSUKAN2RYvMwqxjbv6bavlB+x627498ILlfoKccaNLA2LFL8Z9peX2TE+beo0/U= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=quarantine dis=none) header.from= Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1613991457371450.3184488727296; Mon, 22 Feb 2021 02:57:37 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.87930.165185 (Exim 4.92) (envelope-from ) id 1lE8u3-0004HM-Ai; Mon, 22 Feb 2021 10:57:23 +0000 Received: by outflank-mailman (output) from mailman id 87930.165185; Mon, 22 Feb 2021 10:57:23 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lE8u3-0004HF-7p; Mon, 22 Feb 2021 10:57:23 +0000 Received: by outflank-mailman (input) for mailman id 87930; Mon, 22 Feb 2021 10:57:22 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lE8u1-0004GV-Uy for xen-devel@lists.xenproject.org; Mon, 22 Feb 2021 10:57:21 +0000 Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 8a651254-2653-4f72-b939-40e592837b4c; Mon, 22 Feb 2021 10:57:20 +0000 (UTC) Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id AEEADAF21; Mon, 22 Feb 2021 10:57:19 +0000 (UTC) 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" X-Inumbo-ID: 8a651254-2653-4f72-b939-40e592837b4c X-Virus-Scanned: by amavisd-new at test-mx.suse.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1613991439; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Qwwk9cXc8T/+fcdIQ8thR6iikFAxZizICApHFhBhDOw=; b=Aa8Rn3JV3/A++QN/tQ0BfOq7HlP0wKM43rw/+19LnVLknS9984ew0c13s+XKbMpmkPU+Gc lRIxWegqDVd8xxURcpwSCAY5vyrHMqAq2QbhC54iSPnyi4OKWlNLnHMxVbMzLlhLeQyDSH F6DRACguw8IiYKB7peSMPkuvicZUF1w= Subject: [PATCH v3 2/2] VMX: use a single, global APIC access page From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: Andrew Cooper , Wei Liu , =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= , Ian Jackson , George Dunlap , Kevin Tian , Jun Nakajima References: <4731a3a3-906a-98ac-11ba-6a0723903391@suse.com> Message-ID: <774a0bf2-d2a4-7dba-bf15-fec8b0ec8c5f@suse.com> Date: Mon, 22 Feb 2021 11:57:19 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 MIME-Version: 1.0 In-Reply-To: <4731a3a3-906a-98ac-11ba-6a0723903391@suse.com> Content-Language: en-US Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) Content-Type: text/plain; charset="utf-8" The address of this page is used by the CPU only to recognize when to access the virtual APIC page instead. No accesses would ever go to this page. It only needs to be present in the (CPU) page tables so that address translation will produce its address as result for respective accesses. By making this page global, we also eliminate the need to refcount it, or to assign it to any domain in the first place. Signed-off-by: Jan Beulich Reviewed-by: Kevin Tian --- v3: Split p2m insertion change to a separate patch. v2: Avoid insertion when !has_vlapic(). Split off change to p2m_get_iommu_flags(). --- I did further consider not allocating any real page at all, but just using the address of some unpopulated space (which would require announcing this page as reserved to Dom0, so it wouldn't put any PCI MMIO BARs there). But I thought this would be too controversial, because of the possible risks associated with this. --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -66,8 +66,7 @@ boolean_param("force-ept", opt_force_ept static void vmx_ctxt_switch_from(struct vcpu *v); static void vmx_ctxt_switch_to(struct vcpu *v); =20 -static int vmx_alloc_vlapic_mapping(struct domain *d); -static void vmx_free_vlapic_mapping(struct domain *d); +static int alloc_vlapic_mapping(void); static void vmx_install_vlapic_mapping(struct vcpu *v); static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr, unsigned int flags); @@ -78,6 +77,8 @@ static int vmx_msr_read_intercept(unsign static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content); static void vmx_invlpg(struct vcpu *v, unsigned long linear); =20 +static mfn_t __read_mostly apic_access_mfn; + /* Values for domain's ->arch.hvm_domain.pi_ops.flags. */ #define PI_CSW_FROM (1u << 0) #define PI_CSW_TO (1u << 1) @@ -401,7 +402,6 @@ static int vmx_domain_initialise(struct .to =3D vmx_ctxt_switch_to, .tail =3D vmx_do_resume, }; - int rc; =20 d->arch.ctxt_switch =3D &csw; =20 @@ -411,28 +411,14 @@ static int vmx_domain_initialise(struct */ d->arch.hvm.vmx.exec_sp =3D is_hardware_domain(d) || opt_ept_exec_sp; =20 - if ( !has_vlapic(d) ) - return 0; - - if ( (rc =3D vmx_alloc_vlapic_mapping(d)) !=3D 0 ) - return rc; - return 0; } =20 -static void vmx_domain_relinquish_resources(struct domain *d) -{ - if ( !has_vlapic(d) ) - return; - - vmx_free_vlapic_mapping(d); -} - static void domain_creation_finished(struct domain *d) { - if ( has_vlapic(d) && !mfn_eq(d->arch.hvm.vmx.apic_access_mfn, _mfn(0)= ) && + if ( has_vlapic(d) && !mfn_eq(apic_access_mfn, _mfn(0)) && set_mmio_p2m_entry(d, gaddr_to_gfn(APIC_DEFAULT_PHYS_BASE), - d->arch.hvm.vmx.apic_access_mfn, PAGE_ORDER_4K= ) ) + apic_access_mfn, PAGE_ORDER_4K) ) domain_crash(d); } =20 @@ -2415,7 +2401,6 @@ static struct hvm_function_table __initd .cpu_up_prepare =3D vmx_cpu_up_prepare, .cpu_dead =3D vmx_cpu_dead, .domain_initialise =3D vmx_domain_initialise, - .domain_relinquish_resources =3D vmx_domain_relinquish_resources, .domain_creation_finished =3D domain_creation_finished, .vcpu_initialise =3D vmx_vcpu_initialise, .vcpu_destroy =3D vmx_vcpu_destroy, @@ -2662,7 +2647,7 @@ const struct hvm_function_table * __init { set_in_cr4(X86_CR4_VMXE); =20 - if ( vmx_vmcs_init() ) + if ( vmx_vmcs_init() || alloc_vlapic_mapping() ) { printk("VMX: failed to initialise.\n"); return NULL; @@ -3217,7 +3202,7 @@ gp_fault: return X86EMUL_EXCEPTION; } =20 -static int vmx_alloc_vlapic_mapping(struct domain *d) +static int __init alloc_vlapic_mapping(void) { struct page_info *pg; mfn_t mfn; @@ -3225,52 +3210,28 @@ static int vmx_alloc_vlapic_mapping(stru if ( !cpu_has_vmx_virtualize_apic_accesses ) return 0; =20 - pg =3D alloc_domheap_page(d, MEMF_no_refcount); + pg =3D alloc_domheap_page(NULL, 0); if ( !pg ) return -ENOMEM; =20 - if ( !get_page_and_type(pg, d, PGT_writable_page) ) - { - /* - * The domain can't possibly know about this page yet, so failure - * here is a clear indication of something fishy going on. - */ - domain_crash(d); - return -ENODATA; - } - mfn =3D page_to_mfn(pg); clear_domain_page(mfn); - d->arch.hvm.vmx.apic_access_mfn =3D mfn; + apic_access_mfn =3D mfn; =20 return 0; } =20 -static void vmx_free_vlapic_mapping(struct domain *d) -{ - mfn_t mfn =3D d->arch.hvm.vmx.apic_access_mfn; - - d->arch.hvm.vmx.apic_access_mfn =3D _mfn(0); - if ( !mfn_eq(mfn, _mfn(0)) ) - { - struct page_info *pg =3D mfn_to_page(mfn); - - put_page_alloc_ref(pg); - put_page_and_type(pg); - } -} - static void vmx_install_vlapic_mapping(struct vcpu *v) { paddr_t virt_page_ma, apic_page_ma; =20 - if ( mfn_eq(v->domain->arch.hvm.vmx.apic_access_mfn, _mfn(0)) ) + if ( !has_vlapic(v->domain) || mfn_eq(apic_access_mfn, _mfn(0)) ) return; =20 ASSERT(cpu_has_vmx_virtualize_apic_accesses); =20 virt_page_ma =3D page_to_maddr(vcpu_vlapic(v)->regs_page); - apic_page_ma =3D mfn_to_maddr(v->domain->arch.hvm.vmx.apic_access_mfn); + apic_page_ma =3D mfn_to_maddr(apic_access_mfn); =20 vmx_vmcs_enter(v); __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma); --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -58,7 +58,6 @@ struct ept_data { #define _VMX_DOMAIN_PML_ENABLED 0 #define VMX_DOMAIN_PML_ENABLED (1ul << _VMX_DOMAIN_PML_ENABLED) struct vmx_domain { - mfn_t apic_access_mfn; /* VMX_DOMAIN_* */ unsigned int status; =20 From nobody Mon May 6 09:17:26 2024 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; dkim=pass; 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; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1618224080; cv=none; d=zohomail.com; s=zohoarc; b=OHWMloencIeyEViwthHov2SELW5W0Ga+0G9hWRcBNzQ4aHdUiql23pHYix2Yd7fL8EsgnPzMR+tyWdO07pICSxrG/1rSuXEDKktoOz4HK/BZJuRqMgqBSjajog5n2LEJKIimFiq15kvKr8oZC47Vfl6OoFRbKpcEiWZaj25TVk4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1618224080; 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=B8XdBCV3ZHHBXe8G2hAxtsic+SP3eU55ZEg8/ttTlE8=; b=awoR5Zq9ar+ABHx9ly3aVl+eTOMywo2/ZXa2gyzQ5HPJsIxRx4NGQ9qT65rb7RuslPV8Pwimmnjflo2MuaC2l7B2EDZ0NImyOTDZRtHLOMWPkN8z8fHDHL2Bl7auNYNjsYP1PUOs3AK0TXw8o3we6T3ZLnFVX77Yv8C0s4/JZB0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=quarantine dis=none) header.from= Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1618224080750160.26452831007418; Mon, 12 Apr 2021 03:41:20 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.108921.207823 (Exim 4.92) (envelope-from ) id 1lVtzu-0007J8-Ur; Mon, 12 Apr 2021 10:40:50 +0000 Received: by outflank-mailman (output) from mailman id 108921.207823; Mon, 12 Apr 2021 10:40:50 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lVtzu-0007J1-Rl; Mon, 12 Apr 2021 10:40:50 +0000 Received: by outflank-mailman (input) for mailman id 108921; Mon, 12 Apr 2021 10:40:50 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lVtzu-0007Iw-6y for xen-devel@lists.xenproject.org; Mon, 12 Apr 2021 10:40:50 +0000 Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id f83a7bb4-9236-424c-b0c1-f508be185464; Mon, 12 Apr 2021 10:40:48 +0000 (UTC) Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 1C3FBAFF3; Mon, 12 Apr 2021 10:40:48 +0000 (UTC) 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" X-Inumbo-ID: f83a7bb4-9236-424c-b0c1-f508be185464 X-Virus-Scanned: by amavisd-new at test-mx.suse.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1618224048; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=B8XdBCV3ZHHBXe8G2hAxtsic+SP3eU55ZEg8/ttTlE8=; b=F6Mx/R3NZXDMaJCRGUeP/JGvovnsVDjpNcXAo841kiP+k6015KT8mgtcZuGaRpXVykMt8W g0Vokvr1giV60l5PNISQc+pDqXD5b41U61pgCvD5+nNizgjEgZobOebEy+2L7BIuCFKi31 d+FU6UYijqjMPGSwoUDbJByMIYdCnR4= From: Jan Beulich Subject: [PATCH v4] VMX: use a single, global APIC access page To: "xen-devel@lists.xenproject.org" Cc: Andrew Cooper , Wei Liu , =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= , George Dunlap , Kevin Tian , Jun Nakajima , Tim Deegan References: <4731a3a3-906a-98ac-11ba-6a0723903391@suse.com> Message-ID: <1c489e77-6e65-6121-6c28-3c4bd377223c@suse.com> Date: Mon, 12 Apr 2021 12:40:48 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: <4731a3a3-906a-98ac-11ba-6a0723903391@suse.com> Content-Language: en-US Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) Content-Type: text/plain; charset="utf-8" The address of this page is used by the CPU only to recognize when to access the virtual APIC page instead. No accesses would ever go to this page. It only needs to be present in the (CPU) page tables so that address translation will produce its address as result for respective accesses. By making this page global, we also eliminate the need to refcount it, or to assign it to any domain in the first place. Signed-off-by: Jan Beulich Reviewed-by: Kevin Tian --- v4: Set PGC_extra on the page. Make shadow mode work. v3: Split p2m insertion change to a separate patch. v2: Avoid insertion when !has_vlapic(). Split off change to p2m_get_iommu_flags(). --- I did further consider not allocating any real page at all, but just using the address of some unpopulated space (which would require announcing this page as reserved to Dom0, so it wouldn't put any PCI MMIO BARs there). But I thought this would be too controversial, because of the possible risks associated with this. --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -66,8 +66,7 @@ boolean_param("force-ept", opt_force_ept static void vmx_ctxt_switch_from(struct vcpu *v); static void vmx_ctxt_switch_to(struct vcpu *v); =20 -static int vmx_alloc_vlapic_mapping(struct domain *d); -static void vmx_free_vlapic_mapping(struct domain *d); +static int alloc_vlapic_mapping(void); static void vmx_install_vlapic_mapping(struct vcpu *v); static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr, unsigned int flags); @@ -78,6 +77,8 @@ static int vmx_msr_read_intercept(unsign static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content); static void vmx_invlpg(struct vcpu *v, unsigned long linear); =20 +static mfn_t __read_mostly apic_access_mfn; + /* Values for domain's ->arch.hvm_domain.pi_ops.flags. */ #define PI_CSW_FROM (1u << 0) #define PI_CSW_TO (1u << 1) @@ -401,7 +402,6 @@ static int vmx_domain_initialise(struct .to =3D vmx_ctxt_switch_to, .tail =3D vmx_do_resume, }; - int rc; =20 d->arch.ctxt_switch =3D &csw; =20 @@ -411,28 +411,22 @@ static int vmx_domain_initialise(struct */ d->arch.hvm.vmx.exec_sp =3D is_hardware_domain(d) || opt_ept_exec_sp; =20 - if ( !has_vlapic(d) ) - return 0; - - if ( (rc =3D vmx_alloc_vlapic_mapping(d)) !=3D 0 ) - return rc; - return 0; } =20 -static void vmx_domain_relinquish_resources(struct domain *d) +static void domain_creation_finished(struct domain *d) { - if ( !has_vlapic(d) ) + gfn_t gfn =3D gaddr_to_gfn(APIC_DEFAULT_PHYS_BASE); + uint8_t ipat; + + if ( !has_vlapic(d) || mfn_eq(apic_access_mfn, _mfn(0)) ) return; =20 - vmx_free_vlapic_mapping(d); -} + ASSERT(epte_get_entry_emt(d, gfn_x(gfn), apic_access_mfn, 0, &ipat, + true) =3D=3D MTRR_TYPE_WRBACK); + ASSERT(ipat); =20 -static void domain_creation_finished(struct domain *d) -{ - if ( has_vlapic(d) && !mfn_eq(d->arch.hvm.vmx.apic_access_mfn, _mfn(0)= ) && - set_mmio_p2m_entry(d, gaddr_to_gfn(APIC_DEFAULT_PHYS_BASE), - d->arch.hvm.vmx.apic_access_mfn, PAGE_ORDER_4K= ) ) + if ( set_mmio_p2m_entry(d, gfn, apic_access_mfn, PAGE_ORDER_4K) ) domain_crash(d); } =20 @@ -2415,7 +2409,6 @@ static struct hvm_function_table __initd .cpu_up_prepare =3D vmx_cpu_up_prepare, .cpu_dead =3D vmx_cpu_dead, .domain_initialise =3D vmx_domain_initialise, - .domain_relinquish_resources =3D vmx_domain_relinquish_resources, .domain_creation_finished =3D domain_creation_finished, .vcpu_initialise =3D vmx_vcpu_initialise, .vcpu_destroy =3D vmx_vcpu_destroy, @@ -2662,7 +2655,7 @@ const struct hvm_function_table * __init { set_in_cr4(X86_CR4_VMXE); =20 - if ( vmx_vmcs_init() ) + if ( vmx_vmcs_init() || alloc_vlapic_mapping() ) { printk("VMX: failed to initialise.\n"); return NULL; @@ -3224,7 +3217,7 @@ gp_fault: return X86EMUL_EXCEPTION; } =20 -static int vmx_alloc_vlapic_mapping(struct domain *d) +static int __init alloc_vlapic_mapping(void) { struct page_info *pg; mfn_t mfn; @@ -3232,52 +3225,31 @@ static int vmx_alloc_vlapic_mapping(stru if ( !cpu_has_vmx_virtualize_apic_accesses ) return 0; =20 - pg =3D alloc_domheap_page(d, MEMF_no_refcount); + pg =3D alloc_domheap_page(NULL, 0); if ( !pg ) return -ENOMEM; =20 - if ( !get_page_and_type(pg, d, PGT_writable_page) ) - { - /* - * The domain can't possibly know about this page yet, so failure - * here is a clear indication of something fishy going on. - */ - domain_crash(d); - return -ENODATA; - } + /* Arrange for epte_get_entry_emt() to recognize this page as "special= ". */ + pg->count_info |=3D PGC_extra; =20 mfn =3D page_to_mfn(pg); clear_domain_page(mfn); - d->arch.hvm.vmx.apic_access_mfn =3D mfn; + apic_access_mfn =3D mfn; =20 return 0; } =20 -static void vmx_free_vlapic_mapping(struct domain *d) -{ - mfn_t mfn =3D d->arch.hvm.vmx.apic_access_mfn; - - d->arch.hvm.vmx.apic_access_mfn =3D _mfn(0); - if ( !mfn_eq(mfn, _mfn(0)) ) - { - struct page_info *pg =3D mfn_to_page(mfn); - - put_page_alloc_ref(pg); - put_page_and_type(pg); - } -} - static void vmx_install_vlapic_mapping(struct vcpu *v) { paddr_t virt_page_ma, apic_page_ma; =20 - if ( mfn_eq(v->domain->arch.hvm.vmx.apic_access_mfn, _mfn(0)) ) + if ( !has_vlapic(v->domain) || mfn_eq(apic_access_mfn, _mfn(0)) ) return; =20 ASSERT(cpu_has_vmx_virtualize_apic_accesses); =20 virt_page_ma =3D page_to_maddr(vcpu_vlapic(v)->regs_page); - apic_page_ma =3D mfn_to_maddr(v->domain->arch.hvm.vmx.apic_access_mfn); + apic_page_ma =3D mfn_to_maddr(apic_access_mfn); =20 vmx_vmcs_enter(v); __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma); --- a/xen/arch/x86/mm/shadow/set.c +++ b/xen/arch/x86/mm/shadow/set.c @@ -94,6 +94,22 @@ shadow_get_page_from_l1e(shadow_l1e_t sl ASSERT(!sh_l1e_is_magic(sl1e)); ASSERT(shadow_mode_refcounts(d)); =20 + /* + * VMX'es APIC access MFN is just a surrogate page. It doesn't actual= ly + * get accessed, and hence there's no need to refcount it (and refcoun= ting + * would fail, due to the page having no owner). + */ + if ( mfn_valid(mfn =3D shadow_l1e_get_mfn(sl1e)) ) + { + const struct page_info *pg =3D mfn_to_page(mfn); + + if ( !page_get_owner(pg) && (pg->count_info & PGC_extra) ) + { + ASSERT(type =3D=3D p2m_mmio_direct); + return 0; + } + } + res =3D get_page_from_l1e(sl1e, d, d); =20 /* --- a/xen/arch/x86/mm/shadow/types.h +++ b/xen/arch/x86/mm/shadow/types.h @@ -276,9 +276,20 @@ int shadow_set_l4e(struct domain *d, sha static void inline shadow_put_page_from_l1e(shadow_l1e_t sl1e, struct domain *d) { + mfn_t mfn; + if ( !shadow_mode_refcounts(d) ) return; =20 + if ( mfn_valid(mfn =3D shadow_l1e_get_mfn(sl1e)) ) + { + const struct page_info *pg =3D mfn_to_page(mfn); + + /* See the respective comment in shadow_get_page_from_l1e(). */ + if ( !page_get_owner(pg) && (pg->count_info & PGC_extra) ) + return; + } + put_page_from_l1e(sl1e, d); } =20 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -58,7 +58,6 @@ struct ept_data { #define _VMX_DOMAIN_PML_ENABLED 0 #define VMX_DOMAIN_PML_ENABLED (1ul << _VMX_DOMAIN_PML_ENABLED) struct vmx_domain { - mfn_t apic_access_mfn; /* VMX_DOMAIN_* */ unsigned int status; =20