From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753491AbdI0PRw (ORCPT ); Wed, 27 Sep 2017 11:17:52 -0400 Received: from mail-by2nam03on0084.outbound.protection.outlook.com ([104.47.42.84]:59616 "EHLO NAM03-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753185AbdI0POO (ORCPT ); Wed, 27 Sep 2017 11:14:14 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; From: Brijesh Singh To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, x86@kernel.org Cc: Tom Lendacky , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Borislav Petkov , "Kirill A. Shutemov" , Laura Abbott , Andy Lutomirski , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Andrew Morton , Dan Williams , Kees Cook , Brijesh Singh Subject: [Part1 PATCH v5 10/17] x86/mm, resource: Use PAGE_KERNEL protection for ioremap of memory pages Date: Wed, 27 Sep 2017 10:13:22 -0500 Message-Id: <20170927151329.70011-11-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20170927151329.70011-1-brijesh.singh@amd.com> References: <20170927151329.70011-1-brijesh.singh@amd.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Originating-IP: [165.204.78.1] X-ClientProxiedBy: BN6PR04CA0033.namprd04.prod.outlook.com (10.174.93.150) To CY1PR12MB0152.namprd12.prod.outlook.com (10.161.173.22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: fde6a537-803a-44f5-67f6-08d505ba6314 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(2017030254152)(48565401081)(2017052603199)(201703131423075)(201703031133081)(201702281549075);SRVR:CY1PR12MB0152; X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0152;3:xBQiDQci2BRrJEhaRF/5FJgcHen3wKWvnlAv8Z0xKx/JWe3sMriOHZVrxlblc29tmsMuVs5WDWb0bIPlIiryAUG9N2hAIB/kQl2ny8cw2lK/KXZiFEsCCwjhu2y1BbJs9xig953CMlTwEg/8xpPREBcW6BK8C7nCxh7k/NvgvhjAPavPDGsCuPYHjY/i1Z+g0HACHnT29Qqt0i6QbqBDZh9QTwRza39C3pUgd+q77bKCOh+XEp5KLqdbYNJLv1+K;25:5vbq1v4VM43Nrpm0451z5e6dqQhXQrORd4lBg86aNz+Yfg5yGx3d3WaWKAEzgT2GJcynqAVstbXeyDMXb3bN50401FKLsce0tOnBJKrCcLvzDWiCpyecKB0cIjUrXkHqYiicdfuI83httbvDKuMOcULh5bZGErWsGgNpEiE9A10bpGDo5incewWxtSyJrzDa4w3wTkn69fSs+5pArhHneLNoc4RHx5i3aV0xkPbp5+0luZzljFe0XAQcNfMM4AjosaGvZfn0X+3bg1lyxNfTxdGTsp5LhotY496iJ6fCer3Rcfc/DdUu6rxSGqzV4bPDa5wofePwlZAl70kM+p6AOw==;31:Qx+X70rcwI0+f7kyVQkCYclEyVEClRX5rF8srCbe6r7QCDn4wDRC+g3+AnwTNP1kBHVjYhQKpHM50wcJJ66WJaJuSLCPEK9Qg4qDTNx7Y8I1qv07+HOT6MWTLkBcfIruQnMA6NyrgFiC31uw/o3+CRXVoPRr2X+3r1aZQqxyoLH3Ea0uNbW34dLkwCl8T/fPk+bjXBksDB8jAOGYgSKsS166RzNH661ecNBNuxclB4Y= X-MS-TrafficTypeDiagnostic: CY1PR12MB0152: X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0152;20:HKOpe6yXNxUOh3Z0BtDWcH4f3tMW71fxkrT1OG6Mx2ctyracfkqO1wJou51ES0Wgywgks+AL0UNJ2mkGEiWi+dgjD9Xp9bvWxviAPdUQbFdV2iZ/Mi17lDme9YORB/FyrkiXbYHkHqhP+uvbGTDw1mPE7om53iYuwhoXhPd1zDzLK4/Jk8WnmZb4a2l30WhN90jcarE3Xuj2P9XHWi+iAqaqsM0rc7kZcAy9LAo7VOnRX97dkkfXfTaFOOLvld71lWZNTDwGMv1DwzOTlKSAEHnnULEVKKoeTX9Otb50QSd0eFFZTpC4+lLeni9+KQLeGGGNiDVdBaoyUOyfEp/2wiCKF+TetoaR491Nb2y9FskjKvz+mQsKm0uOqEUfNAmGLhyCtZrD7iUpOEUQFf5M2VjLA4DAIMVi6K1PwlcLsjsM4pJURbb58gotpkR8nZym2NTcPSUgWHb1WkOukyj7gwlV5YWqmdYRn2pR5+N03340kamjA4Pevp/hhXImk8FN;4:JvMdhNqw5fqJbZg1tHgk+HGBul2WAYNteZYR4Ay4xeMrfWlPAv+UTTR4gryl9ftgPXCMq3PLXgMAiterVe6myav3fooz/DMjkc0IYHpBiKGJx4uPR2eZxyREY6InX/AbJ+RcdGGpk8478001tBAt/NVGZl+VjNd4P2rd6cDJNT498X8NiiCvyk2wC2E/GAYbgMnoDlS9lQTYMeJWMFOrzQ9jY5yiHE48lmUUSzfXhGnaFJDIxgCkaixe9AgR100ZCFX2h1PdWT4KJtz/9JDTupLB1U+tlpDBoSOTutsb4q9frijlRfORUw67HpWYsWZMH6xrhbmkAxUs0g4xT9oMrYCU+fgmRWGAkhFk6fxqGaA= X-Exchange-Antispam-Report-Test: UriScan:(9452136761055)(767451399110)(228905959029699); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(10201501046)(3002001)(93006095)(93001095)(100000703101)(100105400095)(6055026)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123560025)(20161123555025)(20161123562025)(20161123564025)(20161123558100)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:CY1PR12MB0152;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:CY1PR12MB0152; X-Forefront-PRVS: 04433051BF X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(346002)(376002)(39860400002)(199003)(189002)(3846002)(25786009)(6116002)(23676002)(53416004)(106356001)(8936002)(4326008)(54906003)(1076002)(6486002)(50226002)(8676002)(305945005)(50466002)(81156014)(81166006)(6666003)(68736007)(36756003)(189998001)(7736002)(105586002)(97736004)(2870700001)(53936002)(7416002)(2950100002)(101416001)(478600001)(16526017)(76176999)(50986999)(316002)(47776003)(66066001)(86362001)(33646002)(5660300001)(575784001)(2906002);DIR:OUT;SFP:1101;SCL:1;SRVR:CY1PR12MB0152;H:ubuntu-010236106000.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtDWTFQUjEyTUIwMTUyOzIzOld5N2VVWW8vWStxWWxIZExqdEZ1eEZhYlNE?= =?utf-8?B?QmRPUkw2QWRsK21IckltR2MvVVNlUzJNbnNrSkxtWHlXVE1vNndPRzhQK3hC?= =?utf-8?B?V1VKREVXN2JkWWhKaS9PcGhOQUhZMWxINkY4aENubE0xZ2hxWXo0TVVrWWx1?= =?utf-8?B?ajFRSllsSURTeDFNWFdZRSs5T1FwSGFYY2l5QXZzcXRld1RjUlF4ZElIeG1X?= =?utf-8?B?T1dyNjNWUWtqYU02bVZncW5yOFVTbjZUNzFjZ1l3TXhJYlJlK1RSTlp5ZEtD?= =?utf-8?B?WmV5VHdIQVJKeU9OOVF4TlMra2d6U00zUy96bC9zaHlqdzVNaU51d296WVgx?= =?utf-8?B?MVpmNVJrTjFtbXJocE40cGVDR0Z0Nkl5REZmZ1ZpNE9FcDBmOGZ1Z1drNmdj?= =?utf-8?B?WUVMTUY1K3F6STMzejg1bE1leG9remVUQWVUNWxpUm10cVNDQkN0SERRNXpE?= =?utf-8?B?dTQ1YnhXZmw3NVg1YnU0bXhZOGNNTCtoamhFYjZtS2Njck9WTC9kMm5LYyt5?= =?utf-8?B?NjZRMTRPTEVnU05yOWNtR0lmUFpubHUrTTdnZHR2d0ZmREhQUldmb094aDV3?= =?utf-8?B?WEIvakI4WHdheGZQVG5Wazc4dWdMbHdCTXdxT3hQUi9TTWVmYmNld3NqcGhj?= =?utf-8?B?Z21uZEZJaVZkcnFJMXdpMkJwR09ZNlgrWUdEZVpDeStFeEt1NjNVSzlJb1Uz?= =?utf-8?B?cnZmOEhXTlh6SGs3VDg4WG9rcFBBZ0NqazkxMnZodmROTTRRNklOVW1RaTNl?= =?utf-8?B?eHlBT3FJRzFaK05TMnR1TXV2VW5uTWhIdnV2N2Z1citESlpxN0h2OFNOc1lY?= =?utf-8?B?VG5IMnVIWVovaW1kUXE5czhocG9SRzlienA1WGhhL08zYVhpaURmNkhkV3Fs?= =?utf-8?B?WWZIRmwwcXYyVXIxWUVwSit6VDRVZ3BveEY3cTRLQUwrY084VEIrbW9OVm9D?= =?utf-8?B?SW5pajd0aVlhak45SmJCQ3MrRkx3UlRxODdZQ0k3MVlDdjVuRnI2c1JxNE9C?= =?utf-8?B?K09ZRnRKN3c3VWw3TVpsbER1NGFCSnZvSktxRHlsVFJKSThCVFEzN1ZPOGY3?= =?utf-8?B?VDRWc3BDcndQbEdEQWRocE5qeFMwNGV4bGRmbjRtdm9Rcy9HSk95NlhQNHVw?= =?utf-8?B?b2RnbzZwZ2NQNEJIMmZMWW5DRlZNdTdSLytuOWIrb1FONU1rbXMwTHVQOVA1?= =?utf-8?B?TXo0TFNjcjhPTHpZVkVEZ1RQci9Qa2JGcUpwOHVvb0xlY1hCOVRlWERlNE9L?= =?utf-8?B?RU9WQnQ0RisyUU1TTUo0MWJDWFZrR0xkbFU1RC91bDJnWlA0Q3VHLzBZNnMv?= =?utf-8?B?cXpJQ0NsY1ZDYitXQUNRbFVzL21TQ0tWSFQ5OFRKckQwc2pqdUs1Mm1hQlgz?= =?utf-8?B?VWhlOElqdUZyNzl1NlNYUytxZzNtbEp4TU9ZMUJXZGNqRDZJSldlTlFhRHQx?= =?utf-8?B?d2VNR3RFOENrRjR0b0I5TUt1bFVKK3dyRFRVWVgxdWU0WndrRWN2MENjOUdZ?= =?utf-8?Q?VC318UEieqWbv6a18aa2yQG54=3D?= X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0152;6:cmKU3O+L6NIdbclSZZwpFvqdjYEWIbQwgH1e7OiuM/ANb8oNcgh1HCUZSs0f2z/AjImAxtT1YSB8MgeliIyH3FWfuonDm9cudHvRMRZHlguSWF7kWVesqGuW9Qc2m+iduyNWG5BbFSmkdrSOuDcfLEU+9PCXPK6up9ST6cCHpNWIvvqmpjKg5hBqEo27avXpOgPdCrdPBlJ3l2z0jgD/tkGrKSv8vafnzjwLNPGwEM0sFGqoGa0d+4w61GIHzKPvgpIh5CVOLJJMMJMge/cgs6VqGDgjCDwIOI3nT+tH2HSG0bvYvqmfLh306lvhKdEcRi6uQFlfrS4MxWrygYMT9Q==;5:TT3XAFtZ3JDfOb1EUoU12GK1lro/klHbG0BDcc+x0KyDj5fnKwFwdLHXoJfbEFn5ubYuJjmtaUJn0Zf6JniH5c63WRpXrKKSnQknaycv4mjtBQZfEpn3CevawXfa/PesVtc1Sb19rrCmMBtLg6W0bg==;24:QmeN5rvj2fX9K5vC3zfD9BxE94vxmzH6IwIcCysegtKCgHpwRr17ra2XoEPWSGyBbOERSsmEoTimpOALIaICLOKYKBPuv0bAgAEIYutFmGg=;7:fHmOqKm2CyYpFVC5J1CFENpScrvgXKC5UJvXPbw7oivOyvb0TXsse2FSdazAvzRpNwAIXh0UJV7cZx2wsawWdzcoChySmTI5Y7GW25BDe3vFcbIa9rytAs6istfnMpdm/MSpxK6aQk721xt3+BtYN5Ie2eDaVgWdntZyh2ahL9VI/TEHxQ4u0MVWzGM6l3Qi+zQnZXrPW9gSYme/gVYIji3wF7MOw2Av6RyiqLbHXAE= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0152;20:XYLbQUmQ6r6RdGRsiYzaFfWKcbT3heWZPRbIlYt6gdpuZ6S8a+nVcjoRcxEqBZuUQvTSiZaTHiZPIkf2SVVwL83OtEB20Se3ZLZbZ9jTIvIHH/UD9No30e9alVX92t4eWN7q6FRSeYylPB3ZROGoOfiQEDVTc/Dk+/QK13B80wM4dIZpVBRj4RHo9eiOQnGbdv2EvBjgEVvoiPinLWfy6h7fxW0XSSbrNVl/0ADOwXlPF/PD/qFYyGVZkG6I5nJp X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Sep 2017 15:14:01.0567 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR12MB0152 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Tom Lendacky In order for memory pages to be properly mapped when SEV is active, we need to use the PAGE_KERNEL protection attribute as the base protection. This will insure that memory mapping of, e.g. ACPI tables, receives the proper mapping attributes. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Borislav Petkov Cc: "Kirill A. Shutemov" Cc: Laura Abbott Cc: Andy Lutomirski Cc: "Jérôme Glisse" Cc: Andrew Morton Cc: Dan Williams Cc: Kees Cook Cc: x86@kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Tom Lendacky Signed-off-by: Brijesh Singh --- arch/x86/mm/ioremap.c | 79 ++++++++++++++++++++++++++++++++++++++++++-------- include/linux/ioport.h | 3 ++ kernel/resource.c | 19 ++++++++++++ 3 files changed, 89 insertions(+), 12 deletions(-) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 52cc0f4ed494..6e4573b1da34 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -27,6 +27,11 @@ #include "physaddr.h" +struct ioremap_mem_flags { + bool system_ram; + bool desc_other; +}; + /* * Fix up the linear direct mapping of the kernel to avoid cache attribute * conflicts. @@ -56,17 +61,59 @@ int ioremap_change_attr(unsigned long vaddr, unsigned long size, return err; } -static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages, - void *arg) +static bool __ioremap_check_ram(struct resource *res) { + unsigned long start_pfn, stop_pfn; unsigned long i; - for (i = 0; i < nr_pages; ++i) - if (pfn_valid(start_pfn + i) && - !PageReserved(pfn_to_page(start_pfn + i))) - return 1; + if ((res->flags & IORESOURCE_SYSTEM_RAM) != IORESOURCE_SYSTEM_RAM) + return false; - return 0; + start_pfn = (res->start + PAGE_SIZE - 1) >> PAGE_SHIFT; + stop_pfn = (res->end + 1) >> PAGE_SHIFT; + if (stop_pfn > start_pfn) { + for (i = 0; i < (stop_pfn - start_pfn); ++i) + if (pfn_valid(start_pfn + i) && + !PageReserved(pfn_to_page(start_pfn + i))) + return true; + } + + return false; +} + +static int __ioremap_check_desc_other(struct resource *res) +{ + return (res->desc != IORES_DESC_NONE); +} + +static int __ioremap_res_check(struct resource *res, void *arg) +{ + struct ioremap_mem_flags *flags = arg; + + if (!flags->system_ram) + flags->system_ram = __ioremap_check_ram(res); + + if (!flags->desc_other) + flags->desc_other = __ioremap_check_desc_other(res); + + return flags->system_ram && flags->desc_other; +} + +/* + * To avoid multiple resource walks, this function walks resources marked as + * IORESOURCE_MEM and IORESOURCE_BUSY and looking for system RAM and/or a + * resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES). + */ +static void __ioremap_check_mem(resource_size_t addr, unsigned long size, + struct ioremap_mem_flags *flags) +{ + u64 start, end; + + start = (u64)addr; + end = start + size - 1; + memset(flags, 0, sizeof(*flags)); + + walk_mem_res(start, end, flags, __ioremap_res_check); } /* @@ -87,9 +134,10 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, unsigned long size, enum page_cache_mode pcm, void *caller) { unsigned long offset, vaddr; - resource_size_t pfn, last_pfn, last_addr; + resource_size_t last_addr; const resource_size_t unaligned_phys_addr = phys_addr; const unsigned long unaligned_size = size; + struct ioremap_mem_flags mem_flags; struct vm_struct *area; enum page_cache_mode new_pcm; pgprot_t prot; @@ -108,13 +156,12 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, return NULL; } + __ioremap_check_mem(phys_addr, size, &mem_flags); + /* * Don't allow anybody to remap normal RAM that we're using.. */ - pfn = phys_addr >> PAGE_SHIFT; - last_pfn = last_addr >> PAGE_SHIFT; - if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL, - __ioremap_check_ram) == 1) { + if (mem_flags.system_ram) { WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n", &phys_addr, &last_addr); return NULL; @@ -146,7 +193,15 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, pcm = new_pcm; } + /* + * If the page being mapped is in memory and SEV is active then + * make sure the memory encryption attribute is enabled in the + * resulting mapping. + */ prot = PAGE_KERNEL_IO; + if (sev_active() && mem_flags.desc_other) + prot = pgprot_encrypted(prot); + switch (pcm) { case _PAGE_CACHE_MODE_UC: default: diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 617d8a2aac67..c04d584ab5a1 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -270,6 +270,9 @@ extern int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *)); extern int +walk_mem_res(u64 start, u64 end, void *arg, + int (*func)(struct resource *, void *)); +extern int walk_system_ram_res(u64 start, u64 end, void *arg, int (*func)(struct resource *, void *)); extern int diff --git a/kernel/resource.c b/kernel/resource.c index 8430042fa77b..54ba6de3757c 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -397,6 +397,8 @@ static int find_next_iomem_res(struct resource *res, unsigned long desc, res->start = p->start; if (res->end > p->end) res->end = p->end; + res->flags = p->flags; + res->desc = p->desc; return 0; } @@ -467,6 +469,23 @@ int walk_system_ram_res(u64 start, u64 end, void *arg, arg, func); } +/* + * This function calls the @func callback against all memory ranges, which + * are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY. + */ +int walk_mem_res(u64 start, u64 end, void *arg, + int (*func)(struct resource *, void *)) +{ + struct resource res; + + res.start = start; + res.end = end; + res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + + return __walk_iomem_res_desc(&res, IORES_DESC_NONE, true, + arg, func); +} + #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY) /* -- 2.9.5