From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752687AbdLEBKp (ORCPT ); Mon, 4 Dec 2017 20:10:45 -0500 Received: from mail-by2nam03on0057.outbound.protection.outlook.com ([104.47.42.57]:42880 "EHLO NAM03-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752539AbdLEBFs (ORCPT ); Mon, 4 Dec 2017 20:05:48 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; From: Brijesh Singh To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, x86@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 Subject: [Part2 PATCH v9 25/38] KVM: SVM: Add KVM_SEV_INIT command Date: Mon, 4 Dec 2017 19:04:25 -0600 Message-Id: <20171205010438.5773-26-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20171205010438.5773-1-brijesh.singh@amd.com> References: <20171205010438.5773-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: CY4PR0601CA0087.namprd06.prod.outlook.com (52.132.96.156) To CY1PR12MB0149.namprd12.prod.outlook.com (10.161.173.19) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: cd8e8a2c-be83-45e6-3055-08d53b7c3fd1 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(5600026)(4604075)(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(48565401081)(2017052603286);SRVR:CY1PR12MB0149; X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0149;3:S5ux/zFlPzY2I/AkZKIhh2HThWkIA3zvCVRJJ9d6cP5+P+FFs+pAseoQoEfX/JIuoaytKigRIsw/4xAhoqf13QcfbRM4iKowqXoJtzHCXpcLAgadKYAribK8TrZDqQ+jcAfyVpHypd8AjSRDghI+nteRbhN3tb3n5AtdbBdkyBXyAtbeLUI7YDreooL8wA7GbuNSIcVt+7A6K5I+TZulnVOrW5MIyTxn3HDmThMk3+lvCt0PkPUhd4C0IgY1hUUf;25:LZ/7o0t64znfPa+uyyk912J2M+p2UKhCYxeV7+39lb0SAiOObuidu8nnnhXFyL961Dz1EG1imNnBlUxdEC5WXHIkJvDLP4RheM7HB+a+2f8AdqfPkVdaP2qfD5+pYKcpRAlnuFSev3vC2Z8Lv5g7rczDskFbZhwUE0b7CTuz7QDKO0V90rudzTfliDpRW7McdItsOBA1yVYl04zE5cGfnjWEFRWc+P0bJ2aPdcHgSyzMNAjKYq6bYhA19YTnjwdEurH4pECHvf67sIn2kNziPS6iRacy/RLWN7RKC6BVw2YKqYmCUL3kigfV6e41BQGawUMwLVeV+Wp09J97b4emYg==;31:WFPSCO5ksMyIFBATWcDjgbZnBRnByopo/Ofa8aDS47ZD1JdDqrqzLpa9mmoGJ51novOStrml2eUjJLPRoM2+LdYlb+c/WclFzP7I3TQbclYPWKyQR1KgJz8gJkyDlAJMIsyrveKitno1pONH+zvzu0ZTMzDcx1Y0XB3G+IgQMUDfuabLThNgQRS4kfZHlfl2QV/umVSFFFyYfrmboj+oyDQnmxO2gF2wkY3JjSV7bhg= X-MS-TrafficTypeDiagnostic: CY1PR12MB0149: X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0149;20:beP3cG8pgokFxhkboXPA9iYK2NPf32q3HWMEHzCjgfLNl0NMY/1ZtvE8f+p//RDbPh0VQil8g4bQ9zeAIVNRcd24Ef3k874jQuVcD/5+NZPaQSRrw5ME0phDSvCJrtRsrbu54tGqOhDRwMn7FkyX7feOzuRO9OihDjVTSwxA0EDyOLa2h0zXkqISsD6pXGZcRYvQYNsbJ1NYMhp+aTjS5y5SzWOzTeDH/sLRsLL65h3J511e4/xt1aVpYRgndIcXu46lxMGQ5S0b5vHykwBgunkTkH9DlS+mS4bjcNuCc/8EUiprIndC46/JWKvPmGh5M8PWWTkYpBmisbJf4Gg66HGJUo6N34Y+U22pFwEMR2O1IJgpIomHP6sQv3CYqQQaqakcMSADNLZOzIoCIAxRzriKw5G5/lyp7C3SUQx8jieyRMBKZegiF6Xygl0KIARh64ajr8VbFVSTSxqIl8rL/H8D96GJ55uvjRq6Q7KjuT6Mtr12HBrNzmZ7W0ydwT2h;4:fcFcUVoVUhGrB17jZ3h4BdWi38iIcw09CVLjA0aazSSRfA3vXxDGK1sF1rHPYwQD2yWjSWap6aBb3BXwi52eSn4OTKG0d4E25CFILY0aOsQFCmdNQliwfDxEqrsDb/xOIPMtTqYgToLGP4+80hLeEPlRxF87+w5mHOksBWLRO8ewOARA/djWxXiQT0qOX3NtOSs5hizblSlFc/IlFLmg/rOyOrPV3IQDybP0caYiyQD+Q2foT/POv5Ertscm/IpHfrUo/feSAz6pGmJsm190I6I/kSagiiTd6HcaGFHLr9S87LrCGrlQ/gXi9W2oo+IEg8bTrleoMxLVav3QspzEXQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(9452136761055)(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040450)(2401047)(5005006)(8121501046)(93006095)(93001095)(10201501046)(3002001)(3231022)(6055026)(6041248)(20161123558100)(20161123555025)(20161123562025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123560025)(6072148)(201708071742011);SRVR:CY1PR12MB0149;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:CY1PR12MB0149; X-Forefront-PRVS: 0512CC5201 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(366004)(39860400002)(346002)(376002)(189002)(199003)(16526018)(189998001)(106356001)(478600001)(7416002)(2870700001)(101416001)(23676004)(52116002)(97736004)(86362001)(7696005)(33646002)(54906003)(25786009)(105586002)(76176011)(316002)(2950100002)(6666003)(7736002)(2906002)(6486002)(50226002)(81166006)(81156014)(8936002)(53936002)(8676002)(4326008)(1076002)(305945005)(66066001)(6116002)(53416004)(5660300001)(47776003)(68736007)(3846002)(50466002)(36756003);DIR:OUT;SFP:1101;SCL:1;SRVR:CY1PR12MB0149;H:wsp141597wss.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtDWTFQUjEyTUIwMTQ5OzIzOkU5S2NlY1VFZVA4Vmo5cGEyRDlSODdoYXYy?= =?utf-8?B?MWNzenhBVGhRcTBHb1NnOC9RakFLdHFwd3Z3VmFPMm12Skg2dDRPc2J1Zzdo?= =?utf-8?B?azlxWGpDTmhmcVF4aHB5cThCeHhtSHV1U0NvUzBMOFVsMmUzanlzb0ZDRzBR?= =?utf-8?B?SmdpYVNTOURPb1V0N3BkZ3JnLzBZdWRsQVgwUnVaYi94VnhyY1A1TzM5RFNz?= =?utf-8?B?WmN1S1J4UlAzZmdvOVVINzlSVW9IMTJjSzE3SHFkRkVIL1lCdDFwUWVKYWtr?= =?utf-8?B?STd4ZHdFTFdocVFmN2ZJT3BmMmt3VFBTRlB0ekJaeWxGVEpxTUxlS0ZuTmM4?= =?utf-8?B?ZExxS1A1eU11dHAyK2RaUDJCa3ZwNjdVWktKQjRCeGN0bnpuNWN3TVJicTZm?= =?utf-8?B?RGw4akJGY1VIWEdpUVRZaVRVTGd2WVh4bS85OWFoYVpaMno2Qmo0NVhoQnh1?= =?utf-8?B?S0dFY2dIQjRleFBnVU1PTnIrRjNhdnNhMzZhWnEyZUo4TlJ4MXR4aWd5eGM1?= =?utf-8?B?ZmV5d2VnMU9JWWp3WGNLOW1ENmd2bEFRQUZxaWVDczY2dVF4a25YcXpTL0xj?= =?utf-8?B?VjlnVGN3a0E3Wi95bFZkZG1Ydi9QUmFrTThvaUp4c05zSHdTVHpJT0gzNHgr?= =?utf-8?B?UWk4WFVrRXdJai85dEZxWkVWUlJaa3lLTGNFaHpHL0gwQ3pZUk1veTd1S21j?= =?utf-8?B?Y1dLRUpzb2oyK3NPSXIzN21kVW1zQ0c1bVhndndUbEsvWnZMZHZCODlKS21Q?= =?utf-8?B?UzBLYXI1SnRVRzA1N1NVODB4NW5PTm40WnFCci84bk0rbnlibEJWeUNzWkJT?= =?utf-8?B?dDF4Tis1MHIxRkQ4dFVzYzBaRlJsU1d4N25xWjZaYmUzV3VyKzJ2blViU2JU?= =?utf-8?B?ZVVpaitVTTJoYmlIV3drSEk5cWxTcjhubWt6RzBhcmFWZzZsVVV2ZmhpL3Ux?= =?utf-8?B?S1A4VkZYSXJFbHNOVGdpcHl4TFhMSTJrTXBRL2E0ejZPUDFYc0NWMkRMSjF4?= =?utf-8?B?STQ1Vy82YnJEMG45U0J0NEZYRXZRTVRGRU91dk1NUVN6NFdaSnYzbVA0ZUFl?= =?utf-8?B?N1dBVzh2clhGOHBjMkQ1QkhFSG5vUk96MUgwa3ZGVDJ0QUs2ckpGaWVlZ0ZG?= =?utf-8?B?dW54YjdLOHg4VklqOUxUT2RMVUxPdjMvalh6TFMvbE55ZTgrMDJuWjZhNEU4?= =?utf-8?B?NjJSbWdMNzJWcnFzMEh3UU43SUF1S2EyR0pUaG85MzRDWnAvanRxMHZLY2x4?= =?utf-8?B?dk4yMGYvVjNWM3dhTmdjd2lNVHIzNFpNNlFTQW95dU4vaDBRa3FLVFFNZEw3?= =?utf-8?B?ZHNMQVZJV2RPOXRnTnl2UklxenFWRitwZHFldHJHdmtHT2s4UlRpUkh1a3hY?= =?utf-8?B?V0dSNlc4clFCOVpZOWZicE9oV2pDUlgzWUNNRUl1cm9oK2R1aG03K3hkUU5n?= =?utf-8?B?NGcvWDNsZnRKUDdxdSs4SVRLLy9SK1NoY2o3UXJKYUxEbXhjKzhuSUpJTXZj?= =?utf-8?Q?zEq9++rgQuZDCgUald8yewyC8=3D?= X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0149;6:m3qKF+lQaJExVQ/2RVRvsW+gcDHCMM+slO+efVMuUtDN/2xO+iNVRbH3V6F+wJjUcdhOZIF4WhXKOyT8awF89S1N4AxvlepehOmAML3u/mlMY2H2kTx9Qu/0eCTCSosfqDNEX82Te04MHm6bxqSuHRcohSYt8PrhfqCjl0IbZHUkOqk2dBBNEY88t574O1ZvFJNqYgPBX+hl3RtKGkgR0UU5HBTuog+Kt6xlJSNAPMV7HjDuXRn/Y61LeJlDSWswpdMtxJg6kZa/5rUfSPzWtE2pKrRjJBT5m1Miuj5hogQSIX3k30JkM4J0qu0GOZrAq7DMq6YgZlKbQCIGQoV95eTBbOzFr6roIyjsm+rtMvo=;5:LwbQzf9SW4CeAi8h9TVdR+6q2XrUftJQuyDGJ0A0fIN7x4tSicmBSegM/nLFeHaAt5WF+4gZGGWxeRIJl1fQkSGJuwHbfeN6yuQqFSbAticv8lwu3zJDr+hLMPCDlZ9A8cjMZHwumh4V94MOdHHaq+OinPlu0XnJwjjkB6X7z80=;24:qaoy3nPDJt0u06v/1mgmx2OJVjDK0+pRisjycati5hW0IL5UnaTZuDf2PrGSsDwJrwLz/XGYW9uvPqhuhdtHNWuc7k4E3MgGlV5gB7WUXJ0=;7:kyPeRhw8MCy/frDOO1pOjpDab63Kdjq/SoVQbUr1GBrPytZCdpnNOTJX/GnOw2n72OTkwd/dSR61iLT0993Bd6khv9StdSsDImDFB6jjda5Q+C64f099bk5dbF0TMIioJW0wuX/LD5dkkW2t40pzqMa9hP57tdtFT7YFzcRxN5OB/s/mLHPIgHd+ZKcX1ZVTRQFwnCYOLY4hd9+pmZRL9hvxIXes0W8WFDKTrYeayB/sc3aB2P+3AvH0Zf2Yx0CZ SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY1PR12MB0149;20:x0+0EPAW9nGCxvno14aGBfe9qLT6+BcbLwyCNE4wkhYGG9BnwVOCDpaX0zmLJLFp3Tkgvd6535fR65k/mB07QJTWQ5IiN2XqIb2h1IOTIBgIkD9+ukjaWKWt/SIclJVKaCKtvcVn/LDtF0CYcQNhmijcXs9gcnl5JyEhhR97jG88PHCYhpReGrs6nS1yWsQXpy30NJnSjAAbdF4sWnwKjH7NvpfkuRQU08YwtPc4TsuEpPei/6Bt521k9zMui341 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Dec 2017 01:05:16.9513 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: cd8e8a2c-be83-45e6-3055-08d53b7c3fd1 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR12MB0149 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 Reviewed-by: Borislav Petkov --- 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 58b7cc30466b..384dcfda43cc 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 ca63642517a7..51186107eb22 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -325,6 +326,20 @@ enum { #define VMCB_AVIC_APIC_BAR_MASK 0xFFFFFFFFFF000ULL static unsigned int max_sev_asid; +static unsigned int min_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) { @@ -1065,6 +1080,15 @@ static __init int sev_hardware_setup(void) if (!max_sev_asid) return 1; + /* Minimum ASID value that should be used for SEV guest */ + min_sev_asid = cpuid_edx(0x8000001F); + + /* Initialize SEV ASID bitmap */ + sev_asid_bitmap = kcalloc(BITS_TO_LONGS(max_sev_asid), + sizeof(unsigned long), GFP_KERNEL); + if (!sev_asid_bitmap) + return 1; + status = kmalloc(sizeof(*status), GFP_KERNEL); if (!status) return 1; @@ -1194,6 +1218,9 @@ static __exit void svm_hardware_unsetup(void) { int cpu; + if (svm_sev_enabled()) + kfree(sev_asid_bitmap); + for_each_possible_cpu(cpu) svm_cpu_uninit(cpu); @@ -1384,6 +1411,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); @@ -1466,6 +1496,29 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu) return 0; } +static void __sev_asid_free(int asid) +{ + int pos; + + pos = asid - 1; + clear_bit(pos, sev_asid_bitmap); +} + +static void sev_asid_free(struct kvm *kvm) +{ + struct kvm_sev_info *sev = &kvm->arch.sev_info; + + __sev_asid_free(sev->asid); +} + +static void sev_vm_destroy(struct kvm *kvm) +{ + if (!sev_guest(kvm)) + return; + + sev_asid_free(kvm); +} + static void avic_vm_destroy(struct kvm *kvm) { unsigned long flags; @@ -1484,6 +1537,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; @@ -5556,6 +5615,75 @@ static int enable_smi_window(struct kvm_vcpu *vcpu) return 0; } +static int sev_asid_new(void) +{ + int pos; + + /* + * SEV-enabled guest must use asid from min_sev_asid to max_sev_asid. + */ + pos = find_next_zero_bit(sev_asid_bitmap, max_sev_asid, min_sev_asid - 1); + 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 = -EBUSY; + asid = sev_asid_new(); + if (asid < 0) + return ret; + + ret = sev_platform_init(&argp->error); + if (ret) + goto e_free; + + sev->active = true; + sev->asid = asid; + + return 0; + +e_free: + __sev_asid_free(asid); + 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, @@ -5572,7 +5700,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, @@ -5671,6 +5799,8 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { .pre_enter_smm = svm_pre_enter_smm, .pre_leave_smm = svm_pre_leave_smm, .enable_smi_window = enable_smi_window, + + .mem_enc_op = svm_mem_enc_op, }; static int __init svm_init(void) -- 2.9.5