From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752494AbdJTCj7 (ORCPT ); Thu, 19 Oct 2017 22:39:59 -0400 Received: from mail-bl2nam02on0071.outbound.protection.outlook.com ([104.47.38.71]:59884 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752198AbdJTCff (ORCPT ); Thu, 19 Oct 2017 22:35:35 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; From: Brijesh Singh To: kvm@vger.kernel.org Cc: bp@alien8.de, 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, linux-kernel@vger.kernel.org Subject: [Part2 PATCH v6 25/38] KVM: SVM: Add KVM_SEV_INIT command Date: Thu, 19 Oct 2017 21:34:00 -0500 Message-Id: <20171020023413.122280-26-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20171020023413.122280-1-brijesh.singh@amd.com> References: <20171020023413.122280-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: MWHPR1701CA0020.namprd17.prod.outlook.com (10.172.58.30) To SN1PR12MB0157.namprd12.prod.outlook.com (10.162.3.144) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a90aa397-5dc4-41ad-fd6e-08d5176336cf X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(48565401081)(4534020)(4602075)(4627075)(201703031133081)(201702281549075)(2017052603199);SRVR:SN1PR12MB0157; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0157;3:1ZzSeAVuOBIpFoxAlhP0iffmnVpjDckieFVLVaLrBOFQJklJEDzfoedSdynIa3UsyCu+SwJZpM3TrxD1twg6XEitWImz32xvCbsOKU+vIvD1/UW3pIZosHwcTrvt+eTH9HJwj4+YvF9IXuJLoAi0NMaGLezqAplzVUl+k0OTvxUJUdolC3maazkKYX6QRGHSSO9HUTlYUfgHzYfMdRCzyYmZseM5+NQkscDChG4UHkJcfzQfEcKayMJdEZYODfRA;25:xXqf/xtITcVACoG6dRwm11R/fvi4640Ob1qRF4EdEb/SLlf76Kg9qad/n8qNQs0O3lK5OXO59XvjQGUsX3ajH5AK4fzhGT8LgnsQo9Hu7b7cIbvwI5DEHZOvVs020WTQIUjg2zN6kv2rJqhttKwQS93XAzytJp2wEXPFhza1QQXA7dioRzViyKgwa+3/8hkQHjM1kkzaEvM4cE5wcSp9JcmEEg2WjT+he54ZfVPBdOINzIZG/lDtbbdFzoBfAZwObx3n+J62WIoTGGYxV376PDOuy28YyDAQNm5maaadEYoVp1Fcwmai5/RFIjiFB1k46fs2uOIfr02+ZxU5THf2EQ==;31:DbsADMc0XjE4LojhH7tKIi2aVTmYEBZGdl+gyTl47S+QSlvg36qsLOHdimJNj7zH3rbD6uBG3Nqoi6OC4JvDPGP1d9nhVpuv9uWFYwAK0lsVQE6cGBGMH1M1WnC7NkbcfE+tLgDYkuwBcz7uJDEwfID/QiVEx5+dlUX+i/FkNf7dJZIMPVjIEeiMXKSeRV1FAQgWgKPL1LJb3vehfAvfXobTz8vjlrGTdQJYsiPDYRc= X-MS-TrafficTypeDiagnostic: SN1PR12MB0157: X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0157;20:PHgYJiT5ghBY3UfyMdgSms/5zo0peua9nfvDPvz9Iu5F8zUuRaCSNzyXYV3TB3mUxUxLriOyR96chv/8YeAE36TuxAAFzH57Hp9HOuGUoSePW8W2ngg8aNiCw5y2vLMISJg5q1UmfE/dsTIGs3jljldxW9jc3/XAiDOrNxvd1vamBgB/Xe7Tu6t4UdkiR16xWxyPmfjzrMBH5TcQt9/ylZIAXtq0/yLb23dBMJZgvR00t7U+efOfu4tg05Y8gcz5jBm36i++Ks6z6CdlMgnpVhq3L47vpj9alJXBgzRC1uAg6Ud5mrkHu7qEC7r2Hedghbv2kDzv2ufZTbHKbqrvNVvoHALNNyy5JIhv0XAPTe+RYQGO1vZCEJ1UvREN4GOCXOVOczz7ZY8wl51E18871i6CvNMUytLvus+ZvsciJfKQgGHIvRaNPBOiqrwBaGHQom+Xk41av7SXVv5gRNyk7OFYNGeSkqw7GyJ4TbRBFruL4leg9x+eUQeSym1gCjow;4:rXaWju1PrB+H9Jhe7vZ7an8o5fuOGQj9JBAGg1No9qazNX/2ujmHQS0HxWV3aouh0mbv2lb2bFBwzR8krh7R4dbv2FQMj11Y6jlDqZMMmdksep0IzO7pMZcIiqXi6ZpCfhFH2YhGQcfGeJS+nAvp7WLhbT3CHlfCpQCYh2Q68r6X+ZornoYSzwDW7TDgOIhfennypaMcVCAxbMV6BvKtveuB8vJuU2yEWqXS+XcoJqYPPR8sBtfWr7f8/8JKntmEui2TJMZMWWWFRvubUQpTDoMeIaQgrlKqBijSLNG9webBTGYc2Dxs6KfvBWlK5YwwpPQsj4Et1j+UWSrM5q4x3g== 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)(3231020)(100000703101)(100105400095)(10201501046)(93006095)(93001095)(3002001)(6055026)(6041248)(20161123555025)(20161123564025)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(20161123560025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:SN1PR12MB0157;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:SN1PR12MB0157; X-Forefront-PRVS: 0466CA5A45 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(346002)(376002)(39860400002)(199003)(189002)(36756003)(7736002)(68736007)(50466002)(1076002)(478600001)(4326008)(16526018)(316002)(53936002)(6486002)(86362001)(305945005)(53416004)(54906003)(50226002)(2351001)(106356001)(101416001)(81166006)(105586002)(8676002)(2361001)(76176999)(2870700001)(2906002)(50986999)(6916009)(23676002)(66066001)(47776003)(6666003)(97736004)(6116002)(2950100002)(189998001)(8936002)(3846002)(33646002)(81156014)(7416002)(5660300001)(25786009);DIR:OUT;SFP:1101;SCL:1;SRVR:SN1PR12MB0157;H:ubuntu-010236106000.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtTTjFQUjEyTUIwMTU3OzIzOnptWklJOXVVTUNMSlNyaW9xQXdXeXYxbEpr?= =?utf-8?B?VlBURTUvQXRsNFFxUGo2aTNjRlJ3aHI0a1NVak9BckpuUVBWbWN1MXFJTjJX?= =?utf-8?B?RHRTNGlwMVV6eGZwaGUwMndreVRMUStGQS9ITi9EVUpVL0h1Y2UyOGpvbUIz?= =?utf-8?B?cm9nYVZySzFPMkhFSVRYODhCR3dkTEIvQjF1eUErRmlWa3c1bEU3Sk56THNL?= =?utf-8?B?ZDlGaFZKWGpXZ1hpT1BHSDBGL0J6MzhXR1lPYlFWRG16aVBPTlF0MUVQeVBD?= =?utf-8?B?T3g1TzZobm9FYU01MnkxaTg4NlFMMTE1dEkxdGxmM3BrUW9oUkw4V0R0NDZP?= =?utf-8?B?WDZ4b2ZUVUN4VER0R3lzYTNEUWNLSFJPOTdGVUd1dnR2c1kvNHRlYm9uSDh6?= =?utf-8?B?OTJBSSthWjVVUkM2a3pTNk9xb2hxdm9SSXozMDlDME5wZ2NNWG5MY1QwMCts?= =?utf-8?B?bEpWVXcyQmFRMi9XT2lVMzR4U1lja1U3TDl4UFd1ZmlqbE5kb0tyam1LV09F?= =?utf-8?B?T3JBNjRqbnVaOHJtOXZyN1J2NzIycVMrVEU2MDRVVk5wQ0RQODFYaWlEUW9u?= =?utf-8?B?MnB3eGY5d0trd1Y2WUR0amNDNnRtaXhiY3hCays4aVFrakgvWVM1dUxlVVpz?= =?utf-8?B?YUlmQlJvSkhKcXV1VGU0SmtsZWRBMjNxL3lWcm9qV0ZSYVQ4ZkxlcFRiUExN?= =?utf-8?B?a21LTERjV21NSUF4Vll0Y1hJdU9NZi9NQXpsMjRlQUtOaEY3d1pHYnhzcGVB?= =?utf-8?B?QzhFMVJNaHdqZk1SWHNHMTBtUjdlL1FMNWpicU1iVU1ocnNFYklscXhRbm1Z?= =?utf-8?B?YS9SWDR6eGFmT3dLQzRKcUF5SHVpcEJOLytneTlmd3ptcDZaQ2RuZXRUS21F?= =?utf-8?B?MW5oS2FDTUE4d3Fmd1lrZFM3c3puMTYrOHQ0YVpGaFF4RG9XVUI5THczMmhm?= =?utf-8?B?Q3d1dzAvQVlEcGtvdzZDVDUxUXRydVN1YS9rM1pFOEhGbzh5K3F1K3Vjc0N0?= =?utf-8?B?OC8zRENDaXBBdVExVmtZS1BWSmhpYXF1Z2xWRS92VXdYNWIxSjY5VVIrS0Vq?= =?utf-8?B?elA1dUlVcXFubWVKdWlXZ213MDRSSzgrdndoc3I5ZU9ZOHVGWmQzZjB4a3Bk?= =?utf-8?B?cmQ5YkNvSHRRZk8rRHl4ZFdWSFE2N085Rmp4TzBZZ2Z0dXpERlRyOFZCOXBN?= =?utf-8?B?KzdSbEFRUEt3Vm1LTEFTeU1kTUhVZU1uMWk5WWxlRGdCalAyaHpVTTFWSnJU?= =?utf-8?B?S2h4b3hsWHlreVlEdXBOTlJkd1BENlZuKzZ1cDJQeks0NmY5YXllMGVSSkdL?= =?utf-8?B?TmtlcGF0SklmUWtzZ0g0VHdhcmtPZGtsemcycDVlMG84UnczcEwxUTRtMlQ2?= =?utf-8?B?NDlFU2FFVmtOb0oxREE4bFM2K2lHTDVmWmpsTEFMVkplZHRRYzVVMHpyKzdr?= =?utf-8?B?NWFQZTZsRGRoZm1oSUNUUFlvaDdJamNYZVYwenJLb1JRdUFsR3dlbzU2RE0v?= =?utf-8?Q?kEAi0PntIRAOAj0RWdlMLLbI3X/Q76qQGd9qlES93K2YOH?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0157;6:majffm6BgnOGMDv9gOD+eUZ/EzVLc/b/yHjwCBBy+1x/U0UDh3YZ49355c/vgoGf30eAfF44X+mrLnKSdQXHOMnWDqDEg9yEHjk7ooqyfqwWIH04Z77b2/x+rqLCxjm/xAYLUHyzSzqsKUIpIGOI6jDiWwchk6o+NbEVVyrZ9+sFpWkSJY7PxwUJ4IKpxUD5GB0pfOaB4RhOfu9BHjnXLJ1ohR8yNSZk0Irtw+TnZ6UxglulLmQcoLeqNtVHnPN7Iodx9PeCUKuPiA9QN+qQ/tqm6Xs+0L9AeTL/Jp+rjaXAfeUE7i+TQfGhcpL2byxqSB5SQ1BazbpIZCS4/lMdaA==;5:qwryGW3+sepx3X9J+h+RRwBpjt9++lvk74GVnGSiUH0ymMCdoo3W7LW4ETGSwvNcpZmQmNzUoJb1kUYZZARBaSPiKxwWJhyHGPKzE8kWIObm6/vqfwUmFc2Xl09QB0KRvJ6/dGxEbOc1kItpP8cFuA==;24:cBdD9gaSdPxkGyQvto1IfytwzHDVxyHBQ6cYVxUQFaUoOe1IBQ4xW5gMjeDj7/hav/H6TOyNtxswanp2Vd/Zo/mh2l/Q+LaS3+X8Iey543c=;7:J/5bRpT2msd2x00FbRFmwtA5pbeQUjLnuxDTwbCh+twqEZS6aIChL57kOzrAvjWFjO7cWhwdsfWghC4H30JEoZ2oZinhNBIqWIQfaf63mHgemMn3EpdWm3QcTIurqQyG4YboaRol8mwTyRJZhItx/BauXoqVM/e9MQh2q02CeSmT+XuLQxcl2cAe02CHMsP/fZfO5iSb61npYkk+u3nm0ONtFRgOelVO4CoP6K4cXdw= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0157;20:9ye2WR4HO4Lg/pUIt2GjXcdIgeu2V7cAZT9wd6CzCEVejcUXfpL1lMNf+t8H2S0w4ROf2el631iSEvqvSZX9QciC2dgIP1KPRwXvo5xVbZEt72LSk91btYW0+azZKMs3zDl25ToGYfDevsGxp5JsxLms29uUGy9mJZn3jFSsZ3lF8Jv6CilhpDVoViH8RHcDfGRWmm6MktEEuoXa84KcTIxIbZk8E8O4tWG0eCxOEePO+/o+V5EP8/y4DSAYjzdn X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Oct 2017 02:35:21.4563 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a90aa397-5dc4-41ad-fd6e-08d5176336cf X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0157 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The command initializes the SEV platform context and allocates a new ASID for this guest from the SEV ASID pool. The firmware must be initialized before we issue any guest launch commands to create a new memory encryption context. 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 | 7 +++ arch/x86/kvm/svm.c | 132 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 3af074452b2b..b8837cff22ec 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -747,6 +747,11 @@ enum kvm_irqchip_mode { KVM_IRQCHIP_SPLIT, /* created with KVM_CAP_SPLIT_IRQCHIP */ }; +struct kvm_sev_info { + bool active; /* SEV enabled guest */ + unsigned int asid; /* ASID used for this guest */ +}; + struct kvm_arch { unsigned int n_used_mmu_pages; unsigned int n_requested_mmu_pages; @@ -834,6 +839,8 @@ struct kvm_arch { bool x2apic_format; bool x2apic_broadcast_quirk_disabled; + + struct kvm_sev_info sev_info; }; struct kvm_vm_stat { diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index d4b62536e305..d496063ccd78 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include #include @@ -324,6 +326,19 @@ enum { #define VMCB_AVIC_APIC_BAR_MASK 0xFFFFFFFFFF000ULL static unsigned int max_sev_asid; +static unsigned long *sev_asid_bitmap; + +static inline bool svm_sev_enabled(void) +{ + return max_sev_asid; +} + +static inline bool sev_guest(struct kvm *kvm) +{ + struct kvm_sev_info *sev = &kvm->arch.sev_info; + + return sev->active; +} static inline void mark_all_dirty(struct vmcb *vmcb) { @@ -1063,6 +1078,11 @@ static int avic_ga_log_notifier(u32 ga_tag) static __init void sev_hardware_setup(void) { max_sev_asid = cpuid_ecx(0x8000001F); + + /* Initialize SEV ASID bitmap */ + if (max_sev_asid) + sev_asid_bitmap = kcalloc(BITS_TO_LONGS(max_sev_asid), + sizeof(unsigned long), GFP_KERNEL); } static __init int svm_hardware_setup(void) @@ -1167,10 +1187,18 @@ static __init int svm_hardware_setup(void) return r; } +static __exit void sev_hardware_unsetup(void) +{ + kfree(sev_asid_bitmap); +} + static __exit void svm_hardware_unsetup(void) { int cpu; + if (svm_sev_enabled()) + sev_hardware_unsetup(); + for_each_possible_cpu(cpu) svm_cpu_uninit(cpu); @@ -1361,6 +1389,9 @@ static void init_vmcb(struct vcpu_svm *svm) svm->vmcb->control.int_ctl |= V_GIF_ENABLE_MASK; } + if (sev_guest(svm->vcpu.kvm)) + svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE; + mark_all_dirty(svm->vmcb); enable_gif(svm); @@ -1443,6 +1474,28 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu) return 0; } +static void sev_asid_free(struct kvm *kvm) +{ + struct kvm_sev_info *sev = &kvm->arch.sev_info; + int pos, asid; + + if (!svm_sev_enabled()) + return; + + asid = sev->asid; + pos = asid - 1; + clear_bit(pos, sev_asid_bitmap); +} + +static void sev_vm_destroy(struct kvm *kvm) +{ + if (!sev_guest(kvm)) + return; + + sev_platform_shutdown(NULL); + sev_asid_free(kvm); +} + static void avic_vm_destroy(struct kvm *kvm) { unsigned long flags; @@ -1461,6 +1514,12 @@ static void avic_vm_destroy(struct kvm *kvm) spin_unlock_irqrestore(&svm_vm_data_hash_lock, flags); } +static void svm_vm_destroy(struct kvm *kvm) +{ + avic_vm_destroy(kvm); + sev_vm_destroy(kvm); +} + static int avic_vm_init(struct kvm *kvm) { unsigned long flags; @@ -5427,6 +5486,75 @@ static void svm_setup_mce(struct kvm_vcpu *vcpu) vcpu->arch.mcg_cap &= 0x1ff; } +static int sev_asid_new(void) +{ + int pos; + + if (!svm_sev_enabled()) + return -EINVAL; + + pos = find_first_zero_bit(sev_asid_bitmap, max_sev_asid); + if (pos >= max_sev_asid) + return -EBUSY; + + set_bit(pos, sev_asid_bitmap); + return pos + 1; +} + +static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + struct kvm_sev_info *sev = &kvm->arch.sev_info; + int asid, ret; + + ret = sev_platform_init(NULL, &argp->error); + if (ret) + return ret; + + ret = -EBUSY; + asid = sev_asid_new(); + if (asid < 0) + goto e_shutdown; + + sev->active = true; + sev->asid = asid; + + return 0; + +e_shutdown: + sev_platform_shutdown(&argp->error); + return ret; +} + +static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) +{ + struct kvm_sev_cmd sev_cmd; + int r; + + if (!svm_sev_enabled()) + return -ENOTTY; + + if (copy_from_user(&sev_cmd, argp, sizeof(struct kvm_sev_cmd))) + return -EFAULT; + + mutex_lock(&kvm->lock); + + switch (sev_cmd.id) { + case KVM_SEV_INIT: + r = sev_guest_init(kvm, &sev_cmd); + break; + default: + r = -EINVAL; + goto out; + } + + if (copy_to_user(argp, &sev_cmd, sizeof(struct kvm_sev_cmd))) + r = -EFAULT; + +out: + mutex_unlock(&kvm->lock); + return r; +} + static struct kvm_x86_ops svm_x86_ops __ro_after_init = { .cpu_has_kvm_support = has_svm, .disabled_by_bios = is_disabled, @@ -5443,7 +5571,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { .vcpu_reset = svm_vcpu_reset, .vm_init = avic_vm_init, - .vm_destroy = avic_vm_destroy, + .vm_destroy = svm_vm_destroy, .prepare_guest_switch = svm_prepare_guest_switch, .vcpu_load = svm_vcpu_load, @@ -5537,6 +5665,8 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { .deliver_posted_interrupt = svm_deliver_avic_intr, .update_pi_irte = svm_update_pi_irte, .setup_mce = svm_setup_mce, + + .mem_enc_op = svm_mem_enc_op, }; static int __init svm_init(void) -- 2.9.5