From patchwork Wed Feb 7 17:39:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Vallejo X-Patchwork-Id: 13548814 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7F622C4828F for ; Wed, 7 Feb 2024 17:40:41 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.677847.1054742 (Exim 4.92) (envelope-from ) id 1rXluL-0005iE-FU; Wed, 07 Feb 2024 17:40:25 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 677847.1054742; Wed, 07 Feb 2024 17:40:25 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rXluL-0005i7-CT; Wed, 07 Feb 2024 17:40:25 +0000 Received: by outflank-mailman (input) for mailman id 677847; Wed, 07 Feb 2024 17:40:23 +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 1rXluJ-0005Tj-IS for xen-devel@lists.xenproject.org; Wed, 07 Feb 2024 17:40:23 +0000 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [2a00:1450:4864:20::629]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f762fe44-c5df-11ee-98f5-efadbce2ee36; Wed, 07 Feb 2024 18:40:21 +0100 (CET) Received: by mail-ej1-x629.google.com with SMTP id a640c23a62f3a-a2a17f3217aso110280766b.2 for ; Wed, 07 Feb 2024 09:40:21 -0800 (PST) Received: from EMEAENGAAD19049.citrite.net (default-46-102-197-194.interdsl.co.uk. [46.102.197.194]) by smtp.gmail.com with ESMTPSA id op3-20020a170906bce300b00a37669280d1sm976355ejb.141.2024.02.07.09.40.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Feb 2024 09:40:19 -0800 (PST) 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: f762fe44-c5df-11ee-98f5-efadbce2ee36 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1707327621; x=1707932421; 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=+hjQ03fb4gTy1nB5aYDQXgvwccHLoP4GL/zVeSr+oE4=; b=FWuphzI+t9EusMvTOLYSbPCBE0rojA0TSYYslW1S2FTkw7z459xTXBW0zQDljPPZuL N6PsmJ5N8V0L//WGixo1Vrr9DD7j6gNs/kIuPAuVVcivS3pJfxdMn6/xgC8KltshQMdE pNrwN5Y5j2QoPzDE+T/D+BcWjX/AaL+voI1KM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707327621; x=1707932421; 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=+hjQ03fb4gTy1nB5aYDQXgvwccHLoP4GL/zVeSr+oE4=; b=MtcEy8iE0XuU8rZWhTC6SyWIwPmHa+bxwX3KT85cNca65hxtIBu/3KD4K1jB/H0LH7 kiqnjuMzK5ZI3GuW42P1B9/S0GgZsi8cxkHacTfdrwEFsaFI2kwm6oMGmvEWDKSe7sh2 m6ZOSPsjFP/6t+IrVl0VrA5TqNaTjNK1ArFRJ1uln0bhDDaKg+mFitDaVB+axDXxOU1y 6G9WKZGbklHAMH7mANnTfXt3xrHr8C3fyUh+zJJxekRJNyLqXi87+tCXj8khAEgQszDm ZDgXAZGMJ8+ZEbZ5OSt3IDjZixSIGGWs5gA801tfDSpmdG9ekOn6v3Ywf8JYr78sFled ef5w== X-Gm-Message-State: AOJu0Yweqssvhyy7pr0nN7bG/h5YTqTMV7Q5NGokLcInZ1ynpw/0X34l r+XOZXIFRpoqJrlmHz7+W7qXCNxCPyfedAazTVx53EbywyCUKF/dRiRrx0+xFSsKj2x+4au6/ao s X-Google-Smtp-Source: AGHT+IHXF4iCI5cUyuRNUfpzz5Nygg8GIH0vsQ0EZmE3VpuusshmPnBXuPJdBt5m9k7Mcz+oFVS0XQ== X-Received: by 2002:a17:906:1c5:b0:a35:103e:3614 with SMTP id 5-20020a17090601c500b00a35103e3614mr4214546ejj.52.1707327620723; Wed, 07 Feb 2024 09:40:20 -0800 (PST) X-Forwarded-Encrypted: i=1; AJvYcCXAS9JeEvannetqUxhv+QgmoRsEdjhaEIVOAi6+SmbdeoIyM4R9mh2xgAQBkALvkDnr2n63Q83ejxNypl8yn5tIL0/CsOQh5VtR9zVzpmyTTtTWsxO+C5/DMwMb2J4TO3qp1DJaIKW/bTAqi90aHYgiJh1nZvqxa1CjWcr4Ca8brIS+dYe6vENEMMGfizXYa91EmZrSDslDEfu/BexVP3EWe6yNwrxIxz1yoA== From: Alejandro Vallejo To: Xen-devel Cc: Alejandro Vallejo , Wei Liu , Anthony PERARD , Juergen Gross , Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [PATCH 1/3] tools/xg: Move xc_cpu_policy_t to xenguest.h Date: Wed, 7 Feb 2024 17:39:55 +0000 Message-Id: <20240207173957.19811-2-alejandro.vallejo@cloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240207173957.19811-1-alejandro.vallejo@cloud.com> References: <20240207173957.19811-1-alejandro.vallejo@cloud.com> MIME-Version: 1.0 This enables a set of follow-up simplifications in the toolstack. No functional change. Signed-off-by: Alejandro Vallejo --- tools/include/xenguest.h | 8 +++++++- tools/libs/guest/xg_private.h | 10 ---------- xen/include/xen/lib/x86/cpu-policy.h | 6 ++++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/tools/include/xenguest.h b/tools/include/xenguest.h index e01f494b772a..4e9078fdee4d 100644 --- a/tools/include/xenguest.h +++ b/tools/include/xenguest.h @@ -784,7 +784,13 @@ xen_pfn_t *xc_map_m2p(xc_interface *xch, unsigned long *mfn0); #if defined(__i386__) || defined(__x86_64__) -typedef struct xc_cpu_policy xc_cpu_policy_t; +#include + +typedef 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]; +} xc_cpu_policy_t; /* Create and free a xc_cpu_policy object. */ xc_cpu_policy_t *xc_cpu_policy_init(void); diff --git a/tools/libs/guest/xg_private.h b/tools/libs/guest/xg_private.h index d73947094f2e..d1940f1ea482 100644 --- a/tools/libs/guest/xg_private.h +++ b/tools/libs/guest/xg_private.h @@ -170,14 +170,4 @@ int pin_table(xc_interface *xch, unsigned int type, unsigned long mfn, #define M2P_SIZE(_m) ROUNDUP(((_m) * sizeof(xen_pfn_t)), M2P_SHIFT) #define M2P_CHUNKS(_m) (M2P_SIZE((_m)) >> M2P_SHIFT) -#if defined(__x86_64__) || defined(__i386__) -#include - -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]; -}; -#endif /* x86 */ - #endif /* XG_PRIVATE_H */ diff --git a/xen/include/xen/lib/x86/cpu-policy.h b/xen/include/xen/lib/x86/cpu-policy.h index d5e447e9dc06..0cd454dfc0b6 100644 --- a/xen/include/xen/lib/x86/cpu-policy.h +++ b/xen/include/xen/lib/x86/cpu-policy.h @@ -85,6 +85,8 @@ unsigned int x86_cpuid_lookup_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx); */ const char *x86_cpuid_vendor_to_str(unsigned int vendor); +#define XENLIB_MAX(x, y) ((x) < (y) ? (y) : (x)) + #define CPUID_GUEST_NR_BASIC (0xdu + 1) #define CPUID_GUEST_NR_CACHE (5u + 1) #define CPUID_GUEST_NR_FEAT (2u + 1) @@ -92,8 +94,8 @@ const char *x86_cpuid_vendor_to_str(unsigned int vendor); #define CPUID_GUEST_NR_XSTATE (62u + 1) #define CPUID_GUEST_NR_EXTD_INTEL (0x8u + 1) #define CPUID_GUEST_NR_EXTD_AMD (0x21u + 1) -#define CPUID_GUEST_NR_EXTD MAX(CPUID_GUEST_NR_EXTD_INTEL, \ - CPUID_GUEST_NR_EXTD_AMD) +#define CPUID_GUEST_NR_EXTD XENLIB_MAX(CPUID_GUEST_NR_EXTD_INTEL, \ + CPUID_GUEST_NR_EXTD_AMD) /* * Maximum number of leaves a struct cpu_policy turns into when serialised for From patchwork Wed Feb 7 17:39:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Vallejo X-Patchwork-Id: 13548813 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 433A3C4829C for ; Wed, 7 Feb 2024 17:40:39 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.677848.1054753 (Exim 4.92) (envelope-from ) id 1rXluM-0005ww-NN; Wed, 07 Feb 2024 17:40:26 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 677848.1054753; Wed, 07 Feb 2024 17:40:26 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rXluM-0005wp-JX; Wed, 07 Feb 2024 17:40:26 +0000 Received: by outflank-mailman (input) for mailman id 677848; Wed, 07 Feb 2024 17:40:24 +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 1rXluK-0005Tj-Mx for xen-devel@lists.xenproject.org; Wed, 07 Feb 2024 17:40:24 +0000 Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [2a00:1450:4864:20::633]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f80944d2-c5df-11ee-98f5-efadbce2ee36; Wed, 07 Feb 2024 18:40:22 +0100 (CET) Received: by mail-ej1-x633.google.com with SMTP id a640c23a62f3a-a2d7e2e7fe0so10964766b.1 for ; Wed, 07 Feb 2024 09:40:22 -0800 (PST) Received: from EMEAENGAAD19049.citrite.net (default-46-102-197-194.interdsl.co.uk. [46.102.197.194]) by smtp.gmail.com with ESMTPSA id op3-20020a170906bce300b00a37669280d1sm976355ejb.141.2024.02.07.09.40.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Feb 2024 09:40:21 -0800 (PST) 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: f80944d2-c5df-11ee-98f5-efadbce2ee36 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1707327621; x=1707932421; 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=mVtApRo3oDb95gESnvgdip5hWmKbe9Gt8uYW92ZcjgY=; b=IHKLTSYqGYMG2FbH4XhU2/4dg8HjyG7XKMChdFW0AzS2SS0+rBa/mIg1pLePXoV6Cj 6TloVV9S5DRGe8SpK3kjoXh02ycAD5nidZo6V5bSfqYnhBKbsd41VkZRGCJD4l/J9HQR H7r123liUYtSaJWYGIsGgCtS3qIJxLiLhAIBg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707327621; x=1707932421; 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=mVtApRo3oDb95gESnvgdip5hWmKbe9Gt8uYW92ZcjgY=; b=SaLmk5gg3BKOST9x3myILd3xwm54635Y2x7M7a083+S4m+ULArgLdIUNt9mEhHHZEx EE/rqEnhV7AmYnVOM7+CJF0D8O+hZb2tbgSgZYpp2KONPiun4ZJZXb+GzPV23fndW3R4 NoK7zTL7ZSi9KZwvijWv+b7un7PDRwfE324OesvI9CjzQYuK/bTe8R48EpSS6ZAeKCyi GiVaBUErcuvNR8+fkgbVEd8ydvuk0jKsycM3Kki1xsIlIrsFCPzTLzeozbQVNWMW0CEI owdC0sbvieVAKSo70O/Q3qtPDI0WDZ0UA0Ze0q7ULl78ZmoYUNtpkUKjdYPvO1QTJVO1 Jy/g== X-Gm-Message-State: AOJu0YybHxX/YS3sJS14HVpOq+zdbp9VGCErpy6JHzYhbQfKBXpU941t SsB/Yt2WQwpJPLcMwTqeH95ho5J+dDKHs0nGmt7HutWxSfMxQIajGwzzqDj6RoNaebax3kTyk+f Q X-Google-Smtp-Source: AGHT+IFti7lLnLxiOpm9L+6Lm+EqtJakdk0jtGAtrQZIv4hyXS+2eHGRGr7hF7VGK4dj1jA3WvSInw== X-Received: by 2002:a17:907:7d89:b0:a38:c2f9:4ee with SMTP id oz9-20020a1709077d8900b00a38c2f904eemr337167ejc.0.1707327621345; Wed, 07 Feb 2024 09:40:21 -0800 (PST) X-Forwarded-Encrypted: i=1; AJvYcCUu8JHBp8+s80ogwlQxOobccH2V6n8CB4NFjDsKsHcVsCjocjr8+LHqnciFLJV+cvz9ipel+qPrGpwUWU0rHratbFeRltuKDTAyMOW8946xPYF9IEOF5rfdEE2QGfsdEe6kvCdzeDMMsbTxduZ22i6lh+riJqeTHys8O8ScEF3Au59iVHk08WNMgf8KFBgY313lRhjvzc7aJz80UODN6Nv1XJ6A6Xi9E/la8Q== From: Alejandro Vallejo To: Xen-devel Cc: Alejandro Vallejo , Wei Liu , Anthony PERARD , Juergen Gross , Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [PATCH 2/3] tools/xg: Streamline cpu policy serialise/deserialise calls Date: Wed, 7 Feb 2024 17:39:56 +0000 Message-Id: <20240207173957.19811-3-alejandro.vallejo@cloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240207173957.19811-1-alejandro.vallejo@cloud.com> References: <20240207173957.19811-1-alejandro.vallejo@cloud.com> MIME-Version: 1.0 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 --- Splitting this patch in several is quite annoying, as it implies artificially creating duplicates of the (de)serialization functions, and applying them little by little. The resulting diffs are not much better than this. --- tools/include/xenguest.h | 6 +-- tools/libs/guest/xg_cpuid_x86.c | 62 ++++++++++++++--------------- tools/libs/guest/xg_sr_common_x86.c | 54 +++++++++---------------- tools/misc/xen-cpuid.c | 40 +++++-------------- 4 files changed, 61 insertions(+), 101 deletions(-) diff --git a/tools/include/xenguest.h b/tools/include/xenguest.h index 4e9078fdee4d..5c287b4a210c 100644 --- a/tools/include/xenguest.h +++ b/tools/include/xenguest.h @@ -789,7 +789,9 @@ xen_pfn_t *xc_map_m2p(xc_interface *xch, typedef struct xc_cpu_policy { struct cpu_policy policy; xen_cpuid_leaf_t leaves[CPUID_MAX_SERIALISED_LEAVES]; + uint32_t nr_leaves; xen_msr_entry_t msrs[MSR_MAX_SERIALISED_ENTRIES]; + uint32_t nr_msrs; } xc_cpu_policy_t; /* Create and free a xc_cpu_policy object. */ @@ -805,9 +807,7 @@ int xc_cpu_policy_set_domain(xc_interface *xch, uint32_t domid, xc_cpu_policy_t *policy); /* Manipulate a policy via architectural representations. */ -int xc_cpu_policy_serialise(xc_interface *xch, const xc_cpu_policy_t *policy, - 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); diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x86.c index 4453178100ad..5699a26b946e 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) } } -static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy, - unsigned int nr_leaves, unsigned int nr_entries) +static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy) { uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1; int rc; rc = x86_cpuid_copy_from_buffer(&policy->policy, policy->leaves, - nr_leaves, &err_leaf, &err_subleaf); + policy->nr_leaves, &err_leaf, &err_subleaf); if ( rc ) { if ( err_leaf != -1 ) @@ -851,7 +850,7 @@ static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy, } rc = x86_msr_copy_from_buffer(&policy->policy, policy->msrs, - nr_entries, &err_msr); + policy->nr_msrs, &err_msr); if ( rc ) { if ( err_msr != -1 ) @@ -878,7 +877,10 @@ int xc_cpu_policy_get_system(xc_interface *xch, unsigned int policy_idx, return rc; } - rc = deserialize_policy(xch, policy, nr_leaves, nr_msrs); + policy->nr_leaves = nr_leaves; + policy->nr_msrs = nr_msrs; + + rc = deserialize_policy(xch, policy); if ( rc ) { errno = -rc; @@ -903,7 +905,10 @@ int xc_cpu_policy_get_domain(xc_interface *xch, uint32_t domid, return rc; } - rc = deserialize_policy(xch, policy, nr_leaves, nr_msrs); + policy->nr_leaves = nr_leaves; + policy->nr_msrs = nr_msrs; + + rc = deserialize_policy(xch, policy); if ( rc ) { errno = -rc; @@ -917,17 +922,14 @@ int xc_cpu_policy_set_domain(xc_interface *xch, uint32_t domid, xc_cpu_policy_t *policy) { uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1; - unsigned int nr_leaves = ARRAY_SIZE(policy->leaves); - unsigned int nr_msrs = ARRAY_SIZE(policy->msrs); int rc; - rc = xc_cpu_policy_serialise(xch, policy, policy->leaves, &nr_leaves, - policy->msrs, &nr_msrs); + rc = xc_cpu_policy_serialise(xch, policy); if ( rc ) return rc; - rc = xc_set_domain_cpu_policy(xch, domid, nr_leaves, policy->leaves, - nr_msrs, policy->msrs, + rc = 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,34 +944,32 @@ int xc_cpu_policy_set_domain(xc_interface *xch, uint32_t domid, return rc; } -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) { + unsigned int nr_leaves = ARRAY_SIZE(p->leaves); + unsigned int nr_msrs = ARRAY_SIZE(p->msrs); int rc; - if ( leaves ) + rc = x86_cpuid_copy_to_buffer(&p->policy, p->leaves, &nr_leaves); + if ( rc ) { - rc = x86_cpuid_copy_to_buffer(&p->policy, leaves, nr_leaves); - if ( rc ) - { - ERROR("Failed to serialize CPUID policy"); - errno = -rc; - return -1; - } + ERROR("Failed to serialize CPUID policy"); + errno = -rc; + return -1; } - if ( msrs ) + p->nr_leaves = nr_leaves; + + rc = x86_msr_copy_to_buffer(&p->policy, p->msrs, &nr_msrs); + if ( rc ) { - rc = x86_msr_copy_to_buffer(&p->policy, msrs, nr_msrs); - if ( rc ) - { - ERROR("Failed to serialize MSR policy"); - errno = -rc; - return -1; - } + ERROR("Failed to serialize MSR policy"); + errno = -rc; + return -1; } + p->nr_msrs = nr_msrs; + errno = 0; return 0; } diff --git a/tools/libs/guest/xg_sr_common_x86.c b/tools/libs/guest/xg_sr_common_x86.c index 563b4f016877..832047756e58 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" int write_x86_tsc_info(struct xc_sr_context *ctx) { @@ -45,54 +46,37 @@ int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec) int write_x86_cpu_policy_records(struct xc_sr_context *ctx) { xc_interface *xch = ctx->xch; - struct xc_sr_record cpuid = { .type = REC_TYPE_X86_CPUID_POLICY, }; - struct xc_sr_record msrs = { .type = REC_TYPE_X86_MSR_POLICY, }; - uint32_t nr_leaves = 0, nr_msrs = 0; - xc_cpu_policy_t *policy = NULL; + struct xc_sr_record record; + xc_cpu_policy_t *policy = xc_cpu_policy_init(); int rc; - if ( xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs) < 0 ) - { - PERROR("Unable to get CPU Policy size"); - return -1; - } - - cpuid.data = malloc(nr_leaves * sizeof(xen_cpuid_leaf_t)); - msrs.data = malloc(nr_msrs * sizeof(xen_msr_entry_t)); - policy = xc_cpu_policy_init(); - if ( !cpuid.data || !msrs.data || !policy ) - { - ERROR("Cannot allocate memory for CPU Policy"); - rc = -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 = -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 = -1; - goto out; - } - cpuid.length = nr_leaves * sizeof(xen_cpuid_leaf_t); - if ( cpuid.length ) + record = (struct xc_sr_record) { + .type = REC_TYPE_X86_CPUID_POLICY, + .data = policy->leaves, + .length = policy->nr_leaves * sizeof(*policy->leaves), + }; + if ( record.length ) { - rc = write_record(ctx, &cpuid); + rc = write_record(ctx, &record); if ( rc ) goto out; } - msrs.length = nr_msrs * sizeof(xen_msr_entry_t); - if ( msrs.length ) + record = (struct xc_sr_record) { + .type = REC_TYPE_X86_MSR_POLICY, + .data = policy->msrs, + .length = policy->nr_msrs * sizeof(*policy->msrs), + }; + if ( record.length ) { - rc = write_record(ctx, &msrs); + rc = write_record(ctx, &record); if ( rc ) goto out; } @@ -100,8 +84,6 @@ int write_x86_cpu_policy_records(struct xc_sr_context *ctx) rc = 0; out: - free(cpuid.data); - free(msrs.data); xc_cpu_policy_destroy(policy); return rc; diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c index 46abdb914092..1d4761d9ad9f 100644 --- a/tools/misc/xen-cpuid.c +++ b/tools/misc/xen-cpuid.c @@ -403,17 +403,18 @@ static void dump_info(xc_interface *xch, bool detail) 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(const char *name, xc_cpu_policy_t *policy) { - unsigned int l; + const xen_cpuid_leaf_t *leaves = policy->leaves; + const xen_msr_entry_t *msrs = policy->msrs; + uint32_t nr_leaves = policy->nr_leaves; + uint32_t nr_msrs = policy->nr_msrs; printf("%s policy: %u leaves, %u MSRs\n", name, nr_leaves, nr_msrs); printf(" CPUID:\n"); printf(" %-8s %-8s -> %-8s %-8s %-8s %-8s\n", "leaf", "subleaf", "eax", "ebx", "ecx", "edx"); - for ( l = 0; l < nr_leaves; ++l ) + for ( uint32_t l = 0; l < nr_leaves; ++l ) { /* Skip empty leaves. */ if ( !leaves[l].a && !leaves[l].b && !leaves[l].c && !leaves[l].d ) @@ -426,7 +427,7 @@ static void print_policy(const char *name, printf(" MSRs:\n"); printf(" %-8s -> %-16s\n", "index", "value"); - for ( l = 0; l < nr_msrs; ++l ) + for ( uint32_t l = 0; l < nr_msrs; ++l ) printf(" %08x -> %016"PRIx64"\n", msrs[l].idx, msrs[l].val); } @@ -533,8 +534,6 @@ int main(int argc, char **argv) [ XEN_SYSCTL_cpu_policy_pv_default ] = "PV Default", [ XEN_SYSCTL_cpu_policy_hvm_default ] = "HVM Default", }; - xen_cpuid_leaf_t *leaves; - xen_msr_entry_t *msrs; uint32_t i, max_leaves, max_msrs; xc_interface *xch = xc_interface_open(0, 0, 0); @@ -551,36 +550,21 @@ int main(int argc, char **argv) printf("Xen reports there are maximum %u leaves and %u MSRs\n", max_leaves, max_msrs); - leaves = calloc(max_leaves, sizeof(xen_cpuid_leaf_t)); - if ( !leaves ) - err(1, "calloc(max_leaves)"); - msrs = calloc(max_msrs, sizeof(xen_msr_entry_t)); - if ( !msrs ) - err(1, "calloc(max_msrs)"); - if ( domid != -1 ) { char name[20]; - uint32_t nr_leaves = max_leaves; - uint32_t nr_msrs = max_msrs; 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"); snprintf(name, sizeof(name), "Domain %d", domid); - print_policy(name, leaves, nr_leaves, msrs, nr_msrs); + print_policy(name, policy); } else { /* Get system policies */ for ( i = 0; i < ARRAY_SIZE(sys_policies); ++i ) { - uint32_t nr_leaves = max_leaves; - uint32_t nr_msrs = max_msrs; - if ( xc_cpu_policy_get_system(xch, i, policy) ) { if ( errno == EOPNOTSUPP ) @@ -592,18 +576,12 @@ int main(int argc, char **argv) err(1, "xc_cpu_policy_get_system(, %s, )", sys_policies[i]); } - if ( xc_cpu_policy_serialise(xch, policy, leaves, &nr_leaves, - msrs, &nr_msrs) ) - err(1, "xc_cpu_policy_serialise"); - print_policy(sys_policies[i], leaves, nr_leaves, - msrs, nr_msrs); + print_policy(sys_policies[i], policy); } } xc_cpu_policy_destroy(policy); - free(leaves); - free(msrs); xc_interface_close(xch); } else if ( mode == MODE_INFO || mode == MODE_DETAIL ) From patchwork Wed Feb 7 17:39:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Vallejo X-Patchwork-Id: 13548811 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EBC4BC4828D for ; Wed, 7 Feb 2024 17:40:37 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.677849.1054758 (Exim 4.92) (envelope-from ) id 1rXluN-00060T-1S; Wed, 07 Feb 2024 17:40:27 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 677849.1054758; Wed, 07 Feb 2024 17:40:26 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1rXluM-0005zY-SE; Wed, 07 Feb 2024 17:40:26 +0000 Received: by outflank-mailman (input) for mailman id 677849; Wed, 07 Feb 2024 17:40:25 +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 1rXluL-0005Tj-6h for xen-devel@lists.xenproject.org; Wed, 07 Feb 2024 17:40:25 +0000 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [2a00:1450:4864:20::535]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f82012e9-c5df-11ee-98f5-efadbce2ee36; Wed, 07 Feb 2024 18:40:22 +0100 (CET) Received: by mail-ed1-x535.google.com with SMTP id 4fb4d7f45d1cf-55f50cf2021so1147683a12.1 for ; Wed, 07 Feb 2024 09:40:22 -0800 (PST) Received: from EMEAENGAAD19049.citrite.net (default-46-102-197-194.interdsl.co.uk. [46.102.197.194]) by smtp.gmail.com with ESMTPSA id op3-20020a170906bce300b00a37669280d1sm976355ejb.141.2024.02.07.09.40.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Feb 2024 09:40:21 -0800 (PST) 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: f82012e9-c5df-11ee-98f5-efadbce2ee36 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1707327622; x=1707932422; 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=ldOTwPyqzlRUxWLHaw7i5K1+RmAlnFbaE9qRDYjtAH0=; b=OEEhh8ObTtLBmFFcrGBrcK0UiNVrx5h45tMxZKhrzlGM3EnSHiMP9ZCpte4ySlJe56 9Py2EaM8xNIjPk88uRU0obzCBeyc+3ug3BGosS6j9G9igXeCh5kPtWXpKDltVxv7XsXG q9P+lXJBSF/OW0+AHfKzQvfsyOuve10PNzesU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707327622; x=1707932422; 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=ldOTwPyqzlRUxWLHaw7i5K1+RmAlnFbaE9qRDYjtAH0=; b=XM7y/XavkxbSTvmieY7p0ACePy61zumc0oY1Cc5C5CXJ9SXSA01vFIv9Q3Pf9zAZeo h31OBCnfh7tr7IwH1oF+G1LShn755EEgRoM1xIGQ756u8mkHuxrO/1S8/oU8uM6BdzCG CMZjXhGzp5MUMF7mmMgCYFaCN/Xu3RezPqHptHlVcMJ1ceffWV3gcC1KTvo5QlWl7o3d FCZcxVJwpieTp7PbBg6Tq0q1ybLOIJOzxttc+9qQ5cbDlPJtB+qaNj8Yx/ygYAdKGW7L IIhmRIwiy+n/s3ILGkSti9jttNHM1G7iEr1i32EEEIRxqybCUfeGjZoFt6IeKS4Bp7Jd 2TQA== X-Gm-Message-State: AOJu0YwyCZaKHrlgtZl8guA0g2GfKLWj9dTH44Bd+H82EbTgodIojHaP GtWRS88Ddlo0yZpmIzxf8gVTr5KE6d7QH2FlBRzpsKJeRh2JkhmCjB9cxUD9UrkmkE/ThcKz/11 l X-Google-Smtp-Source: AGHT+IE3MMy7s/KceVpl0+osxKbEUSaPxMA3zbux6Npx3Vw8SZaWADt2bnx3dI6X45hSB1uwO9zP+A== X-Received: by 2002:a17:906:168e:b0:a38:41bf:f6f6 with SMTP id s14-20020a170906168e00b00a3841bff6f6mr3284144ejd.77.1707327621876; Wed, 07 Feb 2024 09:40:21 -0800 (PST) X-Forwarded-Encrypted: i=1; AJvYcCU3evZJ50jo+0bSNFkZnb7WnQH7a1v5kbysvosyVpbX6zqd3DmZFqDLPSyJfq7ElGFRcP6ky6K7IttyTpe+NbP+gPvsMEptIhhVaEDevy8pSlXI7VZG2WK+1657Su3lnKVcxrgzmro= From: Alejandro Vallejo To: Xen-devel Cc: Alejandro Vallejo , Wei Liu , Anthony PERARD , Juergen Gross Subject: [PATCH 3/3] tools/xg: Clean up xend-style overrides for CPU policies Date: Wed, 7 Feb 2024 17:39:57 +0000 Message-Id: <20240207173957.19811-4-alejandro.vallejo@cloud.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240207173957.19811-1-alejandro.vallejo@cloud.com> References: <20240207173957.19811-1-alejandro.vallejo@cloud.com> MIME-Version: 1.0 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 --- tools/libs/guest/xg_cpuid_x86.c | 444 +++++++++----------------------- 1 file changed, 128 insertions(+), 316 deletions(-) diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x86.c index 5699a26b946e..cee0be80ba5b 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) +static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy) +{ + uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1; + int rc; + + rc = x86_cpuid_copy_from_buffer(&policy->policy, policy->leaves, + policy->nr_leaves, &err_leaf, &err_subleaf); + if ( rc ) + { + if ( err_leaf != -1 ) + ERROR("Failed to deserialise CPUID (err leaf %#x, subleaf %#x) (%d = %s)", + err_leaf, err_subleaf, -rc, strerror(-rc)); + return rc; + } + + rc = x86_msr_copy_from_buffer(&policy->policy, policy->msrs, + policy->nr_msrs, &err_msr); + if ( rc ) + { + if ( err_msr != -1 ) + ERROR("Failed to deserialise MSR (err MSR %#x) (%d = %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 = {}; @@ -260,102 +288,34 @@ static int compare_leaves(const void *l, const void *r) return 0; } -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 = { xend->leaf, xend->subleaf }; - return bsearch(&key, leaves, nr_leaves, sizeof(*leaves), compare_leaves); + return bsearch(&key, p->leaves, ARRAY_SIZE(p->leaves), + sizeof(*p->leaves), compare_leaves); } -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 = -1, err_subleaf = -1, err_msr = -1; - /* - * Three full policies. The host, default for the domain type, - * and domain current. - */ - xen_cpuid_leaf_t *host = NULL, *def = NULL, *cur = NULL; - unsigned int nr_host, nr_def, nr_cur; - - if ( (rc = xc_domain_getinfo_single(xch, domid, &di)) < 0 ) - { - PERROR("Failed to obtain d%d info", domid); - rc = -errno; - goto fail; - } - hvm = di.flags & XEN_DOMINF_hvm_guest; - - rc = xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs); - if ( rc ) - { - PERROR("Failed to obtain policy info size"); - rc = -errno; - goto fail; - } - - rc = -ENOMEM; - if ( (host = calloc(nr_leaves, sizeof(*host))) == NULL || - (def = calloc(nr_leaves, sizeof(*def))) == NULL || - (cur = calloc(nr_leaves, sizeof(*cur))) == NULL ) - { - ERROR("Unable to allocate memory for %u CPUID leaves", nr_leaves); - goto fail; - } - - /* Get the domain's current policy. */ - nr_msrs = 0; - nr_cur = nr_leaves; - rc = get_domain_cpu_policy(xch, domid, &nr_cur, cur, &nr_msrs, NULL); - if ( rc ) - { - PERROR("Failed to obtain d%d current policy", domid); - rc = -errno; - goto fail; - } - - /* Get the domain type's default policy. */ - nr_msrs = 0; - nr_def = nr_leaves; - rc = get_system_cpu_policy(xch, hvm ? XEN_SYSCTL_cpu_policy_hvm_default - : 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 = -errno; - goto fail; - } - - /* Get the host policy. */ - nr_msrs = 0; - nr_host = nr_leaves; - rc = 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 = -errno; - goto fail; - } + if ( !xend ) + return 0; - rc = -EINVAL; for ( ; xend->leaf != XEN_CPUID_INPUT_UNUSED; ++xend ) { - xen_cpuid_leaf_t *cur_leaf = find_leaf(cur, nr_cur, xend); - const xen_cpuid_leaf_t *def_leaf = find_leaf(def, nr_def, xend); - const xen_cpuid_leaf_t *host_leaf = find_leaf(host, nr_host, xend); + xen_cpuid_leaf_t *cur_leaf = find_leaf(cur, xend); + const xen_cpuid_leaf_t *def_leaf = find_leaf(def, xend); + const xen_cpuid_leaf_t *host_leaf = find_leaf(host, xend); if ( cur_leaf == NULL || def_leaf == NULL || host_leaf == NULL ) { ERROR("Missing leaf %#x, subleaf %#x", xend->leaf, xend->subleaf); - goto fail; + return -EINVAL; } for ( unsigned int i = 0; i < ARRAY_SIZE(xend->policy); i++ ) @@ -384,7 +344,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; } clear_bit(31 - j, cur_reg); @@ -394,25 +354,7 @@ static int xc_cpuid_xend_policy( } } - /* Feed the transformed currrent policy back up to Xen. */ - rc = 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 = -errno; - goto fail; - } - - /* Success! */ - - fail: - free(cur); - free(def); - free(host); - - return rc; + return 0; } static int compare_msr(const void *l, const void *r) @@ -426,107 +368,34 @@ static int compare_msr(const void *l, const void *r) return lhs->idx < rhs->idx ? -1 : 1; } -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 = { .idx = index }; - return bsearch(&key, msrs, nr_msrs, sizeof(*msrs), compare_msr); + return bsearch(&key, p->msrs, ARRAY_SIZE(p->msrs), + sizeof(*p->msrs), compare_msr); } - 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 = -1, err_subleaf = -1, err_msr = -1; - /* - * Three full policies. The host, default for the domain type, - * and domain current. - */ - xen_msr_entry_t *host = NULL, *def = NULL, *cur = NULL; - unsigned int nr_host, nr_def, nr_cur; - - if ( (rc = xc_domain_getinfo_single(xch, domid, &di)) < 0 ) - { - PERROR("Failed to obtain d%d info", domid); - rc = -errno; - goto out; - } - hvm = di.flags & XEN_DOMINF_hvm_guest; - - rc = xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs); - if ( rc ) - { - PERROR("Failed to obtain policy info size"); - rc = -errno; - goto out; - } - - if ( (host = calloc(nr_msrs, sizeof(*host))) == NULL || - (def = calloc(nr_msrs, sizeof(*def))) == NULL || - (cur = calloc(nr_msrs, sizeof(*cur))) == NULL ) - { - ERROR("Unable to allocate memory for %u CPUID leaves", nr_leaves); - rc = -ENOMEM; - goto out; - } - - /* Get the domain's current policy. */ - nr_leaves = 0; - nr_cur = nr_msrs; - rc = get_domain_cpu_policy(xch, domid, &nr_leaves, NULL, &nr_cur, cur); - if ( rc ) - { - PERROR("Failed to obtain d%d current policy", domid); - rc = -errno; - goto out; - } - - /* Get the domain type's default policy. */ - nr_leaves = 0; - nr_def = nr_msrs; - rc = get_system_cpu_policy(xch, hvm ? XEN_SYSCTL_cpu_policy_hvm_default - : 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 = -errno; - goto out; - } - - /* Get the host policy. */ - nr_leaves = 0; - nr_host = nr_msrs; - rc = 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 = -errno; - goto out; - } - for ( ; msr->index != XC_MSR_INPUT_UNUSED; ++msr ) { - xen_msr_entry_t *cur_msr = find_msr(cur, nr_cur, msr->index); - const xen_msr_entry_t *def_msr = find_msr(def, nr_def, msr->index); - const xen_msr_entry_t *host_msr = find_msr(host, nr_host, msr->index); - unsigned int i; + xen_msr_entry_t *cur_msr = find_msr(cur, msr->index); + const xen_msr_entry_t *def_msr = find_msr(def, msr->index); + const xen_msr_entry_t *host_msr = find_msr(host, msr->index); if ( cur_msr == NULL || def_msr == NULL || host_msr == NULL ) { ERROR("Missing MSR %#x", msr->index); - rc = -ENOENT; - goto out; + return -ENOENT; } - for ( i = 0; i < ARRAY_SIZE(msr->policy) - 1; i++ ) + for ( size_t i = 0; i < ARRAY_SIZE(msr->policy) - 1; i++ ) { bool val; @@ -542,8 +411,7 @@ static int xc_msr_policy(xc_interface *xch, domid_t domid, { ERROR("MSR index %#x: bad character '%c' in policy string '%s'", msr->index, msr->policy[i], msr->policy); - rc = -EINVAL; - goto out; + return -EINVAL; } if ( val ) @@ -553,25 +421,7 @@ static int xc_msr_policy(xc_interface *xch, domid_t domid, } } - /* Feed the transformed policy back up to Xen. */ - rc = 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 = -errno; - goto out; - } - - /* Success! */ - - out: - free(cur); - free(def); - free(host); - - return rc; + return 0; } int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, @@ -583,14 +433,16 @@ 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 = xc_cpu_policy_init(); - unsigned int i, nr_leaves = ARRAY_SIZE(p->leaves), nr_msrs = 0; - uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1; - uint32_t host_featureset[FEATURESET_NR_ENTRIES] = {}; - uint32_t len = ARRAY_SIZE(host_featureset); - if ( !p ) - return -ENOMEM; + struct xc_cpu_policy *host = xc_cpu_policy_init(); + struct xc_cpu_policy *def = xc_cpu_policy_init(); + struct xc_cpu_policy *cur = xc_cpu_policy_init(); + + if ( !host || !def || !cur ) + { + rc = -ENOMEM; + goto out; + } if ( (rc = xc_domain_getinfo_single(xch, domid, &di)) < 0 ) { @@ -600,21 +452,19 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, } hvm = di.flags & XEN_DOMINF_hvm_guest; - /* Get the host policy. */ - rc = 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 != ENOBUFS ) + /* Get the raw host policy */ + rc = 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 = -errno; goto out; } /* Get the domain's default policy. */ - rc = get_system_cpu_policy(xch, hvm ? XEN_SYSCTL_cpu_policy_hvm_default - : XEN_SYSCTL_cpu_policy_pv_default, - &nr_leaves, p->leaves, &nr_msrs, NULL); + rc = xc_cpu_policy_get_system(xch, hvm ? XEN_SYSCTL_cpu_policy_hvm_default + : XEN_SYSCTL_cpu_policy_pv_default, + def); if ( rc ) { PERROR("Failed to obtain %s default policy", hvm ? "hvm" : "pv"); @@ -622,14 +472,8 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, goto out; } - rc = 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 = %s)", - err_leaf, err_subleaf, -rc, strerror(-rc)); - goto out; - } + /* Copy the deserialised default policy to modify it */ + memcpy(cur, def, sizeof(*cur)); if ( restore ) { @@ -647,18 +491,18 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, * - Re-enable features which have become (possibly) off by default. */ - p->policy.basic.rdrand = test_bit(X86_FEATURE_RDRAND, host_featureset); - p->policy.feat.hle = test_bit(X86_FEATURE_HLE, host_featureset); - p->policy.feat.rtm = test_bit(X86_FEATURE_RTM, host_featureset); + cur->policy.basic.rdrand = host->policy.basic.rdrand; + cur->policy.feat.hle = host->policy.feat.hle; + cur->policy.feat.rtm = host->policy.feat.rtm; if ( hvm ) { - p->policy.feat.mpx = test_bit(X86_FEATURE_MPX, host_featureset); + cur->policy.feat.mpx = host->policy.feat.mpx; } - p->policy.basic.max_leaf = min(p->policy.basic.max_leaf, 0xdu); - p->policy.feat.max_subleaf = 0; - p->policy.extd.max_leaf = min(p->policy.extd.max_leaf, 0x8000001c); + cur->policy.basic.max_leaf = min(cur->policy.basic.max_leaf, 0xdu); + cur->policy.feat.max_subleaf = 0; + cur->policy.extd.max_leaf = min(cur->policy.extd.max_leaf, 0x8000001c); } if ( featureset ) @@ -666,7 +510,7 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, uint32_t disabled_features[FEATURESET_NR_ENTRIES], feat[FEATURESET_NR_ENTRIES] = {}; static const uint32_t deep_features[] = INIT_DEEP_FEATURES; - unsigned int i, b; + unsigned int b; /* * The user supplied featureset may be shorter or longer than @@ -677,14 +521,14 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, /* Check for truncated set bits. */ rc = -EOPNOTSUPP; - for ( i = user_len; i < nr_features; ++i ) + for ( size_t i = user_len; i < nr_features; ++i ) if ( featureset[i] != 0 ) goto out; memcpy(feat, featureset, sizeof(*featureset) * user_len); /* Disable deep dependencies of disabled features. */ - for ( i = 0; i < ARRAY_SIZE(disabled_features); ++i ) + for ( size_t i = 0; i < ARRAY_SIZE(disabled_features); ++i ) disabled_features[i] = ~feat[i] & deep_features[i]; for ( b = 0; b < sizeof(disabled_features) * CHAR_BIT; ++b ) @@ -695,24 +539,24 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, !(dfs = x86_cpu_policy_lookup_deep_deps(b)) ) continue; - for ( i = 0; i < ARRAY_SIZE(disabled_features); ++i ) + for ( size_t i = 0; i < ARRAY_SIZE(disabled_features); ++i ) { feat[i] &= ~dfs[i]; disabled_features[i] &= ~dfs[i]; } } - x86_cpu_featureset_to_policy(feat, &p->policy); + x86_cpu_featureset_to_policy(feat, &cur->policy); } else { - p->policy.extd.itsc = itsc; + cur->policy.extd.itsc = itsc; if ( hvm ) { - p->policy.basic.pae = pae; - p->policy.basic.vmx = nested_virt; - p->policy.extd.svm = nested_virt; + cur->policy.basic.pae = pae; + cur->policy.basic.vmx = nested_virt; + cur->policy.extd.svm = nested_virt; } } @@ -722,8 +566,8 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, 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 = test_bit(X86_FEATURE_HTT, host_featureset); - p->policy.extd.cmp_legacy = test_bit(X86_FEATURE_CMP_LEGACY, host_featureset); + cur->policy.basic.htt = host->policy.basic.htt; + cur->policy.extd.cmp_legacy = host->policy.extd.cmp_legacy; } else { @@ -731,28 +575,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 = vcpu_id * 2 to give the illusion of no SMT. */ - p->policy.basic.htt = true; - p->policy.extd.cmp_legacy = false; + cur->policy.basic.htt = true; + cur->policy.extd.cmp_legacy = false; /* * Leaf 1 EBX[23:16] is Maximum Logical Processors Per Package. * Update to reflect vLAPIC_ID = vCPU_ID * 2, but make sure to avoid * overflow. */ - if ( !p->policy.basic.lppp ) - p->policy.basic.lppp = 2; - else if ( !(p->policy.basic.lppp & 0x80) ) - p->policy.basic.lppp *= 2; + if ( !cur->policy.basic.lppp ) + cur->policy.basic.lppp = 2; + else if ( !(cur->policy.basic.lppp & 0x80) ) + cur->policy.basic.lppp *= 2; - switch ( p->policy.x86_vendor ) + switch ( cur->policy.x86_vendor ) { case X86_VENDOR_INTEL: - for ( i = 0; (p->policy.cache.subleaf[i].type && - i < ARRAY_SIZE(p->policy.cache.raw)); ++i ) + for ( size_t i = 0; (cur->policy.cache.subleaf[i].type && + i < ARRAY_SIZE(cur->policy.cache.raw)); ++i ) { - p->policy.cache.subleaf[i].cores_per_package = - (p->policy.cache.subleaf[i].cores_per_package << 1) | 1; - p->policy.cache.subleaf[i].threads_per_cache = 0; + cur->policy.cache.subleaf[i].cores_per_package = + (cur->policy.cache.subleaf[i].cores_per_package << 1) | 1; + cur->policy.cache.subleaf[i].threads_per_cache = 0; } break; @@ -772,49 +616,45 @@ 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 != 0 && p->policy.extd.apic_id_size < 0x7 ) - p->policy.extd.apic_id_size++; + if ( cur->policy.extd.apic_id_size != 0 && cur->policy.extd.apic_id_size < 0x7 ) + cur->policy.extd.apic_id_size++; - p->policy.extd.nc = (p->policy.extd.nc << 1) | 1; + cur->policy.extd.nc = (cur->policy.extd.nc << 1) | 1; } break; } } - nr_leaves = ARRAY_SIZE(p->leaves); - rc = x86_cpuid_copy_to_buffer(&p->policy, p->leaves, &nr_leaves); - if ( rc ) + if ( xend || msr ) { - ERROR("Failed to serialise CPUID (%d = %s)", -rc, strerror(-rc)); - goto out; + // The overrides are over the serialised form of the policy + if ( (rc = xc_cpu_policy_serialise(xch, cur)) ) + goto out; + + if ( (rc = xc_cpuid_xend_policy(xch, domid, xend, host, def, cur)) ) + goto out; + if ( (rc = xc_msr_policy(xch, domid, msr, host, def, cur)) ) + goto out; + + if ( (rc = deserialize_policy(xch, cur)) ) + goto out; } - rc = xc_set_domain_cpu_policy(xch, domid, nr_leaves, p->leaves, 0, NULL, - &err_leaf, &err_subleaf, &err_msr); + rc = 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 = -errno; goto out; } - if ( xend && (rc = xc_cpuid_xend_policy(xch, domid, xend)) ) - goto out; - - if ( msr ) - { - rc = xc_msr_policy(xch, domid, msr); - if ( rc ) - goto out; - } - rc = 0; out: - xc_cpu_policy_destroy(p); + xc_cpu_policy_destroy(def); + xc_cpu_policy_destroy(host); + xc_cpu_policy_destroy(cur); return rc; } @@ -834,34 +674,6 @@ void xc_cpu_policy_destroy(xc_cpu_policy_t *policy) } } -static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy) -{ - uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1; - int rc; - - rc = x86_cpuid_copy_from_buffer(&policy->policy, policy->leaves, - policy->nr_leaves, &err_leaf, &err_subleaf); - if ( rc ) - { - if ( err_leaf != -1 ) - ERROR("Failed to deserialise CPUID (err leaf %#x, subleaf %#x) (%d = %s)", - err_leaf, err_subleaf, -rc, strerror(-rc)); - return rc; - } - - rc = x86_msr_copy_from_buffer(&policy->policy, policy->msrs, - policy->nr_msrs, &err_msr); - if ( rc ) - { - if ( err_msr != -1 ) - ERROR("Failed to deserialise MSR (err MSR %#x) (%d = %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) {