@@ -217,6 +217,7 @@ void snp_accept_memory(phys_addr_t start, phys_addr_t end);
u64 snp_get_unsupported_features(u64 status);
u64 sev_get_status(void);
void sev_es_stop_this_cpu(void);
+bool sev_kexec_supported(void);
#else
static inline void sev_es_ist_enter(struct pt_regs *regs) { }
static inline void sev_es_ist_exit(void) { }
@@ -246,6 +247,7 @@ static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
static inline u64 sev_get_status(void) { return 0; }
static inline void sev_es_stop_this_cpu(void) { }
+static inline bool sev_kexec_supported(void) { return true; }
#endif
#endif
@@ -28,6 +28,7 @@
#include <asm/setup.h>
#include <asm/set_memory.h>
#include <asm/cpu.h>
+#include <asm/sev.h>
#ifdef CONFIG_ACPI
/*
@@ -269,7 +270,7 @@ static void load_segments(void)
static bool machine_kexec_supported(void)
{
- if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
+ if (!sev_kexec_supported())
return false;
return true;
@@ -1456,6 +1456,21 @@ static void __init sev_es_setup_play_dead(void)
static inline void sev_es_setup_play_dead(void) { }
#endif
+bool sev_kexec_supported(void)
+{
+ if (!cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
+ return true;
+
+ /*
+ * KEXEC with SEV-ES and more than one CPU is only supported
+ * when the AP jump table is installed.
+ */
+ if (num_possible_cpus() > 1)
+ return sev_ap_jumptable_blob_installed;
+ else
+ return true;
+}
+
static void __init alloc_runtime_data(int cpu)
{
struct sev_es_runtime_data *data;