From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752758AbdJDNUH (ORCPT ); Wed, 4 Oct 2017 09:20:07 -0400 Received: from mail-cys01nam02on0075.outbound.protection.outlook.com ([104.47.37.75]:59363 "EHLO NAM02-CY1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752400AbdJDNPW (ORCPT ); Wed, 4 Oct 2017 09:15:22 -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 19/31] KVM: SVM: Add support for KVM_SEV_LAUNCH_START command Date: Wed, 4 Oct 2017 08:14:00 -0500 Message-Id: <20171004131412.13038-20-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: 4d0e3a95-3993-4e10-bf81-08d50b29f350 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:IFBBtxDvkUCpO2uhhUjuXBx/4LCnzwsjexN3yjXjadn910CXyG5R6WlQlGC6FNRfjtuL5838YbCVTHWywDwNQSqfGMStZjGRoEBrvBQr0PsUzSWZhp8woAWuQInyCl1D5VmU9XLLWhk+UAWYow4XHdGfVXgBtbRBNouvtXGMMpML/K6zI5sreLaszRmplnQ+VG6P97GUe5SkYMdLgfBD64WwFaf9oVi83vxlO0RLehr01GMxt2S9uhqYFt5mJnSP;25:ISzbROW+2cRJ7Ox0cDpF6iy+nGvJhBORC60W0AwV7IG/SUDLpjHXKbo88EFUqUTkjmEzrdbDU+wNDTaRLphpOh3zmgvhKCNyD7+PX4MiseDh2FUuzL6a7REU0dmiTxvf0Rc/Y2ZL6PnpSKAhaBpt/6qRVJnXwb1Gm3rvVqaNujGqtf5wqouhyciYpYuq4yJYnynm3YYJk8uL1UfYoES/eCglNniw7cL0rLxXGhmg+YQfB7qiBEF1lhVLTazJIkeq9jD4ebyD690viX++hCMem54m8y6VLnOXZhtJeLGbifGo28qDBMrr0bJvQMt7nFaQeVxqMOTd3CS7kiR+/wCfAA==;31:wp0mEf8SXy9nJxbcm2yjPmb5fzvkKFjIEXc2OyQENDoiD4H4Vm84HMX4L1glx6AeaMvC5b+RxJ+PXnY6DuDcSeOe2J+q4Uro/MdLps2bTZYTpakeiYgPUmgPXV99PmwHwG4qKYNZ9wrJpKrLLZbCpH57R/gr4zIcUmMrLteZ8O1yTDSucBg9fPg0As8ME3NEtDf9sTWOFBYGCKMqcJsULeVWPgDHlB9hYBSsVSAOMPY= X-MS-TrafficTypeDiagnostic: SN1PR12MB0160: X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0160;20:rXgFIx/0VV1Z0ceNLdPgyhg3SRY7g61ZMwRAFrtrXBwteUW/27ZXEYOcldFX72Nq7O0rCfIjNNk5awKg17hDiYr3oUP61NYOgR1Vphw4dAX7LaOGi+A+fYtn1NnFNDnBCCeFUJvls7NiSDMuB6rZ1OzXp4XSIw+drEQm6lvofBrxdUCHEtEkdsQRg3pI0SnwVkn5SIH2KLMEYFEDUqE/cJ81AAdHeXnFsJ937EIG4sIyiPG2Wtg5rp2uBzZ28iPEhgykjw7wtO5Zn5qHHqLTHnmxjt7Cj8zzIqJrdQ3VVtpC6twBVVfPqhsSLHqbl+nWVXiXRXlX3vVFjyY8J1uYTj25QHcpIm1k6JOT9as0jqLMUbWIZALQaOjeDDTZ+0/Z3pcogzcjs8D3JYlgSMDo3/DC2KuX8tiQdhjjVlMB/9YWS/xofvKvzZeEyATBbS3Rv29t4aRgCLn/iW0C7PbJZRc5bRw7Y/hjG63eMRuDt2ZWPQWTmGz+dXp/0idBji01;4:RsjWCuDrcMNALVE5rmapZZOV4rafiG79Mtug91dcpGH5xdj7OwJG45VxBjcHfbHE4clXbvWtOpjDLYiIqfq3Dhz8HQ5I8B7wxLFpKmXcpi1xMy9HsDID/elAsYf8rQzYt4ubiCnHM0oaSXnZzV6n0J36EeJ+EbWd/iIFczoZ/4x4STe5suCQ5LvdHy6NKb+9K5aKqZvoXp5n7Jhzf214zaoyo8uu2XTZRBc0j9UIUg0X7jy+767LAkAuXCRUZJSd19CO5Ud+zq8fe1OzagOwzMRDZUFUF4prJpayK72wBw3kydHx6cWSWfzyL7X/Y9ID3/VviUkVo2b4naO3OFdvWw== 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?MTtTTjFQUjEyTUIwMTYwOzIzOjVFV3lQbXlzU0Z1RTI3SGFlaHg4a1ozWE81?= =?utf-8?B?MGdGcFYvWXozenoxSDVINDlnWjd4c0dHdGRSU2JwS3dGQ0NqcUJvYUUrR1dS?= =?utf-8?B?a2FYcUdsUWV4SUhyOHVEbVBrdUduVWdDZnZ0TVZPcWY0YllySExhdlNvNkVx?= =?utf-8?B?VnJKdkdOVHlETE5lcEpydGVucGZ0dExpbFB1b0xvbXNqbk9NMW1kU0RIekgy?= =?utf-8?B?aTcybXdGUTh6ZFlvbjNSS0hiNWpzd3FRcEJERXNibmdtVVVQU0pQQS9Kc2J5?= =?utf-8?B?ckdnZVZDTi9EMnd2QTJtdmhYMXZGVlFnbnUvbDgvOG9qRVlBZ2lxLzBHeHQx?= =?utf-8?B?OWorelFzZUl2eWllTDV0WWo3ckV3WVNtb1dlc3RYRFJDcjBrUExGRkV5bzNi?= =?utf-8?B?YzRSbFJOVzkyTHF1OTJ2QU1KYktVUksyYUNEcHB1VnFTaURVMkVpOTFaSmF1?= =?utf-8?B?ekdxbzBoVTlMRko0M2c4R0hHdklEeHVET1FSWngxMzkrbzR2RFlNMWFpMnZL?= =?utf-8?B?TjRMWXFJeTFIMVowUGcxRjVSQXg0N3hGQ0dkK1Y4b3BPTkJneitCUm9LZ3l3?= =?utf-8?B?OFY3SFFDU2F3WUl3eGM2Rmlsc0xKQ0thY3RaTitYQzY0d2ZlM0ppNW02R2Zi?= =?utf-8?B?cms1OGZ6OFhNajk1REFqa3hSeWl4amo0U1hkQTQwVHhIWml3MlZ4bU1VeGcv?= =?utf-8?B?clRDRXAzcy9aSG1yait4SmZWNVZiQUVwMXAzOERPZGZyK0UzcWVSMVk5SmVZ?= =?utf-8?B?aFl6Qm92TnRDS2lyYVVhM1lTb2xvUWloeS9Nb3NuSVpXbHRHdGhUVi8yODU3?= =?utf-8?B?WHVuSi9ySWdvQzNlS2d6Rlo4KzUvSUZtOWY3TWNrUkthMDF4KzhYZGhUSHpn?= =?utf-8?B?SlcxQ21hSEZBWTVBRTNDZUVVekp5T3pLVUdSQ1pMN08yQ1NmcG55eTFqS2VW?= =?utf-8?B?ZzBJS2Q2V3ZyNGhqOWdzTXVjanZMclR2U3dJSEUwR0w4M2dlaTNuTkM5Mlkw?= =?utf-8?B?ZkRkNUFXTzVzd0duNDREdmp3eUo3cDJRL3I0RGw0TUUwZXl1UFdVSFBFK0M5?= =?utf-8?B?ajgvWXV0VkFhUTl3NnNiWnAvK3U5cDZLWUhNZjFIYTVxRGMxWGFuUmVnZU5n?= =?utf-8?B?WlhpZytYVkxWTkdYZDhKdWVxNHJ3WEo2U1Izb0dUcjlWUS9XS21iT1dPVlBL?= =?utf-8?B?alNkN1Robk10a0VSR2tzenlzWE4yaDBicTJrWDdGOURUZmlNemI1Wmw4VUUz?= =?utf-8?B?WGFoSFlvV2lPSWhZRmtna1RXcThpMlJzL3J0N21EVHFMUXhyY2tkQ1dGTndr?= =?utf-8?B?Z3B0eVFFNGY5UkJla3lvdldha3ZCWVMxZXIwZWJETFBhV2d6OGpybHdqcStv?= =?utf-8?B?bWRNa0JJWCtvOU03KzBJa2hIKzF2N1VkV056eldXbFhxeUhINFZva0w1YTBE?= =?utf-8?Q?pj8X6Kck++L+xBezPbWiIKKimto?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0160;6:LT4Sp9+ir1C/H0qJCF0OjRz0YIQY8z6g6juFayY3pdqf0d9GaC002gpDoWJFU29RzPrW9qwx47YSsG6ufu6eoqmkIEVBamDr1m/YeIkxrMz5w5UfxS9TQU65RmfYm3bWeUdjGLCruY42kPmupvAnALHJb8tCeQHfsEzkPA4wVO1Dzu5RHsWd1RbbRDqiiPOZAR+0UE5pD+y790fqvor41sWatgu539xLJqRXl7mupuPaOPBip75k33ZzBcoEBuQS6yj7dt3eO9uGdZHiSnvG6JafNJWJ/Kzqpt+vxP03guOgR0rL10jtLPNB+I/PmiGzScXl9WjFPXbiVEqCWeuqEQ==;5:8m0OM1ZDiq9t/awx7DMsb1Rr5ZFrKYE2UikvxREjG5LMH2KehvOcJQD/FWUF0as7U44MuWnjIzLJ6JbS6ZrSzK6zZRw26CxFObWbfCJyvqXOSNMXB3dcRHPLn/XnVocBP98ckW5RX4GkHFqF4I4GAA==;24:6whRdwbajFt7/62FDfxscwoTu8GeTt8fLzNbxRFFlc+LhJnP7xcgzKtVt5nPdn90yi72bFVYnEXvnoXhHTXw7BeS5SMt6eF1FHp9Ob5hKZs=;7:YqfuqLMm9S7Bny2qC8+Ry7Rgs9S8T+5pR4qA7mrdWlvJBpCTNOX0RfJaL9hecWxl6tgyhwnZhyt39cyb65kdMQUoXja7WexVv91WRkDSTOxQWQou2hLfHjydhhC0HSq4BUgefvgYQCF8M/Dnd+EwFh0Hsp1xuwnmH6YXeOH2sdhvidMwtGj/qa6QhU9ZrU6DpiWggPaGhuIqM8SEjoRtgWI9IKqqxC8vuUQkZ5mMZIg= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0160;20:wXbyauV1izncA1EkvRbdoW3pBCwfPrZ59UBeeU1did9wNmRJEOqf5qpy0nuEffytyl4SCiZK0g6wD3c2UYrR5VNhcAc4rpHu+gkgm6OWnbRdc0Ie7MKSCRBTghKksaRJNqokUWCCw6wE+AQBRyUOG4p9hj5gGNXr+t/A47Cw2jJqrJh7DnbdNgjNTbbiLDJTOUuu+7AxftXdA+bE75PJ4d8+1ngY2jC+q6kvqB5ZL9oqKma3CGHKjpTai/gXsrq3 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Oct 2017 13:15:13.0732 (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 KVM_SEV_LAUNCH_START command is used to create a memory encryption context within the SEV firmware. In order to create the memory encryption context, the guest owner's should provide the guest's policy, its public Diffie-Hellman (PDH) key and session information. The command implements the LAUNCH_START flow defined in SEV spec Section 6.2. 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 | 2 + arch/x86/kvm/svm.c | 181 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 6bd49e80a16d..7453ef7cb487 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -750,6 +750,8 @@ enum kvm_irqchip_mode { struct kvm_sev_info { bool active; /* SEV enabled guest */ unsigned int asid; /* ASID used for this guest */ + unsigned int handle; /* SEV firmware handle */ + int fd; /* SEV device fd */ }; struct kvm_arch { diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index a1388e74149f..c599a87810af 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1551,11 +1551,45 @@ static void sev_asid_free(struct kvm *kvm) } } +static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) +{ + struct sev_data_decommission *decommission; + struct sev_data_deactivate *data; + + if (!handle) + return; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return; + + /* deactivate handle */ + data->handle = handle; + sev_guest_deactivate(data, NULL); + + wbinvd_on_all_cpus(); + sev_guest_df_flush(NULL); + kfree(data); + + decommission = kzalloc(sizeof(*decommission), GFP_KERNEL); + if (!decommission) + return; + + /* decommission handle */ + decommission->handle = handle; + sev_guest_decommission(decommission, NULL); + + kfree(decommission); +} + static void sev_vm_destroy(struct kvm *kvm) { + struct kvm_sev_info *sev = &kvm->arch.sev_info; + if (!sev_guest(kvm)) return; + sev_unbind_asid(kvm, sev->handle); sev_firmware_exit(); sev_asid_free(kvm); } @@ -5638,6 +5672,149 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) return ret; } +static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error) +{ + struct sev_data_activate *data; + int asid = sev_get_asid(kvm); + int ret; + + wbinvd_on_all_cpus(); + + ret = sev_guest_df_flush(error); + if (ret) + return ret; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* activate ASID on the given handle */ + data->handle = handle; + data->asid = asid; + ret = sev_guest_activate(data, error); + kfree(data); + + return ret; +} + +static int sev_issue_cmd(int fd, int id, void *data, int *error) +{ + struct fd f; + int ret; + + f = fdget(fd); + if (!f.file) + return -EBADF; + + ret = sev_issue_cmd_external_user(f.file, id, data, error); + + fdput(f); + return ret; +} + +static void *copy_user_blob(u64 __user uaddr, u32 len) +{ + void *data; + + if (!uaddr || !len) + return ERR_PTR(-EINVAL); + + /* verify that blob length does not exceed our limit */ + if (len > SEV_FW_BLOB_MAX_SIZE) + return ERR_PTR(-EINVAL); + + data = kmalloc(len, GFP_KERNEL); + if (!data) + return ERR_PTR(-ENOMEM); + + if (copy_from_user(data, (void __user *)(uintptr_t)uaddr, len)) + goto e_free; + + return data; + +e_free: + kfree(data); + return ERR_PTR(-EFAULT); +} + +static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + struct kvm_sev_info *sev = &kvm->arch.sev_info; + struct sev_data_launch_start *start; + struct kvm_sev_launch_start params; + void *dh_blob, *session_blob; + int *error = &argp->error; + int ret; + + if (!sev_guest(kvm)) + return -ENOTTY; + + if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, + sizeof(struct kvm_sev_launch_start))) + return -EFAULT; + + start = kzalloc(sizeof(*start), GFP_KERNEL); + if (!start) + return -ENOMEM; + + dh_blob = NULL; + if (params.dh_uaddr) { + dh_blob = copy_user_blob(params.dh_uaddr, params.dh_len); + if (IS_ERR(dh_blob)) { + ret = PTR_ERR(dh_blob); + goto e_free; + } + + start->dh_cert_address = __sme_set(__pa(dh_blob)); + start->dh_cert_len = params.dh_len; + } + + session_blob = NULL; + if (params.session_uaddr) { + dh_blob = copy_user_blob(params.session_uaddr, params.session_len); + if (IS_ERR(session_blob)) { + ret = PTR_ERR(session_blob); + goto e_free_dh; + } + + start->session_address = __sme_set(__pa(session_blob)); + start->session_len = params.session_len; + } + + start->handle = params.handle; + start->policy = params.policy; + + /* create memory encryption context */ + ret = sev_issue_cmd(argp->sev_fd, SEV_CMD_LAUNCH_START, start, error); + if (ret) + goto e_free_session; + + /* Bind ASID to this guest */ + ret = sev_bind_asid(kvm, start->handle, error); + if (ret) + goto e_free_session; + + /* return handle to userspace */ + params.handle = start->handle; + if (copy_to_user((void __user *)(uintptr_t)argp->data, ¶ms, + sizeof(struct kvm_sev_launch_start))) { + sev_unbind_asid(kvm, start->handle); + ret = -EFAULT; + goto e_free_session; + } + + sev->handle = start->handle; + sev->fd = argp->sev_fd; + +e_free_session: + kfree(session_blob); +e_free_dh: + kfree(dh_blob); +e_free: + kfree(start); + return ret; +} + static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) { struct kvm_sev_cmd sev_cmd; @@ -5656,6 +5833,10 @@ static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) r = sev_guest_init(kvm, &sev_cmd); break; } + case KVM_SEV_LAUNCH_START: { + r = sev_launch_start(kvm, &sev_cmd); + break; + } default: break; } -- 2.9.5