Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S941972AbcLWRSK (ORCPT ); Fri, 23 Dec 2016 12:18:10 -0500 Received: from mail-by2nam01on0076.outbound.protection.outlook.com ([104.47.34.76]:2144 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1757685AbcLWRSH (ORCPT ); Fri, 23 Dec 2016 12:18:07 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Suravee.Suthikulpanit@amd.com; From: Suravee Suthikulpanit To: , CC: , , , , Suravee Suthikulpanit Subject: [PATCH V6 3/7] perf/amd/iommu: Modify IOMMU API to allow specifying IOMMU index Date: Fri, 23 Dec 2016 20:38:46 +0700 Message-ID: <1482500330-5606-4-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: 19600ad2-c0fa-42f1-65a6-08d42b3921f2 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:DM5PR12MB1449; X-Microsoft-Exchange-Diagnostics: 1;DM5PR12MB1449;3:7x6ZbhOr3U8u6CObGfO57qCqq43U5Wttg+V3uJrnjodu9QFt9baBy1Qn5ekXeHppj8jop0JgwjEdM3H3QYzatBraAOL9JU9rPVT2IxduYoPanMOAuPK+EEo2XmlapoJz2O2gHoQnJdHs80OHGwi+YfsDAaeG9yKEw/+6NM59kaBvgsOXgsO1yE64m6bDqETfcaT84u23jCcpJk5iICGgh8beEm52O+8UvifJqmlN5u0r7vRJdPHGo2RLVom0zrwSNybpVDL5eokDoLI0XCS/0Q==;25:stW1RqOd8H270hNKEbwUp6Hmp1iyYZ0sQievqJelwDo1GG2q9QOWS2aP9+VQZPPnDdvKEcz/Za/Yxyl2kNcEyrEuqjX72GoO46Aif3DsoqITgjWZLe1PMteIrY0LrRfHgWEyTo4PyX+ee3l5tkg1oz5wzGfJeVu0bXxd8Z+iTu4b2wrduNpwwXHod9AGVFiiWb4zWHhEW/1h2K3yFQWAuqf3uyk8cZHLh1F2Zo3ce6RezjBMY+uCClQbMUoKEey+FkFExtMLp9lKc5Eh70YLQnPRQEyJFOoz2G8Z+1a5uAUokoaiE37EwBmKV4mqeWOdxmn7cp0tIVKDeFBT14VkEJYLXo0XjCnOZRnZjBdvazAlxMCBu5baPT/hmQ7eAYOXS/VLK1Ut9OzH1OioUPtGONGSd/JlYDabmPXRMxxDqBUNRNddA+BkcNTvET1SqnMByg7S2pzz+BviRFSnt4tGZw== X-Microsoft-Exchange-Diagnostics: 1;DM5PR12MB1449;31:CzsLAZrd7Gbtu8Ve8a8pgA5P9APd0zFCyuun9rTaQL8T8LHLLr0RZ0vvfomEk/sTS6XqJGcqs0cL6wrIuLKYLtHEuw7dXnlzOPOYAKdUJYiTLKpXcu2OAmKZtNXhl3BKZ8mTknk5ZbL2GVTGkNVKZXnLXyV0hhTGpQ2vTTrn518FXrZXfg48O1Ax3khn9mqwB909yHLV6KYjdFnu6+P5aZNNSIQhu58/MCh42VU7XXN0RcmjsIRh3bb3KVE7m1AI9DQVL7/BxQr4pQmo3v2SJ1OLKbFbvcIvcifqvyYy6lc=;20:updq13rj2iAQ2VQJkOLM1+sSMqzGtuhSEtbFECKpGOvXz+ZXRUVPJKV3qhwfEDuEzbkit42cQ7cGbjpUJUvh45FCqoSukzzdeZJxQFb/u6rEgQT70oqPML2cb0mJiLZRfsr/Jq/XWwxsIlNFzFkxW+PKGStIuwg+zrNyCWuasdOS0uRzjN86quivcM8FBuET6ZvtOesa0rHbeh7gbelWyifcTtLIAUVjSiJ4X+5FWT2Swd9EQbeATi3/+M2pbZDlkGbDxPeDSegPfPL7MJzg+bcu6PTBpaMJwkHQc1Z+PhMdfERnmtIKrdO0Vux9cf3f3X8NWh6MJOOWKDeLh9ohdXyn/zKXw2xyf3ysLD8wrvxRcqdiXHVP3Cn5zJ+oY4GZgb83jCQqhENmGVkNp4K/oYNCrqraMXXoLaU5FanoMlthEwZP55zYNRJ9A0/2KJ+7kCyAszG+kEMl4uVd6djhYzj5O69YAUmYITREjUS46y18weUTBd5xKk8GQe9okHAL 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:tXlLcbJ8ySBROxikxQVWGaaeX95lK4t+MZF96pCTk91uNeZSjXWdtjDGk5cosoKSUR/VnU7Xeg4uSHWmktHbdTJxcZibW3BzQKP2yI00HIYquJduBQLpGCCY2pfrn21utc+C+5HbMjWN4jccL4FhUFGaT8SdyY3X4EcL6e1xbDCqW70QBZ9ICc9Y9v+cVx4fhgHpFqn5j0XVgom6YIk0DsPs9gjde6nI+LQ3Bhh+eT/66HKHP+4SNHNtXLfGBQRi8EyfZ8k+HnTv/J3E/G99l0X4/hloUbcr2wfbOXoYnncMFsYO60bivSEzA4KQPNWMUrtMNAXVEDCd0jd4jCS2FHrenMVJSILX70x+wE8mT5SoGg1/7IlVSscO/CKOugXfNL3+3SyIPnP+ldyFZ/o1X1HhU68zu0Mh4H4dM/id/doSbMcIVNyxljwrLSux97xek4jEzU93iybTKzZMxSITFSuWL6vWyE0GjoHUBm2X7/jl0qq3Y2Lb0qYQ0QTwITlG8tkKbNt3gOpLoYvwJdYAsbTUDs3NhMfgcAWa8Yqc35ZhDTYRK1SraFf3WOCIkeze82Rlo4IIbc0CyeaVeUVNIBFIROSvPCWzhFWDNJ3fLlEOURnSHx4yA0JoywrYd+JKUfri/CEKjVKZq9mJdPgRcrWTdN99JXERp32H5LexC4k= 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)(217873001);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:u+MgUTi2WJFKBuV3NfP2fu63IcG9kCg6ysErHny2N?= =?us-ascii?Q?Ltx64dbhvY+GI5pPVj9WCb60o1hfmVnqLlxwLqRIdJHgr9J2x4iK/LHoKome?= =?us-ascii?Q?w26TJ/a122BLuebX01XZg7Yze9tlhBxbYg0aIHvBEAcWgMBOA/fFwxvEjE6a?= =?us-ascii?Q?2S0/cXlvFq+NPvFqmT7rcgt73h6nOIFhntMvTu4ZrAK7R4akXftmKD9ddmGN?= =?us-ascii?Q?kN3QFHrvV5Mk+eqB3uyla5yfWC2Eof29EdTVlMfUAnBNtZnXX5tarz5nbpcv?= =?us-ascii?Q?4pcrslaUpDXn721qs/Af8wlR/+xzE3OgIBN6knAAtjc7K+SUpAjA1yWO2mfQ?= =?us-ascii?Q?NqGI72CtskQcJL4nHn6+5STztilCH+6GO2QhRsKAhWs0UHkaJ66SzcOnlQmV?= =?us-ascii?Q?o3sFv63sYwLiMndT3uG3t3dH3KIEj6XNcY1HZPQ1m8YnwWviaxXdU5wnSp4A?= =?us-ascii?Q?mYKMivJ7KOxeOpwPpeLn8nqArCP/SJcVYttgBOfl+paUqvp5/mHc57csogqT?= =?us-ascii?Q?5pVfCbq3XQjwWYFdMwzga1CUP1XaR96Qqh7ACACYWh28Y64MNiYz0juOw9up?= =?us-ascii?Q?RNbSADiNWRm2iZDGu2ByCBeXfgQJn+AQEsGt/z12TPw+To1O7T5oHMeHm5MU?= =?us-ascii?Q?5qzghYiczFTo92LDyjHzIp/HKnrU/wSaELcUITa/zlvOEq2VSFu2pXE2vZxy?= =?us-ascii?Q?WBLkE9HjVSfLkX5wxQV40sHQW937bf2tke5spTisvP/G16y6MtQhbLAUhYHU?= =?us-ascii?Q?MS2ZES6y4wUESYKCBo+8FPHr3W8YpivVsnLTTd82ItGTwMnNCladWD8Hc3Gk?= =?us-ascii?Q?1Q2wvGpdr1rMbbrOObb7rbnm7wX2zGBOuguENjhF1JRK6XhQQuU26wpj8I2n?= =?us-ascii?Q?Oex/XJCQNgBbQ514ALDW64VVzMRzFBNBOOG9Cqots3Dfs7ytHZiQZmGMI3xs?= =?us-ascii?Q?THsDBkU6yLNUppSnbcZMlYgxmkYJ1TqO3vbCf7k9VQ+4mcOgRW2iGlLft0S0?= =?us-ascii?Q?NbmxqlEwAO3OZcBEMIfhcjl6wuUPRYlR8T7RrLWc8dJ3jTiie2KOMV9cDWUt?= =?us-ascii?Q?5d2O02dlZD+ZgSDfHhROAgh8oOvMyQ47MxlM51vLPLij/78Nn/CgNUdrfrIc?= =?us-ascii?Q?Goyy9EMjhTsbKYMCoYrGl6MQjsgGmOcQafxfSJoyX/UM9FMdKnPSg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;DM5PR12MB1449;6:4PQU3BfVgaLhopjrM05SfTOSHUfTn3kE2JkG5tOivM+gggEIidkTMXqXqwbK0hoz8Kny9/jmvo2rNHtsctTTzKfhdXpL2vRAQwMF5HiggY12c492CtKgF/L508CJ1XcfqWsuv2FdNX0WLkPScogzEQOJ76GQhjSUrrKE2B21F5ksRetZepoy8Z4/4r87hqA8trGZsAqbsygMbeTWU5ILjKA/HVRPljrJEt8t+cYye1bA/Tw34SD1AW0/3xTmitRfBSjuWgbzHtVftvEYJP7347H9MF9hNFVIypb+fESFqlftoHuaVucbBqMmnVj8eAY0TacAX1Y3ZXTFfLN6/qucSP57q6sYXaijo6Z9+hCyBh6VbQ1sLCj/rdcNU5QkSlOfQecjXHxqqi16apHV5Z8GxM50NZHQDmwJ0nG4pGMSe/Dg/m752PPCyZpyrZdUEOOuF7guuoZUn92H+QrccXZCaA==;5:oUaFfBkdXhYbUeFopHcq1HnAvAUkUw7Ym+Lq2KkD6c8+coLmdzHsuNPA5DrAQXk+RX5O0kE85qAyfc0K82lziQrPQLX6I3tZVYBpiEtftQx+0vJ17Ndcqad/cF4WV9tMsxg2YOWsp0JGOEkWA3uHyg==;24:7se8xIICqesD6IzYdQi99pQHzTEVYtxmg7kF5kmivN5gTPF+tMnWgtjtI/ChHvwlw82twjSg96/7MzP1ADMtUPyrJ8+pQLJ8MFX2GRFg0d4= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;DM5PR12MB1449;7:ghi2nZqiEyDeEUFrR59Rgo58VOfEizt7ZpF0SCaOX1uCjC9Mrw4OuwyXFAmfHzNeYnzSQoRFH+JOnp2rxpssg7opfYV0lBrPpxgn9/nTaphmUzIV6qXc9pj5FFGO5h6HWMUaKrE6eA5DOD/eHySDvvfiUeiRamaQnhLfR2bbLXyDUX6LAwVVkRanrbjq4kAiTVEV6U/5UnUe1NLaliTdDZnb+h2s9gsMHfIVAwNtUePRN68uf8Jgn9yhDf3AGjYkOEWDLBpXzWTgVcbduy5pSXKglvi+KRnHYiOdz7Tofhb13i74gT6p7AE42qosoV3V6tDi+enFtgvwzZkDE+RNVVVbuakAijohf1BTi4tu8tqRya80kvb9HAQgssKgwRQ3zPhruxaxWgimVIgn18mCJOtb81tB9UF/ludbe7ZORuUlKAzh/OoWykR95PQ/Uo7Ejk/xdN/xKJkpIVYuNUx12g==;20:7VnPTwHF1H0oKdpgNt+Q306JPJ1KhQ9glxm256CqxMh+fDv+TkQt1HV26ffQdNuGUl07pDveWGvhnIJnHt7z+rKtYAlHxv+uYhO9OOVDS1BPuZIQM3aC/OFBZRfQwPs76VMoMq6zi72jw+xke2H5S7SuolhiLc/Kyl+Y3k7xtruffW+xjRH0M23KTysM+WDHUyn8Lwk3TMGp7YrKll8b+Wph5xkxW6uPSDCMQBDjB8PzQBZmLynCodcF98aisnBL X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Dec 2016 13:39:31.4842 (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: 9612 Lines: 282 The current amd_iommu_pc_get_set_reg_val() cannot support multi-IOMMU. It is also confusing since it is trying to support set and get in one function. So, this patch breaks it down to amd_iommu_pc_[get|set]_counter(), and modifies them to allow callers to specify IOMMU index. This prepares the driver for supporting multi-IOMMU in subsequent patch. Cc: Peter Zijlstra Cc: Borislav Petkov Cc: Joerg Roedel Signed-off-by: Suravee Suthikulpanit --- arch/x86/events/amd/iommu.c | 45 +++++++++++------------- arch/x86/events/amd/iommu.h | 8 +++-- drivers/iommu/amd_iommu_init.c | 77 +++++++++++++++++++++++++++++++---------- drivers/iommu/amd_iommu_proto.h | 10 ++++-- 4 files changed, 93 insertions(+), 47 deletions(-) diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c index cf94f48..9744dc8 100644 --- a/arch/x86/events/amd/iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -248,46 +248,44 @@ static void perf_iommu_enable_event(struct perf_event *ev) { u8 csource = _GET_CSOURCE(ev); u16 devid = _GET_DEVID(ev); + u8 bank = _GET_BANK(ev); + u8 cntr = _GET_CNTR(ev); u64 reg = 0ULL; reg = csource; - amd_iommu_pc_get_set_reg_val(devid, - _GET_BANK(ev), _GET_CNTR(ev) , - IOMMU_PC_COUNTER_SRC_REG, ®, true); + amd_iommu_pc_set_reg(0, devid, bank, cntr, + IOMMU_PC_COUNTER_SRC_REG, ®); reg = 0ULL | devid | (_GET_DEVID_MASK(ev) << 32); if (reg) reg |= (1UL << 31); - amd_iommu_pc_get_set_reg_val(devid, - _GET_BANK(ev), _GET_CNTR(ev) , - IOMMU_PC_DEVID_MATCH_REG, ®, true); + amd_iommu_pc_set_reg(0, devid, bank, cntr, + IOMMU_PC_DEVID_MATCH_REG, ®); reg = 0ULL | _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32); if (reg) reg |= (1UL << 31); - amd_iommu_pc_get_set_reg_val(devid, - _GET_BANK(ev), _GET_CNTR(ev) , - IOMMU_PC_PASID_MATCH_REG, ®, true); + amd_iommu_pc_set_reg(0, devid, bank, cntr, + IOMMU_PC_PASID_MATCH_REG, ®); reg = 0ULL | _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32); if (reg) reg |= (1UL << 31); - amd_iommu_pc_get_set_reg_val(devid, - _GET_BANK(ev), _GET_CNTR(ev) , - IOMMU_PC_DOMID_MATCH_REG, ®, true); + amd_iommu_pc_set_reg(0, devid, bank, cntr, + IOMMU_PC_DOMID_MATCH_REG, ®); } static void perf_iommu_disable_event(struct perf_event *event) { u64 reg = 0ULL; - amd_iommu_pc_get_set_reg_val(_GET_DEVID(event), - _GET_BANK(event), _GET_CNTR(event), - IOMMU_PC_COUNTER_SRC_REG, ®, true); + amd_iommu_pc_set_reg(0, _GET_DEVID(event), _GET_BANK(event), + _GET_CNTR(event), IOMMU_PC_COUNTER_SRC_REG, ®); } static void perf_iommu_start(struct perf_event *event, int flags) { + u64 val; struct hw_perf_event *hwc = &event->hw; pr_debug("perf: amd_iommu:perf_iommu_start\n"); @@ -297,13 +295,13 @@ static void perf_iommu_start(struct perf_event *event, int flags) WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); hwc->state = 0; - if (flags & PERF_EF_RELOAD) { - u64 prev_raw_count = local64_read(&hwc->prev_count); - amd_iommu_pc_get_set_reg_val(_GET_DEVID(event), - _GET_BANK(event), _GET_CNTR(event), - IOMMU_PC_COUNTER_REG, &prev_raw_count, true); - } + if (!(flags & PERF_EF_RELOAD)) + goto enable; + + val = local64_read(&hwc->prev_count); + amd_iommu_pc_set_counter(0, _GET_BANK(event), _GET_CNTR(event), &val); +enable: perf_iommu_enable_event(event); perf_event_update_userpage(event); @@ -316,9 +314,8 @@ static void perf_iommu_read(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; pr_debug("perf: amd_iommu:perf_iommu_read\n"); - amd_iommu_pc_get_set_reg_val(_GET_DEVID(event), - _GET_BANK(event), _GET_CNTR(event), - IOMMU_PC_COUNTER_REG, &cnt, false); + if (amd_iommu_pc_get_counter(0, _GET_BANK(event), _GET_CNTR(event), &cnt)) + return; /* IOMMU pc counter register is only 48 bits */ cnt &= GENMASK_ULL(48, 0); diff --git a/arch/x86/events/amd/iommu.h b/arch/x86/events/amd/iommu.h index 0ce8c91..71ec9d7 100644 --- a/arch/x86/events/amd/iommu.h +++ b/arch/x86/events/amd/iommu.h @@ -31,7 +31,11 @@ extern u8 amd_iommu_pc_get_max_counters(uint devid); -extern int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, - u8 fxn, u64 *value, bool is_write); +extern int amd_iommu_pc_set_reg(uint idx, u16 devid, u8 bank, u8 cntr, + u8 fxn, u64 *value); + +extern int amd_iommu_pc_set_counter(uint idx, u8 bank, u8 cntr, u64 *value); + +extern int amd_iommu_pc_get_counter(uint idx, u8 bank, u8 cntr, u64 *value); #endif /*_PERF_EVENT_AMD_IOMMU_H_*/ diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index a7e756b..c993c77 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -251,10 +251,6 @@ enum iommu_init_state { static int __init iommu_go_to_state(enum iommu_init_state state); static void init_device_table_dma(void); -static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu, - u8 bank, u8 cntr, u8 fxn, - u64 *value, bool is_write); - static inline void update_last_devid(u16 devid) { if (devid > amd_iommu_last_bdf) @@ -1474,6 +1470,8 @@ static int __init init_iommu_all(struct acpi_table_header *table) return 0; } +static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, + u8 fxn, u64 *value, bool is_write); static void init_iommu_perf_ctr(struct amd_iommu *iommu) { @@ -1485,8 +1483,8 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu) amd_iommu_pc_present = true; /* Check if the performance counters can be written to */ - if ((0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val, true)) || - (0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val2, false)) || + if ((iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true) != 0) || + (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false) != 0) || (val != val2)) { pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n"); amd_iommu_pc_present = false; @@ -2754,15 +2752,18 @@ u8 amd_iommu_pc_get_max_counters(uint idx) } EXPORT_SYMBOL(amd_iommu_pc_get_max_counters); -static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu, - u8 bank, u8 cntr, u8 fxn, - u64 *value, bool is_write) +static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, + u8 fxn, u64 *value, bool is_write) { u32 offset; u32 max_offset_lim; + /* Make sure the IOMMU PC resource is available */ + if (!amd_iommu_pc_present) + return -ENODEV; + /* Check for valid iommu and pc register indexing */ - if (WARN_ON((fxn > 0x28) || (fxn & 7))) + if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7))) return -ENODEV; offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn); @@ -2785,17 +2786,55 @@ static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu, return 0; } -EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val); -int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn, - u64 *value, bool is_write) +int amd_iommu_pc_set_reg(uint idx, u16 devid, u8 bank, u8 cntr, + u8 fxn, u64 *value) { - struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; + struct amd_iommu *iommu = get_amd_iommu(idx); - /* Make sure the IOMMU PC resource is available */ - if (!amd_iommu_pc_present || iommu == NULL) - return -ENODEV; + if (!iommu) + return -EINVAL; + + return iommu_pc_get_set_reg(iommu, bank, cntr, fxn, value, true); +} +EXPORT_SYMBOL(amd_iommu_pc_set_reg); + +int amd_iommu_pc_set_counter(uint idx, u8 bank, u8 cntr, u64 *value) +{ + struct amd_iommu *iommu = get_amd_iommu(idx); + + if (!iommu) + return -EINVAL; - return iommu_pc_get_set_reg_val(iommu, bank, cntr, fxn, - value, is_write); + return iommu_pc_get_set_reg(iommu, bank, cntr, + IOMMU_PC_COUNTER_REG, + value, true); +} +EXPORT_SYMBOL(amd_iommu_pc_set_counter); + +int amd_iommu_pc_get_counter(uint idx, u8 bank, u8 cntr, u64 *value) +{ + struct amd_iommu *iommu = get_amd_iommu(idx); + int ret; + u64 tmp; + + if (!value || !iommu) + return -EINVAL; + /* + * Here, we read the specified counters on all IOMMUs, + * which should have been programmed the same way and + * aggregate the counter values. + */ + + ret = iommu_pc_get_set_reg(iommu, bank, cntr, + IOMMU_PC_COUNTER_REG, + &tmp, false); + if (ret) + return ret; + + /* IOMMU pc counter register is only 48 bits */ + *value = tmp & GENMASK_ULL(48, 0); + + return 0; } +EXPORT_SYMBOL(amd_iommu_pc_get_counter); diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 1f10b3f..1df3ff7 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -57,11 +57,17 @@ extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, extern struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev); /* IOMMU Performance Counter functions */ +#ifndef IOMMU_PC_COUNTER_REG +#define IOMMU_PC_COUNTER_REG 0x00 +#endif + extern bool amd_iommu_pc_supported(void); extern u8 amd_iommu_pc_get_max_banks(uint devid); extern u8 amd_iommu_pc_get_max_counters(uint devid); -extern int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn, - u64 *value, bool is_write); +extern int amd_iommu_pc_set_reg(uint idx, u16 devid, u8 bank, u8 cntr, + u8 fxn, u64 *value); +extern int amd_iommu_pc_set_counter(uint idx, u8 bank, u8 cntr, u64 *value); +extern int amd_iommu_pc_get_counter(uint idx, u8 bank, u8 cntr, u64 *value); #ifdef CONFIG_IRQ_REMAP extern int amd_iommu_create_irq_domain(struct amd_iommu *iommu); -- 1.8.3.1