From nobody Wed Feb 5 12:02:22 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 header.i=dpsmith@apertussolutions.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=pass (i=1 dmarc=pass fromdomain=apertussolutions.com) ARC-Seal: i=2; a=rsa-sha256; t=1736516280; cv=pass; d=zohomail.com; s=zohoarc; b=NYWiwZP7ihydwE9fvPwcHKhhDcivHEJxjxBoK2s2QU/Xlb3etsICDldLwN3OAJwG4Se41Uv95/Rw91Hh1wCyTAx/TO1AD5ivXgNMWOYJnrXJlwST4CbR2Th0riVc9O2B90IQ924S8HIBX+CS0MVsi2tn3DZfBfmE/eesZxqyCaI= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1736516280; h=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=zaIclZ+P2Am/QS9whECQfa2MB2jJxPcdNJMvnaSU7vM=; b=RSO13sN5564b2clqveP0WGeKR/jss16HpQxk7fU4jqk5hQekgMaJ0zh/w4DiIzOiZ6sq/L1gp51OEb2ny8RQ46NEjVAtpbKMmLawRslk281FFAzu5JP7/sBxtCMN3McaIsIpXSnc89wgGVPdA3JctDdMOyyl0eERpOU+TP+5CZk= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass header.i=dpsmith@apertussolutions.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=pass (i=1 dmarc=pass fromdomain=apertussolutions.com) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1736516280431655.264810281859; Fri, 10 Jan 2025 05:38:00 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.869622.1281073 (Exim 4.92) (envelope-from ) id 1tWFCt-0001pB-No; Fri, 10 Jan 2025 13:37:47 +0000 Received: by outflank-mailman (output) from mailman id 869622.1281073; Fri, 10 Jan 2025 13:37:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tWFCt-0001p4-Jv; Fri, 10 Jan 2025 13:37:47 +0000 Received: by outflank-mailman (input) for mailman id 869622; Fri, 10 Jan 2025 13:37:45 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tWFCr-0001Tj-Qk for xen-devel@lists.xenproject.org; Fri, 10 Jan 2025 13:37:45 +0000 Received: from sender4-of-o51.zoho.com (sender4-of-o51.zoho.com [136.143.188.51]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 11371c7b-cf58-11ef-99a4-01e77a169b0f; Fri, 10 Jan 2025 14:37:43 +0100 (CET) Received: by mx.zohomail.com with SMTPS id 1736516242403449.7374866615795; Fri, 10 Jan 2025 05:37:22 -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: 11371c7b-cf58-11ef-99a4-01e77a169b0f ARC-Seal: i=1; a=rsa-sha256; t=1736516246; cv=none; d=zohomail.com; s=zohoarc; b=Ge2D30IO27VeqKRXwsiy17cuGJGBbakTvc8CxdUtzOlVdW76LzLwwNRmctD0/hVq6BK/JtWkQyDsrZY235PkIerA3fhnMoW3fkaoJqffEwb7SG8F58FXTn/NK+Hc7P0BAIoJhIGu1y8fxpe8MfL6TFXQNglMRcBRJ5xMz0tcBWU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1736516246; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=zaIclZ+P2Am/QS9whECQfa2MB2jJxPcdNJMvnaSU7vM=; b=GNx4exy1z6tTRp/E/vh3fiN0RiHbQhxukSPIIv8i8erugiQthxKaSTKafyHHFmdr9A8AYEtPGkKflz38Znek12cbNu1KKhUdu9aYbCWODrkPQHm7tG5QmcNWKCP9ZSUBvrqx1m+Ku1JKhHY+a5QAaT7sfhFat7iHzcI9mvTZigo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=apertussolutions.com; spf=pass smtp.mailfrom=dpsmith@apertussolutions.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1736516246; s=zoho; d=apertussolutions.com; i=dpsmith@apertussolutions.com; h=From:From:To:To:Cc:Cc:Subject:Subject:Date:Date:Message-Id:Message-Id:In-Reply-To:References:MIME-Version:Content-Transfer-Encoding:Reply-To; bh=zaIclZ+P2Am/QS9whECQfa2MB2jJxPcdNJMvnaSU7vM=; b=CAI5rQGUA1zzYGkBfQahJwD4Vd9j4bDMPZIjf1i9GPsAP6fGef+QI5FUcc89Hp62 4cWN3mdpCmKK6XcfwJICvNI06xgVzN9jm+S4MLTyd4vphdhg+6C3XNU2BkW4aaeXfJc 7Q8tnDxOoZPf0Ujp/nK9VoTqFEHlhJBbWYYIH8Ck= From: "Daniel P. Smith" To: xen-devel@lists.xenproject.org Cc: openxt@googlegroups.com, "Daniel P. Smith" , Christopher Clark , Christopher Clark , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini Subject: [PATCH 1/2] gnttab: introduce version agnostic macros Date: Fri, 10 Jan 2025 13:37:10 +0000 Message-Id: <20250110133711.3958202-2-dpsmith@apertussolutions.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250110133711.3958202-1-dpsmith@apertussolutions.com> References: <20250110133711.3958202-1-dpsmith@apertussolutions.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMailClient: External X-ZohoMail-DKIM: pass (identity dpsmith@apertussolutions.com) X-ZM-MESSAGEID: 1736516283632019000 Content-Type: text/plain; charset="utf-8" Introduce a set of macros that abstract version specifics of the grant table structures. This lays the ground work for being able to turn off v2 logic a= nd code. Authored-by: Christopher Clark Signed-off-by: Christopher Clark Signed-off-by: Daniel P. Smith --- xen/common/grant_table.c | 114 +++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 66 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 6c77867f8c..f70a5333d8 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -181,6 +181,7 @@ static int cf_check parse_gnttab_max_maptrack_frames(co= nst char *arg) #ifndef GNTTAB_MAX_VERSION #define GNTTAB_MAX_VERSION 2 #endif +#define get_gt_version(gt) ((gt)->gt_version) =20 unsigned int __read_mostly opt_gnttab_max_version =3D GNTTAB_MAX_VERSION; static bool __read_mostly opt_transitive_grants =3D true; @@ -310,16 +311,30 @@ nr_maptrack_frames(struct grant_table *t) #define SHGNT_PER_PAGE_V1 (PAGE_SIZE / sizeof(grant_entry_v1_t)) #define shared_entry_v1(t, e) \ ((t)->shared_v1[(e)/SHGNT_PER_PAGE_V1][(e)%SHGNT_PER_PAGE_V1]) + +/* Operations providing a single interface agnostic to grant table version= */ #define SHGNT_PER_PAGE_V2 (PAGE_SIZE / sizeof(grant_entry_v2_t)) #define shared_entry_v2(t, e) \ ((t)->shared_v2[(e)/SHGNT_PER_PAGE_V2][(e)%SHGNT_PER_PAGE_V2]) + +#define shared_entry_full_frame(gt, ref) \ + ( get_gt_version(gt) =3D=3D 1 ? shared_entry_v1((gt), (ref)).frame : \ + shared_entry_v2((gt), (ref)).full_page.fra= me ) +#define set_shared_entry(gt, ref, val) \ + ( get_gt_version(gt) =3D=3D 1 ? (shared_entry_v1((gt), (ref)).frame = =3D (val)) : \ + (shared_entry_v2((gt), (ref)).full_page.fr= ame =3D (val)) ) +#define status_addr(gt, ref, flags_addr) \ + ( evaluate_nospec(get_gt_version(gt) =3D=3D 1) ? (flags_addr) : &statu= s_entry((gt), (ref)) ) + #define STGNT_PER_PAGE (PAGE_SIZE / sizeof(grant_status_t)) #define status_entry(t, e) \ ((t)->status[(e)/STGNT_PER_PAGE][(e)%STGNT_PER_PAGE]) + + static grant_entry_header_t * shared_entry_header(struct grant_table *t, grant_ref_t ref) { - switch ( t->gt_version ) + switch ( get_gt_version(t) ) { case 1: /* Returned values should be independent of speculative execution = */ @@ -709,7 +724,7 @@ get_maptrack_handle( /* Number of grant table entries. Caller must hold d's grant table lock. */ static unsigned int nr_grant_entries(struct grant_table *gt) { - switch ( gt->gt_version ) + switch ( get_gt_version(gt) ) { #define f2e(nr, ver) (((nr) << PAGE_SHIFT) / sizeof(grant_entry_v##ver##_t= )) case 1: @@ -1090,23 +1105,20 @@ map_grant_ref( } =20 /* Make sure we do not access memory speculatively */ - status =3D evaluate_nospec(rgt->gt_version =3D=3D 1) ? &shah->flags - : &status_entry(rgt, re= f); + status =3D status_addr(rgt, ref, &shah->flags); =20 if ( !act->pin || (!(op->flags & GNTMAP_readonly) && !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) ) { - if ( (rc =3D _set_status(shah, status, rd, rgt->gt_version, act, + if ( (rc =3D _set_status(shah, status, rd, get_gt_version(rgt), ac= t, op->flags & GNTMAP_readonly, 1, ld->domain_id)) !=3D GNTST_okay ) goto act_release_out; =20 if ( !act->pin ) { - unsigned long gfn =3D evaluate_nospec(rgt->gt_version =3D=3D 1= ) ? - shared_entry_v1(rgt, ref).frame : - shared_entry_v2(rgt, ref).full_page.frame; + unsigned long gfn =3D shared_entry_full_frame(rgt, ref); =20 rc =3D get_paged_frame(gfn, &mfn, &pg, op->flags & GNTMAP_readonly, rd); @@ -1603,11 +1615,7 @@ unmap_common_complete(struct gnttab_unmap_common *op) =20 act =3D active_entry_acquire(rgt, op->ref); sha =3D shared_entry_header(rgt, op->ref); - - if ( evaluate_nospec(rgt->gt_version =3D=3D 1) ) - status =3D &sha->flags; - else - status =3D &status_entry(rgt, op->ref); + status =3D status_addr(rgt, op->ref, &sha->flags); =20 pg =3D !is_iomem_page(act->mfn) ? mfn_to_page(op->mfn) : NULL; =20 @@ -1930,7 +1938,7 @@ gnttab_grow_table(struct domain *d, unsigned int req_= nr_frames) } =20 /* Status pages - version 2 */ - if ( evaluate_nospec(gt->gt_version > 1) ) + if ( evaluate_nospec(get_gt_version(gt) > 1) ) { if ( gnttab_populate_status_frames(d, gt, req_nr_frames) ) goto shared_alloc_failed; @@ -2105,7 +2113,7 @@ gnttab_setup_table( } =20 if ( (op.nr_frames > nr_grant_frames(gt) || - ((gt->gt_version > 1) && + ((get_gt_version(gt) > 1) && (grant_to_status_frames(op.nr_frames) > nr_status_frames(gt))))= && gnttab_grow_table(d, op.nr_frames) ) { @@ -2267,6 +2275,7 @@ gnttab_transfer( mfn_t mfn; unsigned int max_bitsize; struct active_grant_entry *act; + unsigned long frame; =20 if ( !opt_grant_transfer ) return -EOPNOTSUPP; @@ -2354,7 +2363,7 @@ gnttab_transfer( } =20 max_bitsize =3D domain_clamp_alloc_bitsize( - e, e->grant_table->gt_version > 1 || paging_mode_translate(e) + e, get_gt_version(e->grant_table) > 1 || paging_mode_translate= (e) ? BITS_PER_LONG + PAGE_SHIFT : 32 + PAGE_SHIFT); if ( max_bitsize < BITS_PER_LONG + PAGE_SHIFT && (mfn_x(mfn) >> (max_bitsize - PAGE_SHIFT)) ) @@ -2452,22 +2461,12 @@ gnttab_transfer( grant_read_lock(e->grant_table); act =3D active_entry_acquire(e->grant_table, gop.ref); =20 - if ( evaluate_nospec(e->grant_table->gt_version =3D=3D 1) ) - { - grant_entry_v1_t *sha =3D &shared_entry_v1(e->grant_table, gop= .ref); + frame =3D shared_entry_full_frame(e->grant_table, gop.ref); + rc =3D guest_physmap_add_page(e, _gfn(frame), mfn, 0); =20 - rc =3D guest_physmap_add_page(e, _gfn(sha->frame), mfn, 0); - if ( !paging_mode_translate(e) ) - sha->frame =3D mfn_x(mfn); - } - else - { - grant_entry_v2_t *sha =3D &shared_entry_v2(e->grant_table, gop= .ref); + if ( !paging_mode_translate(e) ) + set_shared_entry(e->grant_table, gop.ref, mfn_x(mfn)); =20 - rc =3D guest_physmap_add_page(e, _gfn(sha->full_page.frame), m= fn, 0); - if ( !paging_mode_translate(e) ) - sha->full_page.frame =3D mfn_x(mfn); - } smp_wmb(); shared_entry_header(e->grant_table, gop.ref)->flags |=3D GTF_transfer_completed; @@ -2512,16 +2511,15 @@ release_grant_for_copy( act =3D active_entry_acquire(rgt, gref); sha =3D shared_entry_header(rgt, gref); mfn =3D act->mfn; + status =3D status_addr(rgt, gref, &sha->flags); =20 - if ( evaluate_nospec(rgt->gt_version =3D=3D 1) ) + if ( evaluate_nospec(get_gt_version(rgt) =3D=3D 1) ) { - status =3D &sha->flags; td =3D rd; trans_gref =3D gref; } else { - status =3D &status_entry(rgt, gref); td =3D (act->src_domid =3D=3D rd->domain_id) ? rd : knownalive_domain_from_domid(act->src_domid); trans_gref =3D act->trans_gref; @@ -2573,7 +2571,6 @@ acquire_grant_for_copy( struct active_grant_entry *act; grant_status_t *status; uint32_t old_pin; - domid_t trans_domid; grant_ref_t trans_gref; struct domain *td; mfn_t grant_mfn; @@ -2597,6 +2594,7 @@ acquire_grant_for_copy( /* This call also ensures the above check cannot be passed speculative= ly */ shah =3D shared_entry_header(rgt, gref); act =3D active_entry_acquire(rgt, gref); + old_pin =3D act->pin; =20 /* If already pinned, check the active domid and avoid refcnt overflow= . */ if ( act->pin && @@ -2610,7 +2608,7 @@ acquire_grant_for_copy( goto unlock_out; } =20 - if ( evaluate_nospec(rgt->gt_version =3D=3D 1) ) + if ( evaluate_nospec(get_gt_version(rgt) =3D=3D 1) ) { sha2 =3D NULL; status =3D &shah->flags; @@ -2621,9 +2619,10 @@ acquire_grant_for_copy( status =3D &status_entry(rgt, gref); } =20 - old_pin =3D act->pin; if ( sha2 && (shah->flags & GTF_type_mask) =3D=3D GTF_transitive ) { + domid_t trans_domid; + if ( (!old_pin || (!readonly && !(old_pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)= ))) && (rc =3D _set_status_v2(shah, status, rd, act, readonly, 0, @@ -2752,7 +2751,7 @@ acquire_grant_for_copy( else if ( !old_pin || (!readonly && !(old_pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask= ))) ) { - if ( (rc =3D _set_status(shah, status, rd, rgt->gt_version, act, + if ( (rc =3D _set_status(shah, status, rd, get_gt_version(rgt), ac= t, readonly, 0, ldom)) !=3D GNTST_okay ) goto unlock_out; =20 @@ -3406,7 +3405,7 @@ gnttab_get_version(XEN_GUEST_HANDLE_PARAM(gnttab_get_= version_t) uop) return rc; } =20 - op.version =3D d->grant_table->gt_version; + op.version =3D get_gt_version(d->grant_table); =20 rcu_unlock_domain(d); =20 @@ -3464,7 +3463,7 @@ swap_grant_ref(grant_ref_t ref_a, grant_ref_t ref_b) goto out; } =20 - if ( evaluate_nospec(gt->gt_version =3D=3D 1) ) + if ( evaluate_nospec(get_gt_version(gt) =3D=3D 1) ) { grant_entry_v1_t shared; =20 @@ -3878,10 +3877,7 @@ int gnttab_release_mappings(struct domain *d) =20 act =3D active_entry_acquire(rgt, ref); sha =3D shared_entry_header(rgt, ref); - if ( rgt->gt_version =3D=3D 1 ) - status =3D &sha->flags; - else - status =3D &status_entry(rgt, ref); + status =3D status_addr(rgt, ref, &sha->flags); =20 pg =3D !is_iomem_page(act->mfn) ? mfn_to_page(act->mfn) : NULL; =20 @@ -4047,11 +4043,11 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt,= grant_ref_t ref, =20 grant_read_lock(gt); =20 - if ( gt->gt_version < 1 ) + if ( get_gt_version(gt) < 1 ) rc =3D -EINVAL; else if ( ref >=3D nr_grant_entries(gt) ) rc =3D -ENOENT; - else if ( evaluate_nospec(gt->gt_version =3D=3D 1) ) + else if ( evaluate_nospec(get_gt_version(gt) =3D=3D 1) ) { const grant_entry_v1_t *sha1 =3D &shared_entry_v1(gt, ref); =20 @@ -4072,12 +4068,7 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt, = grant_ref_t ref, if ( !rc && (flags & GTF_type_mask) !=3D GTF_permit_access ) rc =3D -ENXIO; else if ( !rc && status ) - { - if ( evaluate_nospec(gt->gt_version =3D=3D 1) ) - *status =3D flags; - else - *status =3D status_entry(gt, ref); - } + *status =3D *status_addr(gt, ref, &flags); =20 grant_read_unlock(gt); =20 @@ -4131,7 +4122,7 @@ static int gnttab_get_shared_frame_mfn(struct domain = *d, { const struct grant_table *gt =3D d->grant_table; =20 - ASSERT(gt->gt_version !=3D 0); + ASSERT(get_gt_version(gt) !=3D 0); =20 if ( idx >=3D nr_grant_frames(gt) ) { @@ -4204,7 +4195,7 @@ int gnttab_acquire_resource( break; =20 case XENMEM_resource_grant_table_id_status: - if ( gt->gt_version !=3D 2 ) + if ( get_gt_version(gt) !=3D 2 ) break; =20 /* Check that void ** is a suitable representation for gt->status.= */ @@ -4256,7 +4247,7 @@ int gnttab_map_frame(struct domain *d, unsigned long = idx, gfn_t gfn, mfn_t *mfn) =20 grant_write_lock(gt); =20 - if ( evaluate_nospec(gt->gt_version =3D=3D 2) && (idx & XENMAPIDX_gran= t_table_status) ) + if ( evaluate_nospec(get_gt_version(gt) =3D=3D 2) && (idx & XENMAPIDX_= grant_table_status) ) { idx &=3D ~XENMAPIDX_grant_table_status; status =3D true; @@ -4299,7 +4290,7 @@ static void gnttab_usage_print(struct domain *rd) =20 printk("grant-table for remote d%d (v%u)\n" " %u frames (%u max), %u maptrack frames (%u max)\n", - rd->domain_id, gt->gt_version, + rd->domain_id, get_gt_version(gt), nr_grant_frames(gt), gt->max_grant_frames, nr_maptrack_frames(gt), gt->max_maptrack_frames); =20 @@ -4319,17 +4310,8 @@ static void gnttab_usage_print(struct domain *rd) } =20 sha =3D shared_entry_header(gt, ref); - - if ( gt->gt_version =3D=3D 1 ) - { - status =3D sha->flags; - frame =3D shared_entry_v1(gt, ref).frame; - } - else - { - frame =3D shared_entry_v2(gt, ref).full_page.frame; - status =3D status_entry(gt, ref); - } + frame =3D shared_entry_full_frame(gt, ref); + status =3D *status_addr(gt, ref, &sha->flags); =20 first =3D 0; =20 --=20 2.34.1 From nobody Wed Feb 5 12:02:22 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 header.i=dpsmith@apertussolutions.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=pass (i=1 dmarc=pass fromdomain=apertussolutions.com) ARC-Seal: i=2; a=rsa-sha256; t=1736516304; cv=pass; d=zohomail.com; s=zohoarc; b=BHnL7zC+wH1LnGhHnHvSZEsHzAbzIPxzNTMYP9gTtzY4RPMZEyw/KEOX/GAH21BCfn8K5PXwgErPMhSsT2A+BPlkb5b/oQD326U6lUruTEZcopcF6eVkkJyHhB3bOIqhBoBJZn8tqe0WDnIp+qKHLvOVeClc0steB9XOG98UtCk= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1736516304; h=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=TalMMxffA22obSkpHJA9+pUFlwopohYfLzoxicDrWAg=; b=L7dYUmfLfRc4kh4xx1ttnsUFS7XkhnIpk4/jfm+bT2muNIZdd8sswNmrHIHhsN/ZVfs5L4Zaiqk9UDJYSK7Shs8NWs2axR+dVa8JMEUeYTHxl9AD0JGiRwdbggM0OYFekQ7/50Y63jsVoj57P2yYkBCXci8ZDoZXXtbx4hGYyF0= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass header.i=dpsmith@apertussolutions.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=pass (i=1 dmarc=pass fromdomain=apertussolutions.com) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1736516304002527.97246423053; Fri, 10 Jan 2025 05:38:24 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.869631.1281084 (Exim 4.92) (envelope-from ) id 1tWFDF-0002OB-0f; Fri, 10 Jan 2025 13:38:09 +0000 Received: by outflank-mailman (output) from mailman id 869631.1281084; Fri, 10 Jan 2025 13:38:08 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tWFDE-0002O0-SI; Fri, 10 Jan 2025 13:38:08 +0000 Received: by outflank-mailman (input) for mailman id 869631; Fri, 10 Jan 2025 13:38:07 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tWFDD-0001Tj-64 for xen-devel@lists.xenproject.org; Fri, 10 Jan 2025 13:38:07 +0000 Received: from sender4-of-o55.zoho.com (sender4-of-o55.zoho.com [136.143.188.55]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 1dec5cbd-cf58-11ef-99a4-01e77a169b0f; Fri, 10 Jan 2025 14:38:05 +0100 (CET) Received: by mx.zohomail.com with SMTPS id 1736516244589260.226896086339; Fri, 10 Jan 2025 05:37:24 -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: 1dec5cbd-cf58-11ef-99a4-01e77a169b0f ARC-Seal: i=1; a=rsa-sha256; t=1736516248; cv=none; d=zohomail.com; s=zohoarc; b=bge0Npc/yvPU1apIcJZbnCEPHtSDLNiWHQEes6IXzR11LFr2g+Rer8Mdno4C3hhz+AMo3UyWLb8U961X9X1weRlakrP3ZPJnbl6RsmZg+cWwirBv4UsEqOLh2eqYPs3r2mnvnZy0zK8AWUlA+Po2A1sagQYaz5fxuAXTWq+FWk8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1736516248; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=TalMMxffA22obSkpHJA9+pUFlwopohYfLzoxicDrWAg=; b=Bus479CXW8jQiMoj/E8VrbpfuMVq2MQnaeAKvoQx64BLfAD0JxSbzv2IU3yJBTDsEbW2jqjRb9XPDhGs1OlXILN43+cP1O32WQAD7lpjdUbfK0AOaRwxbYlYPuUHxpgXhJVMSJql8QDhXEcAWDCEAkDWH/1OIdpAgi/hDtAFkvg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=apertussolutions.com; spf=pass smtp.mailfrom=dpsmith@apertussolutions.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1736516247; s=zoho; d=apertussolutions.com; i=dpsmith@apertussolutions.com; h=From:From:To:To:Cc:Cc:Subject:Subject:Date:Date:Message-Id:Message-Id:In-Reply-To:References:MIME-Version:Content-Transfer-Encoding:Reply-To; bh=TalMMxffA22obSkpHJA9+pUFlwopohYfLzoxicDrWAg=; b=EtqP8zZ/pq3H7AitaRFXzFZTH43FLC3HWFT7sJfd/FOg7QNBWH85j+jj77GD863w dyYBxwdc/G6IBxFt3GITX+8RWkGrkvPVyHj6RFHFthpJZcGg7gUwIQHW9bHqUqRBXYi +zNblgrmL1eKYzXSFggPCviUYRcSZnfdizlrxn7k= From: "Daniel P. Smith" To: xen-devel@lists.xenproject.org Cc: openxt@googlegroups.com, "Daniel P. Smith" , Christopher Clark , Christopher Clark , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini Subject: [PATCH 2/2] gnttab: make grant table v2 support configurable Date: Fri, 10 Jan 2025 13:37:11 +0000 Message-Id: <20250110133711.3958202-3-dpsmith@apertussolutions.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250110133711.3958202-1-dpsmith@apertussolutions.com> References: <20250110133711.3958202-1-dpsmith@apertussolutions.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMailClient: External X-ZohoMail-DKIM: pass (identity dpsmith@apertussolutions.com) X-ZM-MESSAGEID: 1736516305469019000 Content-Type: text/plain; charset="utf-8" If the v2 interface support is not required, disabling this option will rem= ove substantial amounts of unused code in a critical subsystem. Disables the v2-only GNTTABOP_get_status_frames grant table op. Authored-by: Christopher Clark Signed-off-by: Christopher Clark Signed-off-by: Daniel P. Smith --- docs/misc/xen-command-line.pandoc | 4 +- xen/common/Kconfig | 18 +++++++ xen/common/compat/grant_table.c | 4 ++ xen/common/grant_table.c | 86 ++++++++++++++++++++++++++++--- 4 files changed, 102 insertions(+), 10 deletions(-) diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line= .pandoc index 08b0053f9c..61570308c5 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -1278,8 +1278,8 @@ does not provide `VM_ENTRY_LOAD_GUEST_PAT`. =20 Control various aspects of the grant table behaviour available to guests. =20 -* `max-ver` Select the maximum grant table version to offer to guests. Va= lid -version are 1 and 2. +* `max-ver` Select the maximum grant table version to offer to guests. Only +available when CONFIG_GRANT_TABLE_V2 is set. Valid version are 1 and 2. * `transitive` Permit or disallow the use of transitive grants. Note that= the use of grant table v2 without transitive grants is an ABI breakage from the guests point of view. diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 6166327f4d..378436ca2f 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -23,6 +23,24 @@ config GRANT_TABLE =20 If unsure, say Y. =20 +config GRANT_TABLE_V2 + bool "Grant table version 2 support" if EXPERT + depends on GRANT_TABLE && X86 + help + Grant table interface version 2 is not the default. It has never + been implemented for ARM. + + The version 2 interface enables support for systems with large amounts + of memory and some exotic grant primitives that are not in use by the + supported PV drivers. + + Disabling this option reduces the amount of complex security-critical + hypervisor code in a subsystem of Xen responsible for approximately + 5% of Xen Security Advisories. + + If you do not require large memory support, say N. + If you are paranoid, say N. If unsure, say Y. + config PDX_COMPRESSION bool "PDX (Page inDeX) compression" if EXPERT && !X86 && !RISCV default ARM || PPC diff --git a/xen/common/compat/grant_table.c b/xen/common/compat/grant_tabl= e.c index bbb717bf64..03b99f99dd 100644 --- a/xen/common/compat/grant_table.c +++ b/xen/common/compat/grant_table.c @@ -296,6 +296,9 @@ int compat_grant_table_op( break; =20 case GNTTABOP_get_status_frames: +#ifndef CONFIG_GRANT_TABLE_V2 + rc =3D -ENOSYS; +#else if ( count !=3D 1) { rc =3D -EINVAL; @@ -328,6 +331,7 @@ int compat_grant_table_op( else i =3D 1; } +#endif break; =20 default: diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index f70a5333d8..3a32e44f24 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -59,11 +59,13 @@ struct grant_table { /* Lock protecting the maptrack limit */ spinlock_t maptrack_lock; unsigned int max_version; +#ifdef CONFIG_GRANT_TABLE_V2 /* * Defaults to v1. May be changed with GNTTABOP_set_version. All oth= er * values are invalid. */ unsigned int gt_version; +#endif /* Resource limits of the domain. */ unsigned int max_grant_frames; unsigned int max_maptrack_frames; @@ -83,7 +85,9 @@ struct grant_table { union { void **shared_raw; struct grant_entry_v1 **shared_v1; +#ifdef CONFIG_GRANT_TABLE_V2 union grant_entry_v2 **shared_v2; +#endif }; /* State grant table (see include/public/grant_table.h). */ grant_status_t **status; @@ -178,11 +182,20 @@ static int cf_check parse_gnttab_max_maptrack_frames(= const char *arg) opt_max_maptrack_frames_val); } =20 +#ifdef CONFIG_GRANT_TABLE_V2 + #ifndef GNTTAB_MAX_VERSION #define GNTTAB_MAX_VERSION 2 #endif #define get_gt_version(gt) ((gt)->gt_version) =20 +#else + +#define GNTTAB_MAX_VERSION 1 +#define get_gt_version(gt) 1 + +#endif + unsigned int __read_mostly opt_gnttab_max_version =3D GNTTAB_MAX_VERSION; static bool __read_mostly opt_transitive_grants =3D true; #ifdef CONFIG_PV @@ -193,7 +206,7 @@ static bool __ro_after_init opt_grant_transfer =3D true; =20 static int __init cf_check parse_gnttab(const char *s) { - const char *ss, *e; + const char *ss; int val, rc =3D 0; =20 do { @@ -204,12 +217,17 @@ static int __init cf_check parse_gnttab(const char *s) if ( !strncmp(s, "max-ver:", 8) || !strncmp(s, "max_ver:", 8) ) /* Alias for original XSA-226 pa= tch */ { +#ifdef CONFIG_GRANT_TABLE_V2 + const char *e; long ver =3D simple_strtol(s + 8, &e, 10); =20 if ( e =3D=3D ss && ver >=3D 1 && ver <=3D 2 ) opt_gnttab_max_version =3D ver; else rc =3D -EINVAL; +#else + no_config_param("GRANT_TABLE_V2", "max_ver", s, ss); +#endif } else if ( (val =3D parse_boolean("transitive", s, ss)) >=3D 0 ) opt_transitive_grants =3D val; @@ -313,6 +331,8 @@ nr_maptrack_frames(struct grant_table *t) ((t)->shared_v1[(e)/SHGNT_PER_PAGE_V1][(e)%SHGNT_PER_PAGE_V1]) =20 /* Operations providing a single interface agnostic to grant table version= */ +#ifdef CONFIG_GRANT_TABLE_V2 + #define SHGNT_PER_PAGE_V2 (PAGE_SIZE / sizeof(grant_entry_v2_t)) #define shared_entry_v2(t, e) \ ((t)->shared_v2[(e)/SHGNT_PER_PAGE_V2][(e)%SHGNT_PER_PAGE_V2]) @@ -330,6 +350,14 @@ nr_maptrack_frames(struct grant_table *t) #define status_entry(t, e) \ ((t)->status[(e)/STGNT_PER_PAGE][(e)%STGNT_PER_PAGE]) =20 +#else /* CONFIG_GRANT_TABLE_V2 */ + +#define shared_entry_full_frame(gt, ref) ( shared_entry_v1((gt), (ref)).fr= ame ) +#define set_shared_entry(gt, ref, val) \ + ( shared_entry_v1((gt), (ref)).frame =3D (val) ) +#define status_addr(gt, ref, flags_addr) (flags_addr) + +#endif /* CONFIG_GRANT_TABLE_V2 */ =20 static grant_entry_header_t * shared_entry_header(struct grant_table *t, grant_ref_t ref) @@ -341,10 +369,12 @@ shared_entry_header(struct grant_table *t, grant_ref_= t ref) block_speculation(); return (grant_entry_header_t*)&shared_entry_v1(t, ref); =20 +#ifdef CONFIG_GRANT_TABLE_V2 case 2: /* Returned values should be independent of speculative execution = */ block_speculation(); return &shared_entry_v2(t, ref).hdr; +#endif } =20 ASSERT_UNREACHABLE(); @@ -734,7 +764,7 @@ static unsigned int nr_grant_entries(struct grant_table= *gt) /* Make sure we return a value independently of speculative execut= ion */ block_speculation(); return f2e(nr_grant_frames(gt), 1); - +#ifdef CONFIG_GRANT_TABLE_V2 case 2: BUILD_BUG_ON(f2e(INITIAL_NR_GRANT_FRAMES, 2) < GNTTAB_NR_RESERVED_ENTRIES); @@ -742,6 +772,7 @@ static unsigned int nr_grant_entries(struct grant_table= *gt) /* Make sure we return a value independently of speculative execut= ion */ block_speculation(); return f2e(nr_grant_frames(gt), 2); +#endif #undef f2e } =20 @@ -834,6 +865,7 @@ done: return rc; } =20 +#ifdef CONFIG_GRANT_TABLE_V2 static int _set_status_v2(const grant_entry_header_t *shah, grant_status_t *status, struct domain *rd, @@ -918,7 +950,7 @@ static int _set_status_v2(const grant_entry_header_t *s= hah, done: return rc; } - +#endif =20 static int _set_status(const grant_entry_header_t *shah, grant_status_t *status, @@ -929,11 +961,11 @@ static int _set_status(const grant_entry_header_t *sh= ah, int mapflag, domid_t ldomid) { - - if ( evaluate_nospec(rgt_version =3D=3D 1) ) - return _set_status_v1(shah, rd, act, readonly, mapflag, ldomid); - else +#ifdef CONFIG_GRANT_TABLE_V2 + if ( evaluate_nospec(rgt_version !=3D 1) ) return _set_status_v2(shah, status, rd, act, readonly, mapflag, ld= omid); +#endif + return _set_status_v1(shah, rd, act, readonly, mapflag, ldomid); } =20 /* @@ -1796,6 +1828,12 @@ static int gnttab_populate_status_frames(struct domain *d, struct grant_table *gt, unsigned int req_nr_frames) { +#ifndef CONFIG_GRANT_TABLE_V2 + ASSERT_UNREACHABLE(); + + return 0; +} +#else unsigned int i; unsigned int req_status_frames; =20 @@ -1898,6 +1936,7 @@ gnttab_unpopulate_status_frames(struct domain *d, str= uct grant_table *gt) =20 return 0; } +#endif =20 /* * Grow the grant table. The caller must hold the grant table's @@ -2010,7 +2049,9 @@ int grant_table_init(struct domain *d, int max_grant_= frames, percpu_rwlock_resource_init(>->lock, grant_rwlock); spin_lock_init(>->maptrack_lock); =20 +#ifdef CONFIG_GRANT_TABLE_V2 gt->gt_version =3D 1; +#endif gt->max_grant_frames =3D max_grant_frames; gt->max_maptrack_frames =3D max_maptrack_frames; gt->max_version =3D max_grant_version; @@ -2518,12 +2559,14 @@ release_grant_for_copy( td =3D rd; trans_gref =3D gref; } +#ifdef CONFIG_GRANT_TABLE_V2 else { td =3D (act->src_domid =3D=3D rd->domain_id) ? rd : knownalive_domain_from_domid(act->src_domid); trans_gref =3D act->trans_gref; } +#endif =20 if ( readonly ) { @@ -2613,6 +2656,7 @@ acquire_grant_for_copy( sha2 =3D NULL; status =3D &shah->flags; } +#ifdef CONFIG_GRANT_TABLE_V2 else { sha2 =3D &shared_entry_v2(rgt, gref); @@ -2748,7 +2792,9 @@ acquire_grant_for_copy( act->is_sub_page =3D true; } } - else if ( !old_pin || + else +#endif + if ( !old_pin || (!readonly && !(old_pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask= ))) ) { if ( (rc =3D _set_status(shah, status, rd, get_gt_version(rgt), ac= t, @@ -3165,6 +3211,17 @@ static long gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop) { gnttab_set_version_t op; +#ifndef CONFIG_GRANT_TABLE_V2 + + if ( copy_from_guest(&op, uop, 1) ) + return -EFAULT; + + if ( op.version =3D=3D 1 ) + return 0; + + /* Behave as before set_version was introduced. */ + return -ENOSYS; +#else struct domain *currd =3D current->domain; struct grant_table *gt =3D currd->grant_table; grant_entry_v1_t reserved_entries[GNTTAB_NR_RESERVED_ENTRIES]; @@ -3309,8 +3366,10 @@ gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set= _version_t) uop) res =3D -EFAULT; =20 return res; +#endif } =20 +#ifdef CONFIG_GRANT_TABLE_V2 static long gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gnttab_get_status_frames_t= ) uop, unsigned int count) @@ -3383,6 +3442,7 @@ gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gntta= b_get_status_frames_t) uop, =20 return 0; } +#endif =20 static long gnttab_get_version(XEN_GUEST_HANDLE_PARAM(gnttab_get_version_t) uop) @@ -3471,6 +3531,7 @@ swap_grant_ref(grant_ref_t ref_a, grant_ref_t ref_b) shared_entry_v1(gt, ref_a) =3D shared_entry_v1(gt, ref_b); shared_entry_v1(gt, ref_b) =3D shared; } +#ifdef CONFIG_GRANT_TABLE_V2 else { grant_entry_v2_t shared; @@ -3485,6 +3546,7 @@ swap_grant_ref(grant_ref_t ref_a, grant_ref_t ref_b) shared_entry_v2(gt, ref_b) =3D shared; status_entry(gt, ref_b) =3D status; } +#endif =20 out: if ( act_b !=3D NULL ) @@ -3747,10 +3809,12 @@ long do_grant_table_op( rc =3D gnttab_set_version(guest_handle_cast(uop, gnttab_set_versio= n_t)); break; =20 +#ifdef CONFIG_GRANT_TABLE_V2 case GNTTABOP_get_status_frames: rc =3D gnttab_get_status_frames( guest_handle_cast(uop, gnttab_get_status_frames_t), count); break; +#endif =20 case GNTTABOP_get_version: rc =3D gnttab_get_version(guest_handle_cast(uop, gnttab_get_versio= n_t)); @@ -4054,6 +4118,7 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt, g= rant_ref_t ref, flags =3D sha1->flags; *gfn =3D _gfn(sha1->frame); } +#ifdef CONFIG_GRANT_TABLE_V2 else { const grant_entry_v2_t *sha2 =3D &shared_entry_v2(gt, ref); @@ -4064,6 +4129,7 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt, g= rant_ref_t ref, else *gfn =3D _gfn(sha2->full_page.frame); } +#endif =20 if ( !rc && (flags & GTF_type_mask) !=3D GTF_permit_access ) rc =3D -ENXIO; @@ -4080,6 +4146,9 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt, g= rant_ref_t ref, static int gnttab_get_status_frame_mfn(struct domain *d, unsigned int idx, mfn_t *mfn) { +#ifndef CONFIG_GRANT_TABLE_V2 + ASSERT_UNREACHABLE(); +#else const struct grant_table *gt =3D d->grant_table; =20 ASSERT(gt->gt_version =3D=3D 2); @@ -4113,6 +4182,7 @@ static int gnttab_get_status_frame_mfn(struct domain = *d, /* Make sure idx is bounded wrt nr_status_frames */ *mfn =3D _mfn(virt_to_mfn( gt->status[array_index_nospec(idx, nr_status_frames(gt))])= ); +#endif return 0; } =20 --=20 2.34.1