From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752665AbeAZXwz (ORCPT ); Fri, 26 Jan 2018 18:52:55 -0500 Received: from mail-cys01nam02on0085.outbound.protection.outlook.com ([104.47.37.85]:55264 "EHLO NAM02-CY1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752383AbeAZXww (ORCPT ); Fri, 26 Jan 2018 18:52:52 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Gary.Hook@amd.com; Subject: [PATCH 4/5] iommu/amd - Expose the active IOMMU device table entries From: Gary R Hook To: iommu@lists.linux-foundation.org Cc: joro@8bytes.org, linux-kernel@vger.kernel.org Date: Fri, 26 Jan 2018 17:52:45 -0600 Message-ID: <151701076583.16448.16500299283239245371.stgit@taos> In-Reply-To: <151701071164.16448.3611271062222336838.stgit@taos> References: <151701071164.16448.3611271062222336838.stgit@taos> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Originating-IP: [165.204.78.1] X-ClientProxiedBy: BL0PR1501CA0028.namprd15.prod.outlook.com (52.132.16.41) To CY4PR12MB1208.namprd12.prod.outlook.com (10.168.167.7) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: f4329e56-e903-488d-0d2b-08d56517e8b2 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(7020095)(4652020)(4534165)(4627221)(201703031133081)(201702281549075)(48565401081)(5600026)(4604075)(2017052603307)(7153060)(7193020);SRVR:CY4PR12MB1208; X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1208;3:IvgeKafG4CW/WJb2cSX4NZmWe5VdE5lmkz2PyMluYDXeBkpBvkdVoR+TXvcXmxBkqC1AIotQ+RhfcLxvTe84mru5Jpg7Ap8uKv+l/UEQpb6A2CrsSPKqilPyd9NvsoqQjfwPWIbIELzVMF1Bwz23xNZPG2bTyiZU4wuWSjxjpW90MVnD28AtN3WlKU2k7N8gZxFhHt6IEqQYYH+K60uiYsPm38IU7sv+giRrmleLxGf339vCbKsKc8gxguDQc8Go;25:qW5XAaFRcryt3Yat46UBgsc1MyOEkTtuXUsY1Ogwbw4TDdxZtkXDTrtjBkmfHUK8YWanFi5qR/cH5t/gSxbRrPYiK9+Ivvvdf4c+tnICx6UJxhmOEKarf4hQZW7k8QZZmI0c5ClPDol6PdoiSoTElOasCbib/xmBu2Zk1saRm3nvIwJLX3sTn5+d/TVXHe0DEKGqYtdV6rM3qcPbo464zDfYL3PNNEwdQcNpOdli93Sy4nOZonDqTN7Z9lBQwrnmsLSHlzuFmdUkgb39o+TcY3rE5+K0RZRzKIano8I+DUslCaVU/pbdYfDTKp/fFugPC175wNarmGZwwM2tG7o7Gw==;31:X0lLpDJdFlTuI54XdE/ghDwhQmwT+wD/xNa/iR45PDzzxRNLjO8VEtTD6rDSEdH+cO/NsYlZhfRUBrFWA71zaGBmm9wh6LoDP1/HMzkl0WaZ0Nk9eLkblNGWFehK0jTPET7SFaKQtZjyz+eOpXQWGGtzxadE5U42otmffnzGB/OJziA8mnGvAIT45R8n8vRFN0ZpjDRhn1ZTGcxpb57yQwxHs1xJrkGZ2ghnp56PkLo= X-MS-TrafficTypeDiagnostic: CY4PR12MB1208: X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1208;20:TdHeyxuLuYyR04KdqYCr8UlUh7z3mdB5HC6//73wKKdnUChdlU8iTSdSHLMevg0MpU0eGbxzL6rbJKmB2Msz0shGMOEytsLpoUDRaP8vk3sqf80QbgSDi3gRFyonR+tG0Xd/sk1xGsOfON6GWdT/l2BXZJxuY8kdE5EY/roI+cCHH6HwAvBynMg+tXnQZu72c4Og+blnOYek3Z3LkErvOy43DTW+vQ3cdVxRgiuxHSjFFNhpZLsLl/5gr0T7P5NAI7xLK4I6LQoexPrmu0UvWJuY/e1fF1041jXJbepbx8XAItooiDgWg7lhCcXfnzDVXrEzhmBedSkJYivIhTZXTUl84shUVsbGdwhb1l9vYbY9h9Nw4y5MdluDckc87qstg4NlCNdYxOsI4EWu0LlZfEPs5X5IVw21Gj9qeri5/RqbWGM1QdcEEZzg9KvGQCu5Ktaj61O8ws0dbH5FZ08ZSXNjWqwBbRk+0o7RcGUVEt7gMLNnQHiVcx0SxEX63Xkq;4:osgklzZnHw9/V6TZYzD0GTzpsNn4Yy/ytYtPwCpg1G4uUdet7bqtmcR936g+IKPG564rLFY7GBZCYVI/xVljNS7cd8MoEV2Wm1y+6MfhEYSX2q4yu78eYlqHi9/Q/O4szvZcwrRn+Cyvs1cU0qZDAb10yZOj+XCKSdheQGzsC3049/D+fzM7p5YNe3cIJr1bJkUpBsr3Z22JPv+ZOfVwrym8n1EURb29cj0QiWGaS43UP8J44we8BrpgjI96Dzq5AlIXklY3w1pttN+eaeDmonIhViB2wArfRSZNiTJkEwrDfvLASzcrHQ04gOYDQFSH X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040501)(2401047)(5005006)(8121501046)(93006095)(93001095)(3231078)(2400081)(944501161)(3002001)(10201501046)(6055026)(6041288)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123564045)(20161123558120)(20161123562045)(6072148)(201708071742011);SRVR:CY4PR12MB1208;BCL:0;PCL:0;RULEID:;SRVR:CY4PR12MB1208; X-Forefront-PRVS: 05641FD966 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6049001)(7916004)(346002)(39380400002)(366004)(39860400002)(396003)(376002)(189003)(199004)(2906002)(386003)(9686003)(6116002)(3846002)(478600001)(25786009)(575784001)(97736004)(305945005)(26005)(53936002)(33716001)(186003)(7736002)(77096007)(4326008)(86362001)(16526019)(230700001)(90366009)(8676002)(83506002)(2361001)(76176011)(50466002)(2351001)(106356001)(58126008)(16576012)(316002)(6486002)(33896004)(2486003)(105586002)(47776003)(72206003)(23676004)(103116003)(52116002)(2950100002)(66066001)(6916009)(81156014)(6666003)(68736007)(81166006)(59450400001)(8936002)(5660300001);DIR:OUT;SFP:1101;SCL:1;SRVR:CY4PR12MB1208;H:[127.0.1.1];FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtDWTRQUjEyTUIxMjA4OzIzOnFXa0RwUVF6SHkrR0FjdmVKWmU2Tytqb0lZ?= =?utf-8?B?RHg0UTNqYXFsT0ROay9ZZUt5RUZvbnFnOFRnc25yV3QzVG9FbTZaVG9ITEtC?= =?utf-8?B?U0U2L3RpZUxZeW5Kc044ZDNtb0tEZnEyckdmSzNkQ2ZIeU9MZEpEaHVwZjIy?= =?utf-8?B?Q1E2a09vMnY0R3VkL2JscDdSQmFzTjBJU2ZucVdTYWdFOTNCdmEvcHJuOFJU?= =?utf-8?B?MzdlU1BycUNUcjQ2eTNTWk93eDNjemVvdlVySUlaYlhhTVBsQkNrSjh4dmdt?= =?utf-8?B?STFsQUtwZklmTzAzZThnQ3lhaVMzLzA3L2U3ZTN2TmR6YVVLVW9EMEViYWow?= =?utf-8?B?ekVkNEJmRHN5V0pEaHZaM1UvcUVyV2djNXVlTFBYRUNBMDU2ZXRMenVqaFNJ?= =?utf-8?B?WWo4WlU0NzloTmxybmlpV01rT3R5N0FtUzZZNzFYWTZFZzRsSEtPY1Jlc1Zq?= =?utf-8?B?VG9aS28yUEYxaWdjWUlreWsrSzVTTUJPNFRvK09nNjZEWXZMTGpzMFJNbFZu?= =?utf-8?B?R1ZsVklJT2VEbDRKYkpnWU1FT0U5VWIxZElyWlplVU1Ybk1VelVDbTQxaitw?= =?utf-8?B?ZzVGaGlTQklOaG02U2YySXdpR0I3aWNnSEttN3BXa2NQRExxalB0UlFZemsx?= =?utf-8?B?TE81NUxPc0o5UWc5NHhDSFVtRFhYbDNERXZxMjlRRktuTEVJOGJxSXVpbE5r?= =?utf-8?B?aDd4aWhwdzJqSmJsbnRxUkVmUTJvZXRSQW1NSnhKZ3pWWlowNG1hS2swZ2FL?= =?utf-8?B?RnRxcVRocFJacGlocUVTdVl0RWxzd1dYSElyRHVTOVJ0ZTk3SEMrcUFTS1J0?= =?utf-8?B?ZDhGM3gxVnhhUXhvWUlsdEYyQjV6NmFlMWl1dk9RaGorMkgxM01aSGtmcTB6?= =?utf-8?B?eWY0dzZLb2NqSHhlUzNCMlI3Y2dqK1JuS1RsNDE0WlM4WTRHZG1WckFqam9n?= =?utf-8?B?dUZFb1JmbXp0L3B3dEU2TnN1dDYwTTQ2VTY5M3JKRWZpMWxjeHd3YTBzUnJV?= =?utf-8?B?aVNjZ09VQnFDL0YrZ1d2cHQwSURISVRvS0RBTDRiUHcyQ21GeVhBNkc2Q3kx?= =?utf-8?B?U3RmbC9MT2ZxcFZBRjBRMG5qSDRzYXk2a0FzMHJaL3B1RFQyZ1lqc3lsVzlT?= =?utf-8?B?Y3FWWitFLzVBMmpManRrZHlDQWtKRkk4L1N1S2NYYlB5dmRQVEZxY3NVK3hC?= =?utf-8?B?ekZmU0ZuMU8rK2tZL1o0am4vZmJBYzJWVTBmb0RwbER2cnpmMXJIYWs2b1pZ?= =?utf-8?B?U2k1WkhETXVzUHFPUFdtdjNXYjBuK1BHYUtEUHV6bG1oZVJaaWd6U1ZGRUg5?= =?utf-8?B?SThTeW8weGZzMnNFT2M0MUtMM2tJZDRvSXNZVUk5WWRXcFpYQjhnYlBzb1dt?= =?utf-8?B?M1ZOZGhudVBKdThHcE10Zm5yQm1DYzhQMDFSYzFBd3dXYXN6TlQ2cVNKWEUw?= =?utf-8?B?R2NPazR2bEY5YmR0c0VNazA1WjdXWDdncFJuYzJzUmt1SEE2a3BtMEVFUjdi?= =?utf-8?B?MWQyaC9RTGcrMEtlMmJXdXMzRnJpazlxNHF6ZDEvKzJhL21zemdlSksvdHhu?= =?utf-8?B?WmYxcUFzVVd6L0h4elJPOWdoUzBmTDlVbXlNOXMyakEreHVZNTJOaUY4Vitq?= =?utf-8?B?SllnRTdwRVdneDdPWThWMGpEMXcyVEJtWE9tU1Ayb1BCQWRWb0RFTGlRT0NX?= =?utf-8?B?MGNNc1VuVDJ3TU5vbC9ROUw0T3ltOXowSEIxYkZBMEh4WjE5N2QvbnF2eHhh?= =?utf-8?B?RGhtQzF0Z0kycFFkQXMrOUNKWDVvaUM0WUxNT3E5clpYZlNuaGk4VzFQWE1T?= =?utf-8?B?dTBIMzViTGRhNEI4TmxDck90eUd0cktQOG01dEFVR1h1SWc9PQ==?= X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1208;6:iGfBx/FRoMagpS51qniGECALhC2FFLITLenNPya9CyvZ0TxRts6OOvZvlvNxC4qUpc91UIcqQum1NCLl8bqhK93C0Nn0swF5kNDIVf1nkkWJvfM+cSBaY0P+ZznQNqL2kL75s2VBwibN3b+9PSg7bS5LlbeBxC4pGg8FzS4IvU6c45Cs+OaGAVOyletrey6yTxXOrK2fv82teBNia9NrdZWyw7uS3UeHrA0qYHpxlpGn+GuY7RkGyJotbtsji5L3208978j2YvbGYzSccdTRYdILOuVt3KUDHud5HRNL0XLfjdSg4XJ4c1n6Nv7n/ycIJ+lrd054rzOH3mf/R4qRYzcNJC6mkQm5Elo0hbbZCK4=;5:wolNPoj1943nY889HsiTEwa2Jjt2RxqugF0wvcXPgB7lJ4DYzKpeU5baC7zKLsufe/mBVn73vkQ0xqjF4Lkgr00EAlvECkWHkl1ZUZYvAntzeYTV16XHYHR+Qgq/mUCAFeyd0hXjKS5ydfJErLBgzELh3YSVj20MOHgaRynOE6A=;24:yonHHXbwXaA9pM5qckHZOM//X27uloqkw4huTCX1IiFb3HSxibsdUs3juMtNcbmhmxIgz7VvZ+ryRlO/ls6zkRQag72CdM4TVFimVY0SqgE=;7:cQ3uW5Q2P0lrX3uQW8UYcz7j8IiprcZLfQ3xIOWwFpui/SidiRQsWpXa56oYXU448SE7cXjVtNeRY2mKo9oaq97FAvpodSj/fL/OzFeTYGUZnUJN+kcBrYJULevjQE1rpMf2gBl9o268VrVj1LGqCNcSOFJkLgNMqJpeOb5glNLDwI8vYTsdwsMsEL16as3uqIikOgCBhGxHM1pbmH3KgdlmiqWiXF8A1A36uBEPnZxcU1iwC7yRUJnz5wsg2+yf SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1208;20:DQr8ukKvJlZz33LNvg6Qnmwev5F1Y5sOTsavSa+2fKDZDXefxoKMv1jVl0UZYGf9nHIRH2i3dRD0dPGn4iN8pcS48DV67aRIfDmtx0ih5AirAaNZZXDFONr/ijP00GeZCJE2Hx0abCSBDxdhCIfr6BRrUmuGqrgDF6GH/uWgJ33MPa+zvUtGLPibubX0l1dLpHKc6r/Y1hbelxbUdMp6bjfk9TRn+YJHHHG6i4/wmdUA2YCSwNDg54rvKsmWZ5cE X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Jan 2018 23:52:49.8866 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f4329e56-e903-488d-0d2b-08d56517e8b2 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR12MB1208 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a debugfs entry to dump the active device table entries from the IOMMU's table. 'Active' is determined by non-default values in the first and second long words of the DTE. Aside from IOMMU devices, this output should list every device reported by lspci. Use arrays to store DTE bit field definitions for debugfs printing in verbose mode Signed-off-by: Gary R Hook --- drivers/iommu/amd_iommu_debugfs.c | 182 +++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c index 5066d3976912..87840ae9889d 100644 --- a/drivers/iommu/amd_iommu_debugfs.c +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -22,6 +22,16 @@ #define OSCNPRINTF(fmt, ...) \ scnprintf(OBUFP, OBUFSPC, fmt, ## __VA_ARGS__) +#define MAX_PCI_ID 0xFFFF + +#define PRINTDTE(i) OSCNPRINTF("%02x:%02x:%x - " \ + "%016llx %016llx %016llx %016llx\n", \ + PCI_BUS_NUM(i), PCI_SLOT(i), PCI_FUNC(i), \ + amd_iommu_dev_table[i].data[0], \ + amd_iommu_dev_table[i].data[1], \ + amd_iommu_dev_table[i].data[2], \ + amd_iommu_dev_table[i].data[3]) + static struct dentry *iommu_debugfs_dir; static DEFINE_RWLOCK(iommu_debugfs_lock); @@ -81,9 +91,174 @@ static const struct file_operations amd_iommu_debugfs_dtecount_ops = { .write = NULL, }; +struct bits { + uint bit; + uint len; + char *lbl; + char *note; +}; + +static struct bits dte_lft[] = { + { 0, 1, "V:", "[0]" }, + { 1, 1, "TV:", "[1]" }, + { 7, 2, "Host Access Dirty:", "[8:7]" }, + { 9, 3, "Paging Mode:", "[11:9]" }, + { 52, 1, "PPR:", "[52]" }, + { 53, 1, "GPRP:", "[53]" }, + { 54, 1, "GIoV:", "[54]" }, + { 55, 1, "GV:", "[55]" }, + { 56, 2, "GLX:", "[57:56]" }, + { 61, 1, "IR:", "[61]" }, + { 62, 1, "IW:", "[62]" }, + { 96, 1, "I:", "[96]" }, + { 97, 1, "SE:", "[97]" }, + { 98, 1, "SA:", "[98]" }, + { 99, 2, "IOCtl:", "[100:99]" }, +}; +static uint lftlen = sizeof(dte_lft) / sizeof(struct bits); + +static struct bits dte_rght[] = { + { 101, 1, "Cache:", "[101]" }, + { 102, 1, "SD:", "[102]" }, + { 103, 1, "EX :", "[103]" }, + { 104, 2, "SysMgt:", "[105:104]" }, + { 128, 1, "IV:", "[128]" }, + { 129, 4, "IntTabLen:", "[132:129]" }, + { 133, 1, "IG:", "[133]" }, + { 184, 1, "InitPass:", "[184]" }, + { 185, 1, "EIntPass:", "[185]" }, + { 186, 1, "NMIPass:", "[186]" }, + { 188, 2, "IntClt:", "[189:188]" }, + { 190, 1, "Lint0Pass:", "[190]" }, + { 191, 1, "Lint1Pass:", "[191]" }, + { 246, 1, "AttrV:", "[246]" }, + { 247, 1, "Mode0FC:", "[247]" }, +}; +static uint rghtlen = sizeof(dte_rght) / sizeof(struct bits); + +#define DTE_BIT(ds, p, n) ((ds[p/64] >> (p%64)) & ((1ULL< rghtlen ? lftlen : rghtlen; + + for (j = 0; j < max ; j++) { + lft = &dte_lft[j]; + if (j < lftlen) + oboff += OSCNPRINTF("%-19s%3llx %*s", lft->lbl, + DTE_BIT(dte, lft->bit, lft->len), + (j < rghtlen) ? -16 : 1, + lft->note); + else + oboff += OSCNPRINTF("%38s", ""); + + rght = &dte_rght[j]; + if (j < rghtlen) + oboff += OSCNPRINTF(" %-19s%3llx %s\n", rght->lbl, + DTE_BIT(dte, rght->bit, rght->len), + rght->note); + else + oboff += OSCNPRINTF("\n"); + } + + oboff += OSCNPRINTF("%-28s: %4llx %s\n", "Domain ID", + DTE_BIT(dte, 64, 16), "[79:64]"); + oboff += OSCNPRINTF("%-28s: %4llx %s\n", "Snoop Attribute", + DTE_BIT(dte, 248, 8), "[255:248]"); + oboff += OSCNPRINTF("%-28s: %12llx %s\n", "Page Table Root Pointer", + DTE_BIT(dte, 12, 40) << 12, "[51:12]"); + oboff += OSCNPRINTF("%-28s: %12llx %s\n", + "Interrupt Table Root Pointer", + DTE_BIT(dte, 134, 46) << 6, "[179:134]"); + + part1 = DTE_BIT(dte, 107, 21) << 19; + part2 = DTE_BIT(dte, 80, 16) << 3; + part3 = DTE_BIT(dte, 58, 3); + oboff += OSCNPRINTF("%-28s: %12llx %s\n\n", + "Guest CR3 Table Root Pointer", + (part1 | part2 | part3) << 12, + "[127:107][95:80][60:58]"); + + *buflen = obuflen; + *offset = oboff; + *buf = obuf; +} + +static ssize_t amd_iommu_debugfs_dte_read(struct file *filp, + char __user *ubuf, + size_t count, loff_t *offp) +{ + struct amd_iommu *iommu = filp->private_data; + unsigned int obuflen; + unsigned int oboff = 0; + unsigned int istart, iend; + ssize_t ret; + u32 i, n; + char *obuf; + + if (!iommu) + return 0; + + /* Count the number of valid entries in the device table */ + istart = 0; + iend = MAX_PCI_ID; + n = amd_iommu_count_valid_dtes(istart, iend); + if (amd_iommu_verbose) + obuflen = n * 2048; + else + obuflen = n * 80; + + obuf = kmalloc(OBUFLEN, GFP_KERNEL); + if (!obuf) + return -ENOMEM; + + for (i = istart ; i <= iend ; i++) + if ((amd_iommu_dev_table[i].data[0] ^ 0x3) + || amd_iommu_dev_table[i].data[1]) { + if (amd_iommu_verbose) { + oboff += OSCNPRINTF("Device %02x:%02x.%x\n", + PCI_BUS_NUM(i), + PCI_SLOT(i), + PCI_FUNC(i)); + amd_iommu_print_dte_verbose(i, &obuf, + &obuflen, &oboff); + } else { + oboff += PRINTDTE(i); + } + } + + ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff); + kfree(obuf); + + return ret; +} + +static const struct file_operations amd_iommu_debugfs_dte_ops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = amd_iommu_debugfs_dte_read, + .write = NULL, +}; + static char readmetext[] = +"devicetable Print active entries in the device table\n" "count Count of active devices\n" "verbose Provide additional descriptive text\n" +"\n" +" Dumping the Device Table\n" +"The device table is scanned for entries that appear to be active. The\n" +"default range is from 0 to 0xFFFF, and only active entries will be reported\n" "\n"; static ssize_t amd_iommu_debugfs_readme_read(struct file *filp, @@ -134,6 +309,13 @@ void amd_iommu_debugfs_setup(struct amd_iommu *iommu) if (!d_verbose) goto err; + /* Device Table Entries */ + d_dte = debugfs_create_file("devicetable", 0400, + iommu->debugfs_instance, iommu, + &amd_iommu_debugfs_dte_ops); + if (!d_dte) + goto err; + d_dte = debugfs_create_file("count", 0400, iommu->debugfs_instance, iommu, &amd_iommu_debugfs_dtecount_ops);