From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754243AbdJPPfP (ORCPT ); Mon, 16 Oct 2017 11:35:15 -0400 Received: from mail-cys01nam02on0072.outbound.protection.outlook.com ([104.47.37.72]:39104 "EHLO NAM02-CY1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753992AbdJPPfG (ORCPT ); Mon, 16 Oct 2017 11:35:06 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; From: Brijesh Singh To: x86@kernel.org Cc: bp@alien8.de, 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 , linux-kernel@vger.kernel.org, Brijesh Singh Subject: [Part1 PATCH v6 10/17] x86/mm, resource: Use PAGE_KERNEL protection for ioremap of memory pages Date: Mon, 16 Oct 2017 10:34:16 -0500 Message-Id: <20171016153423.2980-11-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20171016153423.2980-1-brijesh.singh@amd.com> References: <20171016153423.2980-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: BN6PR16CA0015.namprd16.prod.outlook.com (10.172.212.153) To SN1PR12MB0158.namprd12.prod.outlook.com (10.162.3.145) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1a34be15-817f-4907-d582-08d514ab73b0 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(2017030254152)(48565401081)(2017052603199)(201703131423075)(201703031133081)(201702281549075);SRVR:SN1PR12MB0158; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0158;3:I/Fkxdsto8MfjIg74kydc9Bd+qDj8nN6ShBrFIISEt4AKYe3bH3AZjusBZH8ENUU7E042SN2wkH7Z9/nkPFyTaxx1o89+KKb5rHZWQvv/cL5jnGW8nt+jsYt4xQ0o2vq4EiX8DkbR/e62syh12axnQQNR/0ix3UMXAwxpXIhnaNzFgafIaiTwfhUrboYfcKZQhwLIsr9+cqmkwOU/ENh13UN0S1IUxK6PO8daEPf/7YgBySH+rMFCTQQUXSV4Fxe;25:MeFq8cXsGdeZdB5kkkAdTvKUVBNWSLV7jecb7+0CDWpRIQr16pO1KOsq8P4cR0R3cTWz0LQsFdMqfNV+DqSyiExK5XBqWeFDwU4W2peq2ycDamgHYvyfbTQZuKOBx07Wqv7e8VBNzBshrHOrYSy/LLEHYLME07jOkcLxGCpD3FPuxccasdGz1TYcQKpTpMOYOo9wVk7Pn97ESeGIhlFRT2E4j7PtuqScSUdhkiwws310oYfnQ/WM3DictcD8BrIibp4V3yeGtERtyMdyUl9AHzNZVtUhMsB8SDRHl5vV3dDuR/mIIc270HccYC/PM6TRVTqWU0nvrFH2y3LvBRh5hw==;31:fpBGWpvTrRLrCtzNOiLBhy7C50ECO2DLT18Xl0qtu8N0Guvck9HS+tiEZHzXYgyuBCq8zLbr89TK3P8NBTGzdgs9JK8YJGfgeFlPclR+443CugNYNbM5N2OgbUa8jVWiIEyMnrSjvU+40kCnn+2QUgU9Ex2Nj4FErG1SdcLSJiIUtIDnxQNqRgLHPg6mqYoiN5kK96SPxH8Wm32E2VXLP510qCr/j97VrnmpAR20yrc= X-MS-TrafficTypeDiagnostic: SN1PR12MB0158: X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0158;20:1ZPXqK7f8r2dfJpk6lXAtnmwzVF/ZDRUwhEgsM2Uh4Jjtn3C+4pGQvEjG8jlSjUBL852q4RQ5EJj7rcDqleD+O1iWnfav+HAcS9Hy3Rk1WY4OkIqil4pfoGD5bok0V71nqK8nMw9PtMscUAfFCGHYr+45mm/KOajOIBlUqeoVS791bJ5bRKs7vU5uBJT1iDJ/JtIKmeKz8KI7l3iNEdmJc5sbUzPtFvWgeu/TvR9XnaeBbjITEwWMIitB04le8Mtzy8mHkL2eXQ7E2NoZgun4OHzOMDLT5zd4ZBh1fqOdSg/bUfC+Jxaijs1/A9IFFsBw250NEjU2x7mf+rlVQmYGS6JS/a8oAuVPzNEPWZm9jIitZMJ3ww3MzIFGpVyR0ae7b+vnHMhw8B5a962jscece5/q7Xez1+YEWYR1P+b9KAkxMqn0yxK/3xrJKYT2FczBb6gsso4BloMj6Vexf2a063vZPpGUVKreINUlQIs4ZJxKZANdhbDzBiun647HXGm;4:DXD+dzaimajKAXbGzIV5sH2FV3GpGbg9v7J8dDzni3zda3Z46UevdByiPMpFObOcgoNIuDFDf/4esxCkNYvtPEi2g6vH3l35cBOzzoLaDmJdnh2pmBWUTIEXTTbpOKsbFntgDSjgIbuxp7fwwDtXgg2KnUCf/YDaV4WtHutrFahzzcdlxLLNt/R6fvjPbmiwsLXGHoq1mnxVzAPjyi2a/ecq+y40qXBKQ1CVKJhoBakiveztIukSz7Oy62KXN1OLx1v1C/7/S/47JVJr5gXA9jnwt2EELpGGreed//FbQ66CPzD0VUaHhFCCCHdZIoNcuLrkLDr+NH+ym9kgOD7Z7PM04YrkKcifOX6hRXpkLuU= 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)(93006095)(93001095)(100000703101)(100105400095)(3002001)(10201501046)(6055026)(6041248)(20161123562025)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123555025)(20161123564025)(20161123560025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:SN1PR12MB0158;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:SN1PR12MB0158; X-Forefront-PRVS: 0462918D61 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(346002)(376002)(39860400002)(199003)(189002)(54906003)(7416002)(1076002)(316002)(5660300001)(68736007)(2906002)(4326008)(16526018)(7736002)(47776003)(305945005)(23676002)(6666003)(53936002)(575784001)(86362001)(33646002)(2950100002)(6916009)(66066001)(189998001)(97736004)(76176999)(106356001)(101416001)(8676002)(53416004)(105586002)(36756003)(3846002)(6486002)(6116002)(8936002)(50226002)(81166006)(81156014)(2870700001)(25786009)(478600001)(50986999)(2351001)(2361001)(50466002);DIR:OUT;SFP:1101;SCL:1;SRVR:SN1PR12MB0158;H:ubuntu-010236106000.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtTTjFQUjEyTUIwMTU4OzIzOjV1QnRJMXFPRkVFWlZHdy80bW9yV0pWVE01?= =?utf-8?B?MndnK0RvTGFRb2FHd1lBdUNhRGtJcks2ZXJtWDVVY2l3NzJFODk2SEJqOVIr?= =?utf-8?B?T3ozWEZvOFltZ2VXYzhGekNoZGpLdUV2ZmJkdWdCOEtKcm9oWnVERnJxTUI1?= =?utf-8?B?MGFDUy9zV3N6Lzh3ay9qbXVBbG5VMFdYZ05RME9GL1g1cmh4VHIwYm0yemh3?= =?utf-8?B?RG9ZTk82aHZUZm42akJ3MUZEMkdOdDc5Zm5JbHJoeS9WNjhPdnAyUmFZMThJ?= =?utf-8?B?TVZEMzhBSC9wQ2o0VUtEZ00zemk1allGWFVMSmVrL2kzM0lwSVAwK0dQTWNE?= =?utf-8?B?YTFUYmRVM0RnTFBlUnRYNzhQRGRKenlzOEk4RUxEZHRaa3hLNkR5eU8xK0d6?= =?utf-8?B?ZTJyWEp4a01COUdqb2ZPRHA4VzczWjhieDB1UzMxMktKWUpVd01pQjBuUkNZ?= =?utf-8?B?cU43ZmJ5NjhVdlRML01yd3k5L0VwWVIxbVJTYUM1SzM4RUY1MGtHZ0QxY3Mw?= =?utf-8?B?a1JIUHV6YjExVnJoVTlYd0JRcHk1ZzRhckpnMkpIVFJpcGEwUy9IYXNtZHFp?= =?utf-8?B?eTFiS2dJR0FFdUcwZXowNU9uUDFKOFVmdTIvRVpsVEg2dUlteFJzTHUvbFg4?= =?utf-8?B?SGVIYWt2K3VUZnNocGZ5bnJGK2RKR1pnNS8xSVlsSDlaY0NwMEVRUllxdFJH?= =?utf-8?B?UFNYNXhETU9Bekh6NXZQVEJpRnJQcGF3cmhtRU8rNVRpTGVjSytrZ2ZYdTFl?= =?utf-8?B?aFRhSDJZb1ZKNloxSHdsY2RxMWljMkU3Q2NSYjJHYkkzb0V5blVRUkRGOVZR?= =?utf-8?B?NXRMSUF4TnNMcmcwOVZUMDZJT2p5SDhlaEgvNDFOZjBKOWZ2SmVWeDk3d3RG?= =?utf-8?B?VlBNcHFaTXk5VFBncFN1VHdXYWZmaVVEMTBPZFV6SHpBZXVyVVNhOWhzeTJO?= =?utf-8?B?ZENsTW1vWW5ZVXBHZjJTMm8zbFFqVU43cmtxM04yYytNUURZbUVxaHJqWE5o?= =?utf-8?B?UGU0dFZicDAwek5rN1d3MHhWYlB1bUQzem4rL3IwbnZGRHgrTmRnWHV4RHZH?= =?utf-8?B?a25kcnBaNHJaVUF3TE9VM0p3MGdySjhkL0VQS2NYK3A3OHhueVFSSzNmaytN?= =?utf-8?B?amdhcTZWWWhHM05ZaG5xZllUcnVTZGhvQTQ1ckN6ckV0bVN5RzJUNUNIYmkr?= =?utf-8?B?a3l4Y3FWVFNNOU1zNjV2QmNOTFlNZndhMk1WaGd3RmR4UVdBbWFLQlVaMkdK?= =?utf-8?B?UGtuK1JZSnZpcURRcUZESitqbEEwaUI3dW0rSTcxMTQ4NkZhMTNjRnllNUNH?= =?utf-8?B?dk1BbkhtcDAwSlM5UWlWV3Bob3I0NVJuQUNaMGpoNjlxZ2ZYZ2RvZmwwdFVW?= =?utf-8?B?ZmVqNXFPN2ljM0dDcERFaVFmQjRSRzg1ZllXYm54aHNRQ1BtZHJVRk9TbWw4?= =?utf-8?B?SHJOckQwVFl5bmxoN043aDJzUnR6UHVXMHFnL09iUGN3bnhwM20wTnNobVk3?= =?utf-8?B?OThGdEJwTFFPSlEvZU1tYllFS1NZM3hnSzBOdFJhRktUeDdySUkrZFFvMTE1?= =?utf-8?B?aDZlRUIxZ2FNVEdMQkhQTUdPaDE1MEE9PQ==?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0158;6:wY5klPZTVkgpW5/OdDTRH8LvNa4K47++MGeg1fQDAbjhPfaZhXSlN5dRV3hdujM9YG7rz6Jxz88XNpuU32wic5OCjAnnASjl+ym/qEFlJ49Qj0FPfJ1TQDT/Hl7QqSUGrEgdYtaa1nD2X7cpF4QoQBV2qQtYXDOQbk61cSc2MX8FEe9nwvcnDkE0RlELUd4lDeMxN4hWIge/iSXBEcHC0xP1l7teKx7YfAx9bwpKvcYn1FtrbXH8l6wkF7xmFXnhjSv2LaGNE0o+KeyGSCT9/wh9Fe3cHzfNMmCuLNTDYgz3/9R0vD3hIb2qwUxjzwH4yecuOpsPFUM4THdesA+Ozw==;5:aPtULkUsUBSNlYS1NLtlIj4Hj01yYfql4krzfSBuvfgylPBfwa5vsYvB4PAop/3NMkj6eqa8wOtQM7qvw5zswHRkUMNFspAwcMRLN2kGg9lY8pNJ3Z6PQ2n/Bgp+HsEedwALgihyfecTZzY/mKnL1g==;24:5XQBdtxNlZFZjeHLDFxJh6M7yVu01qBgZds1hkupMBlLqCH3eiIWK6LE8TVOneH3dT/Q9+QRC6BTNewYmDTfEr0EjS8qi9AQ5rMoHp6h1Eg=;7:UpBMR5tMrQMN04VTgvKXUEMQ6teDyLoB+D4ui24WFErTDJU/4V9D5EQ+yXW3EHjMYW/zV4jTAPFIjJrm64d1VhynVgZUOKwjV2jRBSKkYZwLvFs52XyZX1xFsDm52c4snzv0qx5VS1jcF702VWF9Sgk9aQyX3sZ7Ap+HdqXl1EKb1D4W4hUiDygJLYobFI4YBtXsWfgj0QjBrENa7EGm2j54ZliKBCQ56P7WdTaWnQQ= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0158;20:BI4xk2ttPFwjg+nD55zdIiHJLzde7tedrnmAReoVjtXmh4Xb90ycI/wwVsEK1AYd0q7IewVnLDCNKng9F8MsgBI8sqnAm62hoN7+47X//bO6fDi5a9oY11A0oDnzwWPK59yFTwhJdL9mZRjTSWwVB1iZ7rn3jO1NJLND9P605wAKcUTDxieAL8tr6AKIrFe1V6a0hcKxAfJMsx+yHRumTH9ngY92INivihqM5sA0WHEoawWeTvlisZmN+edNV/o5 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Oct 2017 15:34:54.3381 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0158 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 Reviewed-by: Borislav Petkov --- 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