From nobody Thu Jan 23 05:58:08 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1737535761; cv=none; d=zohomail.com; s=zohoarc; b=LqUt7Qu0SFnojsL1ipS8Y/5onbrSvp1gZOyOU4oxQ0/pVm/W7uAm0QoDp9UWapIf+/LTYRsO0iYO++G6MZDlHd0bwf1DSwmiYWNU1OptSXPkd/nmHra8RRXSfA+irR48eD++tBk0q6LqU0AguhnNNJ1uWFvn9f7utqVYr1hNLM8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1737535761; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=endtQd7VZePBb35bKElAKKroEOif+pS7TtIOd95sI/A=; b=GYD6fmlXJCg5Y3wRqRYEexCMKX2poMiNETiOmIuMM1av7eCjW/spA0tIbcWHFdK7DCVf/UdkfnRI31dz3GXXVRrqrPgkio6ee8KUsjB/+DM3WwAdcEmMrocscc1v0/KLGnkit4vx3pk7z4W/QL7Cf7GEKBLFSTUnjpCDMhffOoI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1737535761477741.0019597622172; Wed, 22 Jan 2025 00:49:21 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1taWNW-0002u8-LF; Wed, 22 Jan 2025 03:46:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1taWNS-0002sT-Tg; Wed, 22 Jan 2025 03:46:22 -0500 Received: from mgamail.intel.com ([198.175.65.9]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1taWNP-0002y5-IF; Wed, 22 Jan 2025 03:46:22 -0500 Received: from orviesa003.jf.intel.com ([10.64.159.143]) by orvoesa101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jan 2025 00:46:17 -0800 Received: from liuzhao-optiplex-7080.sh.intel.com ([10.239.160.39]) by orviesa003.jf.intel.com with ESMTP; 22 Jan 2025 00:46:13 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1737535579; x=1769071579; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VMFyzU7rJ0ERY+XN36rgAcSEcfJLdF/jbMtrra/GTKA=; b=QNQsjGDijegatLLY46/MZMbH6MeFf3kYNjVizZuOJXC5IMjmUxqVfF9z +og0QgyM5FT6G4WBc9FPJcRSZ9v9Gqhqx8IBN1nj6JBrLq2LA7xOMwHdp DX1jZd8QhwQyklss+eRkX82tqyU3dr+Mf8PDpOJR1OnaBDw3DUJtWzLK2 FV8Fzt38R9wvL6HXVhJv0UOFgJoRV6gZ7IbCPT/MkobHhljBg4CMbba2H ESUW0JArJ8Oyy0W9UdsNkYOXfPlHwB9Dy3cXQ0zdTK2Cwy2CGyM5MtpZB eaq+trml6V9V4q1GQUuKXeifvntIr7mQpGOdPVjzfnM/DkhLijxFqpY2j A==; X-CSE-ConnectionGUID: Tlai2ovITheoaExyZsUnBA== X-CSE-MsgGUID: NkhN/9+hQ+2mkI8X3orfRA== X-IronPort-AV: E=McAfee;i="6700,10204,11322"; a="60451561" X-IronPort-AV: E=Sophos;i="6.13,224,1732608000"; d="scan'208";a="60451561" X-CSE-ConnectionGUID: fA1qO0UsTNWEBq4maCd8bQ== X-CSE-MsgGUID: bO2kWi3pSM6t8TGjTKIFOw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,199,1725346800"; d="scan'208";a="112049753" From: Zhao Liu To: Paolo Bonzini , Eric Blake , Markus Armbruster , Michael Roth , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , Eduardo Habkost , Marcelo Tosatti , Shaoqin Huang , Eric Auger , Peter Maydell , Laurent Vivier , Thomas Huth , Sebastian Ott , Gavin Shan Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-arm@nongnu.org, Dapeng Mi , Yi Lai , Zhao Liu Subject: [RFC v2 2/5] i386/kvm: Support basic KVM PMU filter Date: Wed, 22 Jan 2025 17:05:14 +0800 Message-Id: <20250122090517.294083-3-zhao1.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250122090517.294083-1-zhao1.liu@intel.com> References: <20250122090517.294083-1-zhao1.liu@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=198.175.65.9; envelope-from=zhao1.liu@intel.com; helo=mgamail.intel.com X-Spam_score_int: -73 X-Spam_score: -7.4 X-Spam_bar: ------- X-Spam_report: (-7.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-2.996, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @intel.com) X-ZM-MESSAGEID: 1737535762163019000 Content-Type: text/plain; charset="utf-8" Filter PMU events with raw format in i386 code. For i386, raw format indicates that the PMU event code is already encoded according to the KVM ioctl requirements, and can be delivered directly to KVM without additional encoding work. Signed-off-by: Zhao Liu --- Changes since v1: * Stop check whether per-event actions are the same, as "action" has been a global parameter. (Dapeng) * Make pmu filter related functions return int in target/i386/kvm/kvm.c. --- include/system/kvm_int.h | 2 + target/i386/kvm/kvm.c | 123 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/include/system/kvm_int.h b/include/system/kvm_int.h index 4de6106869b0..743fed29b17b 100644 --- a/include/system/kvm_int.h +++ b/include/system/kvm_int.h @@ -17,6 +17,7 @@ #include "hw/boards.h" #include "hw/i386/topology.h" #include "io/channel-socket.h" +#include "system/kvm-pmu.h" =20 typedef struct KVMSlot { @@ -166,6 +167,7 @@ struct KVMState uint16_t xen_gnttab_max_frames; uint16_t xen_evtchn_max_pirq; char *device; + KVMPMUFilter *pmu_filter; }; =20 void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml, diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 6c749d4ee812..b82adbed50f4 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -34,6 +34,7 @@ #include "system/system.h" #include "system/hw_accel.h" #include "system/kvm_int.h" +#include "system/kvm-pmu.h" #include "system/runstate.h" #include "kvm_i386.h" #include "../confidential-guest.h" @@ -110,6 +111,7 @@ typedef struct { static void kvm_init_msrs(X86CPU *cpu); static int kvm_filter_msr(KVMState *s, uint32_t msr, QEMURDMSRHandler *rdm= sr, QEMUWRMSRHandler *wrmsr); +static int kvm_filter_pmu_event(KVMState *s); =20 const KVMCapabilityInfo kvm_arch_required_capabilities[] =3D { KVM_CAP_INFO(SET_TSS_ADDR), @@ -3346,6 +3348,14 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } } =20 + if (s->pmu_filter) { + ret =3D kvm_filter_pmu_event(s); + if (ret < 0) { + error_report("Could not set KVM PMU filter"); + return ret; + } + } + return 0; } =20 @@ -5942,6 +5952,82 @@ static int kvm_handle_wrmsr(X86CPU *cpu, struct kvm_= run *run) g_assert_not_reached(); } =20 +static bool kvm_config_pmu_event(KVMPMUFilter *filter, + struct kvm_pmu_event_filter *kvm_filter) +{ + KVMPMUFilterEventList *events; + KVMPMUFilterEvent *event; + uint64_t code; + int idx =3D 0; + + kvm_filter->nevents =3D filter->nevents; + events =3D filter->events; + while (events) { + assert(idx < kvm_filter->nevents); + + event =3D events->value; + switch (event->format) { + case KVM_PMU_EVENT_FMT_RAW: + code =3D event->u.raw.code; + break; + default: + g_assert_not_reached(); + } + + kvm_filter->events[idx++] =3D code; + events =3D events->next; + } + + return true; +} + +static int kvm_install_pmu_event_filter(KVMState *s) +{ + struct kvm_pmu_event_filter *kvm_filter; + KVMPMUFilter *filter =3D s->pmu_filter; + int ret; + + kvm_filter =3D g_malloc0(sizeof(struct kvm_pmu_event_filter) + + filter->nevents * sizeof(uint64_t)); + + switch (filter->action) { + case KVM_PMU_FILTER_ACTION_ALLOW: + kvm_filter->action =3D KVM_PMU_EVENT_ALLOW; + break; + case KVM_PMU_FILTER_ACTION_DENY: + kvm_filter->action =3D KVM_PMU_EVENT_DENY; + break; + default: + g_assert_not_reached(); + } + + if (!kvm_config_pmu_event(filter, kvm_filter)) { + goto fail; + } + + ret =3D kvm_vm_ioctl(s, KVM_SET_PMU_EVENT_FILTER, kvm_filter); + if (ret) { + error_report("KVM_SET_PMU_EVENT_FILTER fails (%s)", strerror(-ret)= ); + goto fail; + } + + g_free(kvm_filter); + return 0; +fail: + g_free(kvm_filter); + return -EINVAL; +} + +static int kvm_filter_pmu_event(KVMState *s) +{ + if (!kvm_vm_check_extension(s, KVM_CAP_PMU_EVENT_FILTER)) { + error_report("KVM PMU filter is not supported by Host."); + return -1; + } + + return kvm_install_pmu_event_filter(s); +} + static bool has_sgx_provisioning; =20 static bool __kvm_enable_sgx_provisioning(KVMState *s) @@ -6537,6 +6623,35 @@ static void kvm_arch_set_xen_evtchn_max_pirq(Object = *obj, Visitor *v, s->xen_evtchn_max_pirq =3D value; } =20 +static void kvm_arch_check_pmu_filter(const Object *obj, const char *name, + Object *child, Error **errp) +{ + KVMPMUFilter *filter =3D KVM_PMU_FILTER(child); + KVMPMUFilterEventList *events =3D filter->events; + + if (!filter->nevents) { + error_setg(errp, + "Empty KVM PMU filter."); + return; + } + + while (events) { + KVMPMUFilterEvent *event =3D events->value; + + switch (event->format) { + case KVM_PMU_EVENT_FMT_RAW: + break; + default: + error_setg(errp, + "Unsupported PMU event format %s.", + KVMPMUEventEncodeFmt_str(events->value->format)); + return; + } + + events =3D events->next; + } +} + void kvm_arch_accel_class_init(ObjectClass *oc) { object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOptio= n", @@ -6576,6 +6691,14 @@ void kvm_arch_accel_class_init(ObjectClass *oc) NULL, NULL); object_class_property_set_description(oc, "xen-evtchn-max-pirq", "Maximum number of Xen PIRQs"); + + object_class_property_add_link(oc, "pmu-filter", + TYPE_KVM_PMU_FILTER, + offsetof(KVMState, pmu_filter), + kvm_arch_check_pmu_filter, + OBJ_PROP_LINK_STRONG); + object_class_property_set_description(oc, "pmu-filter", + "Set the KVM PMU filter"); } =20 void kvm_set_max_apic_id(uint32_t max_apic_id) --=20 2.34.1