Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760414AbcLWONB (ORCPT ); Fri, 23 Dec 2016 09:13:01 -0500 Received: from mail-by2nam01on0041.outbound.protection.outlook.com ([104.47.34.41]:6241 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751257AbcLWOM6 (ORCPT ); Fri, 23 Dec 2016 09:12:58 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Suravee.Suthikulpanit@amd.com; From: Suravee Suthikulpanit To: , CC: , , , , Suravee Suthikulpanit Subject: [PATCH V6 7/7] perf/amd/iommu: Enable support for multiple IOMMUs Date: Fri, 23 Dec 2016 20:38:50 +0700 Message-ID: <1482500330-5606-8-git-send-email-Suravee.Suthikulpanit@amd.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1482500330-5606-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1482500330-5606-1-git-send-email-Suravee.Suthikulpanit@amd.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: BN6PR1301CA0025.namprd13.prod.outlook.com (10.174.84.166) To DM5PR12MB1449.namprd12.prod.outlook.com (10.172.38.138) X-MS-Office365-Filtering-Correlation-Id: 11b5e9ae-1d12-4506-26d7-08d42b39328b X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:DM5PR12MB1449; X-Microsoft-Exchange-Diagnostics: 1;DM5PR12MB1449;3:MOyJUwqwyZHv8RYgE3OhxNzHLc3guiEC5tgzSOWrTFaNBWbE9S0uS574v9CsXqtQngvlBcpA25ExkLibKDdwZ3Ejk8e4kTWyt5PpNIyeGp7KI+a/JV3/bnfihhLEc/7Lg4VQzApv6u6V31Aws3TFlqX6XCu9Gjzaefy3F5MCe/+XPIr/+PCiXXzWH3YUtRvybB67dX/vmRj4rHO4IRpCzeQiEECGIv7p9jvdA8tgSjVDRuM4QDNVqy+gPeLASxduFIFCtihAMxyVtKo6f46KgQ==;25:nyS1M8BC5sVbS59US/JxqgC3QGVq65EsCbiokMk5Jb77SKsKXaL3ODFvK/YG7rp5XJSUYdHRU0HZK1l9FgWZpGLVJfzafxzc9QCeT7Fd96zcpKLMZ4SL+0FDzsxTXS2YKvDyE38vzZVDHLKl+S1FNQExKw4dxJEesjnLmI1lEERSngXOgFg7uIxQBVZUofmKARdzPyIqv24Ee7MS8FfjbymaleeN0pdYFXogo9gyU1rOjwAexOa/HcJpIrhR+TkjOthQgQ28ccbWgIiiQvCK/TiEwMVMGvinOSuKVF8RwV2BoI5D9oJtaStC+GCiqmrIfMuxnuLIGUVGfJCAJ8a4Bs+d+h0Sb+XeqwG83sozCFQ8f0iJBtz8sEzT5nVVaW/iDp8LLHWz7GMukGCucaok6lg3L+7Lbu4IgDjZp+Gbpn0YDNU+V2T0/8hOn5TrJ2K6pHzi0mC3Ws3LQ+KS4m2Kwg== X-Microsoft-Exchange-Diagnostics: 1;DM5PR12MB1449;31:4l7um+pwJXmle0DxOmM8mr2ypcD/Q8EBqCWfK9EKClV/X9JZKt5UFaG1pfVk/JAaUKizLaDDl2viqo7bjmihXPGdF481aBiZ/JO1bdLUMsuwmYYuYQV4lK25s+A9Qoe5zTLgvfMqMsTvn+2KWPqlOqS8T4V4mnxtCcQxOnh6dtY7ie7X0VYnEhgPAEk4hy/yhYAc5UcurDiFsKZHtQivr7XFH46O0ugMmTR6QOgSyb0+Kb9GgtNao4PwEIVI7u7M/FYn1AhstqJ9viUaNtCCDg==;20:jb3kmIDVHBM8JoLvgrJqSruEyw49o+7O82kvide+TLTCsCIdovdjQOaTTtfJ7bGsu+AHBTi+pRXY46la48y9xwshDOAluUQcRVlrGOShhC7uS6Xo7dzAYezNZlZlr/pRKzdcteZW3FP2SVauabXsf47CmBv8bxioh71TdHrWkiNVGnCu5LDlJznNw8mYDPJswv3699Un+3HqeIEhzQ2kWjTIC1OzHkZj7y2BSJLi5tzvazK7VsA9+02JsmHtFs4RUnr8qa68HsBT/0b+EEiXi3gr3UV1EthHYJBeCMAhaSxeZVHcyGt4n23p3j1EnlIJMjpHSk+7UdrmctW1tTTFUfa3I46Wsl9etuFo6i563w+RSVXdkABwGYZHGK1wsmZjd4HECjdw5wiU0A5bqkFoiitFRAH+3LX7A7cFW/ne+NYTf7YzjHn6Ij/sLRfaR3iKvPiTwJA0R9rzk02YK6Lstz1Db9ATX4JVNCQS+6g0KF/Y8FLi1F75TZMnC/Yc+zrl X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6055026)(6041248)(20161123564025)(20161123562025)(20161123555025)(20161123558021)(20161123560025)(6072148);SRVR:DM5PR12MB1449;BCL:0;PCL:0;RULEID:;SRVR:DM5PR12MB1449; X-Microsoft-Exchange-Diagnostics: 1;DM5PR12MB1449;4:SMSd0xOs/QH7s3pS4fys/jkiKZo0LXuy+OWZ/87CykW0432J+fWydAcjlPZeGV5WDf+dhzcKjPYAlgob39BcZrMGlvRajdfzd3J3Iamdzxj8ZYz+swt/u4PpXS63S+qk139grX8al0hQpYPl9eu9ElOZ9o0APliW89+A2sXTX3YTHYsurQsfpq66eappZHjs68AWb/ptnwywIt7m0xhzXx//GJh67KzWlKtXAagWX/I4xlEgTRsVj6RGSk/sN2AwrI13qgaqUxq9bSAgra5o17WO1tA6O1pXtvoMQVdP/J+7x6VxO+Xxw8faUQZPb4ZltHmoUuSqvCS0h/h6H1ZuRQdmHQq9TRUsn52w8rHK8r2ieI6gKTFvlJ2h9Poq1/aAVrtxlE2D2cXDqyVLi8A0g02Nb8XDfzU8iU+QsHpRMZbObdMq0fC/+159y8I885WYq+/CCPXA9MOU6GZitTCc+Eo7dRVhYOezpyy/8h0PJ9QWO/6V/L0dgRcUjqZ/OGyeCKr+uF0Ezk3q0Nff9NRQb5N6t+nlKVMt0U0MYFpnre2MjPpMlaXc718iiT05G8Ax2ENJzvuivKTJL6a07hWgk3Bha9gbKQxMEAh5KJmgSFQR1GUB56grwDY3MSbDRwFzQwqF4tqZjG7z5mkdTGF+SIIxw7c6EhZE73VblhPJo2o= X-Forefront-PRVS: 016572D96D X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(7916002)(39450400003)(39840400002)(39410400002)(39850400002)(39860400002)(189002)(199003)(305945005)(86362001)(47776003)(7736002)(50226002)(81166006)(81156014)(5003940100001)(68736007)(8676002)(48376002)(106356001)(50466002)(3846002)(6116002)(4326007)(2906002)(50986999)(53416004)(92566002)(66066001)(42186005)(97736004)(105586002)(36756003)(5001770100001)(38730400001)(6666003)(76176999)(101416001)(5660300001)(189998001)(25786008)(2950100002)(6486002);DIR:OUT;SFP:1101;SCL:1;SRVR:DM5PR12MB1449;H:ssuthiku-ubuntu-lt.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DM5PR12MB1449;23:YRU3+o5Yy+lXNwBLJFLQWlYLQe/guScaJYAFIVeMA?= =?us-ascii?Q?skyTaIoWMapJPEkwa9DQWRBN0G2gLOcHDhVQRoVKbsL6dSS3924bRRYKYLo7?= =?us-ascii?Q?AtiYMZ/93ouZuh7fsiXJ3W2JWcfS9XSVSIWlJ4lWvLDJWylRx9rc5vAQNZc9?= =?us-ascii?Q?/Y6LQD+AO1MEqN8rEResOvX2lqjdRXnGRYFGv3LqFeEvzWnf0k+OWKY+7Kaw?= =?us-ascii?Q?3L+NLrHhW46Bpo3qV6P19GW0mNlu8Umke5kvBygT3a7+CjacZA7Oarrnsfm0?= =?us-ascii?Q?eJhNQwrI2a0J91inT9aQ38wGD84GSmZxX6h99QbNJIqbUul2/x5fM4Xt3Ftf?= =?us-ascii?Q?4xC2t6RcYn2rTFfHcg8R7fbbB+aba/2FiBGC5GiaZqoHpqR+TiNtWVPeKfct?= =?us-ascii?Q?pEx3VCF/zCMIqrsowRxeJ3X1rJEDzydMxnabanzogAU29pbq6IIeIF7o0P6X?= =?us-ascii?Q?2yVAgzdZHmuyMy5g/ht+8UzyGQrcwJ0NQNRJlIDowHsDmLYyA1krYpjzU10Q?= =?us-ascii?Q?0koQdruz6ysXKYzeZvXW0xgTdvq5tbCr67SMsQ4Wu+ixLxVMVo4wSFmlfUIL?= =?us-ascii?Q?LB7uRoi54yhvtrPqu2+95oa3lmCmrlf/SRghObru0UBo7f0EBrooyrnPQkvy?= =?us-ascii?Q?ulA4rRJ3k5E7ZwfesPaT+hCB4ejzaW7C/gcAbF8Ed6yikSY9kVlpf4bdmfmb?= =?us-ascii?Q?ECuc+aHjSX6XRa/MzHO+Xn1xLzaIHxaXAuVtZ8qYItU0W1tNowciarn+TSHq?= =?us-ascii?Q?0RYnrHME95+nqNgyNKqHg9C+V/XQEPn791YYkdEKboieYDE9Ck5C/LzKpxej?= =?us-ascii?Q?loDD6osbFfJBthB9xacoHtUGFlVJUC2gS935xkDc8DKH8QcEzMfdAO1VCqL6?= =?us-ascii?Q?8F777OeYgxnVMFGz8u3epKGPNwjpJAWskNwDsPgEpGqgKHv+VgERgQce541D?= =?us-ascii?Q?Aa1d3P+s0n+HVexnBixq9yXzkMfqElZUexsl5bz1J/eI/9eJdzr7JFj/URFn?= =?us-ascii?Q?MgadVm/EJOiuaX2iTV7GzNmiCQIIvVO8QwqDELz+jHET6ntzUYPk42iuYiM5?= =?us-ascii?Q?v/YUuFipFI7PlnIHSlRv6yFEE5QPD8teTGa7GodTtMfarddPrR0reu0SZVtt?= =?us-ascii?Q?SrIL4wZG5pVFoRi2J5OIQ6aP7xs99h9?= X-Microsoft-Exchange-Diagnostics: 1;DM5PR12MB1449;6:7lO9PrKd2/gMtasYoS1b59w4heCZevLhEYWfOAw2PprsJbRB/TvI9A7bjRp4veDyz5bAdxerGHut3FX/7y0gL6bVDfpu/hQe6GupUyHF2fPqt5/FweVsGgTuzwZMe5Z94GX+Wnn6+V45ItV2YGlYS2wCgtyj7lGsoUTYa8YY49zGIDlukHCGuphWRx7uiBXns8R7R3/0tERyOdARNHK1g4H7Wx6zNl7vytd/ZKJfcCOwbl1nr6IDxVtJcaOy2qOCYnvPsT0rYCHOG3aFg/ipsybO7Ue/zLm9fFUlp+CPWe7+jaODFsKhZJN1glDWUKcoCdnpX3lVqpR+qs6yuV4GQ0KW1U941LjimlFkjRxnbaX7QXm7coftmOfiEwRifNdwTk4Lo9lE+gUO2uCh3eTmrMATlm60oMMaa42mVrFWkOCAQcbcy93Ua74mlrDdncTq44ISsPndYjcSzeTKuy77cA==;5:1kzRdrIzG89J3t96xPktRCYr5huwPTPJk+3zXNp8S4SwKPlCm3LsaY+iblzFMkIfm82CZhyugvkaBsaU2MR/4YjVFeF6ro+6X02wdRNx66xyf/G/MYjtELv8jMHTcpXYgtiHcP1R3aHWjptJiT6xCQ==;24:ETgYdpBJWbviNNxmx5cKmLtdWhOsm0c4LU+vWcxteRJCsZiYJjTqfnKz+wXv7WatpaAirY+N1uHE/+sKbPWBGUSIipgkUFeq6WnErfPbKt0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;DM5PR12MB1449;7:h+ZBsfJOoQdTNHuliRfJMhbd6TlHdjOF4BJlqYfZ/h+zmn8dB/ucR03KuWF2C9b5/DxT54H4M/DO0u0MPDTT2RTLgkPhyaZ19bJgg0BRteHHGaclVCS7nt+gruomONLRSS1OFkSJWk70AWWkkS3TkclgZQSYdxUenaN0SL0+SfMDYKrFYaiChZFPTQC5ww+6qYHzbeUfctEgcfvCzkAI5x3M0UA6IcGBX0GXF+vIX/XnYuLH3X0YlCVJt25h5K4e6fQJa6pe8ETeMndeWQbUsjuF4uVGTkYzZsUB3q7AEifyvS38SHSA1vbowbo9siR1/SB45g0n/1UtnA1+mnNq2TOmaZh5fNntp1i/8fd/dVSoNmQJsEWH/5sUtB3F1wdMG2ETYd3iEGlvgrMIs0rTUNoV73Bomm1tVbR2WO+annTSiuiy78NMQ/AXBXU6jbOyhrR7MfkH7A2swd992B1sBQ==;20:anEd26z/EIdeyiyp99T4Ls5zmh0MmvMfZqlErB1eU7Aia0WJ0ki8ci4ZMpR4jjf57FT0ZEPAtox/KXrawFz+I8ZVoDZAennqXCjw2Tc5741b1npzR3yY7ZlDFuDbBDRXO3rJMgXm3qXpFxr7v8pheB24MLDa26tnhRwGqy2YnhXZoboyvuyVl2Y6Vlws6ri8BzN460+FZ9zB8XNOSLBU2LikHip3olWg22G81bYxw775OP3BC/FdCZ4LAwQeGVVk X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Dec 2016 13:39:59.3218 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB1449 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7908 Lines: 260 This patch adds multi-IOMMU support for perf by exposing an AMD IOMMU PMU for each IOMMU found in the system via: /sys/device/amd_iommu_x /* where x is the IOMMU index. */ This allows users to specify different events to be programed onto performance counters of each IOMMU. Cc: Peter Zijlstra Cc: Borislav Petkov Signed-off-by: Suravee Suthikulpanit --- arch/x86/events/amd/iommu.c | 119 ++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c index 2403c78..5fd97b5 100644 --- a/arch/x86/events/amd/iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -35,10 +35,13 @@ #define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xFFFFULL) #define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xFFFFULL) -static struct perf_amd_iommu __perf_iommu; +#define PERF_AMD_IOMMU_NAME_SZ 16 struct perf_amd_iommu { + struct list_head list; struct pmu pmu; + uint idx; + char name[PERF_AMD_IOMMU_NAME_SZ]; u8 max_banks; u8 max_counters; u64 cntr_assign_mask; @@ -46,6 +49,8 @@ struct perf_amd_iommu { const struct attribute_group *attr_groups[4]; }; +LIST_HEAD(perf_amd_iommu_list); + #define format_group attr_groups[0] #define cpumask_group attr_groups[1] #define events_group attr_groups[2] @@ -204,8 +209,7 @@ static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu, static int perf_iommu_event_init(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; - struct perf_amd_iommu *perf_iommu; - u64 config, config1; + struct perf_amd_iommu *pi = container_of(event->pmu, struct perf_amd_iommu, pmu); /* test the event attr type check for PMU enumeration */ if (event->attr.type != event->pmu->type) @@ -227,27 +231,17 @@ static int perf_iommu_event_init(struct perf_event *event) if (event->cpu < 0) return -EINVAL; - perf_iommu = &__perf_iommu; - - if (event->pmu != &perf_iommu->pmu) - return -ENOENT; - - if (perf_iommu) { - config = event->attr.config; - config1 = event->attr.config1; - } else { - return -EINVAL; - } - /* update the hw_perf_event struct with the iommu config data */ - hwc->config = config; - hwc->extra_reg.config = config1; + hwc->idx = pi->idx; + hwc->config = event->attr.config; + hwc->extra_reg.config = event->attr.config1; return 0; } static void perf_iommu_enable_event(struct perf_event *ev) { + struct hw_perf_event *hwc = &ev->hw; u8 csource = _GET_CSOURCE(ev); u16 devid = _GET_DEVID(ev); u8 bank = _GET_BANK(ev); @@ -255,33 +249,34 @@ static void perf_iommu_enable_event(struct perf_event *ev) u64 reg = 0ULL; reg = csource; - amd_iommu_pc_set_reg(0, devid, bank, cntr, + amd_iommu_pc_set_reg(hwc->idx, devid, bank, cntr, IOMMU_PC_COUNTER_SRC_REG, ®); reg = devid | (_GET_DEVID_MASK(ev) << 32); if (reg) reg |= BIT(31); - amd_iommu_pc_set_reg(0, devid, bank, cntr, + amd_iommu_pc_set_reg(hwc->idx, devid, bank, cntr, IOMMU_PC_DEVID_MATCH_REG, ®); reg = _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32); if (reg) reg |= BIT(31); - amd_iommu_pc_set_reg(0, devid, bank, cntr, + amd_iommu_pc_set_reg(hwc->idx, devid, bank, cntr, IOMMU_PC_PASID_MATCH_REG, ®); reg = _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32); if (reg) reg |= BIT(31); - amd_iommu_pc_set_reg(0, devid, bank, cntr, + amd_iommu_pc_set_reg(hwc->idx, devid, bank, cntr, IOMMU_PC_DOMID_MATCH_REG, ®); } static void perf_iommu_disable_event(struct perf_event *event) { + struct hw_perf_event *hwc = &event->hw; u64 reg = 0ULL; - amd_iommu_pc_set_reg(0, _GET_DEVID(event), _GET_BANK(event), + amd_iommu_pc_set_reg(hwc->idx, _GET_DEVID(event), _GET_BANK(event), _GET_CNTR(event), IOMMU_PC_COUNTER_SRC_REG, ®); } @@ -301,7 +296,7 @@ static void perf_iommu_start(struct perf_event *event, int flags) val = local64_read(&hwc->prev_count); - amd_iommu_pc_set_counter(0, _GET_BANK(event), _GET_CNTR(event), &val); + amd_iommu_pc_set_counter(hwc->idx, _GET_BANK(event), _GET_CNTR(event), &val); enable: perf_iommu_enable_event(event); perf_event_update_userpage(event); @@ -314,7 +309,7 @@ static void perf_iommu_read(struct perf_event *event) s64 delta; struct hw_perf_event *hwc = &event->hw; - if (amd_iommu_pc_get_counter(0, _GET_BANK(event), _GET_CNTR(event), &cnt)) + if (amd_iommu_pc_get_counter(hwc->idx, _GET_BANK(event), _GET_CNTR(event), &cnt)) return; /* IOMMU pc counter register is only 48 bits */ @@ -417,14 +412,20 @@ static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu) static __init void amd_iommu_pc_exit(void) { - if (__perf_iommu.events_group != NULL) { - kfree(__perf_iommu.events_group); - __perf_iommu.events_group = NULL; + struct perf_amd_iommu *pi, *next; + + list_for_each_entry_safe(pi, next, &perf_amd_iommu_list, list) { + list_del(&pi->list); + + kfree(pi->events_group); + pi->events_group = NULL; + + kfree(pi); } } -static __init int _init_perf_amd_iommu( - struct perf_amd_iommu *perf_iommu, char *name) +static __init int +init_one_perf_amd_iommu(struct perf_amd_iommu *perf_iommu, uint idx) { int ret; @@ -441,54 +442,62 @@ static __init int _init_perf_amd_iommu( if (_init_events_attrs(perf_iommu) != 0) pr_err("Only support raw events.\n"); - perf_iommu->max_banks = amd_iommu_pc_get_max_banks(0); - perf_iommu->max_counters = amd_iommu_pc_get_max_counters(0); + snprintf(perf_iommu->name, PERF_AMD_IOMMU_NAME_SZ, "amd_iommu_%u", idx); + perf_iommu->idx = idx; + perf_iommu->max_banks = amd_iommu_pc_get_max_banks(idx); + perf_iommu->max_counters = amd_iommu_pc_get_max_counters(idx); if (!perf_iommu->max_banks || !perf_iommu->max_counters) return -EINVAL; /* Init null attributes */ perf_iommu->null_group = NULL; + + /* Setting up PMU */ + perf_iommu->pmu.event_init = perf_iommu_event_init, + perf_iommu->pmu.add = perf_iommu_add, + perf_iommu->pmu.del = perf_iommu_del, + perf_iommu->pmu.start = perf_iommu_start, + perf_iommu->pmu.stop = perf_iommu_stop, + perf_iommu->pmu.read = perf_iommu_read, + perf_iommu->pmu.task_ctx_nr = perf_invalid_context; perf_iommu->pmu.attr_groups = perf_iommu->attr_groups; - ret = perf_pmu_register(&perf_iommu->pmu, name, -1); + ret = perf_pmu_register(&perf_iommu->pmu, perf_iommu->name, -1); if (ret) { pr_err("Error initializing AMD IOMMU perf counters.\n"); amd_iommu_pc_exit(); } else { - pr_info("perf: amd_iommu: Detected. (%d banks, %d counters/bank)\n", - amd_iommu_pc_get_max_banks(0), - amd_iommu_pc_get_max_counters(0)); + pr_info("Detected %s, w/ %d banks, %d counters/bank\n", + perf_iommu->name, + amd_iommu_pc_get_max_banks(idx), + amd_iommu_pc_get_max_counters(idx)); + + list_add_tail(&perf_iommu->list, &perf_amd_iommu_list); } return ret; } -static struct perf_amd_iommu __perf_iommu = { - .pmu = { - .task_ctx_nr = perf_invalid_context, - .event_init = perf_iommu_event_init, - .add = perf_iommu_add, - .del = perf_iommu_del, - .start = perf_iommu_start, - .stop = perf_iommu_stop, - .read = perf_iommu_read, - }, - .max_banks = 0x00, - .max_counters = 0x00, - .cntr_assign_mask = 0ULL, - .format_group = NULL, - .cpumask_group = NULL, - .events_group = NULL, - .null_group = NULL, -}; - static __init int amd_iommu_pc_init(void) { + uint i; + /* Make sure the IOMMU PC resource is available */ if (!amd_iommu_pc_supported()) return -ENODEV; - _init_perf_amd_iommu(&__perf_iommu, "amd_iommu"); + for (i = 0 ; i < amd_iommu_get_num_iommus(); i++) { + int ret; + struct perf_amd_iommu *pi; + + pi = kzalloc(sizeof(struct perf_amd_iommu), GFP_KERNEL); + if (!pi) + return -ENOMEM; + + ret = init_one_perf_amd_iommu(pi, i); + if (ret) + return ret; + } return 0; } -- 1.8.3.1