From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751618AbdIPMfP (ORCPT ); Sat, 16 Sep 2017 08:35:15 -0400 Received: from mail-dm3nam03on0057.outbound.protection.outlook.com ([104.47.41.57]:43351 "EHLO NAM03-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751524AbdIPMfF (ORCPT ); Sat, 16 Sep 2017 08:35:05 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; From: Brijesh Singh To: linux-kernel@vger.kernel.org, x86@kernel.org, kvm@vger.kernel.org Cc: Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" , Borislav Petkov , Andy Lutomirski , Tom Lendacky , "Kirill A. Shutemov" , Laura Abbott , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Andrew Morton , Dan Williams , Kees Cook , Brijesh Singh Subject: [Part1 PATCH v4 10/17] x86/mm, resource: Use PAGE_KERNEL protection for ioremap of memory pages Date: Sat, 16 Sep 2017 07:34:11 -0500 Message-Id: <20170916123418.37807-11-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20170916123418.37807-1-brijesh.singh@amd.com> References: <20170916123418.37807-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: DM3PR12CA0051.namprd12.prod.outlook.com (10.161.151.19) To CY1PR12MB0152.namprd12.prod.outlook.com (10.161.173.22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 124a9af0-3437-41ce-4ff9-08d4fcff52ab X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(48565401081)(300000503095)(300135400095)(2017052603199)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095);SRVR:CY1PR12MB0152; X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0152;3:oZtbNufPSjYTgAiOmSVfNoEectnqjT3L79gCdcyPMqEXM3AGrc+a0f2XeU//wYlu0QEom/oPVCTMRozvHTwSRwToCCtx3n5/aIzivChsnrMLehVkijJSKQzhIAIiHuwwD6Ajb4IkFR2gYgumvNTHRlHIgQ1KIkgQejl7n4WWUkWSrsCAP9hkVaVrcKA0awzZGSy//ZsqSqefiIvUMk6tqHlarp6iKrTBAOCtnK13fq9EyDNPYIoOBc3ON+whLUXd;25:zQUmwBzsul4GpeqQ90aGBEi0wOCBY28HNKdeCN1jepnoOa7hgsQIr49arok1rrUakxRLXvguI2jQfmse/BQRq8iLuTP4gUIEaqKvEQQjeMPwdROzLfYt2YLcEYZIYb/FALSA8SSWLWhKsNuuOHtvXD9iCH37xf3FxtsTJNPFT2AEnZAXvrN7p1ferNZPvbg6NnIEqtUD/J17WFnuOxasNy4YUSxZheVdxILMpIhDURMRX/zfw+A2dHPxb02dtQ1uoBq06okcz7EUIXr+w7cJ4+eQf4D/67tnDY+eds9TZhpC3gIlU96fBX5aN7rKYSTeI/UHFwgGAzOg/QRWGPdfSA==;31:SqxvCfQ6pXMyrRU0bupTTVYo60IXxzHnKGhkqTrcV862TjfK/sly4r9oNhlbGgY7ZhLJBMRTCkbqvilD5GifLObKlgutiYvS0J12s5Y/zFryJpP0Gmy04VZB9RLLoDnbUxnbCOg9rCLDTtHQgzWV1NFTbHsGDfX2TtGwJM8Sj9Hnvi6q6bzSz3V9u4yFQ8GV5pWWOiuQnLkYFvVaDHKCg4b1pHNgmA9UpKaEfgK+Pgk= X-MS-TrafficTypeDiagnostic: CY1PR12MB0152: X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0152;20:/ABpVLGU2WKgGwZH7WQzsAQS67s4mCR0wmsnDnF0Aba07iCcVS3CKR6YS+EsOZHIbTIy0ChEFP+F6WJ+jKv20Fd/qEylbrts7kasY+yNGNkrV1xni5hXvaCRLJir9q9VlCKENBanXHS2jWld3OgRmrrsHEaxCp3hqKPkL2+kAok9a+HYuGarwh8ZXODSaYH8ThZNbxxQG45AEArFZCf+zb+xfBavruUVzDff0gncdukjCLaUFgQjlBfR6yO2ttvVfhp+G60nNyVYBeZ2kBbpLVI5dObgJsqYnD4bqPLdlmN5VIoZytn1O60C+CyL55Hhgn9KqleklMcAVwBRw27RSQe+TYGgNoWeToXtYE0DMwrsSCWnMOmEAC1rgNJyLXpcaajOb0yRkpHkjeCjpVERlXXtP5Wy0ru6UsTiTtexqG1vA0SJo98txCXxLEpL05icq0BO1F4Az+/LRtSiysO4BzLKU60FQ+Zl1y/tIulMqHPNTnKAn/TLU/WRyq++yPk4;4:eg4T0CpWzUYwjrHTi4nqsAsyI5pP+U3VBpyECA87wUrMk1gLMvD51teJF5wkLeKBQUTqbh2DoshtQQqqf5b1rLZ2B7zyEWnKBd59/fQ7PfqmOe61uaYu2gfB3perOFExqO4E+zlZVhbgU85gYPQ4lIvQ7yWWTPAIZFoccoYJLQLBPkZBMkMeW4jkJSl6pJgc4NGfOmShD+O6BlcFeyBE/tkKb+Mi3obqITSZEw/5FPsPSjFegzDqdWtw4Q/4F37evEPQqki1L3MuIDUtS6VQPzGCr0GUfhrOd/Lhd32LCI62K6Heiu/XPJH9coNmr90co+lpNXI315j3jHK7HMgWn+AIoAlxbTGbMniiL4RqXOs= 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)(100000703101)(100105400095)(93006095)(93001095)(3002001)(10201501046)(6055026)(6041248)(20161123564025)(20161123562025)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123560025)(20161123555025)(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: 0432A04947 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(346002)(376002)(199003)(189002)(6486002)(53416004)(81156014)(7416002)(81166006)(50466002)(6666003)(2870700001)(7736002)(54906002)(316002)(8676002)(97736004)(2906002)(305945005)(575784001)(53936002)(5660300001)(86362001)(478600001)(16526017)(1076002)(106356001)(110136004)(3846002)(4326008)(23676002)(50226002)(68736007)(25786009)(6116002)(33646002)(105586002)(101416001)(50986999)(47776003)(2950100002)(8936002)(66066001)(36756003)(189998001)(76176999);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?MTtDWTFQUjEyTUIwMTUyOzIzOnFRWmlMOEQ5SENuUjg4RmFBWC8ycHorVDNo?= =?utf-8?B?UXIwcWtESmUySjhrNm5NOXdZcURSUEJRR0tpcHpZdC9pMTZ6bjFQU1ROU0hx?= =?utf-8?B?MDVma3N4R0JSOUFvL3RPa2FPS01NaHd6UmpUUUlKbDB0OElwK2Q1Y3gyM3JG?= =?utf-8?B?bFpQWlVJbkJ5WmM5WGlaaGozaWpkbU1FWTI3VzRvUzFCd0pRbFdkZ2lMRzdp?= =?utf-8?B?VUlmMFZoZjN0c0NhZ3FneEU1R1Z1SEhNR3YweEdHdXV5dHBQV1lNVEZCTGNV?= =?utf-8?B?dUJhaXhNbUJObkJyNGhYaTcveTNyYStDbWFLZXdpUnd4a3BaWEdORndkK1VO?= =?utf-8?B?R1lrQ3l4VHJSQUFaT2thVm1GeWdLdTdGOVZYNVNCdnBNTGkvYUx2djlSckls?= =?utf-8?B?YlFLR2FaVTM4UGJRNWl6T2hnRC9WMHl0N0RaSVduaWZkaGxtZEhNM2RRWWlE?= =?utf-8?B?aGZtc0RqWEJjUWZkVXNBU1BnZmFBOWMvQlhUWENOZ2toeGczZWNyU1diSG9l?= =?utf-8?B?UnU5bXZUc2ZaMW1TQ0MzMjJkR3F6emxUMWtRL2cwSVpXRDNNaE5TaHlTUEJa?= =?utf-8?B?WC9ZbFV3QUh0WlhqdFliOTE1enVnSlhiSXhzZ3hoS244WFdQS0dJUlJDMTlj?= =?utf-8?B?ZFNiVDZocStmcCt6cTF3Ty9SSlJWRE14UVZCSUJrdlNLK01PNURXVm5FQ3JJ?= =?utf-8?B?d29sYVI5ME5DWjVPSk5iS0xna05Vay9oUkhMYkRyazRFa3FCTGlRUWJhaEhG?= =?utf-8?B?aGYwSG5mWFpZQU5BSG9OOUozb2V3bGQzVXZiZXh1ZzFUMERYOUN0WGFIYnlr?= =?utf-8?B?c0VQZ2dxSXdCWTNLSDdOTnNYNkNkVFpKdnBDSGtXWTdHMXBPQ0hYdkRDR2Fl?= =?utf-8?B?MVp4Z2Uzck9yRlRmcWZ4bXdSSi9QdmFUdCtjeTIwSDlnSG5zQU4xSUhyNVJr?= =?utf-8?B?d1Z3aEF2ZVV6S2Nqbk9Zc09xbTNIbjcvczAzbVZxQSsxTWJUVGhRRVRBclhH?= =?utf-8?B?RGhoaGhUUm5NWDgyMW1XcjBTd1VkVG5qYy9VT0dqUWhrbVVFVlBDaFIxZHlp?= =?utf-8?B?cXg3RVBtVUNFcjcxZTMwZ1RDaFJGczF3dkJJZ0JmK2Y2SVoyV0pNL1l3TGtt?= =?utf-8?B?RjRSam01N3pDMnh2NFQxMkxZUWtXQ0dJK1Z5MXJ0VW1CUmlVeGhYWXQ4UzJm?= =?utf-8?B?a2crQ1dvQmMveVFZWjZzUGFHUm5hZDBpdFlyT003UEdwYStuNEg1QkFPM2Zs?= =?utf-8?B?MER4OVZpSlR6Um1YbTNYK3YwZkhMejdDQmJhZUgxcGxtanczQW9QNXFTdEx3?= =?utf-8?B?a2JreEdlZ3JiSXg4Q0wzSjdHQXRJKzAyeGxUWU1uNjN2czNLRHNVSlhRL1Ns?= =?utf-8?B?aDVIVm5OWUpaRnFPTE12MXdpdEhJcW9KVFI3YXNnREorQ3JwUXVPM2hJeHE0?= =?utf-8?B?MVpCN2JZZDVYU0dHeXpMQ1ZtdTd6aGx0aUZxaEFLQU1iUm5SdGJDalIvRjV2?= =?utf-8?B?UGJHQT09?= X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0152;6:jFK5LRE0PFxZhOll8l0O+zl+sEqxBthOCPRNDfytPBl98i8VHtc9r0QDRIHNEuyTs77cTuJw+IqhTA+/j8AOfZY0LkfWsi47fJCa3t2su9nJRqkDFW89Sp4yZAAiz0CrO/MiRei760fdONIeuq2/jIwkd4b6+9tCXAKPmXBlOnOc0e+gEJasrFx6HFffVGVswWoPSrvCE53RAUbXxKur7kjcwP9J7SEL2MCN9rmTxmHgvScRZfe0Sk2va8rncX/bPVprDj6rgh5f1ckSMOWIGGLq6JXd0xn7pE6JQgnYw+qfwJ5ZEhe3/LHdCWz0EO5VjJOWLHkNelJ+C049ULTDNg==;5:3aqEIRnLCKDdN8/OqiJDmBiBYVaVdTdzFtkB9YKF6OSs4OwWgZfk4ByqsXc/hwOP2B5my1LH+Kq2gDQ9/VDbYkJMTeOCagMtBHN8HKF9lMnVRdFXetGJZtjHSO9sZRH6e/5+s4qLRYWDGvY8n9gAkA==;24:vlFSS3AEdDzA9EzJZnt2k2CX2aTyzefRPRqbieCJklDCcx8xutXgrq4jvx36ZgVmmvkzVGI8tWYx2L2CoxRR/pu20MqiSpB0cVr3qUw6uNo=;7:3LclBQqIs2hTWIOJorFOnz+8XW+JxBnZTv46fiGn4WRqZFsIkzzUO+4irhqu6BiC7Hm0YnwsA5voaH9Ef6r9YHfdwlK4h7ZVocaNGgQ4Fkr+zAy+s1BtAfeF58Z6FvnlyrRI4wlKWn67ySRT//mtpm0X7tzXMlk6s3OqNDrWvxFNg9HPuB/+dAkuX588jI/0+zaPK5QmRwOT6CwdUYCML5tuvubp6VPipycLMJTFBzY= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0152;20:A8j08Gcdw945cavr6fIwMzm/4nRl2j8vpB0G7aBFp6jcmL4kiL5kQdjVcJIm+TZSZWNBmiDmLbrrQ81ALWOFYTce5ThQbeqglZRReDiMoebnUxquWqxRXT6Saaa0SWAtKFwJU3z9soM7UZHZPY3/N9Hkjx0yodrWRKZCr2YQSS2D1lhbXhnqub9i4I2fTabxEOKfQXWvTznIM6PighIxXbxchJjpRlz7atI2NKwKb2vsCA10EfZkL54YQ85O0gFj X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Sep 2017 12:34:49.2713 (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 | 77 ++++++++++++++++++++++++++++++++++++++++++-------- include/linux/ioport.h | 3 ++ kernel/resource.c | 19 +++++++++++++ 3 files changed, 88 insertions(+), 11 deletions(-) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 52cc0f4ed494..812b8a8066ba 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,19 +61,61 @@ 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 int __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 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 1; + } return 0; } +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); +} + /* * Remap an arbitrary physical address space into the kernel virtual * address space. It transparently creates kernel huge I/O mapping when @@ -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