From nobody Wed Feb 5 19:59:12 2025 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=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1734632238; cv=none; d=zohomail.com; s=zohoarc; b=UmwJdFX5wmlXaH8s27ZkTK1jTbyc52OaAhnQIA+KOtBaeG98TvS+EnY2ExCrThC+UCIJXhw6NxRmFZXiz+9HjQscZa/Ok7Tg0yAW9M64sXdtr1ctyLhFaxQYOySG5mexNpNfJN5ERS8HB1rOsvHRvOEV9knnK6mui/LI/iHDJ+E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1734632238; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=r7rrd3s6trX0PM3fTY21ALz1gAXhr7UFRn3XH1zFrF0=; b=i6JkitCBqcs9bfEmw+IXwxnIYqF96iG7z4QO1bUZ3Z1ub6jVXU3NEk/lEG4hYWQS2t/WTZKlAAHBaQJl8FxxNH500cykFZcucWRwk1hXwfsnFG4gDqRoemQRKsoFIBww5GU2fEsaXRMNRt2QYzLdK1pGhMecjSE+xm/qLv6UiXc= 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=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1734632238243165.39638115482444; Thu, 19 Dec 2024 10:17:18 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.861433.1273399 (Exim 4.92) (envelope-from ) id 1tOL56-00083a-BF; Thu, 19 Dec 2024 18:17:04 +0000 Received: by outflank-mailman (output) from mailman id 861433.1273399; Thu, 19 Dec 2024 18:17:04 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tOL56-00083R-7Q; Thu, 19 Dec 2024 18:17:04 +0000 Received: by outflank-mailman (input) for mailman id 861433; Thu, 19 Dec 2024 18:17:02 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tOL54-0007Z2-AV for xen-devel@lists.xenproject.org; Thu, 19 Dec 2024 18:17:02 +0000 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [2a00:1450:4864:20::42b]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 7139613e-be35-11ef-a0d8-8be0dac302b0; Thu, 19 Dec 2024 19:17:01 +0100 (CET) Received: by mail-wr1-x42b.google.com with SMTP id ffacd0b85a97d-385d851e7c3so47936f8f.3 for ; Thu, 19 Dec 2024 10:17:01 -0800 (PST) Received: from lab.home (dynamic-2a00-1028-83a4-4bca-c0bb-96ff-feed-9d50.ipv6.o2.cz. [2a00:1028:83a4:4bca:c0bb:96ff:feed:9d50]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38a1c8ac93csm2089713f8f.95.2024.12.19.10.16.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Dec 2024 10:17:00 -0800 (PST) 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: 7139613e-be35-11ef-a0d8-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734632220; x=1735237020; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=r7rrd3s6trX0PM3fTY21ALz1gAXhr7UFRn3XH1zFrF0=; b=QquTd7fi2AEqSYwsun0yHQ95ExkeEUxLcckXS82LxIWRTL5BlkNXvoDGnKsTh9SZ7T /qb1jc/uIHFk3TGH4dLf1d/iAqs3nwS2GW0fzxnvMfS3LDa5EQI7+1JzL75/ThNAefjn UXVk2nJFevY59mLAceqx//u+usbpRtCULp4i1kIN6bnUNzETgnb9YSiSezdU2ttWZmYf poE57b6rKzasHtb7Z3wcjmDIR3ZArBzVwpOT+SdyJhkb8/L3wJiKrtlDIvliHOD4MwJO w+38OhQBrV5x3apRHXEWv/PXZtnWh9GuhkByFQaVdvSQatIImTwShEyAtmsJn73lwrKX Hm/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734632220; x=1735237020; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=r7rrd3s6trX0PM3fTY21ALz1gAXhr7UFRn3XH1zFrF0=; b=IV4HIkry0acxDqatB3rumlAp/Ih6SWbS36G/iVz20Z+TzO5uHJg4vxKLKKAts51HFy 8aEbKnqnGMHqKsVENHohEceokCTMJzJfzrd+jhiojmt0o4GbH9wgUHOzALebMP9Lpa0e oDhjLE8RSZtXIMsEo2TPU2AvYekSrKpJIlISXZuvcDxM3BdgGbBpQ9+ykFbzzbBka1PT XSbnhYao5qQUdbc1UB3gjUxDY3AQYwsF6WMz4+YwosfaIw0aUeNk0L5qYObr5ZzPxnHl KAmcI+Ctajmhjtguses3+thd2SMjVRn7xMTwFECgYBUTZhsnbTAOKWNUBo6nXdSgTGVd oo1Q== X-Gm-Message-State: AOJu0Yyzp67CnCCnynbomY0lI+Jom+KZ6sgS10CdPhz+/CuDt0A9IX5i Y1iXNi9IhmVhKXmGK7+o/TutQzq0Rm0q6pZc+ty3uaxj0GsPYa83fOS0+w== X-Gm-Gg: ASbGncumK05103qsiWezt3DiQ0wkQiQ0+dgaXxpvbePrjwibcCW1azeaXG9LVYOv4Xc 6u1K42mcPOHFw2kzMYfbdgLDP/bm9UUw2iFlVj1UG845YYxHnEYLJj2ejEC1PsHl6IK2xGif/DZ DRtK0UF/v2i3F7lekwGEe7BsP7Wr8mL5d5R7HSyUvQn09m8qobC1Sj+AwvDvSyA3UKrmbowiXce SPTuTeaNbcppnnO3jHITbpBdIYljh2MxHP55F4hi6dRZ5ZGYBZxbBegWZExVde3vtDEFI3N3Mvx 5cF5NYJ4+RMrFFTUrChqci1PadO8+UtQtBh384Jvh4ibYYD7UgRFB/1m X-Google-Smtp-Source: AGHT+IG6sGvgaupsPXBbHAqlSjnaWCcGO41VPto1cfnUSpDsBERruG5IodVRx03AcjtikwrKPSh/TA== X-Received: by 2002:a05:6000:71b:b0:385:ea11:dd8f with SMTP id ffacd0b85a97d-38a221f780bmr34159f8f.7.1734632220360; Thu, 19 Dec 2024 10:17:00 -0800 (PST) From: "=?UTF-8?q?Petr=20Bene=C5=A1?=" X-Google-Original-From: =?UTF-8?q?Petr=20Bene=C5=A1?= To: xen-devel@lists.xenproject.org Cc: =?UTF-8?q?Petr=20Bene=C5=A1?= , Tamas K Lengyel , Alexandru Isaila , Petre Pircalabu , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH 2/2] x86: Add Support for Paging-Write Feature Date: Thu, 19 Dec 2024 18:16:52 +0000 Message-Id: <95580d02390056ea10eb80439f9d3ef9d2297ecc.1734631969.git.w1benny@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1734632239350116600 From: Petr Bene=C5=A1 This patch introduces a new XENMEM_access_r_pw permission. Functionally, it= is similar to XENMEM_access_r, but for processors with TERTIARY_EXEC_EPT_P= AGING_WRITE support (Intel 12th Gen/Alder Lake and later), it also permits = the CPU to write to the page during guest page-table walks (e.g., updating = A/D bits) without triggering an EPT violation. This behavior works by both enabling the EPT paging-write feature and setti= ng the EPT paging-write flag in the EPT leaf entry. This feature provides a significant performance boost for introspection too= ls that monitor guest page-table updates. Previously, every page-table modi= fication by the guest=E2=80=94including routine updates like setting A/D bi= ts=E2=80=94triggered an EPT violation, adding unnecessary overhead. The new= XENMEM_access_r_pw permission allows these "uninteresting" updates to occu= r without EPT violations, improving efficiency. Additionally, this feature simplifies the handling of race conditions in sc= enarios where an introspection tool: - Sets an "invisible breakpoint" in the altp2m view for a function F - Monitors guest page-table updates to track whether the page containing F = is paged out - Encounters a cleared Access (A) bit on the page containing F while the gu= est is about to execute the breakpoint In the current implementation: - If xc_monitor_inguest_pagefault() is enabled, the introspection tool must= emulate both the breakpoint and the setting of the Access bit. - If xc_monitor_inguest_pagefault() is disabled, Xen handles the EPT violat= ion without notifying the introspection tool, setting the Access bit and em= ulating the instruction. However, Xen fetches the instruction from the defa= ult view instead of the altp2m view, potentially causing the breakpoint to = be missed. With this patch, setting XENMEM_access_r_pw for monitored guest page-tables= prevents EPT violations in these cases. This change enhances performance a= nd reduces complexity for introspection tools, ensuring seamless breakpoint= handling while tracking guest page-table updates. Acked-by: Tamas K Lengyel --- xen/arch/arm/mem_access.c | 4 ++++ xen/arch/arm/mmu/p2m.c | 1 + xen/arch/x86/hvm/hvm.c | 1 + xen/arch/x86/hvm/monitor.c | 1 + xen/arch/x86/hvm/vmx/vmcs.c | 4 +++- xen/arch/x86/include/asm/hvm/vmx/vmcs.h | 3 +++ xen/arch/x86/include/asm/p2m.h | 1 + xen/arch/x86/mm/hap/nested_hap.c | 3 +++ xen/arch/x86/mm/mem_access.c | 3 +++ xen/arch/x86/mm/p2m-ept.c | 4 ++++ xen/include/public/memory.h | 9 +++++++++ xen/include/xen/mem_access.h | 6 ++++++ 12 files changed, 39 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/mem_access.c b/xen/arch/arm/mem_access.c index 0ec3462364..2af92bb402 100644 --- a/xen/arch/arm/mem_access.c +++ b/xen/arch/arm/mem_access.c @@ -32,6 +32,7 @@ static int __p2m_get_mem_access(struct domain *d, gfn_t g= fn, ACCESS(rwx), ACCESS(rx2rw), ACCESS(n2rwx), + ACCESS(r_pw), #undef ACCESS }; =20 @@ -172,6 +173,7 @@ p2m_mem_access_check_and_get_page(vaddr_t gva, unsigned= long flag, break; else goto err; + case XENMEM_access_r_pw: case XENMEM_access_rx2rw: case XENMEM_access_rx: case XENMEM_access_r: @@ -253,6 +255,7 @@ bool p2m_mem_access_check(paddr_t gpa, vaddr_t gla, con= st struct npfec npfec) violation =3D npfec.read_access || npfec.insn_fetch; break; case XENMEM_access_r: + case XENMEM_access_r_pw: violation =3D npfec.write_access || npfec.insn_fetch; break; default: @@ -361,6 +364,7 @@ long p2m_set_mem_access(struct domain *d, gfn_t gfn, ui= nt32_t nr, ACCESS(rwx), ACCESS(rx2rw), ACCESS(n2rwx), + ACCESS(r_pw), #undef ACCESS }; =20 diff --git a/xen/arch/arm/mmu/p2m.c b/xen/arch/arm/mmu/p2m.c index 28df6e5d03..7642dbc7c5 100644 --- a/xen/arch/arm/mmu/p2m.c +++ b/xen/arch/arm/mmu/p2m.c @@ -597,6 +597,7 @@ static void p2m_set_permission(lpae_t *e, p2m_type_t t,= p2m_access_t a) e->p2m.read =3D 0; break; case p2m_access_r: + case p2m_access_r_pw: e->p2m.write =3D 0; e->p2m.xn =3D 1; break; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 74e58c653e..495c8290ca 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -1897,6 +1897,7 @@ int hvm_hap_nested_page_fault(paddr_t gpa, unsigned l= ong gla, violation =3D npfec.read_access || npfec.write_access || npfec= .insn_fetch; break; case p2m_access_r: + case p2m_access_r_pw: violation =3D npfec.write_access || npfec.insn_fetch; break; case p2m_access_w: diff --git a/xen/arch/x86/hvm/monitor.c b/xen/arch/x86/hvm/monitor.c index 74621000b2..523586ca98 100644 --- a/xen/arch/x86/hvm/monitor.c +++ b/xen/arch/x86/hvm/monitor.c @@ -295,6 +295,7 @@ bool hvm_monitor_check_p2m(unsigned long gla, gfn_t gfn= , uint32_t pfec, =20 case XENMEM_access_r: case XENMEM_access_n: + case XENMEM_access_r_pw: if ( pfec & PFEC_write_access ) req.u.mem_access.flags |=3D MEM_ACCESS_R | MEM_ACCESS_W; if ( pfec & PFEC_insn_fetch ) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 147e998371..8c0ea789c1 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -203,6 +203,7 @@ static void __init vmx_display_features(void) P(cpu_has_vmx_bus_lock_detection, "Bus Lock Detection"); P(cpu_has_vmx_notify_vm_exiting, "Notify VM Exit"); P(cpu_has_vmx_virt_spec_ctrl, "Virtualize SPEC_CTRL"); + P(cpu_has_vmx_ept_paging_write, "EPT Paging-Write"); #undef P =20 if ( !printed ) @@ -366,7 +367,8 @@ static int vmx_init_vmcs_config(bool bsp) =20 if ( _vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_TERTIARY_CONTROL= S ) { - uint64_t opt =3D TERTIARY_EXEC_VIRT_SPEC_CTRL; + uint64_t opt =3D (TERTIARY_EXEC_VIRT_SPEC_CTRL | + TERTIARY_EXEC_EPT_PAGING_WRITE); =20 _vmx_tertiary_exec_control =3D adjust_vmx_controls2( "Tertiary Exec Control", 0, opt, diff --git a/xen/arch/x86/include/asm/hvm/vmx/vmcs.h b/xen/arch/x86/include= /asm/hvm/vmx/vmcs.h index 939b87eb50..e1d3398141 100644 --- a/xen/arch/x86/include/asm/hvm/vmx/vmcs.h +++ b/xen/arch/x86/include/asm/hvm/vmx/vmcs.h @@ -273,6 +273,9 @@ extern uint64_t vmx_tertiary_exec_control; #define cpu_has_vmx_virt_spec_ctrl \ (vmx_tertiary_exec_control & TERTIARY_EXEC_VIRT_SPEC_CTRL) =20 +#define cpu_has_vmx_ept_paging_write \ + (vmx_tertiary_exec_control & TERTIARY_EXEC_EPT_PAGING_WRITE) + #define VMX_EPT_EXEC_ONLY_SUPPORTED 0x00000001 #define VMX_EPT_WALK_LENGTH_4_SUPPORTED 0x00000040 #define VMX_EPT_MEMORY_TYPE_UC 0x00000100 diff --git a/xen/arch/x86/include/asm/p2m.h b/xen/arch/x86/include/asm/p2m.h index e6de37f108..aa1bf7c9d0 100644 --- a/xen/arch/x86/include/asm/p2m.h +++ b/xen/arch/x86/include/asm/p2m.h @@ -980,6 +980,7 @@ static inline unsigned int p2m_access_to_iommu_flags(p2= m_access_t p2ma) case p2m_access_r: case p2m_access_rx: case p2m_access_rx2rw: + case p2m_access_r_pw: return IOMMUF_readable; =20 case p2m_access_w: diff --git a/xen/arch/x86/mm/hap/nested_hap.c b/xen/arch/x86/mm/hap/nested_= hap.c index cc7bc6e5ea..255fba7e1c 100644 --- a/xen/arch/x86/mm/hap/nested_hap.c +++ b/xen/arch/x86/mm/hap/nested_hap.c @@ -213,6 +213,9 @@ int nestedhvm_hap_nested_page_fault( case p2m_access_n2rwx: p2ma_10 =3D p2m_access_n; break; + case p2m_access_r_pw: + p2ma_10 =3D p2m_access_r; + break; default: p2ma_10 =3D p2m_access_n; /* For safety, remove all permissions. */ diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c index 60a0cce68a..21b5b7ecda 100644 --- a/xen/arch/x86/mm/mem_access.c +++ b/xen/arch/x86/mm/mem_access.c @@ -45,6 +45,7 @@ static int _p2m_get_mem_access(struct p2m_domain *p2m, gf= n_t gfn, ACCESS(rwx), ACCESS(rx2rw), ACCESS(n2rwx), + ACCESS(r_pw), #undef ACCESS }; =20 @@ -94,6 +95,7 @@ bool p2m_mem_access_emulate_check(struct vcpu *v, break; =20 case XENMEM_access_r: + case XENMEM_access_r_pw: violation =3D data->flags & MEM_ACCESS_WX; break; =20 @@ -312,6 +314,7 @@ bool xenmem_access_to_p2m_access(const struct p2m_domai= n *p2m, ACCESS(rwx), ACCESS(rx2rw), ACCESS(n2rwx), + ACCESS(r_pw), #undef ACCESS }; =20 diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c index 21728397f9..5ad78ae4b5 100644 --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -176,6 +176,10 @@ static void ept_p2m_type_to_flags(const struct p2m_dom= ain *p2m, break; =20 case p2m_access_rwx: break; + case p2m_access_r_pw: + entry->w =3D entry->x =3D 0; + entry->pw =3D !!cpu_has_vmx_ept_paging_write; + break; } =20 /* diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index 5e545ae9a4..bd9fc37b52 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -426,6 +426,15 @@ typedef enum { * pausing the vcpu */ XENMEM_access_n2rwx, + + /* + * Same as XENMEM_access_r, but on processors with + * the TERTIARY_EXEC_EPT_PAGING_WRITE support, + * CPU-initiated page-table walks can still + * write to it (e.g., update A/D bits) + */ + XENMEM_access_r_pw, + /* Take the domain default */ XENMEM_access_default } xenmem_access_t; diff --git a/xen/include/xen/mem_access.h b/xen/include/xen/mem_access.h index 87d93b31f6..2231341b5d 100644 --- a/xen/include/xen/mem_access.h +++ b/xen/include/xen/mem_access.h @@ -64,6 +64,12 @@ typedef enum { * generates an event but does not pause the * vcpu */ =20 + p2m_access_r_pw =3D 10, /* Special: same as R, but on processors with + * the TERTIARY_EXEC_EPT_PAGING_WRITE support, + * CPU-initiated page-table walks can still + * write to it (e.g., update A/D bits) + */ + /* NOTE: Assumed to be only 4 bits right now on x86. */ } p2m_access_t; =20 --=20 2.34.1