From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933105AbdBVPtN (ORCPT ); Wed, 22 Feb 2017 10:49:13 -0500 Received: from mail-co1nam03on0069.outbound.protection.outlook.com ([104.47.40.69]:21724 "EHLO NAM03-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932992AbdBVPtC (ORCPT ); Wed, 22 Feb 2017 10:49:02 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Thomas.Lendacky@amd.com; Subject: Re: [RFC PATCH v4 09/28] x86: Add support for early encryption/decryption of memory To: Borislav Petkov References: <20170216154158.19244.66630.stgit@tlendack-t1.amdoffice.net> <20170216154358.19244.6082.stgit@tlendack-t1.amdoffice.net> <20170220182256.qorlso5f4c72hl6o@pd.tnic> CC: , , , , , , , , , Rik van Riel , =?UTF-8?B?UmFkaW0gS3LEjW3DocWZ?= , Toshimitsu Kani , Arnd Bergmann , Jonathan Corbet , Matt Fleming , "Michael S. Tsirkin" , Joerg Roedel , Konrad Rzeszutek Wilk , Paolo Bonzini , Brijesh Singh , Ingo Molnar , Alexander Potapenko , Andy Lutomirski , "H. Peter Anvin" , Andrey Ryabinin , Thomas Gleixner , Larry Woodman , Dmitry Vyukov From: Tom Lendacky Message-ID: <7b8d7258-d5b5-6dbb-afe3-755f6a453d40@amd.com> Date: Wed, 22 Feb 2017 09:48:52 -0600 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 MIME-Version: 1.0 In-Reply-To: <20170220182256.qorlso5f4c72hl6o@pd.tnic> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: MWHPR07CA0002.namprd07.prod.outlook.com (10.172.94.12) To CY4PR12MB1144.namprd12.prod.outlook.com (10.168.164.136) X-MS-Office365-Filtering-Correlation-Id: 14870b5c-ad41-4276-0a03-08d45b3a5084 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(48565401081);SRVR:CY4PR12MB1144; X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1144;3:Kv3l1VVH72cPACkw7vkHBG+GCPGI1Pk1ID1aAnmgszsyEMQCtVOsDv3hHnB883reo5lCB3La+Acd4yzPAv+LkQd8d8tBmb4JDDNqyZwZ5RevFH8k3b8jXDGSfH2sLv1hvuJvfbC/8WG2qHHCnmJb27ykwjtFFATKkjA2ykug2WxRr/ywbjA8ZyIIvXCFX5aodVqgJ8NsknEWCRghP9e3P4RsSdiuCzz2oxeQdiZaMdXQz1Ri0NCiTZVR9eW36Z8lIJWT7VzpjpzQ837x96FoovkIBJCa+QPuW/DELaDaXCo=;25:rrgWqZW03eTFqsWmFY+nxM5e19qt9h42XRZyWsY6QsNBC7iYc+HNBjsQn4RdR67FeNoLY7ZWj6Ioh3KKXU20kmGlRXr0klSr6sX+Q3L5cUaFZuiNIqasfT8JnL9wJewKNOoX7mqrpYc/T/7jIKiiwx9uyN5kUkYBTvBfTUXIqJnJhOSpIed1k7qq7h+rnRqRWjStJJR63HmXLC8SZCpgUPVVB5zVXyzxOL1LeqTlcO8FHneKf6rCv8r3/Y/Amwrn46ss/GaJiDFcweOYFBA6+O8L06mVthjMiFMrW1AMGxGJJed+PIJL0VtazcEQ7njLmVFGnScb+RgWYUL9WEi9bCB8js1TBZw787uwcl8KkYlEY2t/0t4aqg8S7tJU6ryOQHURf+f4tedIWkLYdHvSywtSWcdWYXN82QfF2hWrpYJRRjdGsH08CQ21HAsMtfoqJJMzpsiEgbYASsD59hX0+Q== X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1144;31:9MYlo6hpAhij7gEEqlfgl1SBx8HDqpMiddPMLvFH77LvWUb5I6YkKg2r2yKCXSnNZj86ADY8IZjsF7GBRhCe0ztU+5nWVXx9l6j6Wxg9Q61+nsxlYi++dYKlHq4yKvnmcdSs2eFb7ND1Jy6H/fOCwTuzYJ1SUHCC3lZFenbtK+bpQ7duC+T1Ohwsi7M3iwYu2Cz9ASMNg0sSTtBpbsFsz8MPJwt2t/MYzTvpFj4Zyyw=;20:ZxsbDlcpg99lAyLjVEg9Y1rgRkgaLfc+6hIZKFXMdlncvPwg6Kulxk+yJdnAQ7FfHuyiztKZTZFZfSsanjxSlJKOR+02Nz56Chqb+duCOaJiFfN2dlptQv3cNLQEyfTPpeQsuxQgTYe1p1/3hFtYK2mXmiSoSJqkVNPZ9WcfCcOvwNOV5lQ1nQxtq9qn1h9rBfBI7up5NsCdUBkV0G2OTtmoXTtCwTggQoZJgTlCdn3QMH5Zy3jNtZwWsiRO20yjrldwSwOJ2mAhoNqMKopasFsDidJ/GpwIf/QpP/goLIhJkEvGLjc68YrVPJU4GFIFDN19x1O86dbcnpcYiv9cZsHbtmI2X0xmSXEi/hXsoTuSD7Vhb3jDXnML8UXUdQL9Yd6rx7YiqTdc1ispcUnq7HAVdkenLyUt1hqulCJdxCxCQRZEjQpWKswU/JVIbQnSZuESPwQllHpFMIxWHJG50VHN0nINOSS0/1dOwiIqDJHqt0NnYoo1igK4GONJyHjW X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026)(6041248)(20161123562025)(20161123555025)(20161123564025)(20161123558025)(20161123560025)(6072148);SRVR:CY4PR12MB1144;BCL:0;PCL:0;RULEID:;SRVR:CY4PR12MB1144; X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1144;4:Kt89Gi/4/YtVIQJwM0RbpVqfSoXnvSR3YBSFQZC2s8mYWhB65xjkv6EfmDrR56n/uW8KpruSl7pFWUMEZTctp0PB4EH9dDEMbbg4bUZo/nJAcb24HJkfze8Sb68HwnlCoX/Yjiqy5oSmzGtPF+Nv9bgZHOOeUIKetOlqPtC3/E8J/twr9iN5MJEIu8fVvnsh6kDvnTWlJxGrkGVUGEyL5lpdzoYGO1aqouafYT9NNF9tL3J7XZpCsZusg/tgmtv6AILppAwpGsCw0L8Nj6aO4E4cKOqv/DMyw0bZ1DHZfw756IHUWmrF7Cjy3Q0ZRMDwubZf1JSpt4D4C+tML1VH/IxFNIOf6E9TiFuwlb+6yxsSZ/RPgH8g4Lk3hTeymVWGxmBZ0WfpwBhFYrRajglnXWxxOzUhrktKLGUUKAdF9YK2OvDdrPWIphGQ3MnMTat0krn5ejV6S5mG3LLEBnKjZx7RhoSlyRtofbdFrLVtsTD3OON3sayCiHH4nko9Ftt/PMPlcWbXJglR/RQHy9HEwElsbiKJyQLgxAJfk1vGm0dqeTzWMGQUwdmGk1fAF7WhAAP1+FUbOwYZv/jBP5R8mSRXhLo7O3XPZW/I/tdoezyXMsNJNzq4fOPp43B/Nyg4ky4XmF26PukVojfF5PlEaeY/WCxn2RdnuhHewQx49UY= X-Forefront-PRVS: 022649CC2C X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6049001)(6009001)(7916002)(39850400002)(39410400002)(39450400003)(39840400002)(39860400002)(52314003)(24454002)(377454003)(189002)(199003)(86362001)(81156014)(31696002)(4326007)(3846002)(83506001)(81166006)(6116002)(305945005)(33646002)(65956001)(47776003)(2950100002)(54906002)(66066001)(65806001)(229853002)(38730400002)(42186005)(7736002)(8676002)(110136004)(7416002)(23676002)(77096006)(6486002)(90366009)(25786008)(36756003)(189998001)(105586002)(68736007)(101416001)(50986999)(54356999)(230700001)(53546006)(106356001)(92566002)(4001350100001)(64126003)(6916009)(5660300001)(6666003)(31686004)(65826007)(6246003)(76176999)(2906002)(97736004)(50466002)(53936002)(217873001);DIR:OUT;SFP:1101;SCL:1;SRVR:CY4PR12MB1144;H:[10.236.64.179];FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtDWTRQUjEyTUIxMTQ0OzIzOnlLelU3ODNtM1duT1hzeGxBSjlCYStqMFBG?= =?utf-8?B?V1VvZFVjdnVScGl0dU0vcTl4MlU2OGJlS1JFalI0ZVdubGJTU2RRMFBWTDVE?= =?utf-8?B?eENGbGZCOU1OcnVqZklKZkxqUnh3cVhMSUVDZWNrWVhFU1J2SDJJcFowWVZU?= =?utf-8?B?M0JmTUQ3UnUrVWY2ZGwzUzRIVXFxVzZ1U3JZd0g5WnNnM1lzY1lYK0UrU1Ba?= =?utf-8?B?bTQxZW91cGcwWEN4UXd1QWhjakVPRmRDbkt4QWIyWkdGekRzbVoxTmVNMjRz?= =?utf-8?B?Z1d4d0U2VEZSZ0k4aklDTWhvYXlWVTg1UFppZHJMVXVoSnhIT0kvT25obGh2?= =?utf-8?B?VWJJSzRJaWt1Um1ITGh6RkxXR1Z6MEM3cEhWL0Q3dXkybEpxaTNiTmlpL2dm?= =?utf-8?B?dWg4enluUFJOczhVc2I4bmZjZlZqdlo4RFZOVlUxQWp1QTZnWC94MUZORzVE?= =?utf-8?B?V2E3UkpyMldhMzNRVk5YbEJGdUtVRmc2K09hNFNjUjFOU2lINzlaN2JEK1ZT?= =?utf-8?B?ek1MaStIbGtKYUp0ZG5MN1JRSzZzT1Y3RzU3cnIvQWZKWnF6VHJndTZaRkRS?= =?utf-8?B?OWJDR3NaZG5PSGh1bmQwVGJQc2t2M3JNaEJHK3RTYWF0SmtZUThDUHpXVGFM?= =?utf-8?B?TjhYV25seUpaVGVWa1pNREdWcjdncXc2Y0MrbjFsbHlZb0tnWm14Z201NE9r?= =?utf-8?B?RlpnV0ZaMXlDWWg2bUdnc1Z6QTVzeUxtc1Jndkk1dHZmMnl5d1VjS2dMazM5?= =?utf-8?B?WEVpVm1JSWxPVm5mNS9yZUZCUlVmell4WVlGd01XYVdmOUM2cFk5SkEra0Vh?= =?utf-8?B?cTA0MS9DZFoxNTYvYUNBUkFmNmJIZ2dpQzhlTXo0bk5rektRU1Y3K1VMOVA0?= =?utf-8?B?d2pnenhodSt4a3NOOWxNaXRROVdLSVhUZmdFR05PaHE1K0xWZGdiTjdHWkVu?= =?utf-8?B?UEw3ZDhCMFJyTnlkYlFjNFNZaGhQT2kxVW8xSksvRmZjUEtlK3drbzd1cU9P?= =?utf-8?B?TEVIc0g4MkRmZ05CRFBqbUo1Qk9hUzlQVGpPUkplVGxxSVduNDl6bjEydDZa?= =?utf-8?B?Z1ZUVGxqR010WDNDaC96K1RaMm1WdTBOMmY0WFRyUGptMjZ4N2Y5eExVQytP?= =?utf-8?B?emVnY2UzSzFmemJWZzlmd1VJVDNESkZjNC9rdUx2S243TWFMNllDMkQrVVUy?= =?utf-8?B?eWFXMjdJc2YzSnhNeks2MHY0Q0FHUEViNUFxWHphbFVrUkxqM3pON1RQWjNt?= =?utf-8?B?UjFFNmJ2UEtZYVgvQTdlT2NQNjFvMGxDVG1xbUdtZSt4Zm94VmlUZnYveE1v?= =?utf-8?B?ZGtzMERBdEpRZUVrKy9hZGNIaHJNOXFLVjJwTXo3c0xtSzh4cVM4ang4Nnhq?= =?utf-8?B?MThNa2F2STZCMUdWVWw1TFZ5UkJLdVgydUJJdXlaOUxLR1lSQTVhTVZ5QWNF?= =?utf-8?B?YXA4VEVLRXNCcWRsU1g1bkx6ZnV0ZlViV2hmemlHSHkrRnpEQ3VFbXNHRVl5?= =?utf-8?B?WTZpdVdaTVBGblgvdWgycGsyNlpQR0RWdjhJSVVJWDBCNk9RVzRCbGpDM2dS?= =?utf-8?B?Ynd0NkduL2QreVB5Z0g0K1p5VkluMy8rZGdDNGJpSUVqamlIS2ZvU0tQSmlC?= =?utf-8?B?WVVmUXFpNUVRWGFlY0k0NE5wMGRHdFRjSGIzY0c1aFRQY0c4akdCSmFudXJO?= =?utf-8?B?NE96d2l1OFk3eENSZ1RSWDNZMkZWUmVySTI3Z1BIRXJUMDIzWHRaazZRME91?= =?utf-8?B?MnJHcWFTV1BYTDlBWDRWSGQ2SDBZS1ZBUjMvdENFVWlvS01YdFRtS1p5UzRN?= =?utf-8?B?dFNXbFpaZmlWeXAxZmw3Nk5xTUFXb3pZMk9Wc243QkEwOUppYmVTTytvK3E1?= =?utf-8?B?blZSbDVxUVlyV2ZmenpvVlU0R2hCeWo0NkcvalpyT2ZqYnYrNHAwdktXVktW?= =?utf-8?B?S3p0SlB6di9BZTE3WlY1dTZDYmVzeFRQMktQUmw5N3B4TElNUGxYQUlJYzJK?= =?utf-8?B?ZVRmOVdHV1p3ZmMxTnZ3ZWh5Zm52NnVuYW52QklSMVBoeXhSSmx4YnhZUjZX?= =?utf-8?B?NjZGMGh6OE9ZbEhiOURNN0k4RkFvSFJoM0RCUFJ4TzZhQjF4OWtKSkllcUk4?= =?utf-8?Q?/ldgaxgH2yHv18qGhMFurT2GMrK6n4KvOjk9wpJDNA1p?= X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1144;6:xpwaHKuX6mF/p3vFZ+kerswjBFIWpNthitq0v+BRYqNZ45+hbWjBpU0LUBCnQFuT4c3+5fuz4Tju5vywu0HxdMCaLGpdCvOn9VjCGoDNiBpQRQ/zam98fUKDSflwUoheweGpL2/7w1mzDszD8WmOKPMYazeFxbfQL+s11XCL41B/ciaTfcok3ke7qr3Kv0SbR1WQnGlXOPv/OlMBDY5e8B+m42IfvuWxHdhsHfqNp52AxfhIlcMhhrJ7q+CoK3Zpfziz6KltWFHCg5DglOxDvdfgh1IiSP9eJR9Yjwd9XuVcx01Lilf/wpNVR7A54L3xutKC0ODpq25fNPSmZS1pUxxBM5GoiGWTGvUO4hmJy6xg5uBTkDM68vbqtVJcdwnPeuyt0AzNwoqu4pT4IIAbndupLU7ZxOiKlpisDlxgfss=;5:zQTPbcz5d4VxsPYrrwJQZK6Zf/dxZnUBD8IlI2fBQe05WQq5smxPukHtX84nZwUuEdeDqfaNg5XqpNigbmNURJdsRUUxFisQagi/IEHqMgMAhDImGU9E4AcaYmPEDcsWENzeqSUB2dK5udPt7dJBo5pjO0Ac5D8s3B//aB9KSi0=;24:ehi6eqI2DiYHjvRnFwU0rQomKfRZU7kEypoTTMx2bNWPzlC+OTpslJb/hbr6l5iF8oku2pVx43mSDJf4/HiCj8ydtsuKoUbIY0GgjFgbkJA= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY4PR12MB1144;7:tq8+JyWNYBlF9M157z4+9T6+el80sKyQ1raH7/ddvUs2BbmSyX3N9TbTUhCJs+0Jico67u/G55IdIjCB4iC3pdAFt4jeqiYrPVPrA8tSzvTeO7cXtVexvOVr2GJgCOO1SJbAfOC7y4bNo88HAGdhxR8vyenC3UufekbLAIIxOSrnHZo9o/24HbkZebrrLdPm3ehqsX24gy6r8XCfdO3a3X3jmtppgE/ndcOY4gSyyfmkdmqF+pj+hs/76GHEXlxy6On6e0knwAuqKzQZtnvJkL55kNuPCqta6ossH+O7I+QYL07EXsvutmKnbKGxoXO9W0cHIJbSj9k4pulLzxx8Vg==;20:m9JkKvkqxvQNdzIr+8owqsU768yr7+RgeAq9j99WxHWkAxIGAKYYT1RHBulqOSXieWjLVe70bJx9+GT//OwXByNgbOZwSnL2Lk4PmVVdVy/wus59rgUPddLq6IQ21Y+Rdy/nO2AxjqZPTGgN7hs9+LN8qwwV0xNkmu2CIWolQtk8TIWuzJKSKlDRtadVJAaO0iEWUWE8ULe28qGkyfx4QU/1NT2CdNZ2xt49yQVdAy8gpfGwWreEpVTtJgTyggCl X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Feb 2017 15:48:55.9163 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR12MB1144 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2/20/2017 12:22 PM, Borislav Petkov wrote: > On Thu, Feb 16, 2017 at 09:43:58AM -0600, Tom Lendacky wrote: >> Add support to be able to either encrypt or decrypt data in place during >> the early stages of booting the kernel. This does not change the memory >> encryption attribute - it is used for ensuring that data present in either >> an encrypted or decrypted memory area is in the proper state (for example >> the initrd will have been loaded by the boot loader and will not be >> encrypted, but the memory that it resides in is marked as encrypted). >> >> The early_memmap support is enhanced to specify encrypted and decrypted >> mappings with and without write-protection. The use of write-protection is >> necessary when encrypting data "in place". The write-protect attribute is >> considered cacheable for loads, but not stores. This implies that the >> hardware will never give the core a dirty line with this memtype. >> >> Signed-off-by: Tom Lendacky >> --- >> arch/x86/include/asm/mem_encrypt.h | 15 +++++++ >> arch/x86/mm/mem_encrypt.c | 79 ++++++++++++++++++++++++++++++++++++ >> 2 files changed, 94 insertions(+) > > ... > >> diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c >> index d71df97..ac3565c 100644 >> --- a/arch/x86/mm/mem_encrypt.c >> +++ b/arch/x86/mm/mem_encrypt.c >> @@ -14,6 +14,9 @@ >> #include >> #include >> >> +#include >> +#include >> + >> extern pmdval_t early_pmd_flags; >> >> /* >> @@ -24,6 +27,82 @@ >> unsigned long sme_me_mask __section(.data) = 0; >> EXPORT_SYMBOL_GPL(sme_me_mask); >> >> +/* Buffer used for early in-place encryption by BSP, no locking needed */ >> +static char sme_early_buffer[PAGE_SIZE] __aligned(PAGE_SIZE); >> + >> +/* >> + * This routine does not change the underlying encryption setting of the >> + * page(s) that map this memory. It assumes that eventually the memory is >> + * meant to be accessed as either encrypted or decrypted but the contents >> + * are currently not in the desired stated. > > state. Will fix. > >> + * >> + * This routine follows the steps outlined in the AMD64 Architecture >> + * Programmer's Manual Volume 2, Section 7.10.8 Encrypt-in-Place. >> + */ >> +static void __init __sme_early_enc_dec(resource_size_t paddr, >> + unsigned long size, bool enc) >> +{ >> + void *src, *dst; >> + size_t len; >> + >> + if (!sme_me_mask) >> + return; >> + >> + local_flush_tlb(); >> + wbinvd(); >> + >> + /* >> + * There are limited number of early mapping slots, so map (at most) >> + * one page at time. >> + */ >> + while (size) { >> + len = min_t(size_t, sizeof(sme_early_buffer), size); >> + >> + /* >> + * Create write protected mappings for the current format > > write-protected Ok. > >> + * of the memory. >> + */ >> + src = enc ? early_memremap_decrypted_wp(paddr, len) : >> + early_memremap_encrypted_wp(paddr, len); >> + >> + /* >> + * Create mappings for the desired format of the memory. >> + */ > > That comment can go - you already say that in the previous one. Ok. > >> + dst = enc ? early_memremap_encrypted(paddr, len) : >> + early_memremap_decrypted(paddr, len); > > Btw, looking at this again, it seems to me that if you write it this > way: > > if (enc) { > src = early_memremap_decrypted_wp(paddr, len); > dst = early_memremap_encrypted(paddr, len); > } else { > src = early_memremap_encrypted_wp(paddr, len); > dst = early_memremap_decrypted(paddr, len); > } > > it might become even more readable. Anyway, just an idea - your decision > which is better. I go back and forth on that one, too. Not sure what I'll do, I guess it will depend on my mood :). > >> + >> + /* >> + * If a mapping can't be obtained to perform the operation, >> + * then eventual access of that area will in the desired > > s/will // Yup. Thanks, Tom > >> + * mode will cause a crash. >> + */ >> + BUG_ON(!src || !dst); >> + >> + /* >> + * Use a temporary buffer, of cache-line multiple size, to >> + * avoid data corruption as documented in the APM. >> + */ >> + memcpy(sme_early_buffer, src, len); >> + memcpy(dst, sme_early_buffer, len); >> + >> + early_memunmap(dst, len); >> + early_memunmap(src, len); >> + >> + paddr += len; >> + size -= len; >> + } >> +} >> + >> +void __init sme_early_encrypt(resource_size_t paddr, unsigned long size) >> +{ >> + __sme_early_enc_dec(paddr, size, true); >> +} >> + >> +void __init sme_early_decrypt(resource_size_t paddr, unsigned long size) >> +{ >> + __sme_early_enc_dec(paddr, size, false); >> +} >> + >> void __init sme_early_init(void) >> { >> unsigned int i; >> >> > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tom Lendacky Subject: Re: [RFC PATCH v4 09/28] x86: Add support for early encryption/decryption of memory Date: Wed, 22 Feb 2017 09:48:52 -0600 Message-ID: <7b8d7258-d5b5-6dbb-afe3-755f6a453d40@amd.com> References: <20170216154158.19244.66630.stgit@tlendack-t1.amdoffice.net> <20170216154358.19244.6082.stgit@tlendack-t1.amdoffice.net> <20170220182256.qorlso5f4c72hl6o@pd.tnic> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <20170220182256.qorlso5f4c72hl6o@pd.tnic> Sender: owner-linux-mm@kvack.org To: Borislav Petkov Cc: linux-arch@vger.kernel.org, linux-efi@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, linux-mm@kvack.org, iommu@lists.linux-foundation.org, Rik van Riel , =?UTF-8?B?UmFkaW0gS3LEjW3DocWZ?= , Toshimitsu Kani , Arnd Bergmann , Jonathan Corbet , Matt Fleming , "Michael S. Tsirkin" , Joerg Roedel , Konrad Rzeszutek Wilk , Paolo Bonzini , Brijesh Singh , Ingo Molnar , Alexander Potapenko , Andy Lutomirski , "H. Peter Anvin" , Andrey Ryabinin , Thomas Gleixner List-Id: linux-efi@vger.kernel.org On 2/20/2017 12:22 PM, Borislav Petkov wrote: > On Thu, Feb 16, 2017 at 09:43:58AM -0600, Tom Lendacky wrote: >> Add support to be able to either encrypt or decrypt data in place during >> the early stages of booting the kernel. This does not change the memory >> encryption attribute - it is used for ensuring that data present in either >> an encrypted or decrypted memory area is in the proper state (for example >> the initrd will have been loaded by the boot loader and will not be >> encrypted, but the memory that it resides in is marked as encrypted). >> >> The early_memmap support is enhanced to specify encrypted and decrypted >> mappings with and without write-protection. The use of write-protection is >> necessary when encrypting data "in place". The write-protect attribute is >> considered cacheable for loads, but not stores. This implies that the >> hardware will never give the core a dirty line with this memtype. >> >> Signed-off-by: Tom Lendacky >> --- >> arch/x86/include/asm/mem_encrypt.h | 15 +++++++ >> arch/x86/mm/mem_encrypt.c | 79 ++++++++++++++++++++++++++++++++++++ >> 2 files changed, 94 insertions(+) > > ... > >> diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c >> index d71df97..ac3565c 100644 >> --- a/arch/x86/mm/mem_encrypt.c >> +++ b/arch/x86/mm/mem_encrypt.c >> @@ -14,6 +14,9 @@ >> #include >> #include >> >> +#include >> +#include >> + >> extern pmdval_t early_pmd_flags; >> >> /* >> @@ -24,6 +27,82 @@ >> unsigned long sme_me_mask __section(.data) = 0; >> EXPORT_SYMBOL_GPL(sme_me_mask); >> >> +/* Buffer used for early in-place encryption by BSP, no locking needed */ >> +static char sme_early_buffer[PAGE_SIZE] __aligned(PAGE_SIZE); >> + >> +/* >> + * This routine does not change the underlying encryption setting of the >> + * page(s) that map this memory. It assumes that eventually the memory is >> + * meant to be accessed as either encrypted or decrypted but the contents >> + * are currently not in the desired stated. > > state. Will fix. > >> + * >> + * This routine follows the steps outlined in the AMD64 Architecture >> + * Programmer's Manual Volume 2, Section 7.10.8 Encrypt-in-Place. >> + */ >> +static void __init __sme_early_enc_dec(resource_size_t paddr, >> + unsigned long size, bool enc) >> +{ >> + void *src, *dst; >> + size_t len; >> + >> + if (!sme_me_mask) >> + return; >> + >> + local_flush_tlb(); >> + wbinvd(); >> + >> + /* >> + * There are limited number of early mapping slots, so map (at most) >> + * one page at time. >> + */ >> + while (size) { >> + len = min_t(size_t, sizeof(sme_early_buffer), size); >> + >> + /* >> + * Create write protected mappings for the current format > > write-protected Ok. > >> + * of the memory. >> + */ >> + src = enc ? early_memremap_decrypted_wp(paddr, len) : >> + early_memremap_encrypted_wp(paddr, len); >> + >> + /* >> + * Create mappings for the desired format of the memory. >> + */ > > That comment can go - you already say that in the previous one. Ok. > >> + dst = enc ? early_memremap_encrypted(paddr, len) : >> + early_memremap_decrypted(paddr, len); > > Btw, looking at this again, it seems to me that if you write it this > way: > > if (enc) { > src = early_memremap_decrypted_wp(paddr, len); > dst = early_memremap_encrypted(paddr, len); > } else { > src = early_memremap_encrypted_wp(paddr, len); > dst = early_memremap_decrypted(paddr, len); > } > > it might become even more readable. Anyway, just an idea - your decision > which is better. I go back and forth on that one, too. Not sure what I'll do, I guess it will depend on my mood :). > >> + >> + /* >> + * If a mapping can't be obtained to perform the operation, >> + * then eventual access of that area will in the desired > > s/will // Yup. Thanks, Tom > >> + * mode will cause a crash. >> + */ >> + BUG_ON(!src || !dst); >> + >> + /* >> + * Use a temporary buffer, of cache-line multiple size, to >> + * avoid data corruption as documented in the APM. >> + */ >> + memcpy(sme_early_buffer, src, len); >> + memcpy(dst, sme_early_buffer, len); >> + >> + early_memunmap(dst, len); >> + early_memunmap(src, len); >> + >> + paddr += len; >> + size -= len; >> + } >> +} >> + >> +void __init sme_early_encrypt(resource_size_t paddr, unsigned long size) >> +{ >> + __sme_early_enc_dec(paddr, size, true); >> +} >> + >> +void __init sme_early_decrypt(resource_size_t paddr, unsigned long size) >> +{ >> + __sme_early_enc_dec(paddr, size, false); >> +} >> + >> void __init sme_early_init(void) >> { >> unsigned int i; >> >> > -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f69.google.com (mail-pg0-f69.google.com [74.125.83.69]) by kanga.kvack.org (Postfix) with ESMTP id 5F6BC6B038A for ; Wed, 22 Feb 2017 10:49:02 -0500 (EST) Received: by mail-pg0-f69.google.com with SMTP id v63so9415304pgv.0 for ; Wed, 22 Feb 2017 07:49:02 -0800 (PST) Received: from NAM03-CO1-obe.outbound.protection.outlook.com (mail-co1nam03on0048.outbound.protection.outlook.com. [104.47.40.48]) by mx.google.com with ESMTPS id g70si1573531pgc.92.2017.02.22.07.49.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 22 Feb 2017 07:49:01 -0800 (PST) Subject: Re: [RFC PATCH v4 09/28] x86: Add support for early encryption/decryption of memory References: <20170216154158.19244.66630.stgit@tlendack-t1.amdoffice.net> <20170216154358.19244.6082.stgit@tlendack-t1.amdoffice.net> <20170220182256.qorlso5f4c72hl6o@pd.tnic> From: Tom Lendacky Message-ID: <7b8d7258-d5b5-6dbb-afe3-755f6a453d40@amd.com> Date: Wed, 22 Feb 2017 09:48:52 -0600 MIME-Version: 1.0 In-Reply-To: <20170220182256.qorlso5f4c72hl6o@pd.tnic> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit Sender: owner-linux-mm@kvack.org List-ID: To: Borislav Petkov Cc: linux-arch@vger.kernel.org, linux-efi@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, linux-mm@kvack.org, iommu@lists.linux-foundation.org, Rik van Riel , =?UTF-8?B?UmFkaW0gS3LEjW3DocWZ?= , Toshimitsu Kani , Arnd Bergmann , Jonathan Corbet , Matt Fleming , "Michael S. Tsirkin" , Joerg Roedel , Konrad Rzeszutek Wilk , Paolo Bonzini , Brijesh Singh , Ingo Molnar , Alexander Potapenko , Andy Lutomirski , "H. Peter Anvin" , Andrey Ryabinin , Thomas Gleixner , Larry Woodman , Dmitry Vyukov On 2/20/2017 12:22 PM, Borislav Petkov wrote: > On Thu, Feb 16, 2017 at 09:43:58AM -0600, Tom Lendacky wrote: >> Add support to be able to either encrypt or decrypt data in place during >> the early stages of booting the kernel. This does not change the memory >> encryption attribute - it is used for ensuring that data present in either >> an encrypted or decrypted memory area is in the proper state (for example >> the initrd will have been loaded by the boot loader and will not be >> encrypted, but the memory that it resides in is marked as encrypted). >> >> The early_memmap support is enhanced to specify encrypted and decrypted >> mappings with and without write-protection. The use of write-protection is >> necessary when encrypting data "in place". The write-protect attribute is >> considered cacheable for loads, but not stores. This implies that the >> hardware will never give the core a dirty line with this memtype. >> >> Signed-off-by: Tom Lendacky >> --- >> arch/x86/include/asm/mem_encrypt.h | 15 +++++++ >> arch/x86/mm/mem_encrypt.c | 79 ++++++++++++++++++++++++++++++++++++ >> 2 files changed, 94 insertions(+) > > ... > >> diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c >> index d71df97..ac3565c 100644 >> --- a/arch/x86/mm/mem_encrypt.c >> +++ b/arch/x86/mm/mem_encrypt.c >> @@ -14,6 +14,9 @@ >> #include >> #include >> >> +#include >> +#include >> + >> extern pmdval_t early_pmd_flags; >> >> /* >> @@ -24,6 +27,82 @@ >> unsigned long sme_me_mask __section(.data) = 0; >> EXPORT_SYMBOL_GPL(sme_me_mask); >> >> +/* Buffer used for early in-place encryption by BSP, no locking needed */ >> +static char sme_early_buffer[PAGE_SIZE] __aligned(PAGE_SIZE); >> + >> +/* >> + * This routine does not change the underlying encryption setting of the >> + * page(s) that map this memory. It assumes that eventually the memory is >> + * meant to be accessed as either encrypted or decrypted but the contents >> + * are currently not in the desired stated. > > state. Will fix. > >> + * >> + * This routine follows the steps outlined in the AMD64 Architecture >> + * Programmer's Manual Volume 2, Section 7.10.8 Encrypt-in-Place. >> + */ >> +static void __init __sme_early_enc_dec(resource_size_t paddr, >> + unsigned long size, bool enc) >> +{ >> + void *src, *dst; >> + size_t len; >> + >> + if (!sme_me_mask) >> + return; >> + >> + local_flush_tlb(); >> + wbinvd(); >> + >> + /* >> + * There are limited number of early mapping slots, so map (at most) >> + * one page at time. >> + */ >> + while (size) { >> + len = min_t(size_t, sizeof(sme_early_buffer), size); >> + >> + /* >> + * Create write protected mappings for the current format > > write-protected Ok. > >> + * of the memory. >> + */ >> + src = enc ? early_memremap_decrypted_wp(paddr, len) : >> + early_memremap_encrypted_wp(paddr, len); >> + >> + /* >> + * Create mappings for the desired format of the memory. >> + */ > > That comment can go - you already say that in the previous one. Ok. > >> + dst = enc ? early_memremap_encrypted(paddr, len) : >> + early_memremap_decrypted(paddr, len); > > Btw, looking at this again, it seems to me that if you write it this > way: > > if (enc) { > src = early_memremap_decrypted_wp(paddr, len); > dst = early_memremap_encrypted(paddr, len); > } else { > src = early_memremap_encrypted_wp(paddr, len); > dst = early_memremap_decrypted(paddr, len); > } > > it might become even more readable. Anyway, just an idea - your decision > which is better. I go back and forth on that one, too. Not sure what I'll do, I guess it will depend on my mood :). > >> + >> + /* >> + * If a mapping can't be obtained to perform the operation, >> + * then eventual access of that area will in the desired > > s/will // Yup. Thanks, Tom > >> + * mode will cause a crash. >> + */ >> + BUG_ON(!src || !dst); >> + >> + /* >> + * Use a temporary buffer, of cache-line multiple size, to >> + * avoid data corruption as documented in the APM. >> + */ >> + memcpy(sme_early_buffer, src, len); >> + memcpy(dst, sme_early_buffer, len); >> + >> + early_memunmap(dst, len); >> + early_memunmap(src, len); >> + >> + paddr += len; >> + size -= len; >> + } >> +} >> + >> +void __init sme_early_encrypt(resource_size_t paddr, unsigned long size) >> +{ >> + __sme_early_enc_dec(paddr, size, true); >> +} >> + >> +void __init sme_early_decrypt(resource_size_t paddr, unsigned long size) >> +{ >> + __sme_early_enc_dec(paddr, size, false); >> +} >> + >> void __init sme_early_init(void) >> { >> unsigned int i; >> >> > -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org