From nobody Mon Feb 9 01:48:41 2026 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; 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=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1767643082; cv=none; d=zohomail.com; s=zohoarc; b=RjiCP3CVE/Gpxzpw71tAQIuReUYM6nrPgv5HrvzPTXQdF4nWSX7IYuToGet64o5wdFlpqQHk97qt5me3NF/lQFYAlCH+sC5QZa4NdU4/ZAtoGOr9DCeK/2C6cYE2WSe1jcC+ucIhmRd6dl9kJ2xIqja4mEsNVOFjQ4KsK7VZEmI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1767643082; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=N2UBxLQak+i5Ob4lOnr175LyFxF1yg59I9tmG5XM1dQ=; b=RYawlgPtGnEmChnBperf7XrmnQgoYbQiPmn/YtJDF8wk3toGrfUeMvLHLTxvXnmASoexbG62WCtb1XHc0BGwxHT7cZq5NnMsXTpvDIKY2mNnfXguLruqaApkqcBoWbxNc2cFJYHy30aCdF1p7OYPONda0ENeUnWrvjihxEUOE1o= 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 1767643082973109.73155470911638; Mon, 5 Jan 2026 11:58:02 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1195722.1513637 (Exim 4.92) (envelope-from ) id 1vcqhi-0000Wf-TG; Mon, 05 Jan 2026 19:57:26 +0000 Received: by outflank-mailman (output) from mailman id 1195722.1513637; Mon, 05 Jan 2026 19:57: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 1vcqhi-0000WY-PL; Mon, 05 Jan 2026 19:57:26 +0000 Received: by outflank-mailman (input) for mailman id 1195722; Mon, 05 Jan 2026 19:57:25 +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 1vcqhg-0000WS-IJ for xen-devel@lists.xenproject.org; Mon, 05 Jan 2026 19:57:25 +0000 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [2a00:1450:4864:20::336]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id bfb571da-ea70-11f0-b15e-2bf370ae4941; Mon, 05 Jan 2026 20:57:23 +0100 (CET) Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-4779cc419b2so2506125e9.3 for ; Mon, 05 Jan 2026 11:57:22 -0800 (PST) Received: from localhost.localdomain (host-92-26-102-188.as13285.net. [92.26.102.188]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47d7f68f4ddsm4237405e9.2.2026.01.05.11.57.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Jan 2026 11:57:19 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: bfb571da-ea70-11f0-b15e-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1767643041; x=1768247841; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=N2UBxLQak+i5Ob4lOnr175LyFxF1yg59I9tmG5XM1dQ=; b=uXthQpcB9ldoKA+qZjHXnTZ+0LMoq56F1JMR2E7ByHnsKRN4pVNdgjqn/ASA01UsYK YUYn3tGhwM+8mJX0DMFnzkzx8JkGyBl6bJB8qlJ70TWI5scQXXVgwsZP0ssTqljOYKEl 1RxUYfHIQfL56J7KNiXxJ05aNPDfnN1XXUQ14= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767643041; x=1768247841; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=N2UBxLQak+i5Ob4lOnr175LyFxF1yg59I9tmG5XM1dQ=; b=fxyZ8VoE7qPhNvbemvVDty3IIiBVJTvj19GNNjMfxI3TwG8HKtWKxLvLwfFsl+jshk j/0JUA2YNNqAHdIb3GKjoWxsjv75NmY5BvIvPm5+6dwj736BqC8+0BmGaac5b/Xcn8g+ MBSjvoXYCMhBv1UcqpKo4pc0XQMnIcRPYnbQkqDgVfx1EFknIpeCvlx1fqVXxArkFuyF bsWGcYkuWbUSQSc7VHDHvX0znbsHG9gGicRY9+VnQqnFfmlY4IcAf5B4kBXIT3cu0xWM kYA6jP8wdNTpP/fnZDJdeBvwsFJSEYw9cM2rReO3hgyDJZ3hY7APSH5NOhIDxcMPfZef 5WuQ== X-Gm-Message-State: AOJu0YwN0Oe4vmgwDwbElQHOeh8HAzenHG5EzmdzzIepCFtxM1kLy0IL ZsL3xSnN23V04+h0MY3aEfE90kzsUtI7kh0AQqiC2fc9ctHnp7RC+UvbLrE8hHlJ5SmgoQgc+ti U8f43 X-Gm-Gg: AY/fxX7R3s3VVu+oQ/k3jgYj3J5S86dGhIH8Nn7bTILEIfIT5cAeLr7ZNOjmf5LMgRL miaiBQKXKc8vnF92FHEduUcJSukRW49DjFnl+loA6cbOuzmC7QrbdF9pxlqiHsbqw6ae4CufVZT m6eG0lcy9sC+A5jM7Du3Rr8WxZLKaiIFkQZxBaorE9l20LsrUrjbnQqU5EcBfEyGjIQuDA+gAtG 1WLgMFwm0PoMfBB16VUt9itr8NceCX5DFJ0St2FfOJMBbv4kKuBacmCCu1dI77IXtbrGelSo8o7 qt9YZ//FivsewP1DT6f6ckZgBC49ENOnY25lip/Os0VxcNSgGkRAtsf3MPZeHMGIIEtn1Y2m2sA hTrfPFM5f6T8MwsPPcNOoTDLneSoAekGsjFQFc2/Gq4pR2eIuh+awUj3Wh5A+6+wPb/b/JSuPFU 29xB8aObdq2Axjff2ZI6+S9DNgpYRgIZlW51RPDMcGSxF4tbAR7b4rHJVbC5pl1A8SdxWPzjRy X-Google-Smtp-Source: AGHT+IE2xy1jvBdQ2UVHXv62JX+gu97k1tDL42/Ig4znjKXkd51TGSwTmmRHpBK+KldektVWEDf+Yg== X-Received: by 2002:a05:600c:8116:b0:477:429b:3b93 with SMTP id 5b1f17b1804b1-47d7f09b7a0mr5117385e9.18.1767643039705; Mon, 05 Jan 2026 11:57:19 -0800 (PST) From: Andrew Cooper To: Xen-devel Cc: Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Oleksii Kurochko , "Daniel P . Smith" Subject: [PATCH] xen: Drop xenoprofile support Date: Mon, 5 Jan 2026 19:57:17 +0000 Message-Id: <20260105195717.601500-1-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.39.5 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1767643085119158500 The most recent xenoprof change was 300ef0cb4fde ("x86: Add Xenoprofile support for AMD Family16h") in 2013, despite there being 42 changes worth of other cleanup/rearranging since then. Oprofile themselves dropped Xen support in commit 0c142c3a096d ("Remove opcontrol and the GUI and processor models dependent on it") in 2014, as pa= rt of releasing version 1.0 and switching over to using operf based on the Lin= ux perf_event subsystem. Linux's version of this patch was merged in commit 24880bef417f ("Merge tag 'oprofile-removal-5.12'") in 2021. Drop xenoprof and all supporting infrastructure, including the hypercall, t= he XSM hook and flask vectors which lose their only caller, and even shrinks struct domain by one pointer which wasn't properly excluded in !CONFIG_XENOPROF builds. Retain the public xenoprof.h header as it is ABI, but note that the functionality is removed. Signed-off-by: Andrew Cooper Acked-By: Daniel P. Smith Acked-by: Oleksii Kurochko # CHANGELOG.md Reviewed-by: Jason Andryuk Reviewed-by: Teddy Astie --- CC: Anthony PERARD CC: Michal Orzel CC: Jan Beulich CC: Julien Grall CC: Roger Pau Monn=C3=A9 CC: Stefano Stabellini CC: Oleksii Kurochko CC: Daniel P. Smith Despite appearing to be architecture neutral, the internals of Xenoprof were entirely x86-specific. Another curiosity is that only the VMX MSR hooks called passive_domain_do_{rd,wr}msr(), and I can't see how this was correct for SVM. The real reason for finally getting around to this is the number of MISRA violations reported by the eclair-x86_64-allcode job that I don't feel like fixing. --- CHANGELOG.md | 3 + docs/misc/xen-command-line.pandoc | 6 - tools/flask/policy/modules/dom0.te | 2 - xen/arch/x86/Makefile | 1 - xen/arch/x86/cpu/vpmu_amd.c | 7 - xen/arch/x86/cpu/vpmu_intel.c | 6 - xen/arch/x86/hvm/svm/entry.S | 1 - xen/arch/x86/hvm/svm/svm.c | 2 - xen/arch/x86/hvm/vmx/vmx.c | 9 - xen/arch/x86/include/asm/xenoprof.h | 95 --- xen/arch/x86/oprofile/Makefile | 6 - xen/arch/x86/oprofile/backtrace.c | 145 ---- xen/arch/x86/oprofile/nmi_int.c | 485 ------------ xen/arch/x86/oprofile/op_counter.h | 41 - xen/arch/x86/oprofile/op_model_athlon.c | 547 ------------- xen/arch/x86/oprofile/op_model_p4.c | 721 ----------------- xen/arch/x86/oprofile/op_model_ppro.c | 348 --------- xen/arch/x86/oprofile/op_x86_model.h | 58 -- xen/arch/x86/oprofile/xenoprof.c | 106 --- xen/arch/x86/traps.c | 4 - xen/common/Kconfig | 11 - xen/common/Makefile | 1 - xen/common/compat/xenoprof.c | 42 - xen/common/domain.c | 6 - xen/common/xenoprof.c | 977 ------------------------ xen/include/Makefile | 1 - xen/include/hypercall-defs.c | 6 - xen/include/public/xen.h | 2 +- xen/include/public/xenoprof.h | 2 +- xen/include/xen/sched.h | 3 - xen/include/xen/xenoprof.h | 49 -- xen/include/xsm/dummy.h | 7 - xen/include/xsm/xsm.h | 7 - xen/xsm/dummy.c | 2 - xen/xsm/flask/hooks.c | 35 - xen/xsm/flask/policy/access_vectors | 4 - 36 files changed, 5 insertions(+), 3743 deletions(-) delete mode 100644 xen/arch/x86/include/asm/xenoprof.h delete mode 100644 xen/arch/x86/oprofile/Makefile delete mode 100644 xen/arch/x86/oprofile/backtrace.c delete mode 100644 xen/arch/x86/oprofile/nmi_int.c delete mode 100644 xen/arch/x86/oprofile/op_counter.h delete mode 100644 xen/arch/x86/oprofile/op_model_athlon.c delete mode 100644 xen/arch/x86/oprofile/op_model_p4.c delete mode 100644 xen/arch/x86/oprofile/op_model_ppro.c delete mode 100644 xen/arch/x86/oprofile/op_x86_model.h delete mode 100644 xen/arch/x86/oprofile/xenoprof.c delete mode 100644 xen/common/compat/xenoprof.c delete mode 100644 xen/common/xenoprof.c delete mode 100644 xen/include/xen/xenoprof.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aaf5986231c..1663f6878ef2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ The format is based on [Keep a Changelog](https://keepach= angelog.com/en/1.0.0/) - The cpuid_mask_* command line options for legacy AMD CPUs. These were deprecated in Xen 4.7 and noted not to work correctly with AMD CPUs f= rom 2011 onwards. + - Xenoprofile support. Oprofile themselves removed support for Xen in = 2014 + prior to the version 1.0 release, and there has been no development s= ince + before then in Xen. =20 ## [4.21.0](https://xenbits.xenproject.org/gitweb/?p=3Dxen.git;a=3Dshortlo= g;h=3DRELEASE-4.21.0) - 2025-11-19 =20 diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line= .pandoc index 805da22c44a5..189d0d2c9d4b 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -508,12 +508,6 @@ character, but for xen to keep the console. =20 > Default: `power` =20 -### cpu_type (x86) -> `=3D arch_perfmon` - -If set, force use of the performance counters for oprofile, rather than de= tecting -available support. - ### cpufreq > `=3D none | {{ | xen } { [:[powersave|performance|ondemand|use= rspace][,[]][,[]]] } [,verbose]} | dom0-kernel | hwp[:[][,verbose]] | amd-cppc[:[active][,verbose]]` =20 diff --git a/tools/flask/policy/modules/dom0.te b/tools/flask/policy/module= s/dom0.te index ad2b4f9ea75f..d30edf8be1fb 100644 --- a/tools/flask/policy/modules/dom0.te +++ b/tools/flask/policy/modules/dom0.te @@ -21,8 +21,6 @@ allow dom0_t xen_t:xen { writeconsole readapic writeapic - privprofile - nonprivprofile kexec firmware sleep diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 1fc651146f10..d8b41cec1620 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_GUEST) +=3D guest/ obj-$(CONFIG_HVM) +=3D hvm/ obj-y +=3D lib/ obj-y +=3D mm/ -obj-$(CONFIG_XENOPROF) +=3D oprofile/ obj-$(CONFIG_PV) +=3D pv/ obj-y +=3D x86_64/ obj-y +=3D x86_emulate/ diff --git a/xen/arch/x86/cpu/vpmu_amd.c b/xen/arch/x86/cpu/vpmu_amd.c index fa157d45dd01..aee99bb88128 100644 --- a/xen/arch/x86/cpu/vpmu_amd.c +++ b/xen/arch/x86/cpu/vpmu_amd.c @@ -12,7 +12,6 @@ =20 #include #include -#include =20 #include #include @@ -363,8 +362,6 @@ static int cf_check amd_vpmu_do_wrmsr(unsigned int msr,= uint64_t msr_content) if ( (type =3D=3D MSR_TYPE_CTRL) && is_pmu_enabled(msr_content) && !vpmu_is_set(vpmu, VPMU_RUNNING) ) { - if ( !acquire_pmu_ownership(PMU_OWNER_HVM) ) - return 0; vpmu_set(vpmu, VPMU_RUNNING); =20 if ( is_svm_vcpu(v) && is_msr_bitmap_on(vpmu) ) @@ -378,7 +375,6 @@ static int cf_check amd_vpmu_do_wrmsr(unsigned int msr,= uint64_t msr_content) vpmu_reset(vpmu, VPMU_RUNNING); if ( is_svm_vcpu(v) && is_msr_bitmap_on(vpmu) ) amd_vpmu_unset_msr_bitmap(v); - release_pmu_ownership(PMU_OWNER_HVM); } =20 if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED) @@ -426,9 +422,6 @@ static void cf_check amd_vpmu_destroy(struct vcpu *v) vpmu->context =3D NULL; vpmu->priv_context =3D NULL; =20 - if ( vpmu_is_set(vpmu, VPMU_RUNNING) ) - release_pmu_ownership(PMU_OWNER_HVM); - vpmu_clear(vpmu); } =20 diff --git a/xen/arch/x86/cpu/vpmu_intel.c b/xen/arch/x86/cpu/vpmu_intel.c index 7ce98ee42e54..1e3b06ef8e68 100644 --- a/xen/arch/x86/cpu/vpmu_intel.c +++ b/xen/arch/x86/cpu/vpmu_intel.c @@ -9,7 +9,6 @@ =20 #include #include -#include #include #include #include @@ -441,9 +440,6 @@ static int cf_check core2_vpmu_alloc_resource(struct vc= pu *v) struct xen_pmu_intel_ctxt *core2_vpmu_cxt =3D NULL; uint64_t *p =3D NULL; =20 - if ( !acquire_pmu_ownership(PMU_OWNER_HVM) ) - return 0; - if ( is_vmx_vcpu(v) ) { if ( vmx_add_host_load_msr(v, MSR_CORE_PERF_GLOBAL_CTRL, 0) ) @@ -487,7 +483,6 @@ static int cf_check core2_vpmu_alloc_resource(struct vc= pu *v) return 1; =20 out_err: - release_pmu_ownership(PMU_OWNER_HVM); =20 xfree(core2_vpmu_cxt); xfree(p); @@ -814,7 +809,6 @@ static void cf_check core2_vpmu_destroy(struct vcpu *v) vpmu->priv_context =3D NULL; if ( is_vmx_vcpu(v) && cpu_has_vmx_msr_bitmap ) core2_vpmu_unset_msr_bitmap(v); - release_pmu_ownership(PMU_OWNER_HVM); vpmu_clear(vpmu); } =20 diff --git a/xen/arch/x86/hvm/svm/entry.S b/xen/arch/x86/hvm/svm/entry.S index 610c64bf4c97..af8db23b033f 100644 --- a/xen/arch/x86/hvm/svm/entry.S +++ b/xen/arch/x86/hvm/svm/entry.S @@ -155,7 +155,6 @@ __UNLIKELY_END(nsvm_hap) * to safely resolve any Spectre-v1 concerns in the above logic. */ stgi -LABEL(svm_stgi_label, 0) call svm_vmexit_handler jmp .Lsvm_do_resume =20 diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 1208999454d3..da113f488b71 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -36,7 +36,6 @@ #include #include #include -#include =20 #include =20 @@ -1152,7 +1151,6 @@ static int cf_check svm_vcpu_initialise(struct vcpu *= v) static void cf_check svm_vcpu_destroy(struct vcpu *v) { svm_destroy_vmcb(v); - passive_domain_destroy(v); } =20 /* diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 05b59cb8e4d2..f4beac192d75 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -48,7 +48,6 @@ #include #include #include -#include =20 #include #include @@ -692,7 +691,6 @@ static void cf_check vmx_vcpu_destroy(struct vcpu *v) */ vmx_vcpu_disable_pml(v); vmx_destroy_vmcs(v); - passive_domain_destroy(v); } =20 /* @@ -3560,9 +3558,6 @@ static int cf_check vmx_msr_read_intercept( break; =20 default: - if ( passive_domain_do_rdmsr(msr, msr_content) ) - goto done; - if ( vmx_read_guest_msr(curr, msr, msr_content) =3D=3D 0 ) break; =20 @@ -3582,7 +3577,6 @@ static int cf_check vmx_msr_read_intercept( goto gp_fault; } =20 -done: HVM_DBG_LOG(DBG_LEVEL_MSR, "returns: ecx=3D%#x, msr_value=3D%#"PRIx64, msr, *msr_content); return X86EMUL_OKAY; @@ -3875,9 +3869,6 @@ static int cf_check vmx_msr_write_intercept( break; =20 default: - if ( passive_domain_do_wrmsr(msr, msr_content) ) - return X86EMUL_OKAY; - if ( vmx_write_guest_msr(v, msr, msr_content) =3D=3D 0 || is_last_branch_msr(msr) ) break; diff --git a/xen/arch/x86/include/asm/xenoprof.h b/xen/arch/x86/include/asm= /xenoprof.h deleted file mode 100644 index dc6f822d3220..000000000000 --- a/xen/arch/x86/include/asm/xenoprof.h +++ /dev/null @@ -1,95 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/*************************************************************************= ***** - * asm-x86/xenoprof.h - * xenoprof x86 arch specific header file - * - * Copyright (c) 2006 Isaku Yamahata - * VA Linux Systems Japan K.K. - */ - -#ifndef __ASM_X86_XENOPROF_H__ -#define __ASM_X86_XENOPROF_H__ - -struct vcpu; - -#ifdef CONFIG_XENOPROF - -#include - -int nmi_reserve_counters(void); -int nmi_setup_events(void); -int nmi_enable_virq(void); -int nmi_start(void); -void nmi_stop(void); -void nmi_disable_virq(void); -void nmi_release_counters(void); - -int xenoprof_arch_init(int *num_events, char *cpu_type); -#define xenoprof_arch_reserve_counters() nmi_reserve_counters() -#define xenoprof_arch_setup_events() nmi_setup_events() -#define xenoprof_arch_enable_virq() nmi_enable_virq() -#define xenoprof_arch_start() nmi_start() -#define xenoprof_arch_stop() nmi_stop() -#define xenoprof_arch_disable_virq() nmi_disable_virq() -#define xenoprof_arch_release_counters() nmi_release_counters() - -int xenoprof_arch_counter(XEN_GUEST_HANDLE_PARAM(void) arg); -int compat_oprof_arch_counter(XEN_GUEST_HANDLE_PARAM(void) arg); -int xenoprof_arch_ibs_counter(XEN_GUEST_HANDLE_PARAM(void) arg); - -struct cpu_user_regs; - -/* AMD IBS support */ -void ibs_init(void); -extern u32 ibs_caps; - -int xenoprofile_get_mode(struct vcpu *, const struct cpu_user_regs *); - -static inline int xenoprof_backtrace_supported(void) -{ - return 1; -} - -void xenoprof_backtrace(struct vcpu *, const struct cpu_user_regs *, - unsigned long depth, int mode); - -int passive_domain_do_rdmsr(unsigned int msr, uint64_t *msr_content); -int passive_domain_do_wrmsr(unsigned int msr, uint64_t msr_content); -void passive_domain_destroy(struct vcpu *v); - -bool nmi_oprofile_send_virq(void); - -#else - -static inline int passive_domain_do_rdmsr(unsigned int msr, - uint64_t *msr_content) -{ - return 0; -} - -static inline int passive_domain_do_wrmsr(unsigned int msr, - uint64_t msr_content) -{ - return 0; -} - -static inline void passive_domain_destroy(struct vcpu *v) {} - -static inline bool nmi_oprofile_send_virq(void) -{ - return false; -} - -#endif /* CONFIG_XENOPROF */ - -#endif /* __ASM_X86_XENOPROF_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/arch/x86/oprofile/Makefile b/xen/arch/x86/oprofile/Makefile deleted file mode 100644 index 956e3d1b5d05..000000000000 --- a/xen/arch/x86/oprofile/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -obj-y +=3D xenoprof.o -obj-y +=3D nmi_int.o -obj-y +=3D op_model_p4.o -obj-y +=3D op_model_ppro.o -obj-y +=3D op_model_athlon.o -obj-y +=3D backtrace.o diff --git a/xen/arch/x86/oprofile/backtrace.c b/xen/arch/x86/oprofile/back= trace.c deleted file mode 100644 index 61de18c8d596..000000000000 --- a/xen/arch/x86/oprofile/backtrace.c +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @file backtrace.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author David Smith - * Modified for Xen by Amitabha Roy - * - */ - -#include -#include -#include -#include - -struct __packed frame_head { - struct frame_head * ebp; - unsigned long ret; -}; -typedef struct frame_head frame_head_t; - -struct __packed frame_head_32bit { - uint32_t ebp; - uint32_t ret; -}; -typedef struct frame_head_32bit frame_head32_t; - -static struct frame_head * -dump_hypervisor_backtrace(struct vcpu *vcpu, const struct frame_head *head, - int mode) -{ - if (!xenoprof_add_trace(vcpu, head->ret, mode)) - return 0; - =20 - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (head >=3D head->ebp) - return NULL; - =20 - return head->ebp; -} - -static inline int is_32bit_vcpu(struct vcpu *vcpu) -{ - if (is_hvm_vcpu(vcpu)) - return !hvm_long_mode_active(vcpu); - else - return is_pv_32bit_vcpu(vcpu); -} - -static struct frame_head * -dump_guest_backtrace(struct vcpu *vcpu, const struct frame_head *head, - int mode) -{ - /* Also check accessibility of one struct frame_head beyond. */ - frame_head_t bufhead[2]; - - if ( is_32bit_vcpu(vcpu) ) - { - frame_head32_t bufhead32[2]; - - if ( raw_copy_from_guest(bufhead32, head, sizeof(bufhead32)) ) - return 0; - bufhead[0].ebp =3D (struct frame_head *)(unsigned long)bufhead32[0= ].ebp; - bufhead[0].ret =3D bufhead32[0].ret; - } - else if ( raw_copy_from_guest(bufhead, head, sizeof(bufhead)) ) - return 0; - =20 - if ( !xenoprof_add_trace(vcpu, bufhead[0].ret, mode) ) - return 0; - =20 - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if ( head >=3D bufhead[0].ebp ) - return NULL; - =20 - return bufhead[0].ebp; -} - -/* - * | | /\ Higher addresses - * | | - * --------------- stack base (address of current_thread_info) - * | thread info | - * . . - * | stack | - * --------------- saved regs->ebp value if valid (frame_head address) - * . . - * --------------- saved regs->rsp value if x86_64 - * | | - * --------------- struct pt_regs * stored on stack if 32-bit - * | | - * . . - * | | - * --------------- %esp - * | | - * | | \/ Lower addresses - * - * Thus, regs (or regs->rsp for x86_64) <-> stack base restricts the - * valid(ish) ebp values. Note: (1) for x86_64, NMI and several other - * exceptions use special stacks, maintained by the interrupt stack table - * (IST). These stacks are set up in trap_init() in - * arch/x86_64/kernel/traps.c. Thus, for x86_64, regs now does not point - * to the kernel stack; instead, it points to some location on the NMI - * stack. On the other hand, regs->rsp is the stack pointer saved when the - * NMI occurred. (2) For 32-bit, regs->esp is not valid because the - * processor does not save %esp on the kernel stack when interrupts occur - * in the kernel mode. - */ -#if defined(CONFIG_FRAME_POINTER) -static int valid_hypervisor_stack(const struct frame_head *head, - const struct cpu_user_regs *regs) -{ - unsigned long headaddr =3D (unsigned long)head; - unsigned long stack =3D (unsigned long)regs->rsp; - unsigned long stack_base =3D (stack & ~(STACK_SIZE - 1)) + STACK_SIZE; - - return headaddr > stack && headaddr < stack_base; -} -#else -/* without fp, it's just junk */ -static int valid_hypervisor_stack(const struct frame_head *head, - const struct cpu_user_regs *regs) -{ - return 0; -} -#endif - -void xenoprof_backtrace(struct vcpu *vcpu, const struct cpu_user_regs *reg= s, - unsigned long depth, int mode) -{ - const struct frame_head *head =3D (void *)regs->rbp; - - if (mode > 1) { - while (depth-- && valid_hypervisor_stack(head, regs)) - head =3D dump_hypervisor_backtrace(vcpu, head, mode); - return; - } - - while (depth-- && head) - head =3D dump_guest_backtrace(vcpu, head, mode); -} diff --git a/xen/arch/x86/oprofile/nmi_int.c b/xen/arch/x86/oprofile/nmi_in= t.c deleted file mode 100644 index 1d6454cf39e8..000000000000 --- a/xen/arch/x86/oprofile/nmi_int.c +++ /dev/null @@ -1,485 +0,0 @@ -/** - * @file nmi_int.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * - * Modified for Xen: by Aravind Menon & Jose Renato Santos - * These modifications are: - * Copyright (C) 2005 Hewlett-Packard Co. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include "op_counter.h" -#include "op_x86_model.h" - -struct op_counter_config counter_config[OP_MAX_COUNTER]; -struct op_ibs_config ibs_config; - -struct op_x86_model_spec const *__read_mostly model; -static struct op_msrs cpu_msrs[NR_CPUS]; -static unsigned long saved_lvtpc[NR_CPUS]; - -static const char *cpu_type; - -static DEFINE_PER_CPU(struct vcpu *, nmi_cont_vcpu); - -static int passive_domain_msr_op_checks(unsigned int msr, int *typep, int = *indexp) -{ - struct vpmu_struct *vpmu =3D vcpu_vpmu(current); - if ( model =3D=3D NULL ) - return 0; - if ( model->is_arch_pmu_msr =3D=3D NULL ) - return 0; - if ( !model->is_arch_pmu_msr(msr, typep, indexp) ) - return 0; - - if ( !vpmu_is_set(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED) ) - if ( ! model->allocated_msr(current) ) - return 0; - return 1; -} - -int passive_domain_do_rdmsr(unsigned int msr, uint64_t *msr_content) -{ - int type, index; - - if ( !passive_domain_msr_op_checks(msr, &type, &index)) - return 0; - - model->load_msr(current, type, index, msr_content); - return 1; -} - -int passive_domain_do_wrmsr(unsigned int msr, uint64_t msr_content) -{ - int type, index; - - if ( !passive_domain_msr_op_checks(msr, &type, &index)) - return 0; - - model->save_msr(current, type, index, msr_content); - return 1; -} - -void passive_domain_destroy(struct vcpu *v) -{ - struct vpmu_struct *vpmu =3D vcpu_vpmu(v); - if ( vpmu_is_set(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED) ) - model->free_msr(v); -} - -bool nmi_oprofile_send_virq(void) -{ - struct vcpu *v =3D xchg(&this_cpu(nmi_cont_vcpu), NULL); - - if (v) - send_guest_vcpu_virq(v, VIRQ_XENOPROF); - - return v; -} - -static int cf_check nmi_callback(const struct cpu_user_regs *regs, int cpu) -{ - int xen_mode, ovf; - - ovf =3D model->check_ctrs(cpu, &cpu_msrs[cpu], regs); - xen_mode =3D ring_0(regs); - if (ovf && is_active(current->domain) && !xen_mode && - !this_cpu(nmi_cont_vcpu)) { - this_cpu(nmi_cont_vcpu) =3D current; - trigger_nmi_continuation(); - } - - if ( ovf =3D=3D 2 ) - current->arch.nmi_pending =3D true; - return 1; -} - - -static void nmi_cpu_save_registers(struct op_msrs *msrs) -{ - unsigned int const nr_ctrs =3D model->num_counters; - unsigned int const nr_ctrls =3D model->num_controls; - struct op_msr *counters =3D msrs->counters; - struct op_msr *controls =3D msrs->controls; - unsigned int i; - - for (i =3D 0; i < nr_ctrs; ++i) { - rdmsrl(counters[i].addr, counters[i].value); - } - - for (i =3D 0; i < nr_ctrls; ++i) { - rdmsrl(controls[i].addr, controls[i].value); - } -} - - -static void cf_check nmi_save_registers(void *dummy) -{ - int cpu =3D smp_processor_id(); - struct op_msrs * msrs =3D &cpu_msrs[cpu]; - model->fill_in_addresses(msrs); - nmi_cpu_save_registers(msrs); -} - - -static void free_msrs(void) -{ - unsigned int i; - - for (i =3D 0; i < nr_cpu_ids; ++i) { - XVFREE(cpu_msrs[i].counters); - XVFREE(cpu_msrs[i].controls); - } -} - - -static int allocate_msrs(void) -{ - unsigned int i; - int success =3D 1; - - for_each_online_cpu (i) { - cpu_msrs[i].counters =3D xvmalloc_array(struct op_msr, - model->num_counters); - if (!cpu_msrs[i].counters) { - success =3D 0; - break; - } - cpu_msrs[i].controls =3D xvmalloc_array(struct op_msr, - model->num_controls); - if (!cpu_msrs[i].controls) { - success =3D 0; - break; - } - } - - if (!success) - free_msrs(); - - return success; -} - - -static void cf_check nmi_cpu_setup(void *dummy) -{ - int cpu =3D smp_processor_id(); - struct op_msrs * msrs =3D &cpu_msrs[cpu]; - model->setup_ctrs(msrs); -} - - -int nmi_setup_events(void) -{ - on_each_cpu(nmi_cpu_setup, NULL, 1); - return 0; -} - -int nmi_reserve_counters(void) -{ - if (!allocate_msrs()) - return -ENOMEM; - - /* - * We need to be careful to install our NMI handler - * without actually triggering any NMIs as this will - * break the core code horrifically. - */ - if (reserve_lapic_nmi() < 0) { - free_msrs(); - return -EBUSY; - } - /* We need to serialize save and setup for HT because the subset - * of msrs are distinct for save and setup operations - */ - on_each_cpu(nmi_save_registers, NULL, 1); - return 0; -} - -int nmi_enable_virq(void) -{ - set_nmi_callback(nmi_callback); - return 0; -} - - -void nmi_disable_virq(void) -{ - unset_nmi_callback(); -} - - -static void nmi_restore_registers(struct op_msrs * msrs) -{ - unsigned int const nr_ctrs =3D model->num_counters; - unsigned int const nr_ctrls =3D model->num_controls; - struct op_msr * counters =3D msrs->counters; - struct op_msr * controls =3D msrs->controls; - unsigned int i; - - for (i =3D 0; i < nr_ctrls; ++i) { - wrmsrl(controls[i].addr, controls[i].value); - } - - for (i =3D 0; i < nr_ctrs; ++i) { - wrmsrl(counters[i].addr, counters[i].value); - } -} - - -static void cf_check nmi_cpu_shutdown(void *dummy) -{ - int cpu =3D smp_processor_id(); - struct op_msrs * msrs =3D &cpu_msrs[cpu]; - nmi_restore_registers(msrs); -} - - -void nmi_release_counters(void) -{ - on_each_cpu(nmi_cpu_shutdown, NULL, 1); - release_lapic_nmi(); - free_msrs(); -} - - -static void cf_check nmi_cpu_start(void *dummy) -{ - int cpu =3D smp_processor_id(); - struct op_msrs const * msrs =3D &cpu_msrs[cpu]; - saved_lvtpc[cpu] =3D apic_read(APIC_LVTPC); - apic_write(APIC_LVTPC, APIC_DM_NMI); - model->start(msrs); -} - - -int nmi_start(void) -{ - on_each_cpu(nmi_cpu_start, NULL, 1); - return 0; -} - - -static void cf_check nmi_cpu_stop(void *dummy) -{ - unsigned int v; - int cpu =3D smp_processor_id(); - struct op_msrs const * msrs =3D &cpu_msrs[cpu]; - model->stop(msrs); - - /* restoring APIC_LVTPC can trigger an apic error because the delivery - * mode and vector nr combination can be illegal. That's by design: on - * power on apic lvt contain a zero vector nr which are legal only for - * NMI delivery mode. So inhibit apic err before restoring lvtpc - */ - if ( (apic_read(APIC_LVTPC) & APIC_DM_MASK) !=3D APIC_DM_NMI - || (apic_read(APIC_LVTPC) & APIC_LVT_MASKED) ) - { - printk("nmi_stop: APIC not good %ul\n", apic_read(APIC_LVTPC)); - mdelay(5000); - } - v =3D apic_read(APIC_LVTERR); - apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); - apic_write(APIC_LVTPC, saved_lvtpc[cpu]); - apic_write(APIC_LVTERR, v); -} - - -void nmi_stop(void) -{ - on_each_cpu(nmi_cpu_stop, NULL, 1); -} - - -static int __init p4_init(const char **cpu_type) -{ - unsigned int cpu_model =3D current_cpu_data.x86_model; - - if ((cpu_model > 6) || (cpu_model =3D=3D 5)) { - printk("xenoprof: Initialization failed. " - "Intel processor model %u for pentium 4 family is not " - "supported\n", cpu_model); - return 0; - } - - switch (current_cpu_data.x86_num_siblings) { - case 1: - *cpu_type =3D "i386/p4"; - model =3D &op_p4_spec; - return 1; - - case 2: - *cpu_type =3D "i386/p4-ht"; - model =3D &op_p4_ht2_spec; - return 1; - } - - printk("Xenoprof ERROR: P4 HyperThreading detected with > 2 threads\n"); - - return 0; -} - - -static int force_arch_perfmon; - -static int __init cf_check force_cpu_type(const char *str) -{ - if (!strcmp(str, "arch_perfmon")) { - force_arch_perfmon =3D 1; - printk(KERN_INFO "oprofile: forcing architectural perfmon\n"); - } - else - return -EINVAL; - - return 0; -} -custom_param("cpu_type", force_cpu_type); - -static int __init ppro_init(const char **cpu_type) -{ - if (force_arch_perfmon && cpu_has_arch_perfmon) - return 0; - - switch (current_cpu_data.x86_model) { - case 14: - *cpu_type =3D "i386/core"; - break; - case 15: - *cpu_type =3D "i386/core_2"; - ppro_has_global_ctrl =3D 1; - break; - default: - /* Unknown */ - return 0; - } - - model =3D &op_ppro_spec; - return 1; -} - -static int __init arch_perfmon_init(const char **cpu_type) -{ - if (!cpu_has_arch_perfmon) - return 0; - *cpu_type =3D "i386/arch_perfmon"; - model =3D &op_arch_perfmon_spec; - arch_perfmon_setup_counters(); - ppro_has_global_ctrl =3D 1; - return 1; -} - -static int __init cf_check nmi_init(void) -{ - unsigned int vendor =3D current_cpu_data.x86_vendor; - unsigned int family =3D current_cpu_data.x86; - - if (!cpu_has_apic) { - printk("xenoprof: Initialization failed. No APIC\n"); - return -ENODEV; - } - - switch (vendor) { - case X86_VENDOR_AMD: - /* Needs to be at least an Athlon (or hammer in 32bit mode) */ - - switch (family) { - default: - printk("xenoprof: Initialization failed. " - "AMD processor family %u is not " - "supported\n", family); - return -ENODEV; - case 0xf: - model =3D &op_athlon_spec; - cpu_type =3D "x86-64/hammer"; - break; - case 0x10: - model =3D &op_athlon_spec; - cpu_type =3D "x86-64/family10"; - ibs_init(); - break; - case 0x11: - model =3D &op_athlon_spec; - cpu_type =3D "x86-64/family11h"; - break; - case 0x12: - model =3D &op_athlon_spec; - cpu_type =3D "x86-64/family12h"; - break; - case 0x14: - model =3D &op_athlon_spec; - cpu_type =3D "x86-64/family14h"; - break; - case 0x15: - model =3D &op_amd_fam15h_spec; - cpu_type =3D "x86-64/family15h"; - break; - case 0x16: - model =3D &op_athlon_spec; - cpu_type =3D "x86-64/family16h"; - break; - } - break; - - case X86_VENDOR_INTEL: - switch (family) { - /* Pentium IV */ - case 0xf: - p4_init(&cpu_type); - break; - - /* A P6-class processor */ - case 6: - ppro_init(&cpu_type); - break; - - default: - break; - } - if (!cpu_type && !arch_perfmon_init(&cpu_type)) { - printk("xenoprof: Initialization failed. " - "Intel processor family %u model %d is not supported\n", - family, current_cpu_data.x86_model); - return -ENODEV; - } - break; - - default: - printk("xenoprof: Initialization failed. " - "Unsupported processor. Unknown vendor %u\n", - vendor); - return -ENODEV; - } - - return 0; -} - -__initcall(nmi_init); - -int xenoprof_arch_init(int *num_events, char *_cpu_type) -{ - if (cpu_type =3D=3D NULL) - return -ENODEV; - *num_events =3D model->num_counters; - strlcpy(_cpu_type, cpu_type, XENOPROF_CPU_TYPE_SIZE); - return 0; -} diff --git a/xen/arch/x86/oprofile/op_counter.h b/xen/arch/x86/oprofile/op_= counter.h deleted file mode 100644 index b515ac9ebc8e..000000000000 --- a/xen/arch/x86/oprofile/op_counter.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file op_counter.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - */ -=20 -#ifndef OP_COUNTER_H -#define OP_COUNTER_H -=20 -#define OP_MAX_COUNTER 8 -=20 -/* Per-perfctr configuration as set via - * oprofilefs. - */ -struct op_counter_config { - unsigned long count; - unsigned long enabled; - unsigned long event; - unsigned long kernel; - unsigned long user; - unsigned long unit_mask; -}; - -extern struct op_counter_config counter_config[]; - -/* AMD IBS configuration */ -struct op_ibs_config { - unsigned long op_enabled; - unsigned long fetch_enabled; - unsigned long max_cnt_fetch; - unsigned long max_cnt_op; - unsigned long rand_en; - unsigned long dispatched_ops; -}; - -extern struct op_ibs_config ibs_config; - -#endif /* OP_COUNTER_H */ diff --git a/xen/arch/x86/oprofile/op_model_athlon.c b/xen/arch/x86/oprofil= e/op_model_athlon.c deleted file mode 100644 index 4c016624a69b..000000000000 --- a/xen/arch/x86/oprofile/op_model_athlon.c +++ /dev/null @@ -1,547 +0,0 @@ -/** - * @file op_model_athlon.h - * athlon / K7 model-specific MSR operations - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * @author Graydon Hoare - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "op_x86_model.h" -#include "op_counter.h" - -#define K7_NUM_COUNTERS 4 -#define K7_NUM_CONTROLS 4 - -#define FAM15H_NUM_COUNTERS 6 -#define FAM15H_NUM_CONTROLS 6 - -#define MAX_COUNTERS FAM15H_NUM_COUNTERS - -#define CTR_READ(msr_content,msrs,c) do {rdmsrl(msrs->counters[(c)].addr, = (msr_content));} while (0) -#define CTR_WRITE(l,msrs,c) wrmsr(msrs->counters[(c)].addr, -(l)) -#define CTR_OVERFLOWED(n) (!((n) & (1ULL<<31))) - -#define CTRL_READ(msr_content,msrs,c) do {rdmsrl(msrs->controls[(c)].addr,= (msr_content));} while (0) -#define CTRL_WRITE(msr_content,msrs,c) do {wrmsrl(msrs->controls[(c)].addr= , (msr_content));} while (0) -#define CTRL_SET_ACTIVE(n) (n |=3D (1ULL<<22)) -#define CTRL_SET_INACTIVE(n) (n &=3D ~(1ULL<<22)) -#define CTRL_CLEAR(val) (val &=3D (1ULL<<21)) -#define CTRL_SET_ENABLE(val) (val |=3D 1ULL<<20) -#define CTRL_SET_USR(val,u) (val |=3D ((u & 1) << 16)) -#define CTRL_SET_KERN(val,k) (val |=3D ((k & 1) << 17)) -#define CTRL_SET_UM(val, m) (val |=3D ((m & 0xff) << 8)) -#define CTRL_SET_EVENT(val, e) (val |=3D (((e >> 8) & 0xf) | (e & 0xff))) -#define CTRL_SET_HOST_ONLY(val, h) (val |=3D ((h & 0x1ULL) << 41)) -#define CTRL_SET_GUEST_ONLY(val, h) (val |=3D ((h & 0x1ULL) << 40)) - -static unsigned long reset_value[MAX_COUNTERS]; - -extern char svm_stgi_label[]; - -u32 ibs_caps =3D 0; -static u64 ibs_op_ctl; - -/* IBS cpuid feature detection */ -#define IBS_CPUID_FEATURES 0x8000001b - -/* IBS MSRs */ -#define MSR_AMD64_IBSFETCHCTL 0xc0011030 -#define MSR_AMD64_IBSFETCHLINAD 0xc0011031 -#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 -#define MSR_AMD64_IBSOPCTL 0xc0011033 -#define MSR_AMD64_IBSOPRIP 0xc0011034 -#define MSR_AMD64_IBSOPDATA 0xc0011035 -#define MSR_AMD64_IBSOPDATA2 0xc0011036 -#define MSR_AMD64_IBSOPDATA3 0xc0011037 -#define MSR_AMD64_IBSDCLINAD 0xc0011038 -#define MSR_AMD64_IBSDCPHYSAD 0xc0011039 -#define MSR_AMD64_IBSCTL 0xc001103a - -/* - * Same bit mask as for IBS cpuid feature flags (Fn8000_001B_EAX), but - * bit 0 is used to indicate the existence of IBS. - */ -#define IBS_CAPS_AVAIL (1LL<<0) -#define IBS_CAPS_RDWROPCNT (1LL<<3) -#define IBS_CAPS_OPCNT (1LL<<4) - -/* IBS randomization macros */ -#define IBS_RANDOM_BITS 12 -#define IBS_RANDOM_MASK ((1ULL << IBS_RANDOM_BITS) - 1) -#define IBS_RANDOM_MAXCNT_OFFSET (1ULL << (IBS_RANDOM_BITS - 5)) - -/* IbsFetchCtl bits/masks */ -#define IBS_FETCH_RAND_EN (1ULL<<57) -#define IBS_FETCH_VAL (1ULL<<49) -#define IBS_FETCH_ENABLE (1ULL<<48) -#define IBS_FETCH_CNT 0xFFFF0000ULL -#define IBS_FETCH_MAX_CNT 0x0000FFFFULL - -/* IbsOpCtl bits */ -#define IBS_OP_CNT_CTL (1ULL<<19) -#define IBS_OP_VAL (1ULL<<18) -#define IBS_OP_ENABLE (1ULL<<17) -#define IBS_OP_MAX_CNT 0x0000FFFFULL - -/* IBS sample identifier */ -#define IBS_FETCH_CODE 13 -#define IBS_OP_CODE 14 - -#define clamp(val, min, max) ({ \ - typeof(val) __val =3D (val); \ - typeof(min) __min =3D (min); \ - typeof(max) __max =3D (max); \ - (void) (&__val =3D=3D &__min); \ - (void) (&__val =3D=3D &__max); \ - __val =3D __val < __min ? __min: __val; \ - __val > __max ? __max: __val; }) - -/* - * 16-bit Linear Feedback Shift Register (LFSR) - */ -static unsigned int lfsr_random(void) -{ - static unsigned int lfsr_value =3D 0xF00D; - unsigned int bit; - - /* Compute next bit to shift in */ - bit =3D ((lfsr_value >> 0) ^ - (lfsr_value >> 2) ^ - (lfsr_value >> 3) ^ - (lfsr_value >> 5)) & 0x0001; - - /* Advance to next register value */ - lfsr_value =3D (lfsr_value >> 1) | (bit << 15); - - return lfsr_value; -} - -/* - * IBS software randomization - * - * The IBS periodic op counter is randomized in software. The lower 12 - * bits of the 20 bit counter are randomized. IbsOpCurCnt is - * initialized with a 12 bit random value. - */ -static inline u64 op_amd_randomize_ibs_op(u64 val) -{ - unsigned int random =3D lfsr_random(); - - if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) - /* - * Work around if the hw can not write to IbsOpCurCnt - * - * Randomize the lower 8 bits of the 16 bit - * IbsOpMaxCnt [15:0] value in the range of -128 to - * +127 by adding/subtracting an offset to the - * maximum count (IbsOpMaxCnt). - * - * To avoid over or underflows and protect upper bits - * starting at bit 16, the initial value for - * IbsOpMaxCnt must fit in the range from 0x0081 to - * 0xff80. - */ - val +=3D (int8_t)(random >> 4); - else - val |=3D (u64)(random & IBS_RANDOM_MASK) << 32; - - return val; -} - -static void cf_check athlon_fill_in_addresses(struct op_msrs * const msrs) -{ - msrs->counters[0].addr =3D MSR_K7_PERFCTR0; - msrs->counters[1].addr =3D MSR_K7_PERFCTR1; - msrs->counters[2].addr =3D MSR_K7_PERFCTR2; - msrs->counters[3].addr =3D MSR_K7_PERFCTR3; - - msrs->controls[0].addr =3D MSR_K7_EVNTSEL0; - msrs->controls[1].addr =3D MSR_K7_EVNTSEL1; - msrs->controls[2].addr =3D MSR_K7_EVNTSEL2; - msrs->controls[3].addr =3D MSR_K7_EVNTSEL3; -} - -static void cf_check fam15h_fill_in_addresses(struct op_msrs * const msrs) -{ - msrs->counters[0].addr =3D MSR_AMD_FAM15H_PERFCTR0; - msrs->counters[1].addr =3D MSR_AMD_FAM15H_PERFCTR1; - msrs->counters[2].addr =3D MSR_AMD_FAM15H_PERFCTR2; - msrs->counters[3].addr =3D MSR_AMD_FAM15H_PERFCTR3; - msrs->counters[4].addr =3D MSR_AMD_FAM15H_PERFCTR4; - msrs->counters[5].addr =3D MSR_AMD_FAM15H_PERFCTR5; - - msrs->controls[0].addr =3D MSR_AMD_FAM15H_EVNTSEL0; - msrs->controls[1].addr =3D MSR_AMD_FAM15H_EVNTSEL1; - msrs->controls[2].addr =3D MSR_AMD_FAM15H_EVNTSEL2; - msrs->controls[3].addr =3D MSR_AMD_FAM15H_EVNTSEL3; - msrs->controls[4].addr =3D MSR_AMD_FAM15H_EVNTSEL4; - msrs->controls[5].addr =3D MSR_AMD_FAM15H_EVNTSEL5; -} - -static void cf_check athlon_setup_ctrs(struct op_msrs const * const msrs) -{ - uint64_t msr_content; - int i; - unsigned int const nr_ctrs =3D model->num_counters; - unsigned int const nr_ctrls =3D model->num_controls; -=20 - /* clear all counters */ - for (i =3D 0 ; i < nr_ctrls; ++i) { - CTRL_READ(msr_content, msrs, i); - CTRL_CLEAR(msr_content); - CTRL_WRITE(msr_content, msrs, i); - } -=09 - /* avoid a false detection of ctr overflows in NMI handler */ - for (i =3D 0; i < nr_ctrs; ++i) { - CTR_WRITE(1, msrs, i); - } - - /* enable active counters */ - for (i =3D 0; i < nr_ctrs; ++i) { - if (counter_config[i].enabled) { - reset_value[i] =3D counter_config[i].count; - - CTR_WRITE(counter_config[i].count, msrs, i); - - CTRL_READ(msr_content, msrs, i); - CTRL_CLEAR(msr_content); - CTRL_SET_ENABLE(msr_content); - CTRL_SET_USR(msr_content, counter_config[i].user); - CTRL_SET_KERN(msr_content, counter_config[i].kernel); - CTRL_SET_UM(msr_content, counter_config[i].unit_mask); - CTRL_SET_EVENT(msr_content, counter_config[i].event); - CTRL_SET_HOST_ONLY(msr_content, 0); - CTRL_SET_GUEST_ONLY(msr_content, 0); - CTRL_WRITE(msr_content, msrs, i); - } else { - reset_value[i] =3D 0; - } - } -} - -static inline void -ibs_log_event(u64 data, struct cpu_user_regs const * const regs, int mode) -{ - struct vcpu *v =3D current; - u32 temp =3D 0; - - temp =3D data & 0xFFFFFFFF; - xenoprof_log_event(v, regs, temp, mode, 0); -=09 - temp =3D (data >> 32) & 0xFFFFFFFF; - xenoprof_log_event(v, regs, temp, mode, 0); -=09 -} - -static inline int handle_ibs(int mode, struct cpu_user_regs const * const = regs) -{ - u64 val, ctl; - struct vcpu *v =3D current; - - if (!ibs_caps) - return 1; - - if (ibs_config.fetch_enabled) { - rdmsrl(MSR_AMD64_IBSFETCHCTL, ctl); - if (ctl & IBS_FETCH_VAL) { - rdmsrl(MSR_AMD64_IBSFETCHLINAD, val); - xenoprof_log_event(v, regs, IBS_FETCH_CODE, mode, 0); - xenoprof_log_event(v, regs, val, mode, 0); - - ibs_log_event(val, regs, mode); - ibs_log_event(ctl, regs, mode); - - rdmsrl(MSR_AMD64_IBSFETCHPHYSAD, val); - ibs_log_event(val, regs, mode); - =09 - /* reenable the IRQ */ - ctl &=3D ~(IBS_FETCH_VAL | IBS_FETCH_CNT); - ctl |=3D IBS_FETCH_ENABLE; - wrmsrl(MSR_AMD64_IBSFETCHCTL, ctl); - } - } - - if (ibs_config.op_enabled) { - rdmsrl(MSR_AMD64_IBSOPCTL, ctl); - if (ctl & IBS_OP_VAL) { - - rdmsrl(MSR_AMD64_IBSOPRIP, val); - xenoprof_log_event(v, regs, IBS_OP_CODE, mode, 0); - xenoprof_log_event(v, regs, val, mode, 0); - =09 - ibs_log_event(val, regs, mode); - - rdmsrl(MSR_AMD64_IBSOPDATA, val); - ibs_log_event(val, regs, mode); - rdmsrl(MSR_AMD64_IBSOPDATA2, val); - ibs_log_event(val, regs, mode); - rdmsrl(MSR_AMD64_IBSOPDATA3, val); - ibs_log_event(val, regs, mode); - rdmsrl(MSR_AMD64_IBSDCLINAD, val); - ibs_log_event(val, regs, mode); - rdmsrl(MSR_AMD64_IBSDCPHYSAD, val); - ibs_log_event(val, regs, mode); - - /* reenable the IRQ */ - ctl =3D op_amd_randomize_ibs_op(ibs_op_ctl); - wrmsrl(MSR_AMD64_IBSOPCTL, ctl); - } - } - - return 1; -} - -static int cf_check athlon_check_ctrs( - unsigned int const cpu, struct op_msrs const * const msrs, - struct cpu_user_regs const * const regs) - -{ - uint64_t msr_content; - int i; - unsigned long eip =3D regs->rip; - int mode =3D 0; - struct vcpu *v =3D current; - unsigned int const nr_ctrs =3D model->num_counters; - -#ifdef CONFIG_AMD_SVM - struct cpu_user_regs *guest_regs =3D guest_cpu_user_regs(); - - if (!guest_mode(regs) && - (eip =3D=3D (unsigned long)svm_stgi_label)) { - /* SVM guest was running when NMI occurred */ - ASSERT(is_hvm_vcpu(v)); - eip =3D guest_regs->rip; - mode =3D xenoprofile_get_mode(v, guest_regs); - } else -#endif - mode =3D xenoprofile_get_mode(v, regs); - - for (i =3D 0 ; i < nr_ctrs; ++i) { - CTR_READ(msr_content, msrs, i); - if (CTR_OVERFLOWED(msr_content)) { - xenoprof_log_event(current, regs, eip, mode, i); - CTR_WRITE(reset_value[i], msrs, i); - } - } - - /* See op_model_ppro.c */ - return handle_ibs(mode, regs); -} - -static inline void start_ibs(void) -{ - u64 val =3D 0; - - if (!ibs_caps) - return; - - if (ibs_config.fetch_enabled) { - val =3D (ibs_config.max_cnt_fetch >> 4) & IBS_FETCH_MAX_CNT; - val |=3D ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0; - val |=3D IBS_FETCH_ENABLE; - wrmsrl(MSR_AMD64_IBSFETCHCTL, val); - } - - if (ibs_config.op_enabled) { - ibs_op_ctl =3D ibs_config.max_cnt_op >> 4; - if (!(ibs_caps & IBS_CAPS_RDWROPCNT)) { - /* - * IbsOpCurCnt not supported. See - * op_amd_randomize_ibs_op() for details. - */ - ibs_op_ctl =3D clamp((unsigned long long)ibs_op_ctl,=20 - 0x0081ULL, 0xFF80ULL); - } else { - /* - * The start value is randomized with a - * positive offset, we need to compensate it - * with the half of the randomized range. Also - * avoid underflows. - */ - ibs_op_ctl =3D min(ibs_op_ctl + IBS_RANDOM_MAXCNT_OFFSET, - IBS_OP_MAX_CNT); - } - if (ibs_caps & IBS_CAPS_OPCNT && ibs_config.dispatched_ops) - ibs_op_ctl |=3D IBS_OP_CNT_CTL; - ibs_op_ctl |=3D IBS_OP_ENABLE; - val =3D op_amd_randomize_ibs_op(ibs_op_ctl); - wrmsrl(MSR_AMD64_IBSOPCTL, val); - } -} -=20 -static void cf_check athlon_start(struct op_msrs const * const msrs) -{ - uint64_t msr_content; - int i; - unsigned int const nr_ctrs =3D model->num_counters; - for (i =3D 0 ; i < nr_ctrs ; ++i) { - if (reset_value[i]) { - CTRL_READ(msr_content, msrs, i); - CTRL_SET_ACTIVE(msr_content); - CTRL_WRITE(msr_content, msrs, i); - } - } - start_ibs(); -} - -static void stop_ibs(void) -{ - if (!ibs_caps) - return; - - if (ibs_config.fetch_enabled) - /* clear max count and enable */ - wrmsrl(MSR_AMD64_IBSFETCHCTL, 0); - - if (ibs_config.op_enabled) - /* clear max count and enable */ - wrmsrl(MSR_AMD64_IBSOPCTL, 0); -} - -static void cf_check athlon_stop(struct op_msrs const * const msrs) -{ - uint64_t msr_content; - int i; - unsigned int const nr_ctrs =3D model->num_counters; - - /* Subtle: stop on all counters to avoid race with - * setting our pm callback */ - for (i =3D 0 ; i < nr_ctrs ; ++i) { - CTRL_READ(msr_content, msrs, i); - CTRL_SET_INACTIVE(msr_content); - CTRL_WRITE(msr_content, msrs, i); - } - - stop_ibs(); -} - -#define IBSCTL_LVTOFFSETVAL (1 << 8) -#define APIC_EILVT_MSG_NMI 0x4 -#define APIC_EILVT_LVTOFF_IBS 1 -#define APIC_EILVTn(n) (0x500 + 0x10 * n) -static inline void __init cf_check init_ibs_nmi_per_cpu(void *arg) -{ - unsigned long reg; - - reg =3D (APIC_EILVT_LVTOFF_IBS << 4) + APIC_EILVTn(0); - apic_write(reg, APIC_EILVT_MSG_NMI << 8); -} - -#define PCI_DEVICE_ID_AMD_10H_NB_MISC 0x1203 -#define IBSCTL 0x1cc -static int __init init_ibs_nmi(void) -{ - int bus, dev, func; - u32 id, value; - u16 vendor_id, dev_id; - int nodes; - - /* per CPU setup */ - on_each_cpu(init_ibs_nmi_per_cpu, NULL, 1); - - nodes =3D 0; - for (bus =3D 0; bus < 256; bus++) { - for (dev =3D 0; dev < 32; dev++) { - for (func =3D 0; func < 8; func++) { - id =3D pci_conf_read32(PCI_SBDF(0, bus, dev, func), - PCI_VENDOR_ID); - - vendor_id =3D id & 0xffff; - dev_id =3D (id >> 16) & 0xffff; - - if ((vendor_id =3D=3D PCI_VENDOR_ID_AMD) && - (dev_id =3D=3D PCI_DEVICE_ID_AMD_10H_NB_MISC)) { - - pci_conf_write32( - PCI_SBDF(0, bus, dev, func), - IBSCTL, - IBSCTL_LVTOFFSETVAL | APIC_EILVT_LVTOFF_IBS); - - value =3D pci_conf_read32(PCI_SBDF(0, bus, dev, func), - IBSCTL); - - if (value !=3D (IBSCTL_LVTOFFSETVAL | - APIC_EILVT_LVTOFF_IBS)) { - printk("Xenoprofile: Failed to setup IBS LVT offset, " - "IBSCTL =3D %#x\n", value); - return 1; - } - nodes++; - } - } - } - } - - if (!nodes) { - printk("Xenoprofile: No CPU node configured for IBS\n"); - return 1; - } - - return 0; -} - -static void __init get_ibs_caps(void) -{ - if (!boot_cpu_has(X86_FEATURE_IBS)) - return; - - /* check IBS cpuid feature flags */ - if (current_cpu_data.extended_cpuid_level >=3D IBS_CPUID_FEATURES) - ibs_caps =3D cpuid_eax(IBS_CPUID_FEATURES); - if (!(ibs_caps & IBS_CAPS_AVAIL)) - /* cpuid flags not valid */ - ibs_caps =3D 0; -} - -void __init ibs_init(void) -{ - get_ibs_caps(); - - if ( !ibs_caps ) - return; - - if (init_ibs_nmi()) { - ibs_caps =3D 0; - return; - } - - printk("Xenoprofile: AMD IBS detected (%#x)\n", - (unsigned)ibs_caps); -} - -struct op_x86_model_spec const op_athlon_spec =3D { - .num_counters =3D K7_NUM_COUNTERS, - .num_controls =3D K7_NUM_CONTROLS, - .fill_in_addresses =3D &athlon_fill_in_addresses, - .setup_ctrs =3D &athlon_setup_ctrs, - .check_ctrs =3D &athlon_check_ctrs, - .start =3D &athlon_start, - .stop =3D &athlon_stop -}; - -struct op_x86_model_spec const op_amd_fam15h_spec =3D { - .num_counters =3D FAM15H_NUM_COUNTERS, - .num_controls =3D FAM15H_NUM_CONTROLS, - .fill_in_addresses =3D &fam15h_fill_in_addresses, - .setup_ctrs =3D &athlon_setup_ctrs, - .check_ctrs =3D &athlon_check_ctrs, - .start =3D &athlon_start, - .stop =3D &athlon_stop -}; diff --git a/xen/arch/x86/oprofile/op_model_p4.c b/xen/arch/x86/oprofile/op= _model_p4.c deleted file mode 100644 index d047258644db..000000000000 --- a/xen/arch/x86/oprofile/op_model_p4.c +++ /dev/null @@ -1,721 +0,0 @@ -/** - * @file op_model_p4.c - * P4 model-specific MSR operations - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Graydon Hoare - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "op_x86_model.h" -#include "op_counter.h" - -#define NUM_EVENTS 39 - -#define NUM_COUNTERS_NON_HT 8 -#define NUM_ESCRS_NON_HT 45 -#define NUM_CCCRS_NON_HT 18 -#define NUM_CONTROLS_NON_HT (NUM_ESCRS_NON_HT + NUM_CCCRS_NON_HT) - -#define NUM_COUNTERS_HT2 4 -#define NUM_ESCRS_HT2 23 -#define NUM_CCCRS_HT2 9 -#define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) - -static unsigned int num_counters =3D NUM_COUNTERS_NON_HT; - - -/* this has to be checked dynamically since the - hyper-threadedness of a chip is discovered at - kernel boot-time. */ -static inline void setup_num_counters(void) -{ - if (boot_cpu_data.x86_num_siblings =3D=3D 2) /* XXX */ - num_counters =3D NUM_COUNTERS_HT2; -} - -static int inline addr_increment(void) -{ - return boot_cpu_data.x86_num_siblings =3D=3D 2 ? 2 : 1; -} - - -/* tables to simulate simplified hardware view of p4 registers */ -struct p4_counter_binding { - int virt_counter; - int counter_address; - int cccr_address; -}; - -struct p4_event_binding { - int escr_select; /* value to put in CCCR */ - int event_select; /* value to put in ESCR */ - struct { - int virt_counter; /* for this counter... */ - int escr_address; /* use this ESCR */ - } bindings[2]; -}; - -/* nb: these CTR_* defines are a duplicate of defines in - event/i386.p4*events. */ - - -#define CTR_BPU_0 (1 << 0) -#define CTR_MS_0 (1 << 1) -#define CTR_FLAME_0 (1 << 2) -#define CTR_IQ_4 (1 << 3) -#define CTR_BPU_2 (1 << 4) -#define CTR_MS_2 (1 << 5) -#define CTR_FLAME_2 (1 << 6) -#define CTR_IQ_5 (1 << 7) - -static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] =3D { - { CTR_BPU_0, MSR_P4_BPU_PERFCTR0, MSR_P4_BPU_CCCR0 }, - { CTR_MS_0, MSR_P4_MS_PERFCTR0, MSR_P4_MS_CCCR0 }, - { CTR_FLAME_0, MSR_P4_FLAME_PERFCTR0, MSR_P4_FLAME_CCCR0 }, - { CTR_IQ_4, MSR_P4_IQ_PERFCTR4, MSR_P4_IQ_CCCR4 }, - { CTR_BPU_2, MSR_P4_BPU_PERFCTR2, MSR_P4_BPU_CCCR2 }, - { CTR_MS_2, MSR_P4_MS_PERFCTR2, MSR_P4_MS_CCCR2 }, - { CTR_FLAME_2, MSR_P4_FLAME_PERFCTR2, MSR_P4_FLAME_CCCR2 }, - { CTR_IQ_5, MSR_P4_IQ_PERFCTR5, MSR_P4_IQ_CCCR5 } -}; - -#define NUM_UNUSED_CCCRS NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT - -/* All cccr we don't use. */ -static int p4_unused_cccr[NUM_UNUSED_CCCRS] =3D { - MSR_P4_BPU_CCCR1, MSR_P4_BPU_CCCR3, - MSR_P4_MS_CCCR1, MSR_P4_MS_CCCR3, - MSR_P4_FLAME_CCCR1, MSR_P4_FLAME_CCCR3, - MSR_P4_IQ_CCCR0, MSR_P4_IQ_CCCR1, - MSR_P4_IQ_CCCR2, MSR_P4_IQ_CCCR3 -}; - -/* p4 event codes in libop/op_event.h are indices into this table. */ - -static const struct p4_event_binding p4_events[NUM_EVENTS] =3D { -=09 - { /* BRANCH_RETIRED */ - 0x05, 0x06,=20 - { {CTR_IQ_4, MSR_P4_CRU_ESCR2}, - {CTR_IQ_5, MSR_P4_CRU_ESCR3} } - }, -=09 - { /* MISPRED_BRANCH_RETIRED */ - 0x04, 0x03,=20 - { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, - { CTR_IQ_5, MSR_P4_CRU_ESCR1} } - }, -=09 - { /* TC_DELIVER_MODE */ - 0x01, 0x01, - { { CTR_MS_0, MSR_P4_TC_ESCR0}, =20 - { CTR_MS_2, MSR_P4_TC_ESCR1} } - }, -=09 - { /* BPU_FETCH_REQUEST */ - 0x00, 0x03,=20 - { { CTR_BPU_0, MSR_P4_BPU_ESCR0}, - { CTR_BPU_2, MSR_P4_BPU_ESCR1} } - }, - - { /* ITLB_REFERENCE */ - 0x03, 0x18, - { { CTR_BPU_0, MSR_P4_ITLB_ESCR0}, - { CTR_BPU_2, MSR_P4_ITLB_ESCR1} } - }, - - { /* MEMORY_CANCEL */ - 0x05, 0x02, - { { CTR_FLAME_0, MSR_P4_DAC_ESCR0}, - { CTR_FLAME_2, MSR_P4_DAC_ESCR1} } - }, - - { /* MEMORY_COMPLETE */ - 0x02, 0x08, - { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, - { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } - }, - - { /* LOAD_PORT_REPLAY */ - 0x02, 0x04,=20 - { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, - { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } - }, - - { /* STORE_PORT_REPLAY */ - 0x02, 0x05, - { { CTR_FLAME_0, MSR_P4_SAAT_ESCR0}, - { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} } - }, - - { /* MOB_LOAD_REPLAY */ - 0x02, 0x03, - { { CTR_BPU_0, MSR_P4_MOB_ESCR0}, - { CTR_BPU_2, MSR_P4_MOB_ESCR1} } - }, - - { /* PAGE_WALK_TYPE */ - 0x04, 0x01, - { { CTR_BPU_0, MSR_P4_PMH_ESCR0}, - { CTR_BPU_2, MSR_P4_PMH_ESCR1} } - }, - - { /* BSQ_CACHE_REFERENCE */ - 0x07, 0x0c,=20 - { { CTR_BPU_0, MSR_P4_BSU_ESCR0}, - { CTR_BPU_2, MSR_P4_BSU_ESCR1} } - }, - - { /* IOQ_ALLOCATION */ - 0x06, 0x03,=20 - { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, - { 0, 0 } } - }, - - { /* IOQ_ACTIVE_ENTRIES */ - 0x06, 0x1a,=20 - { { CTR_BPU_2, MSR_P4_FSB_ESCR1}, - { 0, 0 } } - }, - - { /* FSB_DATA_ACTIVITY */ - 0x06, 0x17,=20 - { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, - { CTR_BPU_2, MSR_P4_FSB_ESCR1} } - }, - - { /* BSQ_ALLOCATION */ - 0x07, 0x05,=20 - { { CTR_BPU_0, MSR_P4_BSU_ESCR0}, - { 0, 0 } } - }, - - { /* BSQ_ACTIVE_ENTRIES */ - 0x07, 0x06, - { { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */}, =20 - { 0, 0 } } - }, - - { /* X87_ASSIST */ - 0x05, 0x03,=20 - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } - }, - - { /* SSE_INPUT_ASSIST */ - 0x01, 0x34, - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } - }, - =20 - { /* PACKED_SP_UOP */ - 0x01, 0x08,=20 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } - }, - =20 - { /* PACKED_DP_UOP */ - 0x01, 0x0c,=20 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } - }, - - { /* SCALAR_SP_UOP */ - 0x01, 0x0a,=20 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } - }, - - { /* SCALAR_DP_UOP */ - 0x01, 0x0e, - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } - }, - - { /* 64BIT_MMX_UOP */ - 0x01, 0x02,=20 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } - }, - =20 - { /* 128BIT_MMX_UOP */ - 0x01, 0x1a,=20 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } - }, - - { /* X87_FP_UOP */ - 0x01, 0x04,=20 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } - }, - =20 - { /* X87_SIMD_MOVES_UOP */ - 0x01, 0x2e,=20 - { { CTR_FLAME_0, MSR_P4_FIRM_ESCR0}, - { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} } - }, - =20 - { /* MACHINE_CLEAR */ - 0x05, 0x02,=20 - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } - }, - - { /* GLOBAL_POWER_EVENTS */ - 0x06, 0x13 /* older manual says 0x05, newer 0x13 */, - { { CTR_BPU_0, MSR_P4_FSB_ESCR0}, - { CTR_BPU_2, MSR_P4_FSB_ESCR1} } - }, - =20 - { /* TC_MS_XFER */ - 0x00, 0x05,=20 - { { CTR_MS_0, MSR_P4_MS_ESCR0}, - { CTR_MS_2, MSR_P4_MS_ESCR1} } - }, - - { /* UOP_QUEUE_WRITES */ - 0x00, 0x09, - { { CTR_MS_0, MSR_P4_MS_ESCR0}, - { CTR_MS_2, MSR_P4_MS_ESCR1} } - }, - - { /* FRONT_END_EVENT */ - 0x05, 0x08, - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } - }, - - { /* EXECUTION_EVENT */ - 0x05, 0x0c, - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } - }, - - { /* REPLAY_EVENT */ - 0x05, 0x09, - { { CTR_IQ_4, MSR_P4_CRU_ESCR2}, - { CTR_IQ_5, MSR_P4_CRU_ESCR3} } - }, - - { /* INSTR_RETIRED */ - 0x04, 0x02,=20 - { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, - { CTR_IQ_5, MSR_P4_CRU_ESCR1} } - }, - - { /* UOPS_RETIRED */ - 0x04, 0x01, - { { CTR_IQ_4, MSR_P4_CRU_ESCR0}, - { CTR_IQ_5, MSR_P4_CRU_ESCR1} } - }, - - { /* UOP_TYPE */ =20 - 0x02, 0x02,=20 - { { CTR_IQ_4, MSR_P4_RAT_ESCR0}, - { CTR_IQ_5, MSR_P4_RAT_ESCR1} } - }, - - { /* RETIRED_MISPRED_BRANCH_TYPE */ - 0x02, 0x05,=20 - { { CTR_MS_0, MSR_P4_TBPU_ESCR0}, - { CTR_MS_2, MSR_P4_TBPU_ESCR1} } - }, - - { /* RETIRED_BRANCH_TYPE */ - 0x02, 0x04, - { { CTR_MS_0, MSR_P4_TBPU_ESCR0}, - { CTR_MS_2, MSR_P4_TBPU_ESCR1} } - } -}; - - -#define MISC_PMC_ENABLED_P(x) ((x) & 1ULL << 7) - -#define ESCR_RESERVED_BITS 0x80000003ULL -#define ESCR_CLEAR(escr) ((escr) &=3D ESCR_RESERVED_BITS) -#define ESCR_SET_USR_0(escr, usr) ((escr) |=3D (((usr) & 1ULL) << 2)) -#define ESCR_SET_OS_0(escr, os) ((escr) |=3D (((os) & 1ULL) << 3)) -#define ESCR_SET_USR_1(escr, usr) ((escr) |=3D (((usr) & 1ULL))) -#define ESCR_SET_OS_1(escr, os) ((escr) |=3D (((os) & 1ULL) << 1)) -#define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |=3D (((sel) & 0x3fULL) <= < 25)) -#define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |=3D (((mask) & 0xffffULL)= << 9)) -#define ESCR_READ(escr,ev,i) do {rdmsrl(ev->bindings[(i)].escr_address, (e= scr));} while (0) -#define ESCR_WRITE(escr,ev,i) do {wrmsrl(ev->bindings[(i)].escr_address, (= escr));} while (0) - -#define CCCR_RESERVED_BITS 0x38030FFFULL -#define CCCR_CLEAR(cccr) ((cccr) &=3D CCCR_RESERVED_BITS) -#define CCCR_SET_REQUIRED_BITS(cccr) ((cccr) |=3D 0x00030000ULL) -#define CCCR_SET_ESCR_SELECT(cccr, sel) ((cccr) |=3D (((sel) & 0x07ULL) <<= 13)) -#define CCCR_SET_PMI_OVF_0(cccr) ((cccr) |=3D (1ULL<<26)) -#define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |=3D (1ULL<<27)) -#define CCCR_SET_ENABLE(cccr) ((cccr) |=3D (1ULL<<12)) -#define CCCR_SET_DISABLE(cccr) ((cccr) &=3D ~(1ULL<<12)) -#define CCCR_READ(msr_content, i) do {rdmsrl(p4_counters[(i)].cccr_address= , (msr_content));} while (0) -#define CCCR_WRITE(msr_content, i) do {wrmsrl(p4_counters[(i)].cccr_addres= s, (msr_content));} while (0) -#define CCCR_OVF_P(cccr) ((cccr) & (1ULL<<31)) -#define CCCR_CLEAR_OVF(cccr) ((cccr) &=3D (~(1ULL<<31))) - -#define CTR_READ(msr_content,i) do {rdmsrl(p4_counters[(i)].counter_addres= s, (msr_content));} while (0) -#define CTR_WRITE(msr_content,i) do {wrmsrl(p4_counters[(i)].counter_addre= ss, -(msr_content));} while (0) -#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000ULL)) - - -/* this assigns a "stagger" to the current CPU, which is used throughout - the code in this module as an extra array offset, to select the "even" - or "odd" part of all the divided resources. */ -static unsigned int get_stagger(void) -{ - int cpu =3D smp_processor_id(); - return (cpu !=3D cpumask_first(per_cpu(cpu_sibling_mask, cpu))); -} - - -/* finally, mediate access to a real hardware counter - by passing a "virtual" counter numer to this macro, - along with your stagger setting. */ -#define VIRT_CTR(stagger, i) ((i) + ((num_counters) * (stagger))) - -static unsigned long reset_value[NUM_COUNTERS_NON_HT]; - - -static void cf_check p4_fill_in_addresses(struct op_msrs * const msrs) -{ - unsigned int i; - unsigned int addr, stag; - - setup_num_counters(); - stag =3D get_stagger(); - - /* the counter registers we pay attention to */ - for (i =3D 0; i < num_counters; ++i) { - msrs->counters[i].addr =3D=20 - p4_counters[VIRT_CTR(stag, i)].counter_address; - } - - /* FIXME: bad feeling, we don't save the 10 counters we don't use. */ - - /* 18 CCCR registers */ - for (i =3D 0, addr =3D MSR_P4_BPU_CCCR0 + stag; - addr <=3D MSR_P4_IQ_CCCR5; ++i, addr +=3D addr_increment()) { - msrs->controls[i].addr =3D addr; - } -=09 - /* 43 ESCR registers in three or four discontiguous group */ - for (addr =3D MSR_P4_BSU_ESCR0 + stag; - addr < MSR_P4_IQ_ESCR0; ++i, addr +=3D addr_increment()) { - msrs->controls[i].addr =3D addr; - } - - /* no IQ_ESCR0/1 on some models, we save a seconde time BSU_ESCR0/1 - * to avoid special case in nmi_{save|restore}_registers() */ - if (boot_cpu_data.x86_model >=3D 0x3) { - for (addr =3D MSR_P4_BSU_ESCR0 + stag; - addr <=3D MSR_P4_BSU_ESCR1; ++i, addr +=3D addr_increment()) { - msrs->controls[i].addr =3D addr; - } - } else { - for (addr =3D MSR_P4_IQ_ESCR0 + stag; - addr <=3D MSR_P4_IQ_ESCR1; ++i, addr +=3D addr_increment()) { - msrs->controls[i].addr =3D addr; - } - } - - for (addr =3D MSR_P4_RAT_ESCR0 + stag; - addr <=3D MSR_P4_SSU_ESCR0; ++i, addr +=3D addr_increment()) { - msrs->controls[i].addr =3D addr; - } -=09 - for (addr =3D MSR_P4_MS_ESCR0 + stag; - addr <=3D MSR_P4_TC_ESCR1; ++i, addr +=3D addr_increment()) {=20 - msrs->controls[i].addr =3D addr; - } -=09 - for (addr =3D MSR_P4_IX_ESCR0 + stag; - addr <=3D MSR_P4_CRU_ESCR3; ++i, addr +=3D addr_increment()) {=20 - msrs->controls[i].addr =3D addr; - } - - /* there are 2 remaining non-contiguously located ESCRs */ - - if (num_counters =3D=3D NUM_COUNTERS_NON_HT) { =09 - /* standard non-HT CPUs handle both remaining ESCRs*/ - msrs->controls[i++].addr =3D MSR_P4_CRU_ESCR5; - msrs->controls[i++].addr =3D MSR_P4_CRU_ESCR4; - - } else if (stag =3D=3D 0) { - /* HT CPUs give the first remainder to the even thread, as - the 32nd control register */ - msrs->controls[i++].addr =3D MSR_P4_CRU_ESCR4; - - } else { - /* and two copies of the second to the odd thread, - for the 22st and 23nd control registers */ - msrs->controls[i++].addr =3D MSR_P4_CRU_ESCR5; - msrs->controls[i++].addr =3D MSR_P4_CRU_ESCR5; - } -} - - -static void pmc_setup_one_p4_counter(unsigned int ctr) -{ - int i; - int const maxbind =3D 2; - uint64_t cccr =3D 0; - uint64_t escr =3D 0; - unsigned int counter_bit; - const struct p4_event_binding *ev =3D NULL; - unsigned int stag; - - stag =3D get_stagger(); -=09 - /* convert from counter *number* to counter *bit* */ - counter_bit =3D 1 << VIRT_CTR(stag, ctr); -=09 - /* find our event binding structure. */ - if (counter_config[ctr].event <=3D 0 || counter_config[ctr].event > NUM_E= VENTS) { - printk(KERN_ERR "oprofile: P4 event code %#lx out of range\n", - counter_config[ctr].event); - return; - } -=09 - ev =3D &(p4_events[counter_config[ctr].event - 1]); -=09 - for (i =3D 0; i < maxbind; i++) { - if (ev->bindings[i].virt_counter & counter_bit) { - - /* modify ESCR */ - ESCR_READ(escr, ev, i); - ESCR_CLEAR(escr); - if (stag =3D=3D 0) { - ESCR_SET_USR_0(escr, counter_config[ctr].user); - ESCR_SET_OS_0(escr, counter_config[ctr].kernel); - } else { - ESCR_SET_USR_1(escr, counter_config[ctr].user); - ESCR_SET_OS_1(escr, counter_config[ctr].kernel); - } - ESCR_SET_EVENT_SELECT(escr, ev->event_select); - ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask); =09 - ESCR_WRITE(escr, ev, i); - =20 - /* modify CCCR */ - CCCR_READ(cccr, VIRT_CTR(stag, ctr)); - CCCR_CLEAR(cccr); - CCCR_SET_REQUIRED_BITS(cccr); - CCCR_SET_ESCR_SELECT(cccr, ev->escr_select); - if (stag =3D=3D 0) { - CCCR_SET_PMI_OVF_0(cccr); - } else { - CCCR_SET_PMI_OVF_1(cccr); - } - CCCR_WRITE(cccr, VIRT_CTR(stag, ctr)); - return; - } - } - - printk(KERN_ERR=20 - "oprofile: P4 event code %#lx no binding, stag %d ctr %d\n", - counter_config[ctr].event, stag, ctr); -} - - -static void cf_check p4_setup_ctrs(struct op_msrs const * const msrs) -{ - unsigned int i; - uint64_t msr_content; - unsigned int addr; - unsigned int stag; - - stag =3D get_stagger(); - - rdmsrl(MSR_IA32_MISC_ENABLE, msr_content); - if (! MISC_PMC_ENABLED_P(msr_content)) { - printk(KERN_ERR "oprofile: P4 PMC not available\n"); - return; - } - - /* clear the cccrs we will use */ - for (i =3D 0 ; i < num_counters ; i++) { - rdmsrl(p4_counters[VIRT_CTR(stag, i)].cccr_address, msr_content); - CCCR_CLEAR(msr_content); - CCCR_SET_REQUIRED_BITS(msr_content); - wrmsrl(p4_counters[VIRT_CTR(stag, i)].cccr_address, msr_content); - } - - /* clear cccrs outside our concern */ - for (i =3D stag ; i < NUM_UNUSED_CCCRS ; i +=3D addr_increment()) { - rdmsrl(p4_unused_cccr[i], msr_content); - CCCR_CLEAR(msr_content); - CCCR_SET_REQUIRED_BITS(msr_content); - wrmsrl(p4_unused_cccr[i], msr_content); - } - - /* clear all escrs (including those outside our concern) */ - for (addr =3D MSR_P4_BSU_ESCR0 + stag; - addr < MSR_P4_IQ_ESCR0; addr +=3D addr_increment()) { - wrmsrl(addr, 0x0ULL); - } - - /* On older models clear also MSR_P4_IQ_ESCR0/1 */ - if (boot_cpu_data.x86_model < 0x3) { - wrmsrl(MSR_P4_IQ_ESCR0, 0x0ULL); - wrmsrl(MSR_P4_IQ_ESCR1, 0x0ULL); - } - - for (addr =3D MSR_P4_RAT_ESCR0 + stag; - addr <=3D MSR_P4_SSU_ESCR0; ++i, addr +=3D addr_increment()) { - wrmsrl(addr, 0x0ULL); - } -=09 - for (addr =3D MSR_P4_MS_ESCR0 + stag; - addr <=3D MSR_P4_TC_ESCR1; addr +=3D addr_increment()){=20 - wrmsrl(addr, 0x0ULL); - } -=09 - for (addr =3D MSR_P4_IX_ESCR0 + stag; - addr <=3D MSR_P4_CRU_ESCR3; addr +=3D addr_increment()){=20 - wrmsrl(addr, 0x0ULL); - } - - if (num_counters =3D=3D NUM_COUNTERS_NON_HT) { =09 - wrmsrl(MSR_P4_CRU_ESCR4, 0x0ULL); - wrmsrl(MSR_P4_CRU_ESCR5, 0x0ULL); - } else if (stag =3D=3D 0) { - wrmsrl(MSR_P4_CRU_ESCR4, 0x0ULL); - } else { - wrmsrl(MSR_P4_CRU_ESCR5, 0x0ULL); - } =09 -=09 - /* setup all counters */ - for (i =3D 0 ; i < num_counters ; ++i) { - if (counter_config[i].enabled) { - reset_value[i] =3D counter_config[i].count; - pmc_setup_one_p4_counter(i); - CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i)); - } else { - reset_value[i] =3D 0; - } - } -} - -static int cf_check p4_check_ctrs( - unsigned int const cpu, struct op_msrs const * const msrs, - struct cpu_user_regs const * const regs) -{ - unsigned long ctr, stag, real; - uint64_t msr_content; - int i; - int ovf =3D 0; - unsigned long eip =3D regs->rip; - int mode =3D xenoprofile_get_mode(current, regs); - - stag =3D get_stagger(); - - for (i =3D 0; i < num_counters; ++i) { - =09 - if (!reset_value[i])=20 - continue; - - /*=20 - * there is some eccentricity in the hardware which - * requires that we perform 2 extra corrections: - * - * - check both the CCCR:OVF flag for overflow and the - * counter high bit for un-flagged overflows. - * - * - write the counter back twice to ensure it gets - * updated properly. - *=20 - * the former seems to be related to extra NMIs happening - * during the current NMI; the latter is reported as errata - * N15 in intel doc 249199-029, pentium 4 specification - * update, though their suggested work-around does not - * appear to solve the problem. - */ - =09 - real =3D VIRT_CTR(stag, i); - - CCCR_READ(msr_content, real); - CTR_READ(ctr, real); - if (CCCR_OVF_P(msr_content) || CTR_OVERFLOW_P(ctr)) { - xenoprof_log_event(current, regs, eip, mode, i); - CTR_WRITE(reset_value[i], real); - CCCR_CLEAR_OVF(msr_content); - CCCR_WRITE(msr_content, real); - CTR_WRITE(reset_value[i], real); - ovf =3D 1; - } - } - - /* P4 quirk: you have to re-unmask the apic vector */ - apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); - - return ovf; -} - - -static void cf_check p4_start(struct op_msrs const * const msrs) -{ - unsigned int stag; - uint64_t msr_content; - int i; - - stag =3D get_stagger(); - - for (i =3D 0; i < num_counters; ++i) { - if (!reset_value[i]) - continue; - CCCR_READ(msr_content, VIRT_CTR(stag, i)); - CCCR_SET_ENABLE(msr_content); - CCCR_WRITE(msr_content, VIRT_CTR(stag, i)); - } -} - - -static void cf_check p4_stop(struct op_msrs const * const msrs) -{ - unsigned int stag; - uint64_t msr_content; - int i; - - stag =3D get_stagger(); - - for (i =3D 0; i < num_counters; ++i) { - CCCR_READ(msr_content, VIRT_CTR(stag, i)); - CCCR_SET_DISABLE(msr_content); - CCCR_WRITE(msr_content, VIRT_CTR(stag, i)); - } -} - - -struct op_x86_model_spec const op_p4_ht2_spec =3D { - .num_counters =3D NUM_COUNTERS_HT2, - .num_controls =3D NUM_CONTROLS_HT2, - .fill_in_addresses =3D &p4_fill_in_addresses, - .setup_ctrs =3D &p4_setup_ctrs, - .check_ctrs =3D &p4_check_ctrs, - .start =3D &p4_start, - .stop =3D &p4_stop -}; - - -struct op_x86_model_spec const op_p4_spec =3D { - .num_counters =3D NUM_COUNTERS_NON_HT, - .num_controls =3D NUM_CONTROLS_NON_HT, - .fill_in_addresses =3D &p4_fill_in_addresses, - .setup_ctrs =3D &p4_setup_ctrs, - .check_ctrs =3D &p4_check_ctrs, - .start =3D &p4_start, - .stop =3D &p4_stop -}; diff --git a/xen/arch/x86/oprofile/op_model_ppro.c b/xen/arch/x86/oprofile/= op_model_ppro.c deleted file mode 100644 index 4bbb4502c7da..000000000000 --- a/xen/arch/x86/oprofile/op_model_ppro.c +++ /dev/null @@ -1,348 +0,0 @@ -/** - * @file op_model_ppro.h - * pentium pro / P6 model-specific MSR operations - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon - * @author Philippe Elie - * @author Graydon Hoare - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "op_x86_model.h" -#include "op_counter.h" - -struct arch_msr_pair { - u64 counter; - u64 control; -}; - -/* - * Intel "Architectural Performance Monitoring" CPUID - * detection/enumeration details: - */ -union cpuid10_eax { - struct { - unsigned int version_id:8; - unsigned int num_counters:8; - unsigned int bit_width:8; - unsigned int mask_length:8; - } split; - unsigned int full; -}; - -static int num_counters =3D 2; -static int counter_width =3D 32; - -#define CTR_OVERFLOWED(n) (!((n) & (1ULL<<(counter_width-1)))) - -#define CTRL_READ(msr_content,msrs,c) do {rdmsrl((msrs->controls[(c)].addr= ), (msr_content));} while (0) -#define CTRL_WRITE(msr_content,msrs,c) do {wrmsrl((msrs->controls[(c)].add= r), (msr_content));} while (0) -#define CTRL_SET_ACTIVE(n) (n |=3D (1ULL<<22)) -#define CTRL_SET_INACTIVE(n) (n &=3D ~(1ULL<<22)) -#define CTRL_CLEAR(x) (x &=3D (1ULL<<21)) -#define CTRL_SET_ENABLE(val) (val |=3D 1ULL<<20) -#define CTRL_SET_USR(val,u) (val |=3D ((u & 1ULL) << 16)) -#define CTRL_SET_KERN(val,k) (val |=3D ((k & 1ULL) << 17)) -#define CTRL_SET_UM(val, m) (val |=3D (m << 8)) -#define CTRL_SET_EVENT(val, e) (val |=3D e) -#define IS_ACTIVE(val) (val & (1ULL << 22) ) -#define IS_ENABLE(val) (val & (1ULL << 20) ) -static unsigned long reset_value[OP_MAX_COUNTER]; -int ppro_has_global_ctrl =3D 0; - -static void cf_check ppro_fill_in_addresses(struct op_msrs * const msrs) -{ - int i; - - for (i =3D 0; i < num_counters; i++) - msrs->counters[i].addr =3D MSR_P6_PERFCTR(i); - for (i =3D 0; i < num_counters; i++) - msrs->controls[i].addr =3D MSR_P6_EVNTSEL(i); -} - - -static void cf_check ppro_setup_ctrs(struct op_msrs const * const msrs) -{ - uint64_t msr_content; - int i; - - if (cpu_has_arch_perfmon) { - union cpuid10_eax eax; - eax.full =3D cpuid_eax(0xa); - - /* - * For Core2 (family 6, model 15), don't reset the - * counter width: - */ - if (!(eax.split.version_id =3D=3D 0 && - current_cpu_data.x86 =3D=3D 6 && - current_cpu_data.x86_model =3D=3D 15)) { - - if (counter_width < eax.split.bit_width) - counter_width =3D eax.split.bit_width; - } - } - - /* clear all counters */ - for (i =3D 0 ; i < num_counters; ++i) { - CTRL_READ(msr_content, msrs, i); - CTRL_CLEAR(msr_content); - CTRL_WRITE(msr_content, msrs, i); - } - - /* avoid a false detection of ctr overflows in NMI handler */ - for (i =3D 0; i < num_counters; ++i) - wrmsrl(msrs->counters[i].addr, ~0x0ULL); - - /* enable active counters */ - for (i =3D 0; i < num_counters; ++i) { - if (counter_config[i].enabled) { - reset_value[i] =3D counter_config[i].count; - - wrmsrl(msrs->counters[i].addr, -reset_value[i]); - - CTRL_READ(msr_content, msrs, i); - CTRL_CLEAR(msr_content); - CTRL_SET_ENABLE(msr_content); - CTRL_SET_USR(msr_content, counter_config[i].user); - CTRL_SET_KERN(msr_content, counter_config[i].kernel); - CTRL_SET_UM(msr_content, counter_config[i].unit_mask); - CTRL_SET_EVENT(msr_content, counter_config[i].event); - CTRL_WRITE(msr_content, msrs, i); - } else { - reset_value[i] =3D 0; - } - } -} - -static int cf_check ppro_check_ctrs( - unsigned int const cpu, struct op_msrs const * const msrs, - struct cpu_user_regs const * const regs) -{ - u64 val; - int i; - int ovf =3D 0; - unsigned long eip =3D regs->rip; - int mode =3D xenoprofile_get_mode(current, regs); - struct arch_msr_pair *msrs_content =3D vcpu_vpmu(current)->context; - - for (i =3D 0 ; i < num_counters; ++i) { - if (!reset_value[i]) - continue; - rdmsrl(msrs->counters[i].addr, val); - if (CTR_OVERFLOWED(val)) { - xenoprof_log_event(current, regs, eip, mode, i); - wrmsrl(msrs->counters[i].addr, -reset_value[i]); - if ( is_passive(current->domain) && (mode !=3D 2) && - vpmu_is_set(vcpu_vpmu(current), - VPMU_PASSIVE_DOMAIN_ALLOCATED)= ) - { - if ( IS_ACTIVE(msrs_content[i].control) ) - { - msrs_content[i].counter =3D val; - if ( IS_ENABLE(msrs_content[i].control) ) - ovf =3D 2; - } - } - if ( !ovf ) - ovf =3D 1; - } - } - - /* Only P6 based Pentium M need to re-unmask the apic vector but it - * doesn't hurt other P6 variant */ - apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); - - return ovf; -} - - -static void cf_check ppro_start(struct op_msrs const * const msrs) -{ - uint64_t msr_content; - int i; - - for (i =3D 0; i < num_counters; ++i) { - if (reset_value[i]) { - CTRL_READ(msr_content, msrs, i); - CTRL_SET_ACTIVE(msr_content); - CTRL_WRITE(msr_content, msrs, i); - } - } - /* Global Control MSR is enabled by default when system power on. - * However, this may not hold true when xenoprof starts to run. - */ - if ( ppro_has_global_ctrl ) - wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, (1ULL<=3D MSR_IA32_PERFCTR0) && - (msr_index < (MSR_IA32_PERFCTR0 + num_counters)) ) - { - *type =3D MSR_TYPE_ARCH_COUNTER; - *index =3D msr_index - MSR_IA32_PERFCTR0; - return 1; - } - if ( (msr_index >=3D MSR_P6_EVNTSEL(0)) && - (msr_index < (MSR_P6_EVNTSEL(num_counters))) ) - { - *type =3D MSR_TYPE_ARCH_CTRL; - *index =3D msr_index - MSR_P6_EVNTSEL(0); - return 1; - } - - return 0; -} - -static int cf_check ppro_allocate_msr(struct vcpu *v) -{ - struct vpmu_struct *vpmu =3D vcpu_vpmu(v); - struct arch_msr_pair *msr_content; - - msr_content =3D xvzalloc_array(struct arch_msr_pair, num_counters); - if ( !msr_content ) - goto out; - vpmu->context =3D (void *)msr_content; - vpmu_clear(vpmu); - vpmu_set(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED); - return 1; -out: - printk(XENLOG_G_WARNING "Insufficient memory for oprofile," - " oprofile is unavailable on dom%d vcpu%d\n", - v->vcpu_id, v->domain->domain_id); - return 0; -} - -static void cf_check ppro_free_msr(struct vcpu *v) -{ - struct vpmu_struct *vpmu =3D vcpu_vpmu(v); - - if ( !vpmu_is_set(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED) ) - return; - XVFREE(vpmu->context); - vpmu_reset(vpmu, VPMU_PASSIVE_DOMAIN_ALLOCATED); -} - -static void cf_check ppro_load_msr( - struct vcpu *v, int type, int index, u64 *msr_content) -{ - struct arch_msr_pair *msrs =3D vcpu_vpmu(v)->context; - switch ( type ) - { - case MSR_TYPE_ARCH_COUNTER: - *msr_content =3D msrs[index].counter; - break; - case MSR_TYPE_ARCH_CTRL: - *msr_content =3D msrs[index].control; - break; - } -} - -static void cf_check ppro_save_msr( - struct vcpu *v, int type, int index, u64 msr_content) -{ - struct arch_msr_pair *msrs =3D vcpu_vpmu(v)->context; - - switch ( type ) - { - case MSR_TYPE_ARCH_COUNTER: - msrs[index].counter =3D msr_content; - break; - case MSR_TYPE_ARCH_CTRL: - msrs[index].control =3D msr_content; - break; - } -} - -/* - * Architectural performance monitoring. - * - * Newer Intel CPUs (Core1+) have support for architectural - * events described in CPUID 0xA. See the IA32 SDM Vol3b.18 for details. - * The advantage of this is that it can be done without knowing about - * the specific CPU. - */ -void arch_perfmon_setup_counters(void) -{ - union cpuid10_eax eax; - - eax.full =3D cpuid_eax(0xa); - - /* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */ - if (eax.split.version_id =3D=3D 0 && current_cpu_data.x86 =3D=3D 6 && - current_cpu_data.x86_model =3D=3D 15) { - eax.split.version_id =3D 2; - eax.split.num_counters =3D 2; - eax.split.bit_width =3D 40; - } - - num_counters =3D min_t(u8, eax.split.num_counters, OP_MAX_COUNTER); - - op_arch_perfmon_spec.num_counters =3D num_counters; - op_arch_perfmon_spec.num_controls =3D num_counters; - op_ppro_spec.num_counters =3D num_counters; - op_ppro_spec.num_controls =3D num_counters; -} - -struct op_x86_model_spec __read_mostly op_ppro_spec =3D { - .num_counters =3D 2, - .num_controls =3D 2, - .fill_in_addresses =3D &ppro_fill_in_addresses, - .setup_ctrs =3D &ppro_setup_ctrs, - .check_ctrs =3D &ppro_check_ctrs, - .start =3D &ppro_start, - .stop =3D &ppro_stop, - .is_arch_pmu_msr =3D &ppro_is_arch_pmu_msr, - .allocated_msr =3D &ppro_allocate_msr, - .free_msr =3D &ppro_free_msr, - .load_msr =3D &ppro_load_msr, - .save_msr =3D &ppro_save_msr -}; - -struct op_x86_model_spec __read_mostly op_arch_perfmon_spec =3D { - /* num_counters/num_controls filled in at runtime */ - .fill_in_addresses =3D &ppro_fill_in_addresses, - .setup_ctrs =3D &ppro_setup_ctrs, - .check_ctrs =3D &ppro_check_ctrs, - .start =3D &ppro_start, - .stop =3D &ppro_stop, - .is_arch_pmu_msr =3D &ppro_is_arch_pmu_msr, - .allocated_msr =3D &ppro_allocate_msr, - .free_msr =3D &ppro_free_msr, - .load_msr =3D &ppro_load_msr, - .save_msr =3D &ppro_save_msr -}; diff --git a/xen/arch/x86/oprofile/op_x86_model.h b/xen/arch/x86/oprofile/o= p_x86_model.h deleted file mode 100644 index 35bc3c1e222c..000000000000 --- a/xen/arch/x86/oprofile/op_x86_model.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file op_x86_model.h - * interface to x86 model-specific MSR operations - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Graydon Hoare - */ - -#ifndef OP_X86_MODEL_H -#define OP_X86_MODEL_H - -struct op_msr { - unsigned long addr; - uint64_t value; -}; - -struct op_msrs { - struct op_msr * counters; - struct op_msr * controls; -}; - -struct pt_regs; - -/* The model vtable abstracts the differences between - * various x86 CPU model's perfctr support. - */ -struct op_x86_model_spec { - unsigned int num_counters; - unsigned int num_controls; - void (*fill_in_addresses)(struct op_msrs * const msrs); - void (*setup_ctrs)(struct op_msrs const * const msrs); - int (*check_ctrs)(unsigned int const cpu,=20 - struct op_msrs const * const msrs, - struct cpu_user_regs const * const regs); - void (*start)(struct op_msrs const * const msrs); - void (*stop)(struct op_msrs const * const msrs); - int (*is_arch_pmu_msr)(u64 msr_index, int *type, int *index); - int (*allocated_msr)(struct vcpu *v); - void (*free_msr)(struct vcpu *v); - void (*load_msr)(struct vcpu * const v, int type, int index, u64 *msr_con= tent); - void (*save_msr)(struct vcpu * const v, int type, int index, u64 m= sr_content); -}; - -extern struct op_x86_model_spec op_ppro_spec; -extern struct op_x86_model_spec op_arch_perfmon_spec; -extern struct op_x86_model_spec const op_p4_spec; -extern struct op_x86_model_spec const op_p4_ht2_spec; -extern struct op_x86_model_spec const op_athlon_spec; -extern struct op_x86_model_spec const op_amd_fam15h_spec; - -void arch_perfmon_setup_counters(void); - -extern int ppro_has_global_ctrl; -extern struct op_x86_model_spec const *model; - -#endif /* OP_X86_MODEL_H */ diff --git a/xen/arch/x86/oprofile/xenoprof.c b/xen/arch/x86/oprofile/xenop= rof.c deleted file mode 100644 index 7f2525bfb4d6..000000000000 --- a/xen/arch/x86/oprofile/xenoprof.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2005 Hewlett-Packard Co. - * written by Aravind Menon & Jose Renato Santos - * (email: xenoprof@groups.hp.com) - * - * Copyright (c) 2006 Isaku Yamahata - * VA Linux Systems Japan K.K. - * x86 specific part - */ - -#include -#include -#include -#include - -#include "op_counter.h" - -int xenoprof_arch_counter(XEN_GUEST_HANDLE_PARAM(void) arg) -{ - struct xenoprof_counter counter; - - if ( copy_from_guest(&counter, arg, 1) ) - return -EFAULT; - - if ( counter.ind >=3D OP_MAX_COUNTER ) - return -E2BIG; - - counter_config[counter.ind].count =3D counter.count; - counter_config[counter.ind].enabled =3D counter.enabled; - counter_config[counter.ind].event =3D counter.event; - counter_config[counter.ind].kernel =3D counter.kernel; - counter_config[counter.ind].user =3D counter.user; - counter_config[counter.ind].unit_mask =3D counter.unit_mask; - - return 0; -} - -int xenoprof_arch_ibs_counter(XEN_GUEST_HANDLE_PARAM(void) arg) -{ - struct xenoprof_ibs_counter ibs_counter; - - if ( copy_from_guest(&ibs_counter, arg, 1) ) - return -EFAULT; - - ibs_config.op_enabled =3D ibs_counter.op_enabled; - ibs_config.fetch_enabled =3D ibs_counter.fetch_enabled; - ibs_config.max_cnt_fetch =3D ibs_counter.max_cnt_fetch; - ibs_config.max_cnt_op =3D ibs_counter.max_cnt_op; - ibs_config.rand_en =3D ibs_counter.rand_en; - ibs_config.dispatched_ops =3D ibs_counter.dispatched_ops; - - return 0; -} - -#ifdef CONFIG_COMPAT -#include - -int compat_oprof_arch_counter(XEN_GUEST_HANDLE_PARAM(void) arg) -{ - struct compat_oprof_counter counter; - - if ( copy_from_guest(&counter, arg, 1) ) - return -EFAULT; - - if ( counter.ind >=3D OP_MAX_COUNTER ) - return -E2BIG; - - counter_config[counter.ind].count =3D counter.count; - counter_config[counter.ind].enabled =3D counter.enabled; - counter_config[counter.ind].event =3D counter.event; - counter_config[counter.ind].kernel =3D counter.kernel; - counter_config[counter.ind].user =3D counter.user; - counter_config[counter.ind].unit_mask =3D counter.unit_mask; - - return 0; -} -#endif - -int xenoprofile_get_mode(struct vcpu *curr, const struct cpu_user_regs *re= gs) -{ - if ( !guest_mode(regs) ) - return 2; - - if ( !is_hvm_vcpu(curr) ) - return guest_kernel_mode(curr, regs); - - switch ( hvm_guest_x86_mode(curr) ) - { - case X86_MODE_REAL: - return 1; - case X86_MODE_VM86: - return 0; - default: /* 16BIT | 32BIT | 64BIT */ - return hvm_get_cpl(curr) !=3D 3; - } -} - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 6ba7ae5202ca..f621b99a5fcc 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -50,7 +50,6 @@ #include #include #include -#include =20 /* * opt_nmi: one of 'ignore', 'dom0', or 'fatal'. @@ -1943,9 +1942,6 @@ bool nmi_check_continuation(void) if ( pci_serr_nmicont() ) ret =3D true; =20 - if ( nmi_oprofile_send_virq() ) - ret =3D true; - return ret; } =20 diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 401d5046f6f5..38320b248a90 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -374,17 +374,6 @@ config EFI_SET_VIRTUAL_ADDRESS_MAP =20 If unsure, say N. =20 -config XENOPROF - bool "Xen Oprofile Support" if EXPERT - depends on X86 - help - Xen OProfile (Xenoprof) is a system-wide profiler for Xen virtual - machine environments, capable of profiling the Xen virtual machine - monitor, multiple Linux guest operating systems, and applications - running on them. - - If unsure, say Y. - config XSM bool "Xen Security Modules support" default ARM diff --git a/xen/common/Makefile b/xen/common/Makefile index 8486c0b5106d..92c97d641e67 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -63,7 +63,6 @@ obj-$(CONFIG_HAS_VMAP) +=3D vmap.o obj-y +=3D vsprintf.o obj-y +=3D wait.o obj-bin-y +=3D warning.init.o -obj-$(CONFIG_XENOPROF) +=3D xenoprof.o obj-y +=3D xmalloc_tlsf.o =20 obj-bin-$(CONFIG_X86) +=3D $(foreach n,decompress bunzip2 unxz unlzma lzo = unlzo unlz4 unzstd earlycpio,$(n).init.o) diff --git a/xen/common/compat/xenoprof.c b/xen/common/compat/xenoprof.c deleted file mode 100644 index 8fbd86c24c01..000000000000 --- a/xen/common/compat/xenoprof.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * compat/xenoprof.c - */ - -#include - -#define COMPAT -#define ret_t int - -#define do_xenoprof_op compat_xenoprof_op - -#define xen_oprof_init xenoprof_init -CHECK_oprof_init; -#undef xen_oprof_init - -#define xenoprof_get_buffer compat_oprof_get_buffer -#define xenoprof_op_get_buffer compat_oprof_op_get_buffer -#define xenoprof_arch_counter compat_oprof_arch_counter - -#define xen_domid_t domid_t -#define compat_domid_t domid_compat_t -CHECK_TYPE(domid); -#undef compat_domid_t -#undef xen_domid_t - -#define xen_oprof_passive xenoprof_passive -CHECK_oprof_passive; -#undef xen_oprof_passive - -#define xenoprof_counter compat_oprof_counter - -#include "../xenoprof.c" - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/common/domain.c b/xen/common/domain.c index 93c71bc766b0..2f4fd844441e 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -1452,11 +1451,6 @@ static void cf_check complete_domain_destroy(struct = rcu_head *head) =20 sched_destroy_domain(d); =20 - /* Free page used by xen oprofile buffer. */ -#ifdef CONFIG_XENOPROF - free_xenoprof_pages(d); -#endif - #ifdef CONFIG_MEM_PAGING xfree(d->vm_event_paging); #endif diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c deleted file mode 100644 index 1926a92fe481..000000000000 --- a/xen/common/xenoprof.c +++ /dev/null @@ -1,977 +0,0 @@ -/* - * Copyright (C) 2005 Hewlett-Packard Co. - * written by Aravind Menon & Jose Renato Santos - * (email: xenoprof@groups.hp.com) - * - * arch generic xenoprof and IA64 support. - * dynamic map/unmap xenoprof buffer support. - * Copyright (c) 2006 Isaku Yamahata - * VA Linux Systems Japan K.K. - */ - -#ifndef COMPAT -#include -#include -#include -#include -#include -#include -#include -#include - -/* Override macros from asm/page.h to make them work with mfn_t */ -#undef virt_to_mfn -#define virt_to_mfn(va) _mfn(__virt_to_mfn(va)) - -#define XENOPROF_DOMAIN_IGNORED 0 -#define XENOPROF_DOMAIN_ACTIVE 1 -#define XENOPROF_DOMAIN_PASSIVE 2 - -#define XENOPROF_IDLE 0 -#define XENOPROF_INITIALIZED 1 -#define XENOPROF_COUNTERS_RESERVED 2 -#define XENOPROF_READY 3 -#define XENOPROF_PROFILING 4 - -#ifndef CONFIG_COMPAT -#define XENOPROF_COMPAT(x) false -typedef struct xenoprof_buf xenoprof_buf_t; -#define xenoprof_buf(d, b, field) ACCESS_ONCE((b)->field) -#else -#include -#define XENOPROF_COMPAT(x) ((x)->is_compat) -typedef union { - struct xenoprof_buf native; - struct compat_oprof_buf compat; -} xenoprof_buf_t; -#define xenoprof_buf(d, b, field) ACCESS_ONCE(*(!(d)->xenoprof->is_compat \ - ? &(b)->native.field \ - : &(b)->compat.field)) -#endif - -/* Limit amount of pages used for shared buffer (per domain) */ -#define MAX_OPROF_SHARED_PAGES 32 - -/* Lock protecting the following global state */ -static DEFINE_SPINLOCK(xenoprof_lock); - -static DEFINE_SPINLOCK(pmu_owner_lock); -int pmu_owner =3D 0; -int pmu_hvm_refcount =3D 0; - -struct xenoprof_vcpu { - int event_size; - xenoprof_buf_t *buffer; -}; - -struct xenoprof { - char *rawbuf; - int npages; - int nbuf; - int bufsize; - int domain_type; -#ifdef CONFIG_COMPAT - bool is_compat; -#endif - struct xenoprof_vcpu *vcpu; -}; - -static struct domain *active_domains[MAX_OPROF_DOMAINS]; -static int active_ready[MAX_OPROF_DOMAINS]; -static unsigned int adomains; - -static struct domain *passive_domains[MAX_OPROF_DOMAINS]; -static unsigned int pdomains; - -static unsigned int activated; -static struct domain *xenoprof_primary_profiler; -static int xenoprof_state =3D XENOPROF_IDLE; -static unsigned long backtrace_depth; - -static u64 total_samples; -static u64 invalid_buffer_samples; -static u64 corrupted_buffer_samples; -static u64 lost_samples; -static u64 active_samples; -static u64 passive_samples; -static u64 idle_samples; -static u64 others_samples; - -int acquire_pmu_ownership(int pmu_ownership) -{ - spin_lock(&pmu_owner_lock); - if ( pmu_owner =3D=3D PMU_OWNER_NONE ) - { - pmu_owner =3D pmu_ownership; - goto out; - } - - if ( pmu_owner =3D=3D pmu_ownership ) - goto out; - - spin_unlock(&pmu_owner_lock); - return 0; - out: - if ( pmu_owner =3D=3D PMU_OWNER_HVM ) - pmu_hvm_refcount++; - spin_unlock(&pmu_owner_lock); - return 1; -} - -void release_pmu_ownership(int pmu_ownership) -{ - spin_lock(&pmu_owner_lock); - if ( pmu_ownership =3D=3D PMU_OWNER_HVM ) - pmu_hvm_refcount--; - if ( !pmu_hvm_refcount ) - pmu_owner =3D PMU_OWNER_NONE; - spin_unlock(&pmu_owner_lock); -} - -int is_active(struct domain *d) -{ - struct xenoprof *x =3D d->xenoprof; - return ((x !=3D NULL) && (x->domain_type =3D=3D XENOPROF_DOMAIN_ACTIVE= )); -} - -int is_passive(struct domain *d) -{ - struct xenoprof *x =3D d->xenoprof; - return ((x !=3D NULL) && (x->domain_type =3D=3D XENOPROF_DOMAIN_PASSIV= E)); -} - -static int is_profiled(struct domain *d) -{ - return (is_active(d) || is_passive(d)); -} - -static void xenoprof_reset_stat(void) -{ - total_samples =3D 0; - invalid_buffer_samples =3D 0; - corrupted_buffer_samples =3D 0; - lost_samples =3D 0; - active_samples =3D 0; - passive_samples =3D 0; - idle_samples =3D 0; - others_samples =3D 0; -} - -static void xenoprof_reset_buf(struct domain *d) -{ - int j; - xenoprof_buf_t *buf; - - if ( d->xenoprof =3D=3D NULL ) - { - printk("xenoprof_reset_buf: ERROR - Unexpected " - "Xenoprof NULL pointer \n"); - return; - } - - for ( j =3D 0; j < d->max_vcpus; j++ ) - { - buf =3D d->xenoprof->vcpu[j].buffer; - if ( buf !=3D NULL ) - { - xenoprof_buf(d, buf, event_head) =3D 0; - xenoprof_buf(d, buf, event_tail) =3D 0; - } - } -} - -static int -share_xenoprof_page_with_guest(struct domain *d, mfn_t mfn, int npages) -{ - int i; - - /* Check if previous page owner has released the page. */ - for ( i =3D 0; i < npages; i++ ) - { - struct page_info *page =3D mfn_to_page(mfn_add(mfn, i)); - - if ( (page->count_info & (PGC_allocated|PGC_count_mask)) !=3D 0 ) - { - printk(XENLOG_G_INFO "dom%d mfn %#lx page->count_info %#lx\n", - d->domain_id, mfn_x(mfn_add(mfn, i)), page->count_info); - return -EBUSY; - } - page_set_owner(page, NULL); - } - - for ( i =3D 0; i < npages; i++ ) - share_xen_page_with_guest(mfn_to_page(mfn_add(mfn, i)), d, SHARE_r= w); - - return 0; -} - -static void -unshare_xenoprof_page_with_guest(struct xenoprof *x) -{ - int i, npages =3D x->npages; - mfn_t mfn =3D virt_to_mfn(x->rawbuf); - - for ( i =3D 0; i < npages; i++ ) - { - struct page_info *page =3D mfn_to_page(mfn_add(mfn, i)); - - BUG_ON(page_get_owner(page) !=3D current->domain); - put_page_alloc_ref(page); - } -} - -static void -xenoprof_shared_gmfn_with_guest( - struct domain *d, unsigned long maddr, unsigned long gmaddr, int npage= s) -{ - int i; - - for ( i =3D 0; i < npages; i++, maddr +=3D PAGE_SIZE, gmaddr +=3D PAGE= _SIZE ) - { - BUG_ON(page_get_owner(maddr_to_page(maddr)) !=3D d); - if ( i =3D=3D 0 ) - gdprintk(XENLOG_WARNING, - "xenoprof unsupported with autotranslated guests\n"); - - } -} - -static int alloc_xenoprof_struct( - struct domain *d, int max_samples, int is_passive) -{ - struct vcpu *v; - int nvcpu, npages, bufsize, max_bufsize; - unsigned max_max_samples; - int i; - - nvcpu =3D 0; - for_each_vcpu ( d, v ) - nvcpu++; - - if ( !nvcpu ) - return -EINVAL; - - d->xenoprof =3D xzalloc(struct xenoprof); - if ( d->xenoprof =3D=3D NULL ) - { - printk("alloc_xenoprof_struct(): memory allocation failed\n"); - return -ENOMEM; - } - - d->xenoprof->vcpu =3D xzalloc_array(struct xenoprof_vcpu, d->max_vcpus= ); - if ( d->xenoprof->vcpu =3D=3D NULL ) - { - xfree(d->xenoprof); - d->xenoprof =3D NULL; - printk("alloc_xenoprof_struct(): vcpu array allocation failed\n"); - return -ENOMEM; - } - - bufsize =3D sizeof(struct xenoprof_buf); - i =3D sizeof(struct event_log); -#ifdef CONFIG_COMPAT - d->xenoprof->is_compat =3D is_pv_32bit_domain(is_passive ? hardware_do= main : d); - if ( XENOPROF_COMPAT(d->xenoprof) ) - { - bufsize =3D sizeof(struct compat_oprof_buf); - i =3D sizeof(struct compat_event_log); - } -#endif - - /* reduce max_samples if necessary to limit pages allocated */ - max_bufsize =3D (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu; - max_max_samples =3D ( (max_bufsize - bufsize) / i ) + 1; - if ( (unsigned)max_samples > max_max_samples ) - max_samples =3D max_max_samples; - - bufsize +=3D (max_samples - 1) * i; - npages =3D (nvcpu * bufsize - 1) / PAGE_SIZE + 1; - - d->xenoprof->rawbuf =3D alloc_xenheap_pages(get_order_from_pages(npage= s), 0); - if ( d->xenoprof->rawbuf =3D=3D NULL ) - { - xfree(d->xenoprof->vcpu); - xfree(d->xenoprof); - d->xenoprof =3D NULL; - return -ENOMEM; - } - - for ( i =3D 0; i < npages; ++i ) - clear_page(d->xenoprof->rawbuf + i * PAGE_SIZE); - - d->xenoprof->npages =3D npages; - d->xenoprof->nbuf =3D nvcpu; - d->xenoprof->bufsize =3D bufsize; - d->xenoprof->domain_type =3D XENOPROF_DOMAIN_IGNORED; - - /* Update buffer pointers for active vcpus */ - i =3D 0; - for_each_vcpu ( d, v ) - { - xenoprof_buf_t *buf =3D (xenoprof_buf_t *) - &d->xenoprof->rawbuf[i * bufsize]; - - d->xenoprof->vcpu[v->vcpu_id].event_size =3D max_samples; - d->xenoprof->vcpu[v->vcpu_id].buffer =3D buf; - xenoprof_buf(d, buf, event_size) =3D max_samples; - xenoprof_buf(d, buf, vcpu_id) =3D v->vcpu_id; - - i++; - /* in the unlikely case that the number of active vcpus changes */ - if ( i >=3D nvcpu ) - break; - } - =20 - return 0; -} - -void free_xenoprof_pages(struct domain *d) -{ - struct xenoprof *x; - int order; - - x =3D d->xenoprof; - if ( x =3D=3D NULL ) - return; - - if ( x->rawbuf !=3D NULL ) - { - order =3D get_order_from_pages(x->npages); - free_xenheap_pages(x->rawbuf, order); - } - - xfree(x->vcpu); - xfree(x); - d->xenoprof =3D NULL; -} - -static int active_index(struct domain *d) -{ - int i; - - for ( i =3D 0; i < adomains; i++ ) - if ( active_domains[i] =3D=3D d ) - return i; - - return -1; -} - -static int set_active(struct domain *d) -{ - int ind; - struct xenoprof *x; - - ind =3D active_index(d); - if ( ind < 0 ) - return -EPERM; - - x =3D d->xenoprof; - if ( x =3D=3D NULL ) - return -EPERM; - - x->domain_type =3D XENOPROF_DOMAIN_ACTIVE; - active_ready[ind] =3D 1; - activated++; - - return 0; -} - -static int reset_active(struct domain *d) -{ - int ind; - struct xenoprof *x; - - ind =3D active_index(d); - if ( ind < 0 ) - return -EPERM; - - x =3D d->xenoprof; - if ( x =3D=3D NULL ) - return -EPERM; - - x->domain_type =3D XENOPROF_DOMAIN_IGNORED; - active_ready[ind] =3D 0; - active_domains[ind] =3D NULL; - activated--; - put_domain(d); - - if ( activated <=3D 0 ) - adomains =3D 0; - - return 0; -} - -static void reset_passive(struct domain *d) -{ - struct xenoprof *x; - - if ( d =3D=3D NULL ) - return; - - x =3D d->xenoprof; - if ( x =3D=3D NULL ) - return; - - x->domain_type =3D XENOPROF_DOMAIN_IGNORED; - unshare_xenoprof_page_with_guest(x); -} - -static void reset_active_list(void) -{ - int i; - - for ( i =3D 0; i < adomains; i++ ) - if ( active_ready[i] ) - reset_active(active_domains[i]); - - adomains =3D 0; - activated =3D 0; -} - -static void reset_passive_list(void) -{ - int i; - - for ( i =3D 0; i < pdomains; i++ ) - { - reset_passive(passive_domains[i]); - put_domain(passive_domains[i]); - passive_domains[i] =3D NULL; - } - - pdomains =3D 0; -} - -static int add_active_list(domid_t domid) -{ - struct domain *d; - - if ( adomains >=3D MAX_OPROF_DOMAINS ) - return -E2BIG; - - d =3D get_domain_by_id(domid); - if ( d =3D=3D NULL ) - return -EINVAL; - - active_domains[adomains] =3D d; - active_ready[adomains] =3D 0; - adomains++; - - return 0; -} - -static int add_passive_list(XEN_GUEST_HANDLE_PARAM(void) arg) -{ - struct xenoprof_passive passive; - struct domain *d; - int ret =3D 0; - - if ( pdomains >=3D MAX_OPROF_DOMAINS ) - return -E2BIG; - - if ( copy_from_guest(&passive, arg, 1) ) - return -EFAULT; - - d =3D get_domain_by_id(passive.domain_id); - if ( d =3D=3D NULL ) - return -EINVAL; - - if ( d->xenoprof =3D=3D NULL ) - { - ret =3D alloc_xenoprof_struct(d, passive.max_samples, 1); - if ( ret < 0 ) - { - put_domain(d); - return -ENOMEM; - } - } - - ret =3D share_xenoprof_page_with_guest( - current->domain, virt_to_mfn(d->xenoprof->rawbuf), - d->xenoprof->npages); - if ( ret < 0 ) - { - put_domain(d); - return ret; - } - - d->xenoprof->domain_type =3D XENOPROF_DOMAIN_PASSIVE; - passive.nbuf =3D d->xenoprof->nbuf; - passive.bufsize =3D d->xenoprof->bufsize; - if ( !paging_mode_translate(current->domain) ) - passive.buf_gmaddr =3D __pa(d->xenoprof->rawbuf); - else - xenoprof_shared_gmfn_with_guest( - current->domain, __pa(d->xenoprof->rawbuf), - passive.buf_gmaddr, d->xenoprof->npages); - - if ( __copy_to_guest(arg, &passive, 1) ) - { - put_domain(d); - return -EFAULT; - } - =20 - passive_domains[pdomains] =3D d; - pdomains++; - - return ret; -} - - -/* Get space in the buffer */ -static int xenoprof_buf_space(int head, int tail, int size) -{ - return ((tail > head) ? 0 : size) + tail - head - 1; -} - -/* Check for space and add a sample. Return 1 if successful, 0 otherwise. = */ -static int xenoprof_add_sample(const struct domain *d, - const struct xenoprof_vcpu *v, - uint64_t eip, int mode, int event) -{ - xenoprof_buf_t *buf =3D v->buffer; - int head, tail, size; - - head =3D xenoprof_buf(d, buf, event_head); - tail =3D xenoprof_buf(d, buf, event_tail); - size =3D v->event_size; - =20 - /* make sure indexes in shared buffer are sane */ - if ( (head < 0) || (head >=3D size) || (tail < 0) || (tail >=3D size) ) - { - corrupted_buffer_samples++; - return 0; - } - - if ( xenoprof_buf_space(head, tail, size) > 0 ) - { - xenoprof_buf(d, buf, event_log[head].eip) =3D eip; - xenoprof_buf(d, buf, event_log[head].mode) =3D mode; - xenoprof_buf(d, buf, event_log[head].event) =3D event; - head++; - if ( head >=3D size ) - head =3D 0; - =20 - xenoprof_buf(d, buf, event_head) =3D head; - } - else - { - xenoprof_buf(d, buf, lost_samples)++; - lost_samples++; - return 0; - } - - return 1; -} - -int xenoprof_add_trace(struct vcpu *vcpu, uint64_t pc, int mode) -{ - struct domain *d =3D vcpu->domain; - - /* Do not accidentally write an escape code due to a broken frame. */ - if ( pc =3D=3D XENOPROF_ESCAPE_CODE ) - { - invalid_buffer_samples++; - return 0; - } - - return xenoprof_add_sample(d, &d->xenoprof->vcpu[vcpu->vcpu_id], - pc, mode, 0); -} - -void xenoprof_log_event(struct vcpu *vcpu, const struct cpu_user_regs *reg= s, - uint64_t pc, int mode, int event) -{ - struct domain *d =3D vcpu->domain; - struct xenoprof_vcpu *v; - xenoprof_buf_t *buf; - - total_samples++; - - /* Ignore samples of un-monitored domains. */ - if ( !is_profiled(d) ) - { - others_samples++; - return; - } - - v =3D &d->xenoprof->vcpu[vcpu->vcpu_id]; - if ( v->buffer =3D=3D NULL ) - { - invalid_buffer_samples++; - return; - } - =20 - buf =3D v->buffer; - - /* Provide backtrace if requested. */ - if ( backtrace_depth > 0 ) - { - if ( xenoprof_buf_space(xenoprof_buf(d, buf, event_head), - xenoprof_buf(d, buf, event_tail), - v->event_size) < 2 ) - { - xenoprof_buf(d, buf, lost_samples)++; - lost_samples++; - return; - } - - /* xenoprof_add_sample() will increment lost_samples on failure */ - if ( !xenoprof_add_sample(d, v, XENOPROF_ESCAPE_CODE, mode, - XENOPROF_TRACE_BEGIN) ) - return; - } - - if ( xenoprof_add_sample(d, v, pc, mode, event) ) - { - if ( is_active(vcpu->domain) ) - active_samples++; - else - passive_samples++; - if ( mode =3D=3D 0 ) - xenoprof_buf(d, buf, user_samples)++; - else if ( mode =3D=3D 1 ) - xenoprof_buf(d, buf, kernel_samples)++; - else - xenoprof_buf(d, buf, xen_samples)++; - =20 - } - - if ( backtrace_depth > 0 ) - xenoprof_backtrace(vcpu, regs, backtrace_depth, mode); -} - - - -static int xenoprof_op_init(XEN_GUEST_HANDLE_PARAM(void) arg) -{ - struct domain *d =3D current->domain; - struct xenoprof_init xenoprof_init; - int ret; - - if ( copy_from_guest(&xenoprof_init, arg, 1) ) - return -EFAULT; - - if ( (ret =3D xenoprof_arch_init(&xenoprof_init.num_events, - xenoprof_init.cpu_type)) ) - return ret; - - /* Only the hardware domain may become the primary profiler here becau= se - * there is currently no cleanup of xenoprof_primary_profiler or assoc= iated - * profiling state when the primary profiling domain is shut down or - * crashes. Once a better cleanup method is present, it will be possi= ble to - * allow another domain to be the primary profiler. - */ - xenoprof_init.is_primary =3D=20 - ((xenoprof_primary_profiler =3D=3D d) || - ((xenoprof_primary_profiler =3D=3D NULL) && is_hardware_domain(d)= )); - if ( xenoprof_init.is_primary ) - xenoprof_primary_profiler =3D current->domain; - - return __copy_to_guest(arg, &xenoprof_init, 1) ? -EFAULT : 0; -} - -#define ret_t long - -#endif /* !COMPAT */ - -static int xenoprof_op_get_buffer(XEN_GUEST_HANDLE_PARAM(void) arg) -{ - struct xenoprof_get_buffer xenoprof_get_buffer; - struct domain *d =3D current->domain; - int ret; - - if ( copy_from_guest(&xenoprof_get_buffer, arg, 1) ) - return -EFAULT; - - /* - * We allocate xenoprof struct and buffers only at first time - * get_buffer is called. Memory is then kept until domain is destroyed. - */ - if ( d->xenoprof =3D=3D NULL ) - { - ret =3D alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, = 0); - if ( ret < 0 ) - return ret; - } - else - d->xenoprof->domain_type =3D XENOPROF_DOMAIN_IGNORED; - - ret =3D share_xenoprof_page_with_guest( - d, virt_to_mfn(d->xenoprof->rawbuf), d->xenoprof->npages); - if ( ret < 0 ) - return ret; - - xenoprof_reset_buf(d); - - xenoprof_get_buffer.nbuf =3D d->xenoprof->nbuf; - xenoprof_get_buffer.bufsize =3D d->xenoprof->bufsize; - if ( !paging_mode_translate(d) ) - xenoprof_get_buffer.buf_gmaddr =3D __pa(d->xenoprof->rawbuf); - else - xenoprof_shared_gmfn_with_guest( - d, __pa(d->xenoprof->rawbuf), xenoprof_get_buffer.buf_gmaddr, - d->xenoprof->npages); - - return __copy_to_guest(arg, &xenoprof_get_buffer, 1) ? -EFAULT : 0; -} - -#define NONPRIV_OP(op) ( (op =3D=3D XENOPROF_init) \ - || (op =3D=3D XENOPROF_enable_virq) \ - || (op =3D=3D XENOPROF_disable_virq) \ - || (op =3D=3D XENOPROF_get_buffer)) -=20 -ret_t do_xenoprof_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) -{ - int ret =3D 0; - =20 - if ( (op < 0) || (op > XENOPROF_last_op) ) - { - gdprintk(XENLOG_DEBUG, "invalid operation %d\n", op); - return -EINVAL; - } - - if ( !NONPRIV_OP(op) && (current->domain !=3D xenoprof_primary_profile= r) ) - { - gdprintk(XENLOG_DEBUG, "denied privileged operation %d\n", op); - return -EPERM; - } - - ret =3D xsm_profile(XSM_HOOK, current->domain, op); - if ( ret ) - return ret; - - spin_lock(&xenoprof_lock); - =20 - switch ( op ) - { - case XENOPROF_init: - ret =3D xenoprof_op_init(arg); - if ( (ret =3D=3D 0) && - (current->domain =3D=3D xenoprof_primary_profiler) ) - xenoprof_state =3D XENOPROF_INITIALIZED; - break; - - case XENOPROF_get_buffer: - if ( !acquire_pmu_ownership(PMU_OWNER_XENOPROF) ) - { - ret =3D -EBUSY; - break; - } - ret =3D xenoprof_op_get_buffer(arg); - break; - - case XENOPROF_reset_active_list: - reset_active_list(); - ret =3D 0; - break; - - case XENOPROF_reset_passive_list: - reset_passive_list(); - ret =3D 0; - break; - - case XENOPROF_set_active: - { - domid_t domid; - if ( xenoprof_state !=3D XENOPROF_INITIALIZED ) - { - ret =3D -EPERM; - break; - } - if ( copy_from_guest(&domid, arg, 1) ) - { - ret =3D -EFAULT; - break; - } - ret =3D add_active_list(domid); - break; - } - - case XENOPROF_set_passive: - if ( xenoprof_state !=3D XENOPROF_INITIALIZED ) - { - ret =3D -EPERM; - break; - } - ret =3D add_passive_list(arg); - break; - - case XENOPROF_reserve_counters: - if ( xenoprof_state !=3D XENOPROF_INITIALIZED ) - { - ret =3D -EPERM; - break; - } - ret =3D xenoprof_arch_reserve_counters(); - if ( !ret ) - xenoprof_state =3D XENOPROF_COUNTERS_RESERVED; - break; - - case XENOPROF_counter: - if ( (xenoprof_state !=3D XENOPROF_COUNTERS_RESERVED) || - (adomains =3D=3D 0) ) - { - ret =3D -EPERM; - break; - } - ret =3D xenoprof_arch_counter(arg); - break; - - case XENOPROF_setup_events: - if ( xenoprof_state !=3D XENOPROF_COUNTERS_RESERVED ) - { - ret =3D -EPERM; - break; - } - ret =3D xenoprof_arch_setup_events(); - if ( !ret ) - xenoprof_state =3D XENOPROF_READY; - break; - - case XENOPROF_enable_virq: - { - int i; - - if ( current->domain =3D=3D xenoprof_primary_profiler ) - { - if ( xenoprof_state !=3D XENOPROF_READY ) - { - ret =3D -EPERM; - break; - } - xenoprof_arch_enable_virq(); - xenoprof_reset_stat(); - for ( i =3D 0; i < pdomains; i++ ) - xenoprof_reset_buf(passive_domains[i]); - } - xenoprof_reset_buf(current->domain); - ret =3D set_active(current->domain); - break; - } - - case XENOPROF_start: - ret =3D -EPERM; - if ( (xenoprof_state =3D=3D XENOPROF_READY) && - (activated =3D=3D adomains) ) - ret =3D xenoprof_arch_start(); - if ( ret =3D=3D 0 ) - xenoprof_state =3D XENOPROF_PROFILING; - break; - - case XENOPROF_stop: - { - struct domain *d; - struct vcpu *v; - int i; - - if ( xenoprof_state !=3D XENOPROF_PROFILING ) - { - ret =3D -EPERM; - break; - } - xenoprof_arch_stop(); - - /* Flush remaining samples. */ - for ( i =3D 0; i < adomains; i++ ) - { - if ( !active_ready[i] ) - continue; - d =3D active_domains[i]; - for_each_vcpu(d, v) - send_guest_vcpu_virq(v, VIRQ_XENOPROF); - } - xenoprof_state =3D XENOPROF_READY; - break; - } - - case XENOPROF_disable_virq: - { - struct xenoprof *x; - if ( (xenoprof_state =3D=3D XENOPROF_PROFILING) &&=20 - (is_active(current->domain)) ) - { - ret =3D -EPERM; - break; - } - if ( (ret =3D reset_active(current->domain)) !=3D 0 ) - break; - x =3D current->domain->xenoprof; - unshare_xenoprof_page_with_guest(x); - release_pmu_ownership(PMU_OWNER_XENOPROF); - break; - } - - case XENOPROF_release_counters: - ret =3D -EPERM; - if ( (xenoprof_state =3D=3D XENOPROF_COUNTERS_RESERVED) || - (xenoprof_state =3D=3D XENOPROF_READY) ) - { - xenoprof_state =3D XENOPROF_INITIALIZED; - xenoprof_arch_release_counters(); - xenoprof_arch_disable_virq(); - reset_passive_list(); - ret =3D 0; - } - break; - - case XENOPROF_shutdown: - ret =3D -EPERM; - if ( xenoprof_state =3D=3D XENOPROF_INITIALIZED ) - { - activated =3D 0; - adomains=3D0; - xenoprof_primary_profiler =3D NULL; - backtrace_depth=3D0; - ret =3D 0; - } - break; - =20 - case XENOPROF_set_backtrace: - ret =3D 0; - if ( !xenoprof_backtrace_supported() ) - ret =3D -EINVAL; - else if ( copy_from_guest(&backtrace_depth, arg, 1) ) - ret =3D -EFAULT; - break; - - case XENOPROF_ibs_counter: - if ( (xenoprof_state !=3D XENOPROF_COUNTERS_RESERVED) || - (adomains =3D=3D 0) ) - { - ret =3D -EPERM; - break; - } - ret =3D xenoprof_arch_ibs_counter(arg); - break; - - case XENOPROF_get_ibs_caps: - ret =3D ibs_caps; - break; - - default: - ret =3D -ENOSYS; - } - - spin_unlock(&xenoprof_lock); - - if ( ret < 0 ) - gdprintk(XENLOG_DEBUG, "operation %d failed: %d\n", op, ret); - - return ret; -} - -#if defined(CONFIG_COMPAT) && !defined(COMPAT) -#undef ret_t -#include "compat/xenoprof.c" -#endif - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/include/Makefile b/xen/include/Makefile index e71f419e8c22..b3184a395b50 100644 --- a/xen/include/Makefile +++ b/xen/include/Makefile @@ -31,7 +31,6 @@ headers-$(CONFIG_HVM) +=3D compat/hvm/hvm_vcpu.h headers-$(CONFIG_HYPFS) +=3D compat/hypfs.h headers-$(CONFIG_KEXEC) +=3D compat/kexec.h headers-$(CONFIG_TRACEBUFFER) +=3D compat/trace.h -headers-$(CONFIG_XENOPROF) +=3D compat/xenoprof.h headers-$(CONFIG_XSM_FLASK) +=3D compat/xsm/flask_op.h =20 headers-n :=3D $(sort $(filter-out $(headers-y),$(headers-n) $(headers-))) diff --git a/xen/include/hypercall-defs.c b/xen/include/hypercall-defs.c index 5782cdfd1496..63755bb8df6e 100644 --- a/xen/include/hypercall-defs.c +++ b/xen/include/hypercall-defs.c @@ -127,9 +127,6 @@ argo_op(unsigned int cmd, void *arg1, void *arg2, unsig= ned long arg3, unsigned l #ifdef CONFIG_PV iret() nmi_op(unsigned int cmd, void *arg) -#ifdef CONFIG_XENOPROF -xenoprof_op(int op, void *arg) -#endif #endif /* CONFIG_PV */ =20 #ifdef CONFIG_COMPAT @@ -269,9 +266,6 @@ xsm_op compat do co= mpat do do nmi_op compat do - - - sched_op compat do compat do do callback_op compat do - - - -#ifdef CONFIG_XENOPROF -xenoprof_op compat do - - - -#endif event_channel_op do do do:1 do:1 do:1 physdev_op compat do hvm hvm do_= arm #ifdef CONFIG_HVM diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 7f15204c3885..b12fd10e6315 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -106,7 +106,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); #define __HYPERVISOR_nmi_op 28 #define __HYPERVISOR_sched_op 29 #define __HYPERVISOR_callback_op 30 -#define __HYPERVISOR_xenoprof_op 31 +#define __HYPERVISOR_xenoprof_op 31 /* Dropped in Xen 4.22 */ #define __HYPERVISOR_event_channel_op 32 #define __HYPERVISOR_physdev_op 33 #define __HYPERVISOR_hvm_op 34 diff --git a/xen/include/public/xenoprof.h b/xen/include/public/xenoprof.h index 2298b6759ed3..f97a67042e07 100644 --- a/xen/include/public/xenoprof.h +++ b/xen/include/public/xenoprof.h @@ -3,7 +3,7 @@ * xenoprof.h * * Interface for enabling system wide profiling based on hardware performa= nce - * counters + * counters. Dropped from Xen in 4.22. * * Copyright (C) 2005 Hewlett-Packard Co. * Written by Aravind Menon & Jose Renato Santos diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 1f77e0869b5d..dc06f6f1131a 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -573,9 +573,6 @@ struct domain /* Control-plane tools handle for this domain. */ xen_domain_handle_t handle; =20 - /* OProfile support. */ - struct xenoprof *xenoprof; - /* Domain watchdog. */ #define NR_DOMAIN_WATCHDOG_TIMERS 2 spinlock_t watchdog_lock; diff --git a/xen/include/xen/xenoprof.h b/xen/include/xen/xenoprof.h deleted file mode 100644 index c3dac447d334..000000000000 --- a/xen/include/xen/xenoprof.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************= ***** - * xenoprof.h - *=20 - * Xenoprof: Xenoprof enables performance profiling in Xen - *=20 - * Copyright (C) 2005 Hewlett-Packard Co. - * written by Aravind Menon & Jose Renato Santos - */ - -#ifndef __XEN_XENOPROF_H__ -#define __XEN_XENOPROF_H__ - -#define PMU_OWNER_NONE 0 -#define PMU_OWNER_XENOPROF 1 -#define PMU_OWNER_HVM 2 - -#ifdef CONFIG_XENOPROF - -#include -#include - -struct domain; -struct vcpu; -struct cpu_user_regs; - -int acquire_pmu_ownership(int pmu_ownership); -void release_pmu_ownership(int pmu_ownership); - -int is_active(struct domain *d); -int is_passive(struct domain *d); -void free_xenoprof_pages(struct domain *d); - -int xenoprof_add_trace(struct vcpu *, uint64_t pc, int mode); - -void xenoprof_log_event(struct vcpu *, const struct cpu_user_regs *, - uint64_t pc, int mode, int event); - -#else -static inline int acquire_pmu_ownership(int pmu_ownership) -{ - return 1; -} - -static inline void release_pmu_ownership(int pmu_ownership) -{ -} -#endif /* CONFIG_XENOPROF */ - -#endif /* __XEN__XENOPROF_H__ */ diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index e801dbcdbaef..b8fd7aeedd9e 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -278,13 +278,6 @@ static XSM_INLINE int cf_check xsm_console_io( return xsm_default_action(XSM_PRIV, d, NULL); } =20 -static XSM_INLINE int cf_check xsm_profile( - XSM_DEFAULT_ARG struct domain *d, int op) -{ - XSM_ASSERT_ACTION(XSM_HOOK); - return xsm_default_action(action, d, NULL); -} - static XSM_INLINE int cf_check xsm_kexec(XSM_DEFAULT_VOID) { XSM_ASSERT_ACTION(XSM_PRIV); diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 2d831d774541..cc32a6c09104 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -101,8 +101,6 @@ struct xsm_ops { =20 int (*console_io)(struct domain *d, int cmd); =20 - int (*profile)(struct domain *d, int op); - int (*kexec)(void); int (*schedop_shutdown)(struct domain *d1, struct domain *d2); =20 @@ -450,11 +448,6 @@ static inline int xsm_console_io(xsm_default_t def, st= ruct domain *d, int cmd) return alternative_call(xsm_ops.console_io, d, cmd); } =20 -static inline int xsm_profile(xsm_default_t def, struct domain *d, int op) -{ - return alternative_call(xsm_ops.profile, d, op); -} - static inline int xsm_kexec(xsm_default_t def) { return alternative_call(xsm_ops.kexec); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 96dc82ac2e29..244ef557528b 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -61,8 +61,6 @@ static const struct xsm_ops __initconst_cf_clobber dummy_= ops =3D { =20 .console_io =3D xsm_console_io, =20 - .profile =3D xsm_profile, - .kexec =3D xsm_kexec, .schedop_shutdown =3D xsm_schedop_shutdown, =20 diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 9f3915617cc8..b250b2706535 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #ifdef CONFIG_HAS_PCI_MSI #include @@ -512,38 +511,6 @@ static int cf_check flask_console_io(struct domain *d,= int cmd) return domain_has_xen(d, perm); } =20 -static int cf_check flask_profile(struct domain *d, int op) -{ - uint32_t perm; - - switch ( op ) - { - case XENOPROF_init: - case XENOPROF_enable_virq: - case XENOPROF_disable_virq: - case XENOPROF_get_buffer: - perm =3D XEN__NONPRIVPROFILE; - break; - case XENOPROF_reset_active_list: - case XENOPROF_reset_passive_list: - case XENOPROF_set_active: - case XENOPROF_set_passive: - case XENOPROF_reserve_counters: - case XENOPROF_counter: - case XENOPROF_setup_events: - case XENOPROF_start: - case XENOPROF_stop: - case XENOPROF_release_counters: - case XENOPROF_shutdown: - perm =3D XEN__PRIVPROFILE; - break; - default: - return avc_unknown_permission("xenoprof op", op); - } - - return domain_has_xen(d, perm); -} - static int cf_check flask_kexec(void) { return domain_has_xen(current->domain, XEN__KEXEC); @@ -1930,8 +1897,6 @@ static const struct xsm_ops __initconst_cf_clobber fl= ask_ops =3D { =20 .console_io =3D flask_console_io, =20 - .profile =3D flask_profile, - .kexec =3D flask_kexec, .schedop_shutdown =3D flask_schedop_shutdown, =20 diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/acc= ess_vectors index 51a1577a66c7..ce907d50a45e 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -38,10 +38,6 @@ class xen readapic # PHYSDEVOP_apic_write writeapic -# Most XENOPROF_* - privprofile -# XENOPROF_{init,enable_virq,disable_virq,get_buffer} - nonprivprofile # kexec hypercall kexec # XENPF_firmware_info, XENPF_efi_runtime_call base-commit: c36ddba28e314e9350f4024972023b52e34ec73e --=20 2.39.5