From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752634AbdJDNRK (ORCPT ); Wed, 4 Oct 2017 09:17:10 -0400 Received: from mail-cys01nam02on0084.outbound.protection.outlook.com ([104.47.37.84]:31550 "EHLO NAM02-CY1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752447AbdJDNP2 (ORCPT ); Wed, 4 Oct 2017 09:15:28 -0400 From: Brijesh Singh To: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Brijesh Singh , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Joerg Roedel , Borislav Petkov , Tom Lendacky Subject: [Part2 PATCH v5 24/31] KVM: SVM: Add support for SEV DEBUG_DECRYPT command Date: Wed, 4 Oct 2017 08:14:05 -0500 Message-Id: <20171004131412.13038-25-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20171004131412.13038-1-brijesh.singh@amd.com> References: <20171004131412.13038-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: MWHPR2201CA0056.namprd22.prod.outlook.com (10.172.59.30) To SN1PR12MB0160.namprd12.prod.outlook.com (10.162.3.147) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 84d2a351-1805-4ac7-ac32-08d50b29f91b X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(2017030254152)(48565401081)(2017052603199)(201703131423075)(201703031133081)(201702281549075);SRVR:SN1PR12MB0160; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0160;3:7/DTwKkdAnZy7oNKAPRLonkNq3ZerQTYzHq5k/VLB+SSr+8NFJmTTf9OYzTyE7iy0P+DCbzYta0QLiL64RrkHUa3gt+HkEZDlcbwMh473R09iWswdAjIpt2/UN8007/23+YyPwSVTL667jOC5+ElAYiXxkEcZSnb/HxLj9qYHyfEn9ApCneDkF4k66bIeQ5aYtvTu2MCf8qmz+jYfC2K3JX94fvCRrxqv3rJzWXLRcZWb6HB0jl92KJOBhGCpUay;25:vO/IoM2781maDGutodjB99F3l1Ea3bBx1A12T2uVohexUKSraP+KNXqu7Zy2kah2gMH2YRFJId6XrZmIRG8Pyvbibn+4vuX1h0WO6CPAZARGfdHTo6sts9lFigzKA/+KWQ4cUANGvpHQN+zEMYbWOBumGBuVQmsNtO8HX0dKWUZlEdsmsgA6aJurWzf6x81pv29XO/v+rf+RQiqOfIgX9f18yyOEqp4AtCIvLb68LMbcPFohdlcv6pjKMkO8by9vz94yq4wZKxTFE0B6f0GjCa1Jy8NbQectTlDGRozSmEeTvLThJjEAV47igeOr/vCL50zCihig7d9wnemkLrPb5A==;31:CjGWRAeCujVI1Vdb+wW84aGmqX5aIWe2kWrR5nu8hU2xCmlReGX9R9bBIv3WpPZU4ydpAH1dT3IQhSY3YHiAyYadkq+rodRxg+GlEzQNQSneJuyQ/hpjAAEOl8KZJKQfpDycVINT4E8hks6Jq+st7fl/FrsQpkI6v4u7nsOhjpzvnqmx6cckBuP9vwlEOl0BTjvi+PwIExLsPnemfgQZRmxm/jKpykJYbDjHBTsc1t8= X-MS-TrafficTypeDiagnostic: SN1PR12MB0160: X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0160;20:0YfRDxYvT6aMJCP7A7dJZ8lhcQdsgpA7PldK7LucbxPWem7COeRCYTgoOJG+FNz8EuQifqPzrKNjPhcNwD80fEiTCD2X7wSIZ+OFHqbiQXFnUYomvpdh5eBFgcUPtCp6/WvqwltnlbaKF81+lSmdFdyJedmUZhA0yCSCnTh+Mceol3fgCTiziWUmROzShp4fpv99M05lEAnn9XC9xz4TGKZjYw2O7rtWOtBCx5YI5gVKiruwQpcH2pOR8RaTxCwFfmG7YEnUpVpGLsu1ZApSlgAyacvxYwZNGGn3uP6vKzxMwo7kh5P8Od69Dy4Y0wV9TTI5hfpkVxbOIDpLUkmXQku24OHxWafwiDzF8y8km19byglNCWL9+nsv+swv6qm3RWAGvfzaEgDMLCEsNi1mav3u9agwG2qkzZ8UE5LGEVuiRFvGkrNBynKZs+rE9mLJb6SZk9n0dCfZlVACTkkVfLXPAjDLw7I084IZ8cmfa3gTbNBCDXko+6lK5Se26dJz;4:LYYjW3N9Htuz0Zr0a4gW3XAgCzLpgV8OsBcXJK9GHoG8PwkW9XOC/IFRNoRouieeq9suCku3280kU6KaNNq8AVgbKL9/fJGZoCdlQNiY8HSvRnCxQd+rlZbs1LuQEdRPt4AOmxaiDy8An5YSEexQ8aNYq0DfS71GLNUGQm/adM0+auZEGWfPeKlcr7M49O41NsFVmD4jNjNAsWGaZEPQftR6Q7mIn9NllrzyNuylOsrwjEAg2HZuCGqnNuqlhDwus4KexN6ZzO2n7dvPY7Vjx3zDerXaujx2HB/ahC4s2r5HjXzAAQ/NkCRnxTDP3FF2voiyBdNMg7vLWKReiW2iNg== X-Exchange-Antispam-Report-Test: UriScan:(9452136761055)(767451399110); 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)(3002001)(93006095)(93001095)(10201501046)(6055026)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123564025)(20161123562025)(20161123555025)(20161123560025)(20161123558100)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:SN1PR12MB0160;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:SN1PR12MB0160; X-Forefront-PRVS: 0450A714CB X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(39860400002)(346002)(376002)(199003)(189002)(97736004)(86362001)(23676002)(76176999)(53936002)(50986999)(1076002)(6116002)(3846002)(478600001)(36756003)(47776003)(101416001)(33646002)(6486002)(66066001)(189998001)(68736007)(105586002)(53416004)(50466002)(4326008)(54906003)(8936002)(305945005)(6666003)(2870700001)(81166006)(5660300001)(81156014)(25786009)(2906002)(8676002)(7736002)(2950100002)(7416002)(50226002)(106356001)(316002)(16526018);DIR:OUT;SFP:1101;SCL:1;SRVR:SN1PR12MB0160;H:ubuntu-010236106000.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtTTjFQUjEyTUIwMTYwOzIzOmErR01qdjRPckM3ZDI0Mlg0Y1NKdHBncGxF?= =?utf-8?B?c1RvbTZ2bUhrbG11V1JoL3lsQ0JuSHRKUmNzcjc5ZjlZb2VTTkdjeVphYjVs?= =?utf-8?B?ekVxVnlvWEZDL1hoK2NUVGxWMzNkUVNvTkNLTVdGQzBwNWZmN2dSNXpLWWU0?= =?utf-8?B?eVlVbm1QNHlhSks4RjZtandnZGJDZ0s1RHN0N3FPNmxZWTVhQ1E1NXNDSTFQ?= =?utf-8?B?WTBQSjdXZnVqOTNIYWtBcFJVaFhIZ1VnYlovL2ZTaGNTRDNESjc5eWlCVkt1?= =?utf-8?B?QWhMaEYxWXhObFJ6Mnd6NG1waHVEeVFZTnNQditMdGwyVFMzelFFa2ZpR0Er?= =?utf-8?B?VnhOYUNnOStRMHhNRVZXQ1dyOTN4N1g2UnI1SGFPYVBOZ1hMZHFhd0ZpZTlu?= =?utf-8?B?Vk8vVDB6d3E3N0ExUUNWRUlCSUpHOXlneXh4QitBVCs0UXNIUHdzMFNnK3dJ?= =?utf-8?B?Umt3dU9NNmdPajh5N1ZONDJKbkVVWnVxNWNWRFZqWFJ3dmpFNndkaXdJN0dv?= =?utf-8?B?S1Axd09mZEVzR1gyaVFiZGFKOFY3OVd6ZnBUeFlIR050Yi92QUpLNzRqdVhQ?= =?utf-8?B?OUpXZUIwb3RFYVV6eExsakErQnVUcjlZbjI1T0RrRzI4SDFrOXI3TzJRNDNW?= =?utf-8?B?VHMvYW9KeG9mYVA4T2NqY01IWVBkM09KbEpkZTFWY2ZHVGlka3RjRnhNd1hv?= =?utf-8?B?K0p5QlJFMmdZNjZwaXZrMkJrdHFYY3llQkhPWjFlSmdXNDRtc2dBSmR2dm5i?= =?utf-8?B?Z29XejEvYUorNDJEUlVBQm1HNyt3TkhOV0IxWERxZTZpc1BSbEpzZk9BK0xw?= =?utf-8?B?VkhvdjBIUjRUTGZNekNXUnJ4SE5tempHdzltT1g5K2ptWWV2VnBnK3BnOHdY?= =?utf-8?B?S3NwSUFmSHJIUmU3UWNMeU9zZ1h5Y3pPc1NDNmFXdGhKOTFzTjFSYnJ5enVO?= =?utf-8?B?M1Z0Y0VGN3d4Q2lnMWZnU2tDUWRhM1dqYllFTDFacXdjUTh4RFlkS1hBdnVP?= =?utf-8?B?QUJzMTlGREhFRjE1YmtJbjFCeWFZU045djB1d3IyQldydDA3NU1JbmhVdU9C?= =?utf-8?B?K2V3MjZjQTNvaktPL3B6ODVaVklmSHlPY1VzUWNoVkxQZElrUEUrY1dIZzl6?= =?utf-8?B?V1BpRlRRalNsMHpJT0NHdnlhM2FLU2RSMUowNEVkdXRBL0ZvSitiTG9jMmVl?= =?utf-8?B?YkFkajlsTFhiMGh0SnJxenhXdmxNZUhpdXFSdWQ2RTdvWFRuY3NHMDFaeW9u?= =?utf-8?B?TkJYeDBIbTJtMm5xSlNyRE9nMTB1Tnl4VEhmRlp0YS9pS0hZWDlkSEtFRFBz?= =?utf-8?B?cDFxYy9veWltbzUvQmtyb3JZNlN1UEJmVE5hbXVUUzJUS085ay9ldTMrcjdU?= =?utf-8?B?WGtXQVB2SURiUjhvc3FqU29TeXpqTjRjRGtCazlpQ2p6ZzlxQXF1QW5NTGZM?= =?utf-8?Q?T+B8JkrITmTSDBKsnPFM2mxu4E8?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0160;6:MHvTyCYiBsziWJoks11gfdqM4ASj4prmLgzWdxwmzGfo2RlrSNC8qub9IY481p0q0HfuUNET+7u+wxWBIlhF8ImjWB7NesmhB2FB1AxhZBbSi87pixQwqetSueBBKBlyWXat9MiAjJXeUtU9tabe1KlW7q0tCPXTUqpR20b67TvgMPM6HVQnZ5EBOu6gjKOUzzxPbQCIeRvN7EN/ASJMKNdj5am9T6665pd/dvuhvzgPEhGfGTEM3CT1kC3UQL5t2aE7PVUaPEiPDNRAEjbgWEqy8+MDg5JNBSp6gP+6Gm0p8cDyfMN8AXS7aXViRpkLr6d1mE4DWVj8qfOXL/9pzw==;5:/2ppEHvuzhpr7QpYeE8ipnSSwPXcYY4+/avjgbmQjLNT1/X/YpG+a5nUdbq+qkS9aDfhIBeBX8bwFKVmRNP7VC5BzRDaKCwm50xHFl+5RPJxZpOpoVsG6KrpwmLZ7xx49d8jpvWL3Fv0naqc7ZjTUw==;24:nFMrzfjwamN9QGQ0Dh4bj+AMiF7EEr++1uUu+/q0wiUkKiCeQk21r3d2k2EbCoXTR0NaTh3J1J8d2E9jYq0GFgCFrKg9Fi4/8p+Il32e/oU=;7:St6dXypd7brus61THeNr3zn85HvuIE1U+IZ4yRu0OOonjluBkK6OiA/FjHPmJz+MAVWi9yL/ONf7qVeFOj+XR5RY/TycyKNC+0X7bG31KgT+b6FxTyfFDMsGRzRR3zubYUd729ETWesbLDi8OHUCvwGkGD8sJ+SbTRgdWifdHF1qUr6ghFNAffVmGy24WEjmtEusCr5fbfsmPYkncOivTNjdv0h24ZjY80BLbKcDLGE= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0160;20:P4tSax9PBQYGvY5v/BW8/MZRt4VnKFQWF7ueHEH+EKGcmLv/v++Dr42KdnM2lAZVkUAwJgBs0HodgMWojf9eRya/XT15zq80sTBK1YHn0F0n+nUfwxJhEIx1Ma/07by1wCEcsRkJrSrsWhO90iMIwk6DZZ8eDQjBncJZHPzn633AioryAFM5dWGxCYv2cE6FbNkSfw5zyodZnDYLFslJPu5sV9+3vsWsytXOSpfU0JXORFdugQeC+vLs34uSuiu1 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Oct 2017 13:15:22.8073 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0160 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The command is used for decrypting a guest memory region for debug purposes. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Paolo Bonzini Cc: "Radim Krčmář" Cc: Joerg Roedel Cc: Borislav Petkov Cc: Tom Lendacky Cc: x86@kernel.org Cc: kvm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Brijesh Singh --- arch/x86/kvm/svm.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 693724c75e2d..373f6c34e006 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -6113,6 +6113,183 @@ static int sev_guest_status(struct kvm *kvm, struct kvm_sev_cmd *argp) return ret; } +static int __sev_issue_dbg_cmd(struct kvm *kvm, unsigned long src, + unsigned long dst, int size, + int *error, bool enc) +{ + struct kvm_sev_info *sev = &kvm->arch.sev_info; + struct sev_data_dbg *data; + int ret; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->handle = sev->handle; + data->dst_addr = dst; + data->src_addr = src; + data->len = size; + + ret = sev_issue_cmd(kvm, + enc ? SEV_CMD_DBG_ENCRYPT : SEV_CMD_DBG_DECRYPT, + data, error); + kfree(data); + return ret; +} + +/* + * Decrypt source memory into userspace or kernel buffer. If destination buffer + * or len is not aligned to 16-byte boundary then it uses intermediate buffer. + */ +static int __sev_dbg_decrypt(struct kvm *kvm, unsigned long paddr, + unsigned long __user dst_uaddr, + unsigned long dst_kaddr, unsigned long dst_paddr, + int size, int *error) +{ + int ret, offset = 0, len = size; + struct page *tpage = NULL; + + /* + * Debug command works with 16-byte aligned inputs, check if all inputs + * (src, dst and len) are 16-byte aligned. If one of the input is not + * aligned then we decrypt more than requested into a temporary buffer + * and copy the porition of data into destination buffer. + */ + if (!IS_ALIGNED(paddr, 16) || + !IS_ALIGNED(dst_paddr, 16) || + !IS_ALIGNED(size, 16)) { + tpage = (void *)alloc_page(GFP_KERNEL); + if (!tpage) + return -ENOMEM; + + dst_paddr = __sme_page_pa(tpage); + + /* + * if source buffer is not aligned then offset will be used + * when copying the data from the temporary buffer into + * destination buffer. + */ + offset = paddr & 15; + + /* its safe to read more than requested size. */ + len = round_up(size + offset, 16); + + paddr = round_down(paddr, 16); + + /* + * The PSP may write the memory region with different C-bit (e.g + * x86 cache may have a mapping with C=0 and PSP may write the same + * region with C=1) hence lets make sure we invalidate the caches + * so that we can see the recent contents after the command + * completes. + */ + clflush_cache_range(page_address(tpage), PAGE_SIZE); + } + + ret = __sev_issue_dbg_cmd(kvm, paddr, dst_paddr, len, error, false); + + /* + * If temporary buffer is used then copy the data from temporary buffer + * into destination buffer. + */ + if (!ret && tpage) { + /* + * If destination buffer is a userspace buffer then use + * copy_to_user otherwise memcpy. + */ + if (dst_uaddr) { + if (copy_to_user((void __user *)(uintptr_t)dst_uaddr, + page_address(tpage) + offset, size)) + ret = -EFAULT; + } else { + memcpy((void *)dst_kaddr, page_address(tpage) + offset, size); + } + } + + if (tpage) + __free_page(tpage); + + return ret; +} + +static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec) +{ + unsigned long vaddr, vaddr_end, next_vaddr; + unsigned long dst_vaddr, dst_vaddr_end; + struct page **src_p, **dst_p; + struct kvm_sev_dbg debug; + unsigned long n; + int ret, size; + + if (!sev_guest(kvm)) + return -ENOTTY; + + if (copy_from_user(&debug, (void __user *)(uintptr_t)argp->data, + sizeof(struct kvm_sev_dbg))) + return -EFAULT; + + vaddr = debug.src_uaddr; + size = debug.len; + vaddr_end = vaddr + size; + dst_vaddr = debug.dst_uaddr; + dst_vaddr_end = dst_vaddr + size; + + for (; vaddr < vaddr_end; vaddr = next_vaddr) { + int len, s_off, d_off; + + /* lock userspace source and destination page */ + src_p = sev_pin_memory(kvm, vaddr & PAGE_MASK, PAGE_SIZE, &n, 0); + if (!src_p) + return -EFAULT; + + dst_p = sev_pin_memory(kvm, dst_vaddr & PAGE_MASK, PAGE_SIZE, &n, 1); + if (!dst_p) { + sev_unpin_memory(kvm, src_p, n); + return -EFAULT; + } + + /* + * The PSP may write the memory region with different C-bit (e.g + * x86 cache may have a mapping with C=0 and PSP may write the same + * region with C=1) hence lets make sure we invalidate the caches + * so that we can see the recent contents after the command completion. + */ + sev_clflush_pages(src_p, 1); + sev_clflush_pages(dst_p, 1); + + /* + * since user buffer may not be page aligned, calculate the + * offset within the page. + */ + s_off = vaddr & ~PAGE_MASK; + d_off = dst_vaddr & ~PAGE_MASK; + len = min_t(size_t, (PAGE_SIZE - s_off), size); + + ret = __sev_dbg_decrypt(kvm, + __sme_page_pa(src_p[0]) + s_off, + dst_vaddr, 0, + __sme_page_pa(dst_p[0]) + d_off, + len, &argp->error); + + sev_unpin_memory(kvm, src_p, 1); + sev_unpin_memory(kvm, dst_p, 1); + + if (ret) + goto err; + + next_vaddr = vaddr + len; + dst_vaddr = dst_vaddr + len; + size -= len; + } +err: + return ret; +} + +static int sev_dbg_decrypt(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + return sev_dbg_crypt(kvm, argp, true); +} + static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) { struct kvm_sev_cmd sev_cmd; @@ -6151,6 +6328,10 @@ static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) r = sev_guest_status(kvm, &sev_cmd); break; } + case KVM_SEV_DBG_DECRYPT: { + r = sev_dbg_decrypt(kvm, &sev_cmd); + break; + } default: break; } -- 2.9.5