From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751911AbdISUrV (ORCPT ); Tue, 19 Sep 2017 16:47:21 -0400 Received: from mail-by2nam01on0056.outbound.protection.outlook.com ([104.47.34.56]:55572 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751872AbdISUrP (ORCPT ); Tue, 19 Sep 2017 16:47:15 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; From: Brijesh Singh To: linux-kernel@vger.kernel.org, kvm@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 , x86@kernel.org Subject: [Part2 PATCH v4 17/29] KVM: SVM: Add support for SEV LAUNCH_UPDATE_DATA command Date: Tue, 19 Sep 2017 15:46:15 -0500 Message-Id: <20170919204627.3875-18-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20170919204627.3875-1-brijesh.singh@amd.com> References: <20170919204627.3875-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: CY4PR04CA0071.namprd04.prod.outlook.com (10.171.243.164) To SN1PR12MB0158.namprd12.prod.outlook.com (10.162.3.145) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 774e5eef-871d-40a5-35d9-08d4ff9f96eb 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:SN1PR12MB0158; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0158;3:jCnRUG4BsCDFJRq2/DOZZCx8iwoaUBPgiJzJwhl6+0hmJoNoop9BG8e++A6aHCEJMGI/sJSFjsQYi1kYN4O+k53EhXSOpEeEh7Z9jS5R8k3McjMOD+eHl17meO+f90QYMW2zY/vpX9GnZvvreE+UBGO+uZLRjGz50PJnDwsOY27212uYjaM+0aLTyT4jXM5k+K+GRS+V14cfS7cpC6EcHiVrXhZWgo4NWRcff3eB7GDZmIFbpWHcIfhnd1Y6UKaV;25:CNk9/IwuPBVXsj0foPYWpvvP+n82nCXYWgRRZKOdZCBWmaxP8vlPcC7KAVhh/pyywwx7ZCkLFgfiPc6Qi0W/St9oVlvpFWDkLK4Cz6yP9Q2WXCg8yr7aBPGWUE5VQ1pYJr1SSxz1XX6fNecA2c04pWUHY6jIySVitYoe+mJ8SLrd/frSI0nsTHFt7IN6fPHHw0c1JWV6XWA48HfZnL3Wb2f+tjqibi1xWpqLoRHsFRhXbw/EgcR+9RaBCbZbNZtZpN5UqRStSOIphcz9d9U3Palkh5eYxNA6PXQtrVU4Bx7LbHdrLqUVJKPDYVDk46TXaK+K1JREUPEJI+GjzJgzpA==;31:8vKTxQv2IoOHGFDROUrLTgqiKqy/464joFiSFvf19OGfm/u93pAUAchLHG76Cxw/wxXKwQvpFuR9o+bd4bfCv/Hm/BPwOk5s7sldiJL0z8KJImucRhyFQMaF+U5uHIO3OL8QP6TYbm3MCe3DbWc7SFN4uJ9vsLzuJfmMCWHcH6hS0uPithsec3m5xvt70CoHVWmQEBgsI+F0w1mOISmNz5pIU/2R/jLKAr+XUrsRmb0= X-MS-TrafficTypeDiagnostic: SN1PR12MB0158: X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0158;20:RhuxGJ9LgIfR1cYKVAMKj99/dGgvotDQCl1Ba65oAMyHjsSFGIBACSkF2CJ1Q/dNJcLUWnoQcjNpQo5rxQH9PjxECJPEHPSWj3xJiP57LF2LtZV3NxqQvprZgYEdMw8dPwFY/SYs4qNw84C99I5OoPKYpj+ipUVHpZcgxsqr8gSAXW21Uo+zs4GlS/zHo7FRkCRJa6j3pySrLN1SN7H8lxWaP0T7Mn0unp8M4T/oa1Yd6DxAaYyG09yKZKV7XQHkNdK4nyxt4xxX9KrUzbjSaC9GDpZmsiI8AzDEN8+FN5r6HuiXdKKKZ5WjEkg7VmoONDFykMo2GHm1FVqLoZ3EeUvl87jIFG2sOKhR4LWLmjvMiAecPRmxXprgfv1OEJJBGy6C1GEou7bQoTNjVULB4eOeVXVl34Ua1Ff3CFvIk/J/XQyqu5yvP7N/MC1cd0NUJVJjM6jU/jMzSbnpPQO0PnvSsmV0H/imJOamch70rkqz173LdA3MK83/c33/5hb/;4:b5df3GVPiBvwZLxlUdREOBZhUghvarbTitd6/fxquFHgQmjQ0ww3ijBgdFmREIgoS/WgoZLjkwSn+WbkpreUOkpItR9y3FBSs8rOjPlEXHtVGRfXXz8omrKZO7Nk76lyCaKH964Ij3y+bEt6PZoSPxxlwn6ZvI7O7HhSDjZzsX+wAphCJ6XDvXAwOKTVQFhuiWsBkIscpH5jt+e076QJrZoPYvZmQbDOTmbIJteunFfS3F8vkk095N4qu2sN3rtVkWOCWClLCEkrcn08mXQSkCfLsQr/og6zWg3XHjQhpO9T+FHeXTrli0ut41riTST4rcBwnGWb4ibdlJOJYuyaBQ== 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)(93006095)(93001095)(100000703101)(100105400095)(3002001)(10201501046)(6055026)(6041248)(20161123560025)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123555025)(20161123562025)(20161123564025)(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: 04359FAD81 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(346002)(376002)(39860400002)(199003)(189002)(86362001)(50466002)(8936002)(97736004)(6116002)(3846002)(7416002)(81156014)(8676002)(50226002)(2950100002)(81166006)(316002)(478600001)(16526017)(6666003)(7736002)(66066001)(305945005)(47776003)(6486002)(189998001)(53416004)(25786009)(101416001)(2870700001)(50986999)(76176999)(53936002)(2906002)(68736007)(36756003)(106356001)(1076002)(4326008)(5660300001)(105586002)(33646002)(23676002)(54906003);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?MTtTTjFQUjEyTUIwMTU4OzIzOmRJbkhIckpVeGZGeEZ3WEZicU9SZVVoS3py?= =?utf-8?B?ZklxaEllRGs5ZWpTM3p4c295K3RselRZS3pyb1J1dFVsaGNib3lsSVAwUFRu?= =?utf-8?B?Q2RwZmg2ZktocUQxV2FDSTIxYmpvTVhqczhhZW5IRnZEaHh1ZFgvV0tKNUhi?= =?utf-8?B?OVN3V1dFcG9saHRlb2MyRmNpZkVDdUEvRnErWlRDRTJiZ3BBQmZuZmtaaXcr?= =?utf-8?B?bkVZbUR5UTR6NTlsdzJpL3NsbEhqQ0k1UFRVdXJMZ1JDU1JyUnZDOGZ3bEZp?= =?utf-8?B?L3d3QWRYZE5TV3A4ZHl2YlhVUU1RVDlXQ2FjWEhONEYraS8yQ1RKQk1rcFNV?= =?utf-8?B?VklhelB5WloyODl5cHcxSUVqbTlaMDF0VEtzL0U4KzRvU25STjBuZzEwZ05N?= =?utf-8?B?cU1hYzZqajhIUVVGamVscFpEOWxXWk5FZXdlM3lxNi9rWjA5bGZVRk1IMHVX?= =?utf-8?B?b0MyaFpnTTgwRjNGYlZZZ1Y1aDNZakNxWUpObU9Eay9RUC9Xd1IyQzZWNk5I?= =?utf-8?B?ZkNNVFlkU0g1Z2M0RDBJMEhJK2pQMjRRRnArRXZ3TE1SNWd3VFhSYktaOXBq?= =?utf-8?B?NzhoZy9ENUs3bWVEMGk3L2wrT2t1UGg2QWoyVkk5Q0IraEZ3UTRPM3FXRGVB?= =?utf-8?B?V0NTdnhkVkkyd3BoTDRCZEJQTXRTVGsxOGZONEp3T2ozWU5raXNkaFZHditH?= =?utf-8?B?eGU5WlllTFM5Z2FBdnpTQUdIWm5VOG94T2VLeFBlZ3VEYkJIV3NnMjJwQ0pu?= =?utf-8?B?TDdyUEVDV2NnUWc5UjI2REtIVEx1ZWVhU2hweWJtb1RKd1BLdUkxNk5nNWFJ?= =?utf-8?B?MU1DV2lWaXExdGs2Rk5JeUlMM0xEOGdvdjFNeWFTRGwyT1p1bHhEb2txTWdR?= =?utf-8?B?UWE1Y0ZlNEJJZG54MDdyM3V4SmlxU2hKZU1Xd0pXN1ZRRTROMGRxdWlONnFN?= =?utf-8?B?bnVNL2lqYy9RUnZFOFdNaCt2UUFwODl4bjkwdGFkMmcwc052K1FFRmZjR0RP?= =?utf-8?B?ZG9WdWU4V2xxOFJLK0lyblliOG8vUTZSdmprWTh5N2JFS095cVp0cGcrYkZU?= =?utf-8?B?TkE5ck5KRGxEN3V0VWZQWGw5R3VtbHJtNG01MzJJNVE3bTRBN2liTDMzVVIr?= =?utf-8?B?cklMNndhTnNVUmc3czNCaHVNQXNnYXFHZ0cxbzdXNUlmc0h3dVZJZ0JTYVR3?= =?utf-8?B?YlpqQWw4SjE2NDlIWHpEYTBCNm5rNHFIK1RkdHUzSFR3V3ZRVzBYOTE5RFpv?= =?utf-8?B?ZCtyN2RjcFpTOWJmZ1JJdUVSbWJWZmlKRkpVTDVLNmxzNzVJT3BVN2xBRGlk?= =?utf-8?B?SDRLVUFEK0dIYUZ3NWUvREY2OEJpc2twQXZYMS9CTFlVU2h0VzhGallpYSsw?= =?utf-8?B?T0YvYXRCUWxweXhvVkRQL1NvZmUzWEF6L2k3NUZIWk0ySTVLUjRaenJGMStN?= =?utf-8?Q?dfSlFoFaVekB/TWNfWp2wSK9XAE?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0158;6:67dmzQSq4Bg35PcCernwzym7WNXGg0MlrKn66pkZE/VSEiVizxxoloWvnOeeYD0uiWgApN1NHg/nVIJuph3jGg0v8JiKIDF0OJkVGA8HIbQnuMWv4rZpcB8RlfIOLlpHzvNA9XBr8W6G9DLr+fmADdkw0voSiYOh8ucvbJ6ADxzDNiAFSZO1EFKvLb8qaTuwdrRG+YmwLgFRn16+bko32fUJ1g3m8HS+JJwS6HxQFCsjBDzW+0dOqRwJdHqPyTNKvRPQHj9f2LlYZQ7692i5EvJQe29OdO7HUfLoyVh0MV0kxhqmG9QTvLY4o7kREtvyZ5rkEgBAptgxYbZtTtatsg==;5:F5d88vJYr1MteV2JqyW9ovoisA5gJ6kDdLuglN8JtEXv1PZjKAo26/wf7OUCAgeVwp8v6CnX062t9wStUQY64ZmcARJU9hu4uYjyFMmN+0xbo0fIcKkhMyYKMrUZpkiEwSY/Tjrxf/lAVNAdZwlTnA==;24:EAfWRQFDRaDgwpcjiUnuxOywOKsPflXBJPYqdeos+Q2+V6xc8mxGxwpIhg8lG7mifSMJqzZ8H/AN0DY1acx/elewtHuaTBbB75BuI+OL1n0=;7:eKu8w2KGcl8I/uhzVJlwCdST/fWDg7ekl+FtE4VKbDvLshDiJBf2yCrX06m2PU3U2Pv/4YtKppKUs5F7yVzOJpzYX86HyvMq7syQWBCQtiH+l92uAhAv6Ex5D6Im2baYZvp/eUB0hjk3eDlOdkE4fYrGQKxcIGqMngKB6cyKvBTXLuLOEVcVp/T7ZgUHV/Sog0AOeUSImY84QwoR43WBuOzn6Nk9+GAly3x9tbLQjns= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0158;20:hDxJQPs6zO/vwJnJuVY1cKuT8EkwTj8xDYQv6BAb3cjgkXCs+80Qj1KA2Ocb2NKnf4wHjLkLyOb4WpGg6EWm7GJwpWsdqhyAnpZ2If2Zfv+OnZgeqbJ6Obq1/KhD6FsRMJAmUekRRmOlR0xzungEUx4iY9QO63UtMStL/rD3gvstLxYNBMN/eJOG/TfKOf2lj2ju39snd+ye41mqjK4wYkPb8h/vAEKvBXEMnyyferfg/rJkxnHSSsG0dGPf8WkH X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Sep 2017 20:47:05.4058 (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 The command is used for encrypting the guest memory region using the VM encryption key (VEK) created during KVM_SEV_LAUNCH_START. 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/include/asm/kvm_host.h | 1 + arch/x86/kvm/svm.c | 191 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 190 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 7453ef7cb487..86006dcfe574 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -752,6 +752,7 @@ struct kvm_sev_info { unsigned int asid; /* ASID used for this guest */ unsigned int handle; /* SEV firmware handle */ int fd; /* SEV device fd */ + unsigned long locked; /* Number of pages locked */ }; struct kvm_arch { diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 5e3e7d46270b..4667504acca5 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include @@ -326,6 +328,7 @@ enum { static unsigned int max_sev_asid; static unsigned long *sev_asid_bitmap; +#define __sme_page_pa(x) __sme_set(page_to_pfn(x) << PAGE_SHIFT) static inline bool svm_sev_enabled(void) { @@ -1578,6 +1581,82 @@ static void sev_deactivate_handle(struct kvm *kvm) kfree(data); } +static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr, + unsigned long ulen, unsigned long *n, + int write) +{ + struct kvm_sev_info *sev = &kvm->arch.sev_info; + unsigned long npages, pinned, size; + unsigned long locked, lock_limit; + struct page **pages; + int first, last; + + /* calculate number of pages */ + first = (uaddr & PAGE_MASK) >> PAGE_SHIFT; + last = ((uaddr + ulen - 1) & PAGE_MASK) >> PAGE_SHIFT; + npages = (last - first + 1); + + locked = sev->locked + npages; + lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) { + pr_err("locked(%lu) > lock_limit(%lu)\n", locked, lock_limit); + return NULL; + } + + /* Avoid using vmalloc for smaller buffer */ + size = npages * sizeof(struct page *); + if (size > PAGE_SIZE) + pages = vmalloc(size); + else + pages = kmalloc(size, GFP_KERNEL); + + if (!pages) + return NULL; + + /* pin the user virtual address */ + pinned = get_user_pages_fast(uaddr, npages, write ? FOLL_WRITE : 0, pages); + if (pinned != npages) { + pr_err("failed to lock %lu\n", npages); + goto err; + } + + *n = npages; + sev->locked = locked; + + return pages; +err: + if (pinned > 0) + release_pages(pages, pinned, 0); + + kvfree(pages); + return NULL; +} + +static void sev_unpin_memory(struct kvm *kvm, struct page **pages, + unsigned long npages) +{ + struct kvm_sev_info *sev = &kvm->arch.sev_info; + + sev->locked -= npages; + release_pages(pages, npages, 0); + kvfree(pages); +} + +static void sev_clflush_pages(struct page *pages[], unsigned long npages) +{ + uint8_t *page_virtual; + unsigned long i; + + if (npages == 0 || pages == NULL) + return; + + for (i = 0; i < npages; i++) { + page_virtual = kmap_atomic(pages[i]); + clflush_cache_range(page_virtual, PAGE_SIZE); + kunmap_atomic(page_virtual); + } +} + static void sev_vm_destroy(struct kvm *kvm) { struct kvm_sev_info *sev = &kvm->arch.sev_info; @@ -5698,7 +5777,7 @@ static int sev_activate_asid(struct kvm *kvm, unsigned int handle, int *error) return ret; } -static int sev_issue_cmd(int fd, int id, void *data, int *error) +static int __sev_issue_cmd(int fd, int id, void *data, int *error) { struct fd f; int ret; @@ -5713,6 +5792,13 @@ static int sev_issue_cmd(int fd, int id, void *data, int *error) return ret; } +static int sev_issue_cmd(struct kvm *kvm, int id, void *data, int *error) +{ + struct kvm_sev_info *sev = &kvm->arch.sev_info; + + return __sev_issue_cmd(sev->fd, id, data, error); +} + static void *copy_user_blob(u64 __user uaddr, u32 len) { void *data; @@ -5785,7 +5871,7 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) start->policy = params.policy; /* create memory encryption context */ - ret = sev_issue_cmd(argp->sev_fd, SEV_CMD_LAUNCH_START, start, error); + ret = __sev_issue_cmd(argp->sev_fd, SEV_CMD_LAUNCH_START, start, error); if (ret) goto e_free_session; @@ -5815,6 +5901,103 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) return ret; } +static int get_num_contig_pages(int idx, struct page **inpages, + unsigned long npages) +{ + int i = idx + 1, pages = 1; + unsigned long paddr, next_paddr; + + /* find the number of contiguous pages starting from idx */ + paddr = __sme_page_pa(inpages[idx]); + while (i < npages) { + next_paddr = __sme_page_pa(inpages[i++]); + if ((paddr + PAGE_SIZE) == next_paddr) { + pages++; + paddr = next_paddr; + continue; + } + break; + } + + return pages; +} + +static int sev_launch_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + unsigned long vaddr, vaddr_end, next_vaddr, npages, size; + struct kvm_sev_info *sev = &kvm->arch.sev_info; + struct kvm_sev_launch_update_data params; + struct sev_data_launch_update_data *data; + struct page **inpages; + int i, ret, pages; + + if (!sev_guest(kvm)) + return -ENOTTY; + + if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, + sizeof(struct kvm_sev_launch_update_data))) + return -EFAULT; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + vaddr = params.uaddr; + size = params.len; + vaddr_end = vaddr + size; + + /* lock the user memory */ + inpages = sev_pin_memory(kvm, vaddr, size, &npages, 1); + if (!inpages) { + ret = -ENOMEM; + goto e_free; + } + + /* + * PSP will perform the in-place encryption of the memory content (it + * may access the memory range with C=1). Lets make sure that caches + * are flushed so that data is written in DRAM with correct C-bit before + * PSP accesses it. + */ + sev_clflush_pages(inpages, npages); + + for (i = 0; vaddr < vaddr_end; vaddr = next_vaddr, i += pages) { + int offset, len; + + /* + * since user buffer may not be page aligned, calculate the + * offset within the page. + */ + offset = vaddr & (PAGE_SIZE - 1); + + /* calculate the number of pages that can be encrypted in one go */ + pages = get_num_contig_pages(i, inpages, npages); + + len = min_t(size_t, ((pages * PAGE_SIZE) - offset), size); + + data->handle = sev->handle; + data->len = len; + data->address = __sme_page_pa(inpages[i]) + offset; + ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_DATA, data, &argp->error); + if (ret) + goto e_unpin; + + size -= len; + next_vaddr = vaddr + len; + } +e_unpin: + /* content of memory is updated, mark pages dirty */ + for (i = 0; i < npages; i++) { + set_page_dirty_lock(inpages[i]); + mark_page_accessed(inpages[i]); + } + /* unlock the user pages */ + sev_unpin_memory(kvm, inpages, npages); +e_free: + kfree(data); + return ret; +} + static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) { struct kvm_sev_cmd sev_cmd; @@ -5834,6 +6017,10 @@ static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) r = sev_launch_start(kvm, &sev_cmd); break; } + case KVM_SEV_LAUNCH_UPDATE_DATA: { + r = sev_launch_update_data(kvm, &sev_cmd); + break; + } default: break; } -- 2.9.5