Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp1701419ybh; Tue, 14 Jul 2020 05:13:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyba6LvXcNVx++NNKF4wv0JZVrEM/40VURUw0SAMzd+aGnBiOX7Q98AJ3htJy4iAQ3WRL68 X-Received: by 2002:a17:906:c14f:: with SMTP id dp15mr4223667ejc.454.1594728783616; Tue, 14 Jul 2020 05:13:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594728783; cv=none; d=google.com; s=arc-20160816; b=qBJJunfgCsBSWcZgQEo3ZiZcjcapLz308xXG/W1b0bmV7J9bgpQEfFOJnj/VVteRXD hm6Xq3OBmVIxot+lUe0sm8u76E+fes/meGOg4Kr4NFib5i8AxPLb9TJgi/c5rQknQy0t 0nlqBz/FW0qmBhA1xPp2Z2RP7FqW28lvqrLjILFpbZhZ+MqSI1NNQ/qXFC7MPaFciMU5 e2pWcDFWpehbZ0geXUNqdV0brSyqpbX9wfDwAc5RBfhSaZ+MAFHrRlM8yHq1C4JB07M6 bKA8So9AMukBhBukoemglmWvr52Qmcah5zVQvbGC4+2KThRKySikNRxUHZlpfIzM6Pny JIAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=tXh8TmMOrG6gGJZH4DCWuQb9GQGVMuO5krxDOVgFC+c=; b=M/fwSjDh6Zh95be07AhHIRV32FZt2arXCN/mmTQUctLNCj/65VHQnQKNmzxhIGScyK buuojzX6QwnSO3xDDNtR+VVt7mtB5/F6eStK6OrjHUMzbzMCARVW3I1POFxfTwq4dzJa Fai+wx7FSnTg39zqbOUJ0Hkj0+7eigQYPgZMAKwQCJcLS3wbe6GGRnrF/1kFnLBRTrz5 0HRR3/YoeQe6i5MZWccYtth+IkWRTfeda/h7JiGdoUSJ7527sKKUnU/LXPp2GkoWQhca XdRnOWD7HpeIXJF4H7NJ2VnVP7f52xDlK8XuCKty2C9l2rXvZOvMLq+5Lr8u5+a6ibXZ cn4g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=8bytes.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id lu24si10547015ejb.477.2020.07.14.05.12.38; Tue, 14 Jul 2020 05:13:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=8bytes.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728049AbgGNMLp (ORCPT + 99 others); Tue, 14 Jul 2020 08:11:45 -0400 Received: from 8bytes.org ([81.169.241.247]:54824 "EHLO theia.8bytes.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728502AbgGNMLW (ORCPT ); Tue, 14 Jul 2020 08:11:22 -0400 Received: from cap.home.8bytes.org (p5b006776.dip0.t-ipconnect.de [91.0.103.118]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by theia.8bytes.org (Postfix) with ESMTPSA id C4FB6FF1; Tue, 14 Jul 2020 14:11:12 +0200 (CEST) From: Joerg Roedel To: x86@kernel.org Cc: Joerg Roedel , Joerg Roedel , hpa@zytor.com, Andy Lutomirski , Dave Hansen , Peter Zijlstra , Jiri Slaby , Dan Williams , Tom Lendacky , Juergen Gross , Kees Cook , David Rientjes , Cfir Cohen , Erdem Aktas , Masami Hiramatsu , Mike Stunes , Sean Christopherson , Martin Radev , linux-kernel@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org Subject: [PATCH v4 72/75] x86/sev-es: Support CPU offline/online Date: Tue, 14 Jul 2020 14:09:14 +0200 Message-Id: <20200714120917.11253-73-joro@8bytes.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200714120917.11253-1-joro@8bytes.org> References: <20200714120917.11253-1-joro@8bytes.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Joerg Roedel Add a play_dead handler when running under SEV-ES. This is needed because the hypervisor can't deliver an SIPI request to restart the AP. Instead the kernel has to issue a VMGEXIT to halt the VCPU until the hypervisor wakes it up again. Signed-off-by: Joerg Roedel --- arch/x86/include/uapi/asm/svm.h | 1 + arch/x86/kernel/sev-es.c | 64 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h index a19ce9681ec2..20a05839dd9a 100644 --- a/arch/x86/include/uapi/asm/svm.h +++ b/arch/x86/include/uapi/asm/svm.h @@ -84,6 +84,7 @@ /* SEV-ES software-defined VMGEXIT events */ #define SVM_VMGEXIT_MMIO_READ 0x80000001 #define SVM_VMGEXIT_MMIO_WRITE 0x80000002 +#define SVM_VMGEXIT_AP_HLT_LOOP 0x80000004 #define SVM_VMGEXIT_AP_JUMP_TABLE 0x80000005 #define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0 #define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1 diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c index 370cf9bf2c88..b147d97856c3 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #define DR7_RESET_VALUE 0x400 @@ -531,6 +533,66 @@ static bool __init sev_es_setup_ghcb(void) return true; } +#ifdef CONFIG_HOTPLUG_CPU +static void sev_es_ap_hlt_loop(void) +{ + struct ghcb_state state; + struct ghcb *ghcb; + + ghcb = sev_es_get_ghcb(&state); + + while (true) { + vc_ghcb_invalidate(ghcb); + ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_HLT_LOOP); + ghcb_set_sw_exit_info_1(ghcb, 0); + ghcb_set_sw_exit_info_2(ghcb, 0); + + sev_es_wr_ghcb_msr(__pa(ghcb)); + VMGEXIT(); + + /* Wakeup signal? */ + if (ghcb_is_valid_sw_exit_info_2(ghcb) && + ghcb->save.sw_exit_info_2) + break; + } + + sev_es_put_ghcb(&state); +} + +/* + * Play_dead handler when running under SEV-ES. This is needed because + * the hypervisor can't deliver an SIPI request to restart the AP. + * Instead the kernel has to issue a VMGEXIT to halt the VCPU until the + * hypervisor wakes it up again. + */ +static void sev_es_play_dead(void) +{ + play_dead_common(); + + /* IRQs now disabled */ + + sev_es_ap_hlt_loop(); + + /* + * If we get here, the VCPU was woken up again. Jump to CPU + * startup code to get it back online. + */ + + start_cpu(); +} +#else /* CONFIG_HOTPLUG_CPU */ +#define sev_es_play_dead native_play_dead +#endif /* CONFIG_HOTPLUG_CPU */ + +#ifdef CONFIG_SMP +static void __init sev_es_setup_play_dead(void) +{ + smp_ops.play_dead = sev_es_play_dead; +} +#else +static inline void sev_es_setup_play_dead(void) { } +#endif + static void __init sev_es_alloc_runtime_data(int cpu) { struct sev_es_runtime_data *data; @@ -575,6 +637,8 @@ void __init sev_es_init_vc_handling(void) sev_es_init_ghcb(cpu); sev_es_setup_vc_stacks(cpu); } + + sev_es_setup_play_dead(); } static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt) -- 2.27.0