From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S942892AbdAJDfc (ORCPT ); Mon, 9 Jan 2017 22:35:32 -0500 Received: from mail-bl2nam02on0054.outbound.protection.outlook.com ([104.47.38.54]:6720 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932316AbdAJDfQ (ORCPT ); Mon, 9 Jan 2017 22:35:16 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Suravee.Suthikulpanit@amd.com; From: Suravee Suthikulpanit To: , CC: , , , , Suravee Suthikulpanit Subject: [PATCH v7 7/7] perf/amd/iommu: Enable support for multiple IOMMUs Date: Mon, 9 Jan 2017 21:33:47 -0600 Message-ID: <1484019227-11473-8-git-send-email-Suravee.Suthikulpanit@amd.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1484019227-11473-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1484019227-11473-1-git-send-email-Suravee.Suthikulpanit@amd.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [114.109.128.54] X-ClientProxiedBy: SG2PR04CA0045.apcprd04.prod.outlook.com (10.169.49.141) To CY4PR12MB1447.namprd12.prod.outlook.com (10.172.71.139) X-MS-Office365-Filtering-Correlation-Id: d2675dff-4972-4c76-8b99-08d43909b031 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:CY4PR12MB1447; X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1447;3:QeY/+nge+eknZhbmdFIG0izISPCPDkmkQUdC313z1o4zmd38dVbkRWt30ZGGN36bGRuqmreueQn72+gQN2tlTz6i7l/n0a5gLDBy9d2JaUTZUoXcVbSgCr9nyQrc64LQIce04wk4jsz0B0xlB9Pr0a/S6xQkMvOgHelsMw5b1l9kXfH5JCSzLKa8+fTvnMwbkr/ZWwI+Me2eWPQSBtVm+zYxC7E0+OgNJp9oRt+NBWNnZiFIvcr5dOhp109/45BkMxHJggArk3k3vhTNzLzbAg==;25:GoZqae8T3POqTtucTjv+7dIOhYg6tUMlRizZFLiL7b98xqOVM6I3oNmQaVdzDoGSxGGe4rVBqNN3OVQij2mh6T0bPhE7LZSmZUZDuNlkgHaQOvzjSNQeZWdQui4r497JzjoqwfXw+EUoD8voYQDp1IGjsPJaqrXMNPbkgyyb8xB0CW3ryVC1r5fZ1zm6t7YfgqMxUhqwOxNvcx+nDw2UGAcQ8jTLGDDD5T6F55jYTOZVwLP67FAU5ayuxK8lDOJC6T0tNXRCQwKTze0DQsfhXwLiPOp0m/ap9v72X1mS3EpnknAf2nI9Q9wC6ta9Inq52TpoFFJmSZYgk92ewCeTW3+T19uHBNxfvSLSUQXecJsyViVeUIy5GWOC5F/pg5v2DoWgF+emXbSPR2xcp+HoU/QNrnVIJU5E88wm3OTY8wEATmWA7v7Ks1J3RLS0oAH6uSpI/I/8a6wb88YOewT7lw== X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1447;31:C5LlozynqA4V6vNkbioWIAKaJlV8nTnGwxvE/es8hHYNnYaA5ao+ehS/54xlMOYmNxb4iyjcN1HtFxw8XAPDJwLPozdIOw9qRAZmbnR8FZlewTphTXBi8BHDqZwIPJ6fdqKGPiCrGbFWSn6e9hU+hJKGjxcVTRqr8Wi+mOdvLKFE+Zh7aHgl5BGUfoluJ8Q+TeCusz+QdKIpQXsFcMHKs3mCLkUM+hwrt5tk3FBV0ELfeEU79siu0J11ylIN5XdONA3mvnD1MsaraRnAD4+ifA==;20:qj8gRtWDrxS8+QDmVRgvxDLAQJ/YPXlI8eYZTbFIW83YAp6fBa1tOeH6HjS6CEz4hc3cM6Tk0+ezv2cc5v2+AbkQ+gsdJ9MKriYcsZIPe4UtJbSL/cprqKBqJ8/46EkYdzXNcyUMncspIJiq1b6OeAIVVz0jWDL+fGbp+OpZrCCMHH6vX0sRacJAj9ctBYyhhSqH0KAFxrCVIfJGrTvPL6yuzwHC6GoUpNksVwSiRAeaDjCKayfCHtLU6I6JkeoLYA5P8GOCfcQGolJ2qAfm56TnqwwORWMtlYO6RKnVubdflQoYW69VcoQcKZ6cwjIxWLt60pNvFStPmMQ7utTMz2egBDsuVVqhbUmByti1IjTHNGcJwcWIoACOKgHxHPQSnb7xapVTHzPcAxSS8CxTHbJ4xK53vAAgZXYh5vDLvUGVI9Ao45M+UfXQNGSWGINrTeuMlBgtQ/wmtUt1INb1rSpnJPagC4u0ApjV9oOO9qB0FdlaGF5ElMHFEVa3dxFu 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)(5005006)(8121501046)(3002001)(10201501046)(6055026)(6041248)(20161123560025)(20161123558021)(20161123555025)(20161123562025)(20161123564025)(6072148);SRVR:CY4PR12MB1447;BCL:0;PCL:0;RULEID:;SRVR:CY4PR12MB1447; X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1447;4:ydiD18IIrg86UwwYucJgYstPzsQ5iwVzkXBCp5jBOSfY5DFW8vFhxC5hsLYm4dkhGiurv77Md+6HSevllWMQc9g7oF73xttueqiz93U42IJnjMr7Vxl9TxpR6tPh1f4daK4j0PZeeTnddFFKED1mAARA6Pmruq9NkE9iZxWFmvxKwaaZRa8oR49mUU2GKBaPI9gRI+bipAUjmt+5pnGlkGcDCju+BOcRjLN4IMKPAvUSyM2jiaivv+XhwKvNPAN5QpO4DR8yH2MT+fR3arqQw1rJ3pKgfFmb14UzISYOOIsfpmgm/kWofx7zZwj+b5QdLZXNNTJBZbzGeB+MriMvECxqpA/B8amXUSOEA1R2A9I61flXKxXCuL74C+T9y7lufc19uGuF8XlrnlzhCbZgvbVM+8X8ijOXcjmSaX6dqy5QVl01DL9FJrHH7x1ofsgG9mj91+B8/YKBzOFAKeKiZx6vITOBCOFPJJZ0jEaQa2J04i1sxYqVbbnwUMjtb9MqHtVwkGaRQAnzXnWLdTqgDCIECJLwGNxE/z+KLZe2HguqC3wS6IQGLJdaWfl9MIGMRV1mXKCZaES8lwWfokaS6ql2orTl03iVwCS7637yXteSzeySXzQds9h+3Dxw7O+jEh9jJuUf7tgGce7Fq0WrsxrxCHdn4/0Fd9/AUJhRSBw= X-Forefront-PRVS: 01834E39B7 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(7916002)(39410400002)(39850400002)(39840400002)(39860400002)(39450400003)(189002)(199003)(38730400001)(86362001)(54906002)(48376002)(50466002)(25786008)(305945005)(7736002)(189998001)(6486002)(6506006)(97736004)(68736007)(4720700003)(5001770100001)(6666003)(5660300001)(6512007)(101416001)(66066001)(92566002)(6116002)(3846002)(47776003)(2906002)(50986999)(2950100002)(76176999)(42186005)(8676002)(81156014)(5003940100001)(81166006)(36756003)(50226002)(105586002)(106356001)(4326007);DIR:OUT;SFP:1101;SCL:1;SRVR:CY4PR12MB1447;H:ssuthiku-rhel73.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CY4PR12MB1447;23:HkQGxkwlui5FlfHCYpK/5cpWlbSSc8AMwHZzdhvzK?= =?us-ascii?Q?64R8pD5A2hb/QxFQZoC0fGYGdEhiOVFAoKlf6COWw09v0gCHBMNb/3zdbKR1?= =?us-ascii?Q?2O0j2ILbtGP5vMuiWhwlZrUECCJU3z2HtVHaB1Ca+fp2WXuzSFZ5FkcYpKVL?= =?us-ascii?Q?ts8i5XkVx1BJedJ4ObaMGLo/ixdw3T5o3HgFeLvMeF8YOFex7oBSxZbjQcqL?= =?us-ascii?Q?nG6ChRqEm0rrPa7fWxWioSoMD3ka3V2A7KVNNCLhMW8Uqau9zZqbu1JkCOZl?= =?us-ascii?Q?hBCin2oGfxSMp4IPjR5eohu3Z96i8ELRs8pQzV95EqWYxAyjxro3eUZQAVds?= =?us-ascii?Q?BU/3eWKRBv40PuWfYiIyrrBNeal69xmvdffGX6IOcvlXWIBeOT0+3vIosbiI?= =?us-ascii?Q?x3Ji+KQaAT7tRG6l8CvY+HIknxocy/Oc4nRp69BJqJpn0hqRzBMhuxVvBg36?= =?us-ascii?Q?aNp2Wwi10Z4XDVcIeDh3ybxY5gqS8WXED0uCQRPPegHbhwrSNRrWZabl+iEu?= =?us-ascii?Q?bo48Pk4nT1DOlol37VhZkJHo0qNvBeTKfn7C2ANzhMwkOAgULyQHkc/4IK8K?= =?us-ascii?Q?79SULNqY1PBChXWyyVCEX8Ig36PXCFh7ZP+KCoEO1FTAUeWJ2LF8h+nXDDDW?= =?us-ascii?Q?JFZlZvVVXd8AJUintecZlz+9Gbsz4uBE35gFVcCbmBypNyeIDHpDzSvL/nCe?= =?us-ascii?Q?XVIZJO4kMlUPHmVklEOVnOsYLeY0cXKpWNbaonLOCaykpJH71kDjpaOczqzG?= =?us-ascii?Q?/RAgIQEmEE0yPPPNXMtVSvpl+XcSZbJ9ri3/PSrX6PDP/QMNO28x60RXNjwp?= =?us-ascii?Q?ORANpoguekP0CZE51StXIVmD3Ey4qdnhpO9Qcm8olwCxkToEFlxegAt7cu8I?= =?us-ascii?Q?Sf+P2ug3eefTfrVQo2Na4wI+aHYdusKzqpVfvHrWh5hxQs2g99FUBB3H4zXj?= =?us-ascii?Q?US0++btLFNQO/Aj1vcKIKAwpwDcykIGSlmtJeY9L8xXsnU3umxkJbesn4vnq?= =?us-ascii?Q?8hwWkMrldkjpSYsS9TtxKVhwfjj5SxYgFcpspj5bQSjDYWquc5YvLFwzQuTP?= =?us-ascii?Q?24ZviaXJrioanJv0p8YdVHCCeBjf+dU0SG+7b8i+LDUsY12XFi7vGOuJn7LD?= =?us-ascii?Q?TO5c+y1EK7g7aqaUmdg865BFSr1hPRP/aUitjhySRj7yeiLaYHacW5iVGATF?= =?us-ascii?Q?+gCTrqK35+3XxX1vDDCIrt1ARo0WR9P044V?= X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1447;6:0F1exPcw1kxcAA0gywt9Ysn6+n1uuyO3CI1A8Yd9H8YvUgMX3MsUJTh5J+RUlhIW14sCClVdsaBNSjhd1preLiWB6DeCZQZhBUC8MGq+Q4a9esA7FuORdDdZzyBXl5jlq4TzxM6Yhs9JUdQOvz5i5Gum3/FiPrIIxkihdoNZvOHzcRJ9zIj23fsuJ4adHDzwlSWSMwykd0QGwuD0iWOJwCLhwn1Mpin5z4HZjxurhTgJqltEv3sbK0Xe+4kKHEKsF2CP2iZ5RPVXyDLuX+rZNHmuEGxZNX1cICcLpi416UP22H3YLlFr0oDP2FsVU5mMcqxKstaxiUrR5Z6+CaSbBeZpka86+yuScyqzdD/973fIKtpzoleOqGtxD22izhkdixMu3jdnNQTi04oKaZPU+q459iNSQGb+8SCO7/wLd9xEY3i+F/e2KeWj2GRBaeEB9BDnqCBgb+1h/qjs25nbMQ==;5:nEH4XhpwEStFMyO2slz1dAuWD4BeNkd5cdeFbKOcxY/EG51sMRacR+GCBvQEofWndAQPb5WVmzSnNDJkFfYX/OuDAlFLc9pZkVXbnEHlgA5tDwv6yk+CxgQC9Oi3DbW2UT0AexPDfIQukTGRYyjCBaPQ1EMtr3Q5R/l9l0GjCYU=;24:Km7LDqiOEuAImskxyeF5z7FlkjsK0Ks7WBL1mZR1SveeiqdFmERoLgfbPb4kzkAHohTszm1zWFVV/2aFmxxAOgZbBToGGu3xiuV2o3QZ748= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1447;7:78G2RjNZWOYfQ107g3AgYl6QtN2n8uQQLGmfeMLEFu0lufEwD6B+LE1Jxp7xVPDtb+lZCFbo9IXIJwYbXk1vYngy5/Nncj4jOqq/8IewvlstI4AHfTKY0UYsunzGUNK5NMcqFqe4cChbEGodELUC3umQYDvP68ReBXYNV6ETcH/weopzlTQI3xT/H4etYa5HPhd9OoFbqEsC+qTLSMwyhLjmev5/TAVUBG8Dn1pBoYLI/6HNuWVIYmeCT2adDwVbrUFcdK4MFPAhu1BrtP/nqbHx5pxR48Bz31cpD5hexbAkx0Gdb4r5GhIbTW1U8sht3v/IbTzLoOFtUQ+tXdcxw0jT09RphF4KCrJLJJLf7v76ZHD75aMJ91/kGvpfI04hwA+oMV4WzSXMBn7iy1FXHE44PwtSH8bJ+inndd5HutatjTf9ZbDyajqxSgkGi/k1bcCP+bHNTzZEqL13RqObSg==;20:4K6YAXj4IxR1LIyRbedVo6kwGmQwzemDW+6v+8kRIYUOxxESv2JEBnV7TEoPzvYHMaYA/UWoOIg54yZsQaJYQxINpl4BacE3wOMveX8eY1OHW38BhkY975J04vRofZZrQC4E7toisEErucj9zTSO4eP4R7aJ2BWu18pAXMCHOx1I+0CcJXPBcvfAbq5lEEahC0RWcbkG70ZhDzowh1nUj7aaiNpoVq3srJXFRA+SmqZgy5kd+5+YG6cAajblNiS5 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Jan 2017 03:35:11.6589 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR12MB1447 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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