From patchwork Sat May 8 05:52:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Like Xu X-Patchwork-Id: 1475791 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fcc2f60KTz9sWl for ; Sat, 8 May 2021 15:54:18 +1000 (AEST) Received: from localhost ([::1]:40338 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lfFup-0001zE-J8 for incoming@patchwork.ozlabs.org; Sat, 08 May 2021 01:54:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49900) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lfFuX-0001z5-FI for qemu-devel@nongnu.org; Sat, 08 May 2021 01:53:57 -0400 Received: from mga18.intel.com ([134.134.136.126]:46725) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lfFuV-0004pl-BO for qemu-devel@nongnu.org; Sat, 08 May 2021 01:53:57 -0400 IronPort-SDR: BU3ya/ZRUgqkvUBW7vJO86WbIbANJ52D00N3fut+FN3HYOAY0ymO3KXupH2K3EmpNUtBYQhHwr yLE2XIUDGXGQ== X-IronPort-AV: E=McAfee;i="6200,9189,9977"; a="186322595" X-IronPort-AV: E=Sophos;i="5.82,282,1613462400"; d="scan'208";a="186322595" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 May 2021 22:53:45 -0700 IronPort-SDR: 8NO9XZmzt7DoTvwAI91n+PIL3SVinrm98jxPBSID6TBlL/L6aTrBpq1kiscdRQE9IZOwKocmMf A5Fqu6w0dXQg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,282,1613462400"; d="scan'208";a="466375848" Received: from clx-ap-likexu.sh.intel.com ([10.239.48.108]) by fmsmga002.fm.intel.com with ESMTP; 07 May 2021 22:53:43 -0700 From: Like Xu To: Paolo Bonzini , Eduardo Habkost Subject: [PATCH v3 1/2] qdev-properties: Add a new macro to validate bitmask for setter Date: Sat, 8 May 2021 13:52:58 +0800 Message-Id: <20210508055259.128025-1-like.xu@linux.intel.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Received-SPF: none client-ip=134.134.136.126; envelope-from=like.xu@linux.intel.com; helo=mga18.intel.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?b?RGFuaWVsIFAgLiBCZXJyYW5nw6k/?= , Like Xu , Richard Henderson , qemu-devel@nongnu.org, Markus Armbruster , weijiang.yang@intel.com, wei.w.wang@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The new generic DEFINE_PROP_BITMASK_UINT64 could be used to ensure that a user-provided property value complies with its bitmask rule and the default value is recommended to be set in instance_init(). Signed-off-by: Like Xu --- hw/core/qdev-properties.c | 19 +++++++++++++++++++ include/hw/qdev-properties.h | 12 ++++++++++++ include/qapi/qmp/qerror.h | 3 +++ 3 files changed, 34 insertions(+) diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 50f40949f5..3784d3b30d 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -428,6 +428,25 @@ const PropertyInfo qdev_prop_int64 = { .set_default_value = qdev_propinfo_set_default_value_int, }; +static void set_bitmask_uint64(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + Property *prop = opaque; + uint64_t *ptr = object_field_prop_ptr(obj, prop); + + visit_type_uint64(v, name, ptr, errp); + + if (*ptr & ~prop->bitmask) { + error_setg(errp, QERR_INVALID_BITMASK_VALUE, name, prop->bitmask); + } +} + +const PropertyInfo qdev_prop_bitmask_uint64 = { + .name = "int64", + .get = get_uint64, + .set = set_bitmask_uint64, +}; + /* --- string --- */ static void release_string(Object *obj, const char *name, void *opaque) diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 0ef97d60ce..42f0112e14 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -17,6 +17,7 @@ struct Property { const PropertyInfo *info; ptrdiff_t offset; uint8_t bitnr; + uint64_t bitmask; bool set_default; union { int64_t i; @@ -53,6 +54,7 @@ extern const PropertyInfo qdev_prop_uint16; extern const PropertyInfo qdev_prop_uint32; extern const PropertyInfo qdev_prop_int32; extern const PropertyInfo qdev_prop_uint64; +extern const PropertyInfo qdev_prop_bitmask_uint64; extern const PropertyInfo qdev_prop_int64; extern const PropertyInfo qdev_prop_size; extern const PropertyInfo qdev_prop_string; @@ -102,6 +104,16 @@ extern const PropertyInfo qdev_prop_link; .set_default = true, \ .defval.u = (bool)_defval) +/** + * The DEFINE_PROP_BITMASK_UINT64 could be used to ensure that + * a user-provided value complies with certain bitmask rule and + * the default value is recommended to be set in instance_init(). + */ +#define DEFINE_PROP_BITMASK_UINT64(_name, _state, _field, _bitmask) \ + DEFINE_PROP(_name, _state, _field, qdev_prop_bitmask_uint64, uint64_t, \ + .bitmask = (_bitmask), \ + .set_default = false) + #define PROP_ARRAY_LEN_PREFIX "len-" /** diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h index 596fce0c54..aab7902760 100644 --- a/include/qapi/qmp/qerror.h +++ b/include/qapi/qmp/qerror.h @@ -68,4 +68,7 @@ #define QERR_UNSUPPORTED \ "this feature or command is not currently supported" +#define QERR_INVALID_BITMASK_VALUE \ + "the requested value for '%s' violates its bitmask '0x%lx'" + #endif /* QERROR_H */ From patchwork Sat May 8 05:52:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Like Xu X-Patchwork-Id: 1475792 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fcc2l42gRz9sWl for ; Sat, 8 May 2021 15:54:23 +1000 (AEST) Received: from localhost ([::1]:40516 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lfFuv-00026Y-K9 for incoming@patchwork.ozlabs.org; Sat, 08 May 2021 01:54:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49920) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lfFuc-00024P-4t for qemu-devel@nongnu.org; Sat, 08 May 2021 01:54:02 -0400 Received: from mga18.intel.com ([134.134.136.126]:46725) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lfFuX-0004pl-PM for qemu-devel@nongnu.org; Sat, 08 May 2021 01:54:01 -0400 IronPort-SDR: ThJLIgX2Usr1mmFOHp8lXbfc9AVuZguBCOhE+Ito8WA7GArCkvGMXSQ2hNRmMQ85i9Nax7bKRh v7aOOkLDRuVg== X-IronPort-AV: E=McAfee;i="6200,9189,9977"; a="186322598" X-IronPort-AV: E=Sophos;i="5.82,282,1613462400"; d="scan'208";a="186322598" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 May 2021 22:53:47 -0700 IronPort-SDR: vVelElTdnM3bN41kqDDjd6LPFw07n9vLjXblRfZmwyjL8beM+gddm7nnZQNaJ6akqyS1bJ1Tsj tqEs90OLN7PA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,282,1613462400"; d="scan'208";a="466375873" Received: from clx-ap-likexu.sh.intel.com ([10.239.48.108]) by fmsmga002.fm.intel.com with ESMTP; 07 May 2021 22:53:45 -0700 From: Like Xu To: Paolo Bonzini , Eduardo Habkost Subject: [PATCH v3 2/2] target/i386: add "-cpu, lbr-fmt=*" support to enable guest LBR Date: Sat, 8 May 2021 13:52:59 +0800 Message-Id: <20210508055259.128025-2-like.xu@linux.intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210508055259.128025-1-like.xu@linux.intel.com> References: <20210508055259.128025-1-like.xu@linux.intel.com> MIME-Version: 1.0 Received-SPF: none client-ip=134.134.136.126; envelope-from=like.xu@linux.intel.com; helo=mga18.intel.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?b?RGFuaWVsIFAgLiBCZXJyYW5nw6k/?= , Like Xu , Richard Henderson , qemu-devel@nongnu.org, Markus Armbruster , weijiang.yang@intel.com, wei.w.wang@intel.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The last branch recording (LBR) is a performance monitor unit (PMU) feature on Intel processors that records a running trace of the most recent branches taken by the processor in the LBR stack. The QEMU could configure whether it's enabled or not for each guest via CLI. The LBR feature would be enabled on the guest if: - the KVM is enabled and the PMU is enabled and, - the msr-based-feature IA32_PERF_CAPABILITIES is supporterd on KVM and, - the supported returned value for lbr_fmt from this msr is not zero and, - the requested guest vcpu model does support FEAT_1_ECX.CPUID_EXT_PDCM, - the user-provided lbr-fmt value should not violate its bitmask (0x3f) and it should be the same as the host lbr_fmt value or just use the QEMU option "-cpu host,migratable=no" to enable guest LBR. Signed-off-by: Like Xu --- v2-v3 Changelog: - Add a new generic property macro to validate its bitmask; - Differentiate "lbr-fmt=0" from "lbr-fmt not set"; - Do what the user asked for whenever possible; - Treat mismatch or violatation as an error rather than warning; Testcases for a lbr-fmt=5 host: "-cpu host" --> "Disable LBR" "-cpu host,lbr-fmt=0" --> "Disable LBR" "-cpu host,lbr-fmt=5" --> "Enable LBR" "-cpu host,lbr-fmt=6" --> "Error out, lbr mismatch" "-cpu host,lbr-fmt=0xff" --> "Error out, bitmask violatation" "-cpu host,migratable=no" --> "Enable LBR" "-cpu host,migratable=no,lbr-fmt=0" --> "Disable LBR" "-cpu host,migratable=no,lbr-fmt=5" --> "Enable LBR" "-cpu host,migratable=no,lbr-fmt=6" --> "Error out, lbr mismatch" "-cpu host,migratable=no,lbr-fmt=0xff" --> "Error out, bitmask violatation" target/i386/cpu.c | 39 +++++++++++++++++++++++++++++++++++++++ target/i386/cpu.h | 10 ++++++++++ 2 files changed, 49 insertions(+) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index ad99cad0e7..d03306179a 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -6748,6 +6748,41 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) goto out; } + /* + * Override env->features[FEAT_PERF_CAPABILITIES] + * with explicit user-provided settings. + */ + if (cpu->lbr_fmt != ~PERF_CAP_LBR_FMT) { + if ((cpu->lbr_fmt & PERF_CAP_LBR_FMT) != cpu->lbr_fmt) { + error_setg(errp, "invalid lbr-fmt"); + return; + } + env->features[FEAT_PERF_CAPABILITIES] &= ~PERF_CAP_LBR_FMT; + env->features[FEAT_PERF_CAPABILITIES] |= cpu->lbr_fmt; + } + + /* + * We can always validate env->features[FEAT_PERF_CAPABILITIES], + * no matter how it was initialized: + */ + uint64_t requested_lbr_fmt = + env->features[FEAT_PERF_CAPABILITIES] & PERF_CAP_LBR_FMT; + if (requested_lbr_fmt && kvm_enabled()) { + uint64_t host_perf_cap = + x86_cpu_get_supported_feature_word(FEAT_PERF_CAPABILITIES, false); + uint64_t host_lbr_fmt = host_perf_cap & PERF_CAP_LBR_FMT; + if (!cpu->enable_pmu) { + error_setg(errp, "vPMU: LBR is unsupported without pmu=on"); + return; + } + if (requested_lbr_fmt != host_lbr_fmt) { + error_setg(errp, "vPMU: the lbr-fmt value (0x%lx) mismatches " + "the host supported value (0x%lx).", + requested_lbr_fmt, host_lbr_fmt); + return; + } + } + x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid); if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) { @@ -7150,6 +7185,9 @@ static void x86_cpu_initfn(Object *obj) object_property_add_alias(obj, "sse4_1", obj, "sse4.1"); object_property_add_alias(obj, "sse4_2", obj, "sse4.2"); + cpu->lbr_fmt = ~PERF_CAP_LBR_FMT; + object_property_add_alias(obj, "lbr_fmt", obj, "lbr-fmt"); + if (xcc->model) { x86_cpu_load_model(cpu, xcc->model); } @@ -7300,6 +7338,7 @@ static Property x86_cpu_properties[] = { #endif DEFINE_PROP_INT32("node-id", X86CPU, node_id, CPU_UNSET_NUMA_NODE_ID), DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false), + DEFINE_PROP_BITMASK_UINT64("lbr-fmt", X86CPU, lbr_fmt, PERF_CAP_LBR_FMT), DEFINE_PROP_UINT32("hv-spinlocks", X86CPU, hyperv_spinlock_attempts, HYPERV_SPINLOCK_NEVER_NOTIFY), diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 1bc300ce85..bab394e18e 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -354,6 +354,7 @@ typedef enum X86Seg { #define ARCH_CAP_TSX_CTRL_MSR (1<<7) #define MSR_IA32_PERF_CAPABILITIES 0x345 +#define PERF_CAP_LBR_FMT 0x3f #define MSR_IA32_TSX_CTRL 0x122 #define MSR_IA32_TSCDEADLINE 0x6e0 @@ -1726,6 +1727,15 @@ struct X86CPU { */ bool enable_pmu; + /* + * Configure LBR_FMT bits on IA32_PERF_CAPABILITIES MSR. + * This can't be enabled by default yet because it doesn't have + * ABI stability guarantees, as it is only allowed to pass all + * LBR_FMT bits returned by kvm_arch_get_supported_msr_feature() + * (that depends on host CPU and kernel capabilities) to the guest. + */ + uint64_t lbr_fmt; + /* LMCE support can be enabled/disabled via cpu option 'lmce=on/off'. It is * disabled by default to avoid breaking migration between QEMU with * different LMCE configurations.