From nobody Fri Oct 18 06:25:13 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=reject dis=none) header.from=cloud.com ARC-Seal: i=1; a=rsa-sha256; t=1716993067; cv=none; d=zohomail.com; s=zohoarc; b=Dp+WxDld5aMjxQb6nlnfwiERVq2uQBSFmX31AMjybZea0euVFZNPqQw5uU/lxeZmCm2gNyWzsc6Y1TyxAKeoPSuXWZNs9SMwbTpytwR+xlGfzV2RTzkseXp+7dmQ/12w2KRCQyD726LvWLbJPseIAjxNuIAo+4q0pnBMNq0inHs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1716993067; 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=OLhg3CnTs3yrTCfULMEgcsfOyxcHrWQPcRCfZl8y51o=; b=YeU6ZKquaFqSYvO0wkNw7hT70SGsOQkQFh/Z7BJ03Iebo6ahObOB2QSo/OKwQpkOmprZBeh4fQVD2iNMvsAkkiAPK6YW6jGDq+MWakomW3lWkNESkKBFcW0TSEN61q3F5xwLGL9LJ2RUbD6Xs+bdCPRzSolxSSmjdkfqHSCZRdo= 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=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1716993067587391.57509011573245; Wed, 29 May 2024 07:31:07 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.732068.1137884 (Exim 4.92) (envelope-from ) id 1sCKKC-0006n4-Bj; Wed, 29 May 2024 14:30:44 +0000 Received: by outflank-mailman (output) from mailman id 732068.1137884; Wed, 29 May 2024 14:30:44 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sCKKC-0006mx-8M; Wed, 29 May 2024 14:30:44 +0000 Received: by outflank-mailman (input) for mailman id 732068; Wed, 29 May 2024 14:30:43 +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 1sCKKB-0006Xm-4R for xen-devel@lists.xenproject.org; Wed, 29 May 2024 14:30:43 +0000 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [2a00:1450:4864:20::629]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 07273fc0-1dc8-11ef-90a1-e314d9c70b13; Wed, 29 May 2024 16:30:42 +0200 (CEST) Received: by mail-ej1-x629.google.com with SMTP id a640c23a62f3a-a62ef52e837so236580566b.3 for ; Wed, 29 May 2024 07:30:42 -0700 (PDT) Received: from EMEAENGAAD19049.citrite.net ([217.156.233.157]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a626c937b92sm720180266b.68.2024.05.29.07.30.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 May 2024 07:30:40 -0700 (PDT) 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: 07273fc0-1dc8-11ef-90a1-e314d9c70b13 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1716993041; x=1717597841; 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=OLhg3CnTs3yrTCfULMEgcsfOyxcHrWQPcRCfZl8y51o=; b=kAfA0mVn4zFL9VjrbVGUTMeFhuNGOafvVMG+d1rYfm6T425ZJiIU3oRNtzvK6p6KTr 8A1iR43uuqRxxzDoLNq2v9s/uG3xjAsnaz0+50zfx7CCJvL9XWEo94gBpJ75DZrmLM7J 7IlJqpvZXHRnV+1BblU14d5H++wYRt8vk0qNY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716993041; x=1717597841; 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=OLhg3CnTs3yrTCfULMEgcsfOyxcHrWQPcRCfZl8y51o=; b=msXtEEmmMFMjleOO9wH2lIRBtOG3uUJQjnOQhIPBhpYQDKKDVwmmc3XNpx64eDqVoh meulTDQGoy5ZVmKfzt+JT0rS/+a+RJfQVJ14D1h6L6Y2PssRYeA4cE0zf1JpesIea8Kc nheMdwxlWqTu2Rvu4VddbbnEfVB7qxLMM6dGWwt9MBF/GN5BjVexDoIJpmA/yXN7D8G7 TIOIRPy70xic8APgiTnzqtffY8dOBzS9p4Ktk9/6Eibh3wBK3AUJsNpHevm5WYRSakfo IzLI/qU2UeC/LWj1Q16dAAVGq5A66/pRhVQ35jBBLIV0Pp/TfjNVGtXu+LaIeoy45pjT wmRw== X-Gm-Message-State: AOJu0Yy7DeEyWZl5Eg2aN5HUcbn/hL8ppFMUoMH7wAJMjfePGz/D9nU8 qbch+YEntg2mUcr5vbuq4DrSKEA0sJlNPqqYla1E95jaQhXzNybxVXQkz+0zkt3fiZ+oXDOhWkm u X-Google-Smtp-Source: AGHT+IGwXxQgnWzo5aeNTixO7+ynUQSRC4UA4W07qr2Zdq6yTTCP6CWsteUJQjhk8q1Ru8XYg2mhxg== X-Received: by 2002:a17:906:f813:b0:a59:a85d:31c6 with SMTP id a640c23a62f3a-a62651123b4mr1050704066b.66.1716993041280; Wed, 29 May 2024 07:30:41 -0700 (PDT) From: Alejandro Vallejo To: Xen-devel Cc: Alejandro Vallejo , Anthony PERARD , Juergen Gross , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v4 1/2] tools/xg: Streamline cpu policy serialise/deserialise calls Date: Wed, 29 May 2024 15:30:37 +0100 Message-Id: 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 @cloud.com) X-ZM-MESSAGEID: 1716993068713100001 The idea is to use xc_cpu_policy_t as a single object containing both the serialised and deserialised forms of the policy. Note that we need lengths for the arrays, as the serialised policies may be shorter than the array capacities. * Add the serialised lengths to the struct so we can distinguish between length and capacity of the serialisation buffers. * Remove explicit buffer+lengths in serialise/deserialise calls and use the internal buffer inside xc_cpu_policy_t instead. * Refactor everything to use the new serialisation functions. * Remove redundant serialization calls and avoid allocating dynamic memory aside from the policy objects in xen-cpuid. Also minor cleanup in the policy print call sites. No functional change intended. Signed-off-by: Alejandro Vallejo Acked-by: Roger Pau Monn=C3=A9 --- v4: * Clarify with a comment the semantics of the serialised buffer accessors * Remove local variables in policy serialiser --- tools/include/xenguest.h | 14 ++++- tools/libs/guest/xg_cpuid_x86.c | 94 +++++++++++++++++++---------- tools/libs/guest/xg_private.h | 2 + tools/libs/guest/xg_sr_common_x86.c | 56 ++++++----------- tools/misc/xen-cpuid.c | 41 ++++--------- 5 files changed, 108 insertions(+), 99 deletions(-) diff --git a/tools/include/xenguest.h b/tools/include/xenguest.h index e01f494b772a..85d56f26537b 100644 --- a/tools/include/xenguest.h +++ b/tools/include/xenguest.h @@ -799,15 +799,23 @@ int xc_cpu_policy_set_domain(xc_interface *xch, uint3= 2_t domid, xc_cpu_policy_t *policy); =20 /* Manipulate a policy via architectural representations. */ -int xc_cpu_policy_serialise(xc_interface *xch, const xc_cpu_policy_t *poli= cy, - xen_cpuid_leaf_t *leaves, uint32_t *nr_leaves, - xen_msr_entry_t *msrs, uint32_t *nr_msrs); +int xc_cpu_policy_serialise(xc_interface *xch, xc_cpu_policy_t *policy); int xc_cpu_policy_update_cpuid(xc_interface *xch, xc_cpu_policy_t *policy, const xen_cpuid_leaf_t *leaves, uint32_t nr); int xc_cpu_policy_update_msrs(xc_interface *xch, xc_cpu_policy_t *policy, const xen_msr_entry_t *msrs, uint32_t nr); =20 +/* + * Accessors for the serialised forms of the policy. The outputs are point= ers + * into the policy object and not fresh allocations, so their lifetimes ar= e tied + * to the policy object itself. + */ +int xc_cpu_policy_get_leaves(xc_interface *xch, const xc_cpu_policy_t *pol= icy, + const xen_cpuid_leaf_t **leaves, uint32_t *nr= ); +int xc_cpu_policy_get_msrs(xc_interface *xch, const xc_cpu_policy_t *polic= y, + const xen_msr_entry_t **msrs, uint32_t *nr); + /* Compatibility calculations. */ bool xc_cpu_policy_is_compatible(xc_interface *xch, xc_cpu_policy_t *host, xc_cpu_policy_t *guest); diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x8= 6.c index 4453178100ad..6cab5c60bb41 100644 --- a/tools/libs/guest/xg_cpuid_x86.c +++ b/tools/libs/guest/xg_cpuid_x86.c @@ -834,14 +834,13 @@ void xc_cpu_policy_destroy(xc_cpu_policy_t *policy) } } =20 -static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy, - unsigned int nr_leaves, unsigned int nr_entr= ies) +static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy) { uint32_t err_leaf =3D -1, err_subleaf =3D -1, err_msr =3D -1; int rc; =20 rc =3D x86_cpuid_copy_from_buffer(&policy->policy, policy->leaves, - nr_leaves, &err_leaf, &err_subleaf); + policy->nr_leaves, &err_leaf, &err_sub= leaf); if ( rc ) { if ( err_leaf !=3D -1 ) @@ -851,7 +850,7 @@ static int deserialize_policy(xc_interface *xch, xc_cpu= _policy_t *policy, } =20 rc =3D x86_msr_copy_from_buffer(&policy->policy, policy->msrs, - nr_entries, &err_msr); + policy->nr_msrs, &err_msr); if ( rc ) { if ( err_msr !=3D -1 ) @@ -878,7 +877,10 @@ int xc_cpu_policy_get_system(xc_interface *xch, unsign= ed int policy_idx, return rc; } =20 - rc =3D deserialize_policy(xch, policy, nr_leaves, nr_msrs); + policy->nr_leaves =3D nr_leaves; + policy->nr_msrs =3D nr_msrs; + + rc =3D deserialize_policy(xch, policy); if ( rc ) { errno =3D -rc; @@ -903,7 +905,10 @@ int xc_cpu_policy_get_domain(xc_interface *xch, uint32= _t domid, return rc; } =20 - rc =3D deserialize_policy(xch, policy, nr_leaves, nr_msrs); + policy->nr_leaves =3D nr_leaves; + policy->nr_msrs =3D nr_msrs; + + rc =3D deserialize_policy(xch, policy); if ( rc ) { errno =3D -rc; @@ -917,17 +922,14 @@ int xc_cpu_policy_set_domain(xc_interface *xch, uint3= 2_t domid, xc_cpu_policy_t *policy) { uint32_t err_leaf =3D -1, err_subleaf =3D -1, err_msr =3D -1; - unsigned int nr_leaves =3D ARRAY_SIZE(policy->leaves); - unsigned int nr_msrs =3D ARRAY_SIZE(policy->msrs); int rc; =20 - rc =3D xc_cpu_policy_serialise(xch, policy, policy->leaves, &nr_leaves, - policy->msrs, &nr_msrs); + rc =3D xc_cpu_policy_serialise(xch, policy); if ( rc ) return rc; =20 - rc =3D xc_set_domain_cpu_policy(xch, domid, nr_leaves, policy->leaves, - nr_msrs, policy->msrs, + rc =3D xc_set_domain_cpu_policy(xch, domid, policy->nr_leaves, policy-= >leaves, + policy->nr_msrs, policy->msrs, &err_leaf, &err_subleaf, &err_msr); if ( rc ) { @@ -942,32 +944,26 @@ int xc_cpu_policy_set_domain(xc_interface *xch, uint3= 2_t domid, return rc; } =20 -int xc_cpu_policy_serialise(xc_interface *xch, const xc_cpu_policy_t *p, - xen_cpuid_leaf_t *leaves, uint32_t *nr_leaves, - xen_msr_entry_t *msrs, uint32_t *nr_msrs) +int xc_cpu_policy_serialise(xc_interface *xch, xc_cpu_policy_t *p) { int rc; + p->nr_leaves =3D ARRAY_SIZE(p->leaves); + p->nr_msrs =3D ARRAY_SIZE(p->msrs); =20 - if ( leaves ) + rc =3D x86_cpuid_copy_to_buffer(&p->policy, p->leaves, &p->nr_leaves); + if ( rc ) { - rc =3D x86_cpuid_copy_to_buffer(&p->policy, leaves, nr_leaves); - if ( rc ) - { - ERROR("Failed to serialize CPUID policy"); - errno =3D -rc; - return -1; - } + ERROR("Failed to serialize CPUID policy"); + errno =3D -rc; + return -1; } =20 - if ( msrs ) + rc =3D x86_msr_copy_to_buffer(&p->policy, p->msrs, &p->nr_msrs); + if ( rc ) { - rc =3D x86_msr_copy_to_buffer(&p->policy, msrs, nr_msrs); - if ( rc ) - { - ERROR("Failed to serialize MSR policy"); - errno =3D -rc; - return -1; - } + ERROR("Failed to serialize MSR policy"); + errno =3D -rc; + return -1; } =20 errno =3D 0; @@ -1012,6 +1008,42 @@ int xc_cpu_policy_update_msrs(xc_interface *xch, xc_= cpu_policy_t *policy, return rc; } =20 +int xc_cpu_policy_get_leaves(xc_interface *xch, + const xc_cpu_policy_t *policy, + const xen_cpuid_leaf_t **leaves, + uint32_t *nr) +{ + if ( !policy ) + { + ERROR("Failed to fetch CPUID leaves from policy object"); + errno =3D -EINVAL; + return -1; + } + + *leaves =3D policy->leaves; + *nr =3D policy->nr_leaves; + + return 0; +} + +int xc_cpu_policy_get_msrs(xc_interface *xch, + const xc_cpu_policy_t *policy, + const xen_msr_entry_t **msrs, + uint32_t *nr) +{ + if ( !policy ) + { + ERROR("Failed to fetch MSRs from policy object"); + errno =3D -EINVAL; + return -1; + } + + *msrs =3D policy->msrs; + *nr =3D policy->nr_msrs; + + return 0; +} + bool xc_cpu_policy_is_compatible(xc_interface *xch, xc_cpu_policy_t *host, xc_cpu_policy_t *guest) { diff --git a/tools/libs/guest/xg_private.h b/tools/libs/guest/xg_private.h index d73947094f2e..a65dae818f3d 100644 --- a/tools/libs/guest/xg_private.h +++ b/tools/libs/guest/xg_private.h @@ -177,6 +177,8 @@ struct xc_cpu_policy { struct cpu_policy policy; xen_cpuid_leaf_t leaves[CPUID_MAX_SERIALISED_LEAVES]; xen_msr_entry_t msrs[MSR_MAX_SERIALISED_ENTRIES]; + uint32_t nr_leaves; + uint32_t nr_msrs; }; #endif /* x86 */ =20 diff --git a/tools/libs/guest/xg_sr_common_x86.c b/tools/libs/guest/xg_sr_c= ommon_x86.c index 563b4f016877..a0d67c3211c6 100644 --- a/tools/libs/guest/xg_sr_common_x86.c +++ b/tools/libs/guest/xg_sr_common_x86.c @@ -1,4 +1,5 @@ #include "xg_sr_common_x86.h" +#include "xg_sr_stream_format.h" =20 int write_x86_tsc_info(struct xc_sr_context *ctx) { @@ -45,54 +46,39 @@ int handle_x86_tsc_info(struct xc_sr_context *ctx, stru= ct xc_sr_record *rec) int write_x86_cpu_policy_records(struct xc_sr_context *ctx) { xc_interface *xch =3D ctx->xch; - struct xc_sr_record cpuid =3D { .type =3D REC_TYPE_X86_CPUID_POLICY, }; - struct xc_sr_record msrs =3D { .type =3D REC_TYPE_X86_MSR_POLICY, }; - uint32_t nr_leaves =3D 0, nr_msrs =3D 0; - xc_cpu_policy_t *policy =3D NULL; + xc_cpu_policy_t *policy =3D xc_cpu_policy_init(); int rc; =20 - if ( xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs) < 0 ) - { - PERROR("Unable to get CPU Policy size"); - return -1; - } - - cpuid.data =3D malloc(nr_leaves * sizeof(xen_cpuid_leaf_t)); - msrs.data =3D malloc(nr_msrs * sizeof(xen_msr_entry_t)); - policy =3D xc_cpu_policy_init(); - if ( !cpuid.data || !msrs.data || !policy ) - { - ERROR("Cannot allocate memory for CPU Policy"); - rc =3D -1; - goto out; - } - - if ( xc_cpu_policy_get_domain(xch, ctx->domid, policy) ) + if ( !policy || xc_cpu_policy_get_domain(xch, ctx->domid, policy) ) { PERROR("Unable to get d%d CPU Policy", ctx->domid); rc =3D -1; goto out; } - if ( xc_cpu_policy_serialise(xch, policy, cpuid.data, &nr_leaves, - msrs.data, &nr_msrs) ) - { - PERROR("Unable to serialize d%d CPU Policy", ctx->domid); - rc =3D -1; - goto out; - } =20 - cpuid.length =3D nr_leaves * sizeof(xen_cpuid_leaf_t); - if ( cpuid.length ) + + if ( policy->nr_leaves ) { - rc =3D write_record(ctx, &cpuid); + struct xc_sr_record record =3D { + .type =3D REC_TYPE_X86_CPUID_POLICY, + .data =3D policy->leaves, + .length =3D policy->nr_leaves * sizeof(*policy->leaves), + }; + + rc =3D write_record(ctx, &record); if ( rc ) goto out; } =20 - msrs.length =3D nr_msrs * sizeof(xen_msr_entry_t); - if ( msrs.length ) + if ( policy->nr_msrs ) { - rc =3D write_record(ctx, &msrs); + struct xc_sr_record record =3D { + .type =3D REC_TYPE_X86_MSR_POLICY, + .data =3D policy->msrs, + .length =3D policy->nr_msrs * sizeof(*policy->msrs), + }; + + rc =3D write_record(ctx, &record); if ( rc ) goto out; } @@ -100,8 +86,6 @@ int write_x86_cpu_policy_records(struct xc_sr_context *c= tx) rc =3D 0; =20 out: - free(cpuid.data); - free(msrs.data); xc_cpu_policy_destroy(policy); =20 return rc; diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c index 4c4593528dfe..488f43378406 100644 --- a/tools/misc/xen-cpuid.c +++ b/tools/misc/xen-cpuid.c @@ -156,12 +156,18 @@ static void dump_info(xc_interface *xch, bool detail) =20 free(fs); } - -static void print_policy(const char *name, - xen_cpuid_leaf_t *leaves, uint32_t nr_leaves, - xen_msr_entry_t *msrs, uint32_t nr_msrs) +static void print_policy(xc_interface *xch, const char *name, + const xc_cpu_policy_t *policy) { unsigned int l; + const xen_cpuid_leaf_t *leaves; + const xen_msr_entry_t *msrs; + uint32_t nr_leaves, nr_msrs; + + if ( xc_cpu_policy_get_leaves(xch, policy, &leaves, &nr_leaves) ) + err(1, "xc_cpu_policy_get_leaves()"); + if ( xc_cpu_policy_get_msrs(xch, policy, &msrs, &nr_msrs) ) + err(1, "xc_cpu_policy_get_msrs()"); =20 printf("%s policy: %u leaves, %u MSRs\n", name, nr_leaves, nr_msrs); printf(" CPUID:\n"); @@ -287,8 +293,6 @@ int main(int argc, char **argv) [ XEN_SYSCTL_cpu_policy_pv_default ] =3D "PV Default", [ XEN_SYSCTL_cpu_policy_hvm_default ] =3D "HVM Default", }; - xen_cpuid_leaf_t *leaves; - xen_msr_entry_t *msrs; uint32_t i, max_leaves, max_msrs; =20 xc_interface *xch =3D xc_interface_open(0, 0, 0); @@ -305,36 +309,21 @@ int main(int argc, char **argv) printf("Xen reports there are maximum %u leaves and %u MSRs\n", max_leaves, max_msrs); =20 - leaves =3D calloc(max_leaves, sizeof(xen_cpuid_leaf_t)); - if ( !leaves ) - err(1, "calloc(max_leaves)"); - msrs =3D calloc(max_msrs, sizeof(xen_msr_entry_t)); - if ( !msrs ) - err(1, "calloc(max_msrs)"); - if ( domid !=3D -1 ) { char name[20]; - uint32_t nr_leaves =3D max_leaves; - uint32_t nr_msrs =3D max_msrs; =20 if ( xc_cpu_policy_get_domain(xch, domid, policy) ) err(1, "xc_cpu_policy_get_domain(, %d, )", domid); - if ( xc_cpu_policy_serialise(xch, policy, leaves, &nr_leaves, - msrs, &nr_msrs) ) - err(1, "xc_cpu_policy_serialise"); =20 snprintf(name, sizeof(name), "Domain %d", domid); - print_policy(name, leaves, nr_leaves, msrs, nr_msrs); + print_policy(xch, name, policy); } else { /* Get system policies */ for ( i =3D 0; i < ARRAY_SIZE(sys_policies); ++i ) { - uint32_t nr_leaves =3D max_leaves; - uint32_t nr_msrs =3D max_msrs; - if ( xc_cpu_policy_get_system(xch, i, policy) ) { if ( errno =3D=3D EOPNOTSUPP ) @@ -346,18 +335,12 @@ int main(int argc, char **argv) =20 err(1, "xc_cpu_policy_get_system(, %s, )", sys_policie= s[i]); } - if ( xc_cpu_policy_serialise(xch, policy, leaves, &nr_leav= es, - msrs, &nr_msrs) ) - err(1, "xc_cpu_policy_serialise"); =20 - print_policy(sys_policies[i], leaves, nr_leaves, - msrs, nr_msrs); + print_policy(xch, sys_policies[i], policy); } } =20 xc_cpu_policy_destroy(policy); - free(leaves); - free(msrs); xc_interface_close(xch); } else if ( mode =3D=3D MODE_INFO || mode =3D=3D MODE_DETAIL ) --=20 2.34.1 From nobody Fri Oct 18 06:25:13 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=reject dis=none) header.from=cloud.com ARC-Seal: i=1; a=rsa-sha256; t=1716993069; cv=none; d=zohomail.com; s=zohoarc; b=M6qIUQFaX6Qk17sZAqpVDa8lzuo5cbczXVrNtkHvk78oapdSUKUKtRHTiD5xCcbT8K9dfj1xklCm7FtzPVNSfqgOI49EdwUc50pYH9ShLHBHkXEapheujav9p1XIIITB64HI1Mr60B6OPmi1KdHpoYF1VQa2gk1TfmPMP7MvJdY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1716993069; 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=ACDNCT9wciuPyxlqGAwOtlGDI3MKxbnMcgfQ+hZoPRk=; b=nhCQLvSo8T6WWaZi+HHTMjk+KkTdU3sFq9nfnJUvR2WojYWA6QAehPqB9lI0uVmds9afG4lCAx0OmTBGff3c6RoAkMxz/h8KUy6/oH17ucCZXmwnLe6kJjFPfdYpZtPSaY7zsMCaeF6kpqYgRROI6RJut8hF1wvXVbwTuhYO/y4= 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=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1716993069427367.642146468001; Wed, 29 May 2024 07:31:09 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.732069.1137894 (Exim 4.92) (envelope-from ) id 1sCKKE-00073c-Lp; Wed, 29 May 2024 14:30:46 +0000 Received: by outflank-mailman (output) from mailman id 732069.1137894; Wed, 29 May 2024 14:30:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sCKKE-00073V-Iy; Wed, 29 May 2024 14:30:46 +0000 Received: by outflank-mailman (input) for mailman id 732069; Wed, 29 May 2024 14:30: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 1sCKKD-00071F-K3 for xen-devel@lists.xenproject.org; Wed, 29 May 2024 14:30:45 +0000 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [2a00:1450:4864:20::62b]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 0789a1e1-1dc8-11ef-b4bb-af5377834399; Wed, 29 May 2024 16:30:43 +0200 (CEST) Received: by mail-ej1-x62b.google.com with SMTP id a640c23a62f3a-a6341cf2c99so225960566b.0 for ; Wed, 29 May 2024 07:30:43 -0700 (PDT) Received: from EMEAENGAAD19049.citrite.net ([217.156.233.157]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a626c937b92sm720180266b.68.2024.05.29.07.30.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 May 2024 07:30:41 -0700 (PDT) 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: 0789a1e1-1dc8-11ef-b4bb-af5377834399 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1716993042; x=1717597842; 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=ACDNCT9wciuPyxlqGAwOtlGDI3MKxbnMcgfQ+hZoPRk=; b=R6twMvs5QlWwQPwcQ1SiYP/aRjqQhY5umhorzvNzWqJYxXYVwLRcQ7G/koD8ft8SAX rAeXldHe9pfDfZdxW2ndLW5ErBMWUvu5CXBzkUIcZTFyR16/csVB2nZUKb+TPEmAI3UJ KzXVNy4Zrk0a7P4ThGbJIjj+wZUhlAxJXu+YY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716993042; x=1717597842; 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=ACDNCT9wciuPyxlqGAwOtlGDI3MKxbnMcgfQ+hZoPRk=; b=wYPf3E4BxGALTYLl37qM1WeUS2WLxfRyy0b4qshiPm0cGJKe7eWkfhCZdZp1C0bc0n oRdEkvYP6EwhjDpgReL2rO4AapONADeslzvSnPxPJOmBpblJ7wgOi1wJGYdwEX2dKgfG 5eYRjUElaswXk0WTvLPs+jQb2hiZs791ZOpWAFD3T6BSufcXq7I0+TOPLPM3cjTni+LI 9DmzPgGZA+Br5FPQwtPedzxSCWbehjeSEe2hanmOGR/YgEJOzNZGj+xIg9rFSauwi43X WixEFLIxRpsWqzOKgZ5wYORcoVD7SbxR6305Ohab/KWtkZcSGvT/9/tnQ5Sza7xvNZLG TgqQ== X-Gm-Message-State: AOJu0Yy0Bu9iGxwaHeYbnkztlp1sYl/YoGX1uGqBoOeK0qn8tVdYbTsW LbF5t7gi7OzrJcWbBvbicGk0Y5tXMU3yK/d7Akk+z2A5ssVOhi93WnQyGqZRj8wUUqTZlyfhgHi q X-Google-Smtp-Source: AGHT+IEQpWFvsL1H2BKO/eU+9sH/Muc2mBce4oKTznbn9kp74NNLaZnaQfm805NjowAt1d5vQ+SeQA== X-Received: by 2002:a17:906:c113:b0:a62:a9ca:2111 with SMTP id a640c23a62f3a-a62a9ca25admr1011211866b.11.1716993042076; Wed, 29 May 2024 07:30:42 -0700 (PDT) From: Alejandro Vallejo To: Xen-devel Cc: Alejandro Vallejo , Anthony PERARD , Juergen Gross Subject: [PATCH v4 2/2] tools/xg: Clean up xend-style overrides for CPU policies Date: Wed, 29 May 2024 15:30:38 +0100 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @cloud.com) X-ZM-MESSAGEID: 1716993070793100003 Content-Type: text/plain; charset="utf-8" Factor out policy getters/setters from both (CPUID and MSR) policy override functions. Additionally, use host policy rather than featureset when preparing the cur policy, saving one hypercall and several lines of boilerplate. No functional change intended. Signed-off-by: Alejandro Vallejo Reviewed-by: Roger Pau Monn=C3=A9 --- v4: * Indentation adjustment. * Fix unhandled corner case using bsearch() with MSR and leaf buffers --- tools/libs/guest/xg_cpuid_x86.c | 437 ++++++++++---------------------- 1 file changed, 130 insertions(+), 307 deletions(-) diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x8= 6.c index 6cab5c60bb41..552ec2ab7312 100644 --- a/tools/libs/guest/xg_cpuid_x86.c +++ b/tools/libs/guest/xg_cpuid_x86.c @@ -36,6 +36,34 @@ enum { #define bitmaskof(idx) (1u << ((idx) & 31)) #define featureword_of(idx) ((idx) >> 5) =20 +static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy) +{ + uint32_t err_leaf =3D -1, err_subleaf =3D -1, err_msr =3D -1; + int rc; + + rc =3D x86_cpuid_copy_from_buffer(&policy->policy, policy->leaves, + policy->nr_leaves, &err_leaf, &err_sub= leaf); + if ( rc ) + { + if ( err_leaf !=3D -1 ) + ERROR("Failed to deserialise CPUID (err leaf %#x, subleaf %#x)= (%d =3D %s)", + err_leaf, err_subleaf, -rc, strerror(-rc)); + return rc; + } + + rc =3D x86_msr_copy_from_buffer(&policy->policy, policy->msrs, + policy->nr_msrs, &err_msr); + if ( rc ) + { + if ( err_msr !=3D -1 ) + ERROR("Failed to deserialise MSR (err MSR %#x) (%d =3D %s)", + err_msr, -rc, strerror(-rc)); + return rc; + } + + return 0; +} + int xc_get_cpu_levelling_caps(xc_interface *xch, uint32_t *caps) { struct xen_sysctl sysctl =3D {}; @@ -260,102 +288,37 @@ static int compare_leaves(const void *l, const void = *r) return 0; } =20 -static xen_cpuid_leaf_t *find_leaf( - xen_cpuid_leaf_t *leaves, unsigned int nr_leaves, - const struct xc_xend_cpuid *xend) +static xen_cpuid_leaf_t *find_leaf(xc_cpu_policy_t *p, + const struct xc_xend_cpuid *xend) { const xen_cpuid_leaf_t key =3D { xend->leaf, xend->subleaf }; =20 - return bsearch(&key, leaves, nr_leaves, sizeof(*leaves), compare_leave= s); + return bsearch(&key, p->leaves, p->nr_leaves, + sizeof(*p->leaves), compare_leaves); } =20 -static int xc_cpuid_xend_policy( - xc_interface *xch, uint32_t domid, const struct xc_xend_cpuid *xend) +static int xc_cpuid_xend_policy(xc_interface *xch, uint32_t domid, + const struct xc_xend_cpuid *xend, + xc_cpu_policy_t *host, + xc_cpu_policy_t *def, + xc_cpu_policy_t *cur) { - int rc; - bool hvm; - xc_domaininfo_t di; - unsigned int nr_leaves, nr_msrs; - uint32_t err_leaf =3D -1, err_subleaf =3D -1, err_msr =3D -1; - /* - * Three full policies. The host, default for the domain type, - * and domain current. - */ - xen_cpuid_leaf_t *host =3D NULL, *def =3D NULL, *cur =3D NULL; - unsigned int nr_host, nr_def, nr_cur; - - if ( (rc =3D xc_domain_getinfo_single(xch, domid, &di)) < 0 ) - { - PERROR("Failed to obtain d%d info", domid); - rc =3D -errno; - goto fail; - } - hvm =3D di.flags & XEN_DOMINF_hvm_guest; - - rc =3D xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs); - if ( rc ) - { - PERROR("Failed to obtain policy info size"); - rc =3D -errno; - goto fail; - } - - rc =3D -ENOMEM; - if ( (host =3D calloc(nr_leaves, sizeof(*host))) =3D=3D NULL || - (def =3D calloc(nr_leaves, sizeof(*def))) =3D=3D NULL || - (cur =3D calloc(nr_leaves, sizeof(*cur))) =3D=3D NULL ) - { - ERROR("Unable to allocate memory for %u CPUID leaves", nr_leaves); - goto fail; - } - - /* Get the domain's current policy. */ - nr_msrs =3D 0; - nr_cur =3D nr_leaves; - rc =3D get_domain_cpu_policy(xch, domid, &nr_cur, cur, &nr_msrs, NULL); - if ( rc ) - { - PERROR("Failed to obtain d%d current policy", domid); - rc =3D -errno; - goto fail; - } + if ( !xend ) + return 0; =20 - /* Get the domain type's default policy. */ - nr_msrs =3D 0; - nr_def =3D nr_leaves; - rc =3D get_system_cpu_policy(xch, hvm ? XEN_SYSCTL_cpu_policy_hvm_defa= ult - : XEN_SYSCTL_cpu_policy_pv_default, - &nr_def, def, &nr_msrs, NULL); - if ( rc ) - { - PERROR("Failed to obtain %s def policy", hvm ? "hvm" : "pv"); - rc =3D -errno; - goto fail; - } + if ( !host || !def || !cur ) + return -EINVAL; =20 - /* Get the host policy. */ - nr_msrs =3D 0; - nr_host =3D nr_leaves; - rc =3D get_system_cpu_policy(xch, XEN_SYSCTL_cpu_policy_host, - &nr_host, host, &nr_msrs, NULL); - if ( rc ) - { - PERROR("Failed to obtain host policy"); - rc =3D -errno; - goto fail; - } - - rc =3D -EINVAL; for ( ; xend->leaf !=3D XEN_CPUID_INPUT_UNUSED; ++xend ) { - xen_cpuid_leaf_t *cur_leaf =3D find_leaf(cur, nr_cur, xend); - const xen_cpuid_leaf_t *def_leaf =3D find_leaf(def, nr_def, xend); - const xen_cpuid_leaf_t *host_leaf =3D find_leaf(host, nr_host, xen= d); + xen_cpuid_leaf_t *cur_leaf =3D find_leaf(cur, xend); + const xen_cpuid_leaf_t *def_leaf =3D find_leaf(def, xend); + const xen_cpuid_leaf_t *host_leaf =3D find_leaf(host, xend); =20 if ( cur_leaf =3D=3D NULL || def_leaf =3D=3D NULL || host_leaf =3D= =3D NULL ) { ERROR("Missing leaf %#x, subleaf %#x", xend->leaf, xend->suble= af); - goto fail; + return -EINVAL; } =20 for ( unsigned int i =3D 0; i < ARRAY_SIZE(xend->policy); i++ ) @@ -384,7 +347,7 @@ static int xc_cpuid_xend_policy( { ERROR("Bad character '%c' in policy[%d] string '%s'", xend->policy[i][j], i, xend->policy[i]); - goto fail; + return -EINVAL; } =20 clear_bit(31 - j, cur_reg); @@ -394,25 +357,7 @@ static int xc_cpuid_xend_policy( } } =20 - /* Feed the transformed currrent policy back up to Xen. */ - rc =3D xc_set_domain_cpu_policy(xch, domid, nr_cur, cur, 0, NULL, - &err_leaf, &err_subleaf, &err_msr); - if ( rc ) - { - PERROR("Failed to set d%d's policy (err leaf %#x, subleaf %#x, msr= %#x)", - domid, err_leaf, err_subleaf, err_msr); - rc =3D -errno; - goto fail; - } - - /* Success! */ - - fail: - free(cur); - free(def); - free(host); - - return rc; + return 0; } =20 static int compare_msr(const void *l, const void *r) @@ -426,104 +371,37 @@ static int compare_msr(const void *l, const void *r) return lhs->idx < rhs->idx ? -1 : 1; } =20 -static xen_msr_entry_t *find_msr( - xen_msr_entry_t *msrs, unsigned int nr_msrs, - uint32_t index) +static xen_msr_entry_t *find_msr(xc_cpu_policy_t *p, + uint32_t index) { const xen_msr_entry_t key =3D { .idx =3D index }; =20 - return bsearch(&key, msrs, nr_msrs, sizeof(*msrs), compare_msr); + return bsearch(&key, p->msrs, p->nr_msrs, sizeof(*p->msrs), compare_ms= r); } =20 - static int xc_msr_policy(xc_interface *xch, domid_t domid, - const struct xc_msr *msr) + const struct xc_msr *msr, + xc_cpu_policy_t *host, + xc_cpu_policy_t *def, + xc_cpu_policy_t *cur) { - int rc; - bool hvm; - xc_domaininfo_t di; - unsigned int nr_leaves, nr_msrs; - uint32_t err_leaf =3D -1, err_subleaf =3D -1, err_msr =3D -1; - /* - * Three full policies. The host, default for the domain type, - * and domain current. - */ - xen_msr_entry_t *host =3D NULL, *def =3D NULL, *cur =3D NULL; - unsigned int nr_host, nr_def, nr_cur; - - if ( (rc =3D xc_domain_getinfo_single(xch, domid, &di)) < 0 ) - { - PERROR("Failed to obtain d%d info", domid); - rc =3D -errno; - goto out; - } - hvm =3D di.flags & XEN_DOMINF_hvm_guest; - - rc =3D xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs); - if ( rc ) - { - PERROR("Failed to obtain policy info size"); - rc =3D -errno; - goto out; - } - - if ( (host =3D calloc(nr_msrs, sizeof(*host))) =3D=3D NULL || - (def =3D calloc(nr_msrs, sizeof(*def))) =3D=3D NULL || - (cur =3D calloc(nr_msrs, sizeof(*cur))) =3D=3D NULL ) - { - ERROR("Unable to allocate memory for %u CPUID leaves", nr_leaves); - rc =3D -ENOMEM; - goto out; - } - - /* Get the domain's current policy. */ - nr_leaves =3D 0; - nr_cur =3D nr_msrs; - rc =3D get_domain_cpu_policy(xch, domid, &nr_leaves, NULL, &nr_cur, cu= r); - if ( rc ) - { - PERROR("Failed to obtain d%d current policy", domid); - rc =3D -errno; - goto out; - } - - /* Get the domain type's default policy. */ - nr_leaves =3D 0; - nr_def =3D nr_msrs; - rc =3D get_system_cpu_policy(xch, hvm ? XEN_SYSCTL_cpu_policy_hvm_defa= ult - : XEN_SYSCTL_cpu_policy_pv_default, - &nr_leaves, NULL, &nr_def, def); - if ( rc ) - { - PERROR("Failed to obtain %s def policy", hvm ? "hvm" : "pv"); - rc =3D -errno; - goto out; - } + if ( !msr ) + return 0; =20 - /* Get the host policy. */ - nr_leaves =3D 0; - nr_host =3D nr_msrs; - rc =3D get_system_cpu_policy(xch, XEN_SYSCTL_cpu_policy_host, - &nr_leaves, NULL, &nr_host, host); - if ( rc ) - { - PERROR("Failed to obtain host policy"); - rc =3D -errno; - goto out; - } + if ( !host || !def || !cur ) + return -EINVAL; =20 for ( ; msr->index !=3D XC_MSR_INPUT_UNUSED; ++msr ) { - xen_msr_entry_t *cur_msr =3D find_msr(cur, nr_cur, msr->index); - const xen_msr_entry_t *def_msr =3D find_msr(def, nr_def, msr->inde= x); - const xen_msr_entry_t *host_msr =3D find_msr(host, nr_host, msr->i= ndex); unsigned int i; + xen_msr_entry_t *cur_msr =3D find_msr(cur, msr->index); + const xen_msr_entry_t *def_msr =3D find_msr(def, msr->index); + const xen_msr_entry_t *host_msr =3D find_msr(host, msr->index); =20 if ( cur_msr =3D=3D NULL || def_msr =3D=3D NULL || host_msr =3D=3D= NULL ) { ERROR("Missing MSR %#x", msr->index); - rc =3D -ENOENT; - goto out; + return -ENOENT; } =20 for ( i =3D 0; i < ARRAY_SIZE(msr->policy) - 1; i++ ) @@ -542,8 +420,7 @@ static int xc_msr_policy(xc_interface *xch, domid_t dom= id, { ERROR("MSR index %#x: bad character '%c' in policy string = '%s'", msr->index, msr->policy[i], msr->policy); - rc =3D -EINVAL; - goto out; + return -EINVAL; } =20 if ( val ) @@ -553,25 +430,7 @@ static int xc_msr_policy(xc_interface *xch, domid_t do= mid, } } =20 - /* Feed the transformed policy back up to Xen. */ - rc =3D xc_set_domain_cpu_policy(xch, domid, 0, NULL, nr_cur, cur, - &err_leaf, &err_subleaf, &err_msr); - if ( rc ) - { - PERROR("Failed to set d%d's policy (err leaf %#x, subleaf %#x, msr= %#x)", - domid, err_leaf, err_subleaf, err_msr); - rc =3D -errno; - goto out; - } - - /* Success! */ - - out: - free(cur); - free(def); - free(host); - - return rc; + return 0; } =20 int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, @@ -583,14 +442,17 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t= domid, bool restore, int rc; bool hvm; xc_domaininfo_t di; - struct xc_cpu_policy *p =3D xc_cpu_policy_init(); - unsigned int i, nr_leaves =3D ARRAY_SIZE(p->leaves), nr_msrs =3D 0; - uint32_t err_leaf =3D -1, err_subleaf =3D -1, err_msr =3D -1; - uint32_t host_featureset[FEATURESET_NR_ENTRIES] =3D {}; - uint32_t len =3D ARRAY_SIZE(host_featureset); + unsigned int i; =20 - if ( !p ) - return -ENOMEM; + struct xc_cpu_policy *host =3D xc_cpu_policy_init(); + struct xc_cpu_policy *def =3D xc_cpu_policy_init(); + struct xc_cpu_policy *cur =3D xc_cpu_policy_init(); + + if ( !host || !def || !cur ) + { + rc =3D -ENOMEM; + goto out; + } =20 if ( (rc =3D xc_domain_getinfo_single(xch, domid, &di)) < 0 ) { @@ -600,21 +462,19 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t= domid, bool restore, } hvm =3D di.flags & XEN_DOMINF_hvm_guest; =20 - /* Get the host policy. */ - rc =3D xc_get_cpu_featureset(xch, XEN_SYSCTL_cpu_featureset_host, - &len, host_featureset); - /* Tolerate "buffer too small", as we've got the bits we need. */ - if ( rc && errno !=3D ENOBUFS ) + /* Get the raw host policy */ + rc =3D xc_cpu_policy_get_system(xch, XEN_SYSCTL_cpu_policy_host, host); + if ( rc ) { - PERROR("Failed to obtain host featureset"); + PERROR("Failed to obtain host policy"); rc =3D -errno; goto out; } =20 /* Get the domain's default policy. */ - rc =3D get_system_cpu_policy(xch, hvm ? XEN_SYSCTL_cpu_policy_hvm_defa= ult - : XEN_SYSCTL_cpu_policy_pv_default, - &nr_leaves, p->leaves, &nr_msrs, NULL); + rc =3D xc_cpu_policy_get_system(xch, hvm ? XEN_SYSCTL_cpu_policy_hvm_d= efault + : XEN_SYSCTL_cpu_policy_pv_defa= ult, + def); if ( rc ) { PERROR("Failed to obtain %s default policy", hvm ? "hvm" : "pv"); @@ -622,14 +482,8 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t = domid, bool restore, goto out; } =20 - rc =3D x86_cpuid_copy_from_buffer(&p->policy, p->leaves, nr_leaves, - &err_leaf, &err_subleaf); - if ( rc ) - { - ERROR("Failed to deserialise CPUID (err leaf %#x, subleaf %#x) (%d= =3D %s)", - err_leaf, err_subleaf, -rc, strerror(-rc)); - goto out; - } + /* Copy the deserialised default policy to modify it */ + memcpy(cur, def, sizeof(*cur)); =20 if ( restore ) { @@ -647,18 +501,18 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t= domid, bool restore, * - Re-enable features which have become (possibly) off by defaul= t. */ =20 - p->policy.basic.rdrand =3D test_bit(X86_FEATURE_RDRAND, host_featu= reset); - p->policy.feat.hle =3D test_bit(X86_FEATURE_HLE, host_featureset); - p->policy.feat.rtm =3D test_bit(X86_FEATURE_RTM, host_featureset); + cur->policy.basic.rdrand =3D host->policy.basic.rdrand; + cur->policy.feat.hle =3D host->policy.feat.hle; + cur->policy.feat.rtm =3D host->policy.feat.rtm; =20 if ( hvm ) { - p->policy.feat.mpx =3D test_bit(X86_FEATURE_MPX, host_features= et); + cur->policy.feat.mpx =3D host->policy.feat.mpx; } =20 - p->policy.basic.max_leaf =3D min(p->policy.basic.max_leaf, 0xdu); - p->policy.feat.max_subleaf =3D 0; - p->policy.extd.max_leaf =3D min(p->policy.extd.max_leaf, 0x8000001= c); + cur->policy.basic.max_leaf =3D min(cur->policy.basic.max_leaf, 0xd= u); + cur->policy.feat.max_subleaf =3D 0; + cur->policy.extd.max_leaf =3D min(cur->policy.extd.max_leaf, 0x800= 0001c); } =20 if ( featureset ) @@ -702,17 +556,17 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t= domid, bool restore, } } =20 - x86_cpu_featureset_to_policy(feat, &p->policy); + x86_cpu_featureset_to_policy(feat, &cur->policy); } else { - p->policy.extd.itsc =3D itsc; + cur->policy.extd.itsc =3D itsc; =20 if ( hvm ) { - p->policy.basic.pae =3D pae; - p->policy.basic.vmx =3D nested_virt; - p->policy.extd.svm =3D nested_virt; + cur->policy.basic.pae =3D pae; + cur->policy.basic.vmx =3D nested_virt; + cur->policy.extd.svm =3D nested_virt; } } =20 @@ -722,8 +576,8 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t d= omid, bool restore, * On hardware without CPUID Faulting, PV guests see real topology. * As a consequence, they also need to see the host htt/cmp fields. */ - p->policy.basic.htt =3D test_bit(X86_FEATURE_HTT, host_featu= reset); - p->policy.extd.cmp_legacy =3D test_bit(X86_FEATURE_CMP_LEGACY, hos= t_featureset); + cur->policy.basic.htt =3D host->policy.basic.htt; + cur->policy.extd.cmp_legacy =3D host->policy.extd.cmp_legacy; } else { @@ -731,28 +585,28 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t= domid, bool restore, * Topology for HVM guests is entirely controlled by Xen. For now= , we * hardcode APIC_ID =3D vcpu_id * 2 to give the illusion of no SMT. */ - p->policy.basic.htt =3D true; - p->policy.extd.cmp_legacy =3D false; + cur->policy.basic.htt =3D true; + cur->policy.extd.cmp_legacy =3D false; =20 /* * Leaf 1 EBX[23:16] is Maximum Logical Processors Per Package. * Update to reflect vLAPIC_ID =3D vCPU_ID * 2, but make sure to a= void * overflow. */ - if ( !p->policy.basic.lppp ) - p->policy.basic.lppp =3D 2; - else if ( !(p->policy.basic.lppp & 0x80) ) - p->policy.basic.lppp *=3D 2; + if ( !cur->policy.basic.lppp ) + cur->policy.basic.lppp =3D 2; + else if ( !(cur->policy.basic.lppp & 0x80) ) + cur->policy.basic.lppp *=3D 2; =20 - switch ( p->policy.x86_vendor ) + switch ( cur->policy.x86_vendor ) { case X86_VENDOR_INTEL: - for ( i =3D 0; (p->policy.cache.subleaf[i].type && - i < ARRAY_SIZE(p->policy.cache.raw)); ++i ) + for ( i =3D 0; cur->policy.cache.subleaf[i].type && + i < ARRAY_SIZE(cur->policy.cache.raw); ++i ) { - p->policy.cache.subleaf[i].cores_per_package =3D - (p->policy.cache.subleaf[i].cores_per_package << 1) | = 1; - p->policy.cache.subleaf[i].threads_per_cache =3D 0; + cur->policy.cache.subleaf[i].cores_per_package =3D + (cur->policy.cache.subleaf[i].cores_per_package << 1) = | 1; + cur->policy.cache.subleaf[i].threads_per_cache =3D 0; } break; =20 @@ -772,49 +626,46 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t= domid, bool restore, * apic_id_size values greater than 7. Limit the value to * 7 for now. */ - if ( p->policy.extd.nc < 0x7f ) + if ( cur->policy.extd.nc < 0x7f ) { - if ( p->policy.extd.apic_id_size !=3D 0 && p->policy.extd.= apic_id_size < 0x7 ) - p->policy.extd.apic_id_size++; + if ( cur->policy.extd.apic_id_size !=3D 0 && + cur->policy.extd.apic_id_size < 0x7 ) + cur->policy.extd.apic_id_size++; =20 - p->policy.extd.nc =3D (p->policy.extd.nc << 1) | 1; + cur->policy.extd.nc =3D (cur->policy.extd.nc << 1) | 1; } break; } } =20 - nr_leaves =3D ARRAY_SIZE(p->leaves); - rc =3D x86_cpuid_copy_to_buffer(&p->policy, p->leaves, &nr_leaves); - if ( rc ) + if ( xend || msr ) { - ERROR("Failed to serialise CPUID (%d =3D %s)", -rc, strerror(-rc)); - goto out; + /* The overrides are over the serialised form of the policy */ + if ( (rc =3D xc_cpu_policy_serialise(xch, cur)) ) + goto out; + + if ( (rc =3D xc_cpuid_xend_policy(xch, domid, xend, host, def, cur= )) ) + goto out; + if ( (rc =3D xc_msr_policy(xch, domid, msr, host, def, cur)) ) + goto out; + + if ( (rc =3D deserialize_policy(xch, cur)) ) + goto out; } =20 - rc =3D xc_set_domain_cpu_policy(xch, domid, nr_leaves, p->leaves, 0, N= ULL, - &err_leaf, &err_subleaf, &err_msr); + rc =3D xc_cpu_policy_set_domain(xch, domid, cur); if ( rc ) { - PERROR("Failed to set d%d's policy (err leaf %#x, subleaf %#x, msr= %#x)", - domid, err_leaf, err_subleaf, err_msr); rc =3D -errno; goto out; } =20 - if ( xend && (rc =3D xc_cpuid_xend_policy(xch, domid, xend)) ) - goto out; - - if ( msr ) - { - rc =3D xc_msr_policy(xch, domid, msr); - if ( rc ) - goto out; - } - rc =3D 0; =20 out: - xc_cpu_policy_destroy(p); + xc_cpu_policy_destroy(def); + xc_cpu_policy_destroy(host); + xc_cpu_policy_destroy(cur); =20 return rc; } @@ -834,34 +685,6 @@ void xc_cpu_policy_destroy(xc_cpu_policy_t *policy) } } =20 -static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy) -{ - uint32_t err_leaf =3D -1, err_subleaf =3D -1, err_msr =3D -1; - int rc; - - rc =3D x86_cpuid_copy_from_buffer(&policy->policy, policy->leaves, - policy->nr_leaves, &err_leaf, &err_sub= leaf); - if ( rc ) - { - if ( err_leaf !=3D -1 ) - ERROR("Failed to deserialise CPUID (err leaf %#x, subleaf %#x)= (%d =3D %s)", - err_leaf, err_subleaf, -rc, strerror(-rc)); - return rc; - } - - rc =3D x86_msr_copy_from_buffer(&policy->policy, policy->msrs, - policy->nr_msrs, &err_msr); - if ( rc ) - { - if ( err_msr !=3D -1 ) - ERROR("Failed to deserialise MSR (err MSR %#x) (%d =3D %s)", - err_msr, -rc, strerror(-rc)); - return rc; - } - - return 0; -} - int xc_cpu_policy_get_system(xc_interface *xch, unsigned int policy_idx, xc_cpu_policy_t *policy) { --=20 2.34.1