Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752652AbdFGTSH (ORCPT ); Wed, 7 Jun 2017 15:18:07 -0400 Received: from mail-sn1nam01on0070.outbound.protection.outlook.com ([104.47.32.70]:6208 "EHLO NAM01-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752303AbdFGTR6 (ORCPT ); Wed, 7 Jun 2017 15:17:58 -0400 Authentication-Results: vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=none action=none header.from=amd.com; From: Tom Lendacky Subject: [PATCH v6 26/34] iommu/amd: Allow the AMD IOMMU to work with memory encryption To: linux-arch@vger.kernel.org, linux-efi@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, x86@kernel.org, kexec@lists.infradead.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, linux-mm@kvack.org, iommu@lists.linux-foundation.org Cc: Rik van Riel , Radim =?utf-8?b?S3LEjW3DocWZ?= , Toshimitsu Kani , Arnd Bergmann , Jonathan Corbet , Matt Fleming , "Michael S. Tsirkin" , Joerg Roedel , Konrad Rzeszutek Wilk , Paolo Bonzini , Larry Woodman , Brijesh Singh , Ingo Molnar , Borislav Petkov , Andy Lutomirski , "H. Peter Anvin" , Andrey Ryabinin , Alexander Potapenko , Dave Young , Thomas Gleixner , Dmitry Vyukov Date: Wed, 07 Jun 2017 14:17:45 -0500 Message-ID: <20170607191745.28645.81756.stgit@tlendack-t1.amdoffice.net> In-Reply-To: <20170607191309.28645.15241.stgit@tlendack-t1.amdoffice.net> References: <20170607191309.28645.15241.stgit@tlendack-t1.amdoffice.net> 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.77.1] X-ClientProxiedBy: CY4PR18CA0029.namprd18.prod.outlook.com (10.173.177.15) To CY4PR12MB1141.namprd12.prod.outlook.com (10.168.163.149) X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PR12MB1141: X-MS-Office365-Filtering-Correlation-Id: 97f9203a-7278-4302-6867-08d4add9e2c8 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(48565401081)(201703131423075)(201703031133081);SRVR:CY4PR12MB1141; X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1141;3:xIl1uxUGOGVW4NJUuvrSz8ecbbuz4hywZSGFpNnviHSFEmOvs6gzsFAJs/XobhVz61rjPdSUIjo/HyeoOpoun7L5P66MXT9hFZhmX3RguwR7pgik8p04yRCGJ9X88VKJhhFtvQ7nivjdOKR5MwM2XJlnHxRVBwNIKedlvXAyMTbcycy1th3H9nlzeA6T0skwZ4LFZ758Cf+gZvQphWN7E78kVLjcDOcxEWUO0Y97NI8oTrIRYHsyyVLEIDWKvJUvHwvLCecjcpwiHwjUTL4PL1rLT0IlD7u0V+vgTv9s2Nm4PhADjR8HF8F7vs6wZlxCtq+vtV8Taxns+QHw6J1WUb0L+ZOX+/pj7gZrdo+rVwA=;25:oaffDlKs39MzGWC1zGfRaKMJkeGj+z3V8EZSASb9F6iMQD/AojiOZhYLg44a6rPR3h1TxBO0xHI2bIMiycwyWO2Ns0I++OuP7rGnAuqLQUldiftiWMBB9z2DbaOhC48HZw/luTZIx01OyQloNY5mR6YkjVzpI3oOxk967XZNKt9mCtbfU4zI2y3QAJKlz0ftXm+n38pLTBznM8KReRxXYjNCLU2ILnvx9th0P5TIvf86KCu6OKzvCfaEJSz/gfufXqqDRAnofOdZROkDsWLv/sT3WX7O4rsfjMPj1Zc5mwkeNDBhNNIuuERbo3jxmuxrRF+utQiq5/HeHYH5SqhY9foq8jz2iN17nr/7AzREc+dR0wB1VYgqjPGEmCpnWksoFoAHO6HynUu7afqHWILFcKp0hg086JHFdLcU2GQ3XOaPN6lEl+lrNwRXaLKrgXKvTaa2/vEhbpaf1Qofhxi8TeY4mTFZrGMAqT1eAV5jwLM= X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1141;31:TfKrSnH/ZtbzvXAvvcinsuSlQfPk8VJ1eJbTELkX33Z1LfxBkx/xxMHdECv9Hvpnmb7w437E59XaT9yG0mIRMRva+9TaI3vg3ZCE24L5pcpx5VMDZ+1rYPDwfVpPH87zOHxSoNfDvC7aXbHPduRXolgPgvdcoxzr4NdtU7T4Y1iy1jj1kGfqqBy3QhVTQcqwsqchrCAgHLjYumMwFS12AwIXLTwD0G9Tm6ctQzTIPQ4=;20:e9hm3i6wvqlOktSs6TiXNBKRcYqRZgyIyatYVGaUmlJY1MvSHhZX/fI/jHTIxP8NbYlX/S/aWVEZbdDd6sQtPGYN84u5OAWrcXjDaWDK2ycq3P94WSq6P/Y1vnrffkc/ko08ksE7+07HYpgueKpvPZtHsqBc9oK+GHuDJzeqPrpVMuJg6/Yw+1T5ZcJEv08umfrnSCtuQ4eOr0hfG0pACyT5g/6Ocwc2Y1wSQ0sITHMtHklC/dOlRr8GoVmbFaTVrcXNUHPVjhetCpwSwZJY1KsHdoxX/bCxHwmXGT3D6Rpogw2sMVO7bey1iMlucAqeYNlWoCcZV/pDWxB14yksAFD/lmvDuTvnmOV2863qKZ2CAKfSlU9locq0NwUnoh3pddjQLgPeD61566yazTGZ3D/CudEZmjPy2kJgnRcBfZCQgLzkigh+yNmsrJBOVBhZJDRuRc3WOaQqSeAx8ywyIzdJ5TEAG8lMk1aFRFk4lYrWiFk5Y/BX44YK1O+Oo35K X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(8121501046)(5005006)(93006095)(93001095)(100000703101)(100105400095)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123558100)(20161123564025)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(6072148)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:CY4PR12MB1141;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:CY4PR12MB1141; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtDWTRQUjEyTUIxMTQxOzQ6ZUxEd2F3UUNoZFdDaGtMT3lSSWp1c3h0VnNM?= =?utf-8?B?dU1Od0VzaU9nZUk0T1lDWjlCWDErVytrRk5GdHZWdmlGYWxHakFSd3l2SW5u?= =?utf-8?B?bm0vMWhiM1ZjRlA3V1hvL1htWUdRR3F4Y1Vybi9TNWFPTWtpeElNSVZzaEp2?= =?utf-8?B?bm9OdFZCRi92WmltQzY1N0p5WmNBa0t6dXhMVWpwc1JmbTZ4RXhoNm52ZGpU?= =?utf-8?B?b2hWbFJ5NVR0TkRwTURKNGxuZFkxd3h4NklYbzVPTmVVNDR2ajA0WmNYTUEz?= =?utf-8?B?RWc3aGNEeWo5SC94emJpN2daYVhHeDdreU1WdWRBd1VwV0ZwQUwra21kTkpL?= =?utf-8?B?RnBobWFCNEJ0bnF5bzZLSVp6UmNkZGlielVaVFFpQmZFT2NQcElkSkpQNXBI?= =?utf-8?B?RGwwamVtZURYNVZXWnFmTVh2OE5maXNvZTRibTM0bCt2eTE3cDllczhrSkVE?= =?utf-8?B?THZZdnpDVmhNZC9QT2RPRXp2eHI1MldxTmpHYzJUSzB2OGRncUdSSkxOTGpH?= =?utf-8?B?MU56cXQwcFN5eEduYmZsUGRZd2hLbVdIQlg5M3F2MXRpR0VPSFpNdENUMWsz?= =?utf-8?B?b25IbWJUbzV0b09qT1pnSDhlU3p1OGNpaUFzWWFTWWpRTnJQNS8rYVAxa3ds?= =?utf-8?B?dWR5SFc2NmVLRXp1OEkvcjdhN3UrS0JXd1ZVWWZvYVdwajhJTm9QWFRJUHhk?= =?utf-8?B?cFdQM3Axc2U3SUdycEZHMnZPM0hvTEZKTVVTaVA4Y0dPaEhZM0pwdTFDODRm?= =?utf-8?B?WjlybjZldzd6RkJTZkdKbU9iOGZaT0xlZC9sWlk5aEppSmRybHBhbFRyeUlz?= =?utf-8?B?elpYd2U4NU9LZy9lenRwRDg4bWRDRnNRa2VqTU1ZRzlqMG1DbGJyYzZhTTdX?= =?utf-8?B?YW1PTXVnK3lvZldyb0FrL0xVeExFdE4vQ1RaODFqVWdwakxhTkZEVk5CN256?= =?utf-8?B?eVpvNXp1Q1FTSytBdG9lUTEvRGVocWYvMWFrb0pMK0YyUHJDOWFwNUNsTnhN?= =?utf-8?B?a21Ga3RIQURBOHArU0VuK2dHTUFaWWNUb0h6ODhNVFpnVjgvNWdwZ1VYVXQz?= =?utf-8?B?NmRPQ3diL210cFlTbkxKVHp5WUM2ODZWZGpoOWxLMXFDRE8yMEhXQWxzZ0pE?= =?utf-8?B?YmtYSzNDd284Um9PRWQ2dVBZem1LS1ZBV1N0bEowdHVOV1FpZmpVT0tpNlNE?= =?utf-8?B?WjZLZ2xYeHQ4aVg0R2V1dk1uYWhSb0RnZjRybDRTY2g2eTN3ai90V29Va0Nt?= =?utf-8?B?SzdHMWZ6eWtTN3ZmV3IrVTE2UGd4N2VLQ2hKVHVnUWlPTWUyNGl6Y2Q2OG8r?= =?utf-8?B?OURtdXZDenBERkVGZDA5TjBqNXUrWXZLWlRSTVdVNnNBZjlVSzhTcmNWamw4?= =?utf-8?B?VmV2QkhPWU5wZFk0aHlHRE9GREJUcys2LzArQll0YUU2WkNaWFNLSTZmSTBE?= =?utf-8?B?cno5c25kK3lrL09XWmMrL1lhYUU3Zk91RFBKMXNpM1RiQWcrOENjYlNCNnlF?= =?utf-8?B?TjJISTdzVWIrSzV0d0FaUnFLM0x5T0RyK3NGRUZuMFRURjZIcUszd2lNSDJG?= =?utf-8?B?aXJRaDZ1VE5Vd1YwbCtKNFNVZUNkVGk0K1JISkNmaEFhTVVieGZmWUdFbVZL?= =?utf-8?Q?8rdVpnxqt7GV07dc//1?= X-Forefront-PRVS: 03319F6FEF X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(39450400003)(39840400002)(39860400002)(39410400002)(39850400002)(39400400002)(9686003)(54906002)(55016002)(6506006)(66066001)(4326008)(47776003)(110136004)(103116003)(25786009)(38730400002)(72206003)(478600001)(575784001)(83506001)(305945005)(7736002)(86362001)(76176999)(50466002)(53936002)(54356999)(97746001)(7416002)(7406005)(23676002)(1076002)(6116002)(33646002)(3846002)(50986999)(230700001)(53416004)(42186005)(5660300001)(4001350100001)(8676002)(81166006)(2906002)(2950100002)(6666003)(189998001)(921003)(1121003)(217873001);DIR:OUT;SFP:1101;SCL:1;SRVR:CY4PR12MB1141;H:tlendack-t1.amdoffice.net;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtDWTRQUjEyTUIxMTQxOzIzOjBCbGxIMWRmdFN4b2xOUGpJdHBzTUJDcy9D?= =?utf-8?B?c0g4WkI3UjFVMzZRQzJtTHJKL2hPZGdZVnBIRWJ4VGtjcXMySGJWSE9SdWtr?= =?utf-8?B?SDRCR0R6cTRMaERjYzF5VEF6NGNxUUdzUzhhZS8xamZmSVJqUzV3YjhkbDB0?= =?utf-8?B?RWpmck9CNjhpazFsZENLSWU1VXpGcElPbi9YeVNCbXpUSXYvbFljTlg3TTJy?= =?utf-8?B?S1grMjVIYlg0c3NGSnZoU1QzMlFBWDhpNmRGYjU5TFV4S2s0WFZkZlB4YnNO?= =?utf-8?B?ZVl0YmxMU1J6MmdYWmtNUm50d0gxS3ZGaE4wdTNyOERmWE5FNmh6dEVtWmRv?= =?utf-8?B?SVR2SWtQQ2ZBSU9NUzdSYWMvVkZpNUs5UERFdm5uQXhSbUhWSW8wcGNOODQ4?= =?utf-8?B?NGdzWXdHUXlDeGt6bGI0YVBwZm1RcGw1alJlUldnWmswQU9iQm5uSEVla2Js?= =?utf-8?B?c1JXdGI3VEdLM3M1V1g1RlFZUkczeTBhcjdzZ3BXd0FNSC9KUGVrMisrZmFh?= =?utf-8?B?ZEtOa2lTdGxYcER3bjV3K3lWbHBKNG01cGxvU2s0aEpPa0pObjU4bXRKL0xm?= =?utf-8?B?QmpvUkRQREtBb2lnU1dFVCtvWVFqQkJaVUdOWXlWZFB4SFJPZzdaS2ovRHZ3?= =?utf-8?B?UWFWWUd4elNDdGkzSm1tZURjSkVFVWFVNEozNld0d2dJYk9aejZpSnVkVzBw?= =?utf-8?B?OGhNMXJ3N0Z1WnkwcE1ZbWl6VGNRdEs4aCtPVzdMY2NWRE11L1FHVW9lUVFS?= =?utf-8?B?N0FtZDVwdVZyYXdOdUNpZnZsTzFLYkY4Ky91cXBMbENIa0VKS2RrOTZyTCty?= =?utf-8?B?ZnBwWm1FRExsUHZJRFd0bzd2YWRKak1wNEVwcHlaS0xQTnQ1czVSclJpNUVB?= =?utf-8?B?aWRFWG9mQUZsRlRtdFR2UHo3Q0hYUlFUSHV3RytWSlNCczdNc0xHdTNmKzN4?= =?utf-8?B?S2JvRzRTWENYY0VON05YUUNab0VIdUM5bWlMWVR6RHJzbXd2L1lOK25zd2VT?= =?utf-8?B?d3J6UW4xbk00Vi91YVVMSld3TXYrd0tBSy81QXNUSkVQU2tqa094eVJFcG1k?= =?utf-8?B?MmIxQzNiR2Y5OVVWVk1uTkNSTXVZQXZtVlptc3dwVW5weWhGSkhuVmRuWHN5?= =?utf-8?B?T3RIVGhwTllmdW9uenpGeWV0bXNqb3VBMEpnWWJ6T2tUL3VCTzgzU3ZNZUVT?= =?utf-8?B?VHR2Qk9RVXk3U3BCeDNibmJZY3FYcGdzZm81dHFSdDdrQXFZVGN0emt3YWZj?= =?utf-8?B?Ryt3clBjcWZlUEdobG1ZMExxRWczeHNkakl0MHZybStNakpYeC94eGRoOWow?= =?utf-8?B?Und3djBpd3ZQZjZacTR0ZUh5dzB1RnV1UkFhZUpSZTEvVlV3WXNubkh6eGRF?= =?utf-8?B?UFFrT3NhOFpxejJObU5Rd0hLNm92WncrRzd3aXdid21QNUYyeno3Z25DanNO?= =?utf-8?B?bWlCb2RUaVJ5cmVNWGl5VWpxS0p5UVlNeEtVUzh6cnFtWlpVdjlXbXdObnkr?= =?utf-8?B?WGEvQkRQSmxTZG9GTzhCQ25VYXQreDhWZnJ5UU52Tk1SUFh2SzJGR2tIZDBm?= =?utf-8?B?Tk9tK1IxMWMxN1NkNGVxMTdHNHd4V1FoS2lKZm5BVytPdHI0TnhxMkZSbmNk?= =?utf-8?B?WldZQ0tSMHdOc09QVnY0bW55dUNCT1JxZmQ1YlhML3dmajBHSUZ1R0NpYys5?= =?utf-8?B?RWRrTDhSVk1nMCt4SGxmUk1aS3EydU9qcnk2clJpMGxMY3ZTKzExYmZobTZ0?= =?utf-8?Q?EPMQYjSUvDyxfN6beFVUEuzQpPFbwEmYXJNQU=3D?= X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1141;6:/D823NfAyrcLEfSR9azD5OdUlsHhVHXWie7VWIeUgF13qGnu7OqWrJ2YkI9ANoDNOmz1LsmEFNBQ18VLqs3AW5nwhRgSJExjMyCbAoIHSU1d+NvgO0J9npDgVTfU7Bl5y/73uHX45drsFNqV7Hmg0GjJLzcLAhi6Bs25+xKG3LV2FKJKTvncSr8d5MGhDASPpMcQ8kyLk7pVSdjgumABRJE5EfgmZOozwJwuoiGesT8FWxRd1zapwmNsHd7VxCYQ8Edzrn9OTtCZGBdCHZGTRieET/NA9m58AB+keoUAbFtzkSP4B7t7cz3d4R7LkGhzwGJ6mrlN91MfqKKz+XXxudRSoHTsmqfJhXDlk7qR34XDP1ZNqPgMAB/KnRUNDAUknJKBlCvmlbsf3wBUsEUok5Gz11jB3Uw2k3mPAyAeqaNbarG0nD7U85gnZ3qMu6e0VzCmJvkrHqt/2qjhE2oQC3gbdsxA7qNrETQgOn1StXYDAbgjEMDYbSCKY0nvfOVU78PFeV2L8LyIOlu+L1O3Taj3HDxdZ7ZcQeJH1gu4i6w= X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1141;5:2+X3mJ2WmkGS+Y3W46ashrs6OZDKn136rCTVsD1cjAtWaJVXpjPH8VyU+PHaUjc+W3rqPiBdcnWDNewbAU8WOdERRM90rCOMQS86HBQ/PGAdqZJgGKoJ2JruJhRNgWY2oz/tP65y1AvHJRqTXnaNyrhS+JQtojnhC6ejEfnScvAB6NDq2jIkLEtBtrzv9mqJ8+pcvz59tdtwKUvz2clUlelBwPl7A5kZjYzbDImjmiTaNl9zucTwIoO4sdu42Dimg1gnAbks/AMaGptck8+rSU6khrhpEN10O1HmG18qTE7Mhzx2hoxtA++fs+y6ALdvL7qoqJCzpo4wztdSJclsxTRUYP0dXwbx4UoDLyEEIgmxvDKdabLanCbtqUm4ZFHndJizRhUpYjaiP8q1KS1eFhtriv4yxTd/DlM69E2WOIWIVoFjkgxLf/PNKiXuYA1Br0VDftIGczoCvTVI/vY+pyWXWExOntOtUIE/7ikw9HBohhMhRrj7Sb6QEzk3zJDD;24:PoT1iUofadfFzebE/z3VNsut5eMfrFS/ShQ3+MrLpmP7J7uNtVUN86WVWR5FoIljVq8AXyyq4h+CiU2DbtozGBO1kHvGyNu7EyNSKGIZeNE= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1141;7:1YZYLBvFk0sSDsviqxdgnJ0fhtujWVsZmzJ02K5yyyKTF1XnF0EgBdH+R+nBoyqjDpgLwH0FZPMRxu8+Ie3/n3+QFlBl6UrjY2nVATCXajHqweqZstVFEfXSkLaMb8ZZcFe/NV7uULujwyUALLCyDiXfaxojfKxmQJKK+RjZxUc8gTXdpn8/g2sUV4Q2XQ8H/USnz8ySocU8hIuBK2Dzd4me0QGEj7+dc5Nc5uowvU70FkSMB33cy7CF6gckT8OHSYbtftu0klpGykKm/3PdlCXCTPM+v0Jp1ne57K6M9FExVLWnHyh1MDabcxpGqj/uSfnXA2H3oyFGjSYxnOgo6w==;20:2AQwhHEjqoHelBpW/f1r4ZBHTFIcuyr7INU7/pTUEXbwgI2AxEZ83I2gjQwSDfCvOhudoaIJmU/o9pk7dp8K5i4Fb62UL3734MTZWBa9uuUwCqrAmhhTCNysG8H5eg0baesZpIRvKRbQlbA3LQJANk+48uXLqQxzTKIXEUXqLypnkYLxjPlg5pTMiq05SK+95uj5Jtyp/9uZ4rad5NGRu226sVh0IaxHMlVwOuCluV/1iisHD5kB4607QiyHGt8N X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Jun 2017 19:17:48.0219 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR12MB1141 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 11449 Lines: 347 The IOMMU is programmed with physical addresses for the various tables and buffers that are used to communicate between the device and the driver. When the driver allocates this memory it is encrypted. In order for the IOMMU to access the memory as encrypted the encryption mask needs to be included in these physical addresses during configuration. The PTE entries created by the IOMMU should also include the encryption mask so that when the device behind the IOMMU performs a DMA, the DMA will be performed to encrypted memory. Signed-off-by: Tom Lendacky --- arch/x86/include/asm/mem_encrypt.h | 7 +++++++ arch/x86/mm/mem_encrypt.c | 30 ++++++++++++++++++++++++++++++ drivers/iommu/amd_iommu.c | 36 +++++++++++++++++++----------------- drivers/iommu/amd_iommu_init.c | 18 ++++++++++++------ drivers/iommu/amd_iommu_proto.h | 10 ++++++++++ drivers/iommu/amd_iommu_types.h | 2 +- include/asm-generic/mem_encrypt.h | 5 +++++ 7 files changed, 84 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h index c7a2525..d86e544 100644 --- a/arch/x86/include/asm/mem_encrypt.h +++ b/arch/x86/include/asm/mem_encrypt.h @@ -31,6 +31,8 @@ void __init sme_early_decrypt(resource_size_t paddr, void __init sme_early_init(void); +bool sme_iommu_supported(void); + /* Architecture __weak replacement functions */ void __init mem_encrypt_init(void); @@ -62,6 +64,11 @@ static inline void __init sme_early_init(void) { } +static inline bool sme_iommu_supported(void) +{ + return true; +} + #endif /* CONFIG_AMD_MEM_ENCRYPT */ static inline bool sme_active(void) diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c index 5d7c51d..018b58a 100644 --- a/arch/x86/mm/mem_encrypt.c +++ b/arch/x86/mm/mem_encrypt.c @@ -197,6 +197,36 @@ void __init sme_early_init(void) protection_map[i] = pgprot_encrypted(protection_map[i]); } +bool sme_iommu_supported(void) +{ + struct cpuinfo_x86 *c = &boot_cpu_data; + + if (!sme_me_mask || (c->x86 != 0x17)) + return true; + + /* For Fam17h, a specific level of support is required */ + switch (c->microcode & 0xf000) { + case 0x0000: + return false; + case 0x1000: + switch (c->microcode & 0x0f00) { + case 0x0000: + return false; + case 0x0100: + if ((c->microcode & 0xff) < 0x26) + return false; + break; + case 0x0200: + if ((c->microcode & 0xff) < 0x05) + return false; + break; + } + break; + } + + return true; +} + /* Architecture __weak replacement functions */ void __init mem_encrypt_init(void) { diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 63cacf5..94eb130 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -544,7 +544,7 @@ static void dump_dte_entry(u16 devid) static void dump_command(unsigned long phys_addr) { - struct iommu_cmd *cmd = phys_to_virt(phys_addr); + struct iommu_cmd *cmd = iommu_phys_to_virt(phys_addr); int i; for (i = 0; i < 4; ++i) @@ -863,13 +863,15 @@ static void copy_cmd_to_buffer(struct amd_iommu *iommu, writel(tail, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); } -static void build_completion_wait(struct iommu_cmd *cmd, u64 address) +static void build_completion_wait(struct iommu_cmd *cmd, volatile u64 *sem) { + u64 address = iommu_virt_to_phys((void *)sem); + WARN_ON(address & 0x7ULL); memset(cmd, 0, sizeof(*cmd)); - cmd->data[0] = lower_32_bits(__pa(address)) | CMD_COMPL_WAIT_STORE_MASK; - cmd->data[1] = upper_32_bits(__pa(address)); + cmd->data[0] = lower_32_bits(address) | CMD_COMPL_WAIT_STORE_MASK; + cmd->data[1] = upper_32_bits(address); cmd->data[2] = 1; CMD_SET_TYPE(cmd, CMD_COMPL_WAIT); } @@ -1033,7 +1035,7 @@ static int __iommu_queue_command_sync(struct amd_iommu *iommu, iommu->cmd_sem = 0; - build_completion_wait(&sync_cmd, (u64)&iommu->cmd_sem); + build_completion_wait(&sync_cmd, &iommu->cmd_sem); copy_cmd_to_buffer(iommu, &sync_cmd, tail); if ((ret = wait_on_sem(&iommu->cmd_sem)) != 0) @@ -1083,7 +1085,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu) return 0; - build_completion_wait(&cmd, (u64)&iommu->cmd_sem); + build_completion_wait(&cmd, &iommu->cmd_sem); spin_lock_irqsave(&iommu->lock, flags); @@ -1328,7 +1330,7 @@ static bool increase_address_space(struct protection_domain *domain, return false; *pte = PM_LEVEL_PDE(domain->mode, - virt_to_phys(domain->pt_root)); + iommu_virt_to_phys(domain->pt_root)); domain->pt_root = pte; domain->mode += 1; domain->updated = true; @@ -1365,7 +1367,7 @@ static u64 *alloc_pte(struct protection_domain *domain, if (!page) return NULL; - __npte = PM_LEVEL_PDE(level, virt_to_phys(page)); + __npte = PM_LEVEL_PDE(level, iommu_virt_to_phys(page)); /* pte could have been changed somewhere. */ if (cmpxchg64(pte, __pte, __npte) != __pte) { @@ -1481,10 +1483,10 @@ static int iommu_map_page(struct protection_domain *dom, return -EBUSY; if (count > 1) { - __pte = PAGE_SIZE_PTE(phys_addr, page_size); + __pte = PAGE_SIZE_PTE(__sme_set(phys_addr), page_size); __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC; } else - __pte = phys_addr | IOMMU_PTE_P | IOMMU_PTE_FC; + __pte = __sme_set(phys_addr) | IOMMU_PTE_P | IOMMU_PTE_FC; if (prot & IOMMU_PROT_IR) __pte |= IOMMU_PTE_IR; @@ -1700,7 +1702,7 @@ static void free_gcr3_tbl_level1(u64 *tbl) if (!(tbl[i] & GCR3_VALID)) continue; - ptr = __va(tbl[i] & PAGE_MASK); + ptr = iommu_phys_to_virt(tbl[i] & PAGE_MASK); free_page((unsigned long)ptr); } @@ -1715,7 +1717,7 @@ static void free_gcr3_tbl_level2(u64 *tbl) if (!(tbl[i] & GCR3_VALID)) continue; - ptr = __va(tbl[i] & PAGE_MASK); + ptr = iommu_phys_to_virt(tbl[i] & PAGE_MASK); free_gcr3_tbl_level1(ptr); } @@ -1807,7 +1809,7 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats) u64 flags = 0; if (domain->mode != PAGE_MODE_NONE) - pte_root = virt_to_phys(domain->pt_root); + pte_root = iommu_virt_to_phys(domain->pt_root); pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) << DEV_ENTRY_MODE_SHIFT; @@ -1819,7 +1821,7 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats) flags |= DTE_FLAG_IOTLB; if (domain->flags & PD_IOMMUV2_MASK) { - u64 gcr3 = __pa(domain->gcr3_tbl); + u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl); u64 glx = domain->glx; u64 tmp; @@ -3470,10 +3472,10 @@ static u64 *__get_gcr3_pte(u64 *root, int level, int pasid, bool alloc) if (root == NULL) return NULL; - *pte = __pa(root) | GCR3_VALID; + *pte = iommu_virt_to_phys(root) | GCR3_VALID; } - root = __va(*pte & PAGE_MASK); + root = iommu_phys_to_virt(*pte & PAGE_MASK); level -= 1; } @@ -3652,7 +3654,7 @@ static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) dte = amd_iommu_dev_table[devid].data[2]; dte &= ~DTE_IRQ_PHYS_ADDR_MASK; - dte |= virt_to_phys(table->table); + dte |= iommu_virt_to_phys(table->table); dte |= DTE_IRQ_REMAP_INTCTL; dte |= DTE_IRQ_TABLE_LEN; dte |= DTE_IRQ_REMAP_ENABLE; diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 5a11328..2870a6b 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -346,7 +347,7 @@ static void iommu_set_device_table(struct amd_iommu *iommu) BUG_ON(iommu->mmio_base == NULL); - entry = virt_to_phys(amd_iommu_dev_table); + entry = iommu_virt_to_phys(amd_iommu_dev_table); entry |= (dev_table_size >> 12) - 1; memcpy_toio(iommu->mmio_base + MMIO_DEV_TABLE_OFFSET, &entry, sizeof(entry)); @@ -602,7 +603,7 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu) BUG_ON(iommu->cmd_buf == NULL); - entry = (u64)virt_to_phys(iommu->cmd_buf); + entry = iommu_virt_to_phys(iommu->cmd_buf); entry |= MMIO_CMD_SIZE_512; memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET, @@ -631,7 +632,7 @@ static void iommu_enable_event_buffer(struct amd_iommu *iommu) BUG_ON(iommu->evt_buf == NULL); - entry = (u64)virt_to_phys(iommu->evt_buf) | EVT_LEN_MASK; + entry = iommu_virt_to_phys(iommu->evt_buf) | EVT_LEN_MASK; memcpy_toio(iommu->mmio_base + MMIO_EVT_BUF_OFFSET, &entry, sizeof(entry)); @@ -664,7 +665,7 @@ static void iommu_enable_ppr_log(struct amd_iommu *iommu) if (iommu->ppr_log == NULL) return; - entry = (u64)virt_to_phys(iommu->ppr_log) | PPR_LOG_SIZE_512; + entry = iommu_virt_to_phys(iommu->ppr_log) | PPR_LOG_SIZE_512; memcpy_toio(iommu->mmio_base + MMIO_PPR_LOG_OFFSET, &entry, sizeof(entry)); @@ -744,10 +745,10 @@ static int iommu_init_ga_log(struct amd_iommu *iommu) if (!iommu->ga_log_tail) goto err_out; - entry = (u64)virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512; + entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512; memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET, &entry, sizeof(entry)); - entry = ((u64)virt_to_phys(iommu->ga_log) & 0xFFFFFFFFFFFFFULL) & ~7ULL; + entry = (iommu_virt_to_phys(iommu->ga_log) & 0xFFFFFFFFFFFFFULL) & ~7ULL; memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET, &entry, sizeof(entry)); writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET); @@ -2552,6 +2553,11 @@ int __init amd_iommu_detect(void) if (amd_iommu_disabled) return -ENODEV; + if (!sme_iommu_supported()) { + pr_notice("AMD-Vi: IOMMU not supported when SME is active\n"); + return -ENODEV; + } + ret = iommu_go_to_state(IOMMU_IVRS_DETECTED); if (ret) return ret; diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 466260f..3f12fb2 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -87,4 +87,14 @@ static inline bool iommu_feature(struct amd_iommu *iommu, u64 f) return !!(iommu->features & f); } +static inline u64 iommu_virt_to_phys(void *vaddr) +{ + return (u64)__sme_set(virt_to_phys(vaddr)); +} + +static inline void *iommu_phys_to_virt(unsigned long paddr) +{ + return phys_to_virt(__sme_clr(paddr)); +} + #endif /* _ASM_X86_AMD_IOMMU_PROTO_H */ diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 4de8f41..3ce587d 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -343,7 +343,7 @@ #define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL) #define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P) -#define IOMMU_PTE_PAGE(pte) (phys_to_virt((pte) & IOMMU_PAGE_MASK)) +#define IOMMU_PTE_PAGE(pte) (iommu_phys_to_virt((pte) & IOMMU_PAGE_MASK)) #define IOMMU_PTE_MODE(pte) (((pte) >> 9) & 0x07) #define IOMMU_PROT_MASK 0x03 diff --git a/include/asm-generic/mem_encrypt.h b/include/asm-generic/mem_encrypt.h index fb02ff0..bbc49e1 100644 --- a/include/asm-generic/mem_encrypt.h +++ b/include/asm-generic/mem_encrypt.h @@ -27,6 +27,11 @@ static inline u64 sme_dma_mask(void) return 0ULL; } +static inline bool sme_iommu_supported(void) +{ + return true; +} + /* * The __sme_set() and __sme_clr() macros are useful for adding or removing * the encryption mask from a value (e.g. when dealing with pagetable